Merge branch 'server-1.3-branch' into xorg-server-1.2-apple

Conflicts:

	configure.ac
This commit is contained in:
Jeremy Huddleston 2007-11-19 20:27:52 -08:00
commit 3b0201f893
69 changed files with 3367 additions and 673 deletions

View File

@ -815,12 +815,16 @@ static Bool
glxDRIEnterVT (int index, int flags)
{
__GLXDRIscreen *screen = (__GLXDRIscreen *) __glXgetActiveScreen(index);
Bool ret;
LogMessage(X_INFO, "AIGLX: Resuming AIGLX clients after VT switch\n");
if (!(*screen->enterVT) (index, flags))
return FALSE;
glxResumeClients();
return (*screen->enterVT) (index, flags);
return TRUE;
}
static void

View File

@ -28,7 +28,7 @@
#include <X11/Xmd.h>
#include <GL/gl.h>
#include <GL/glxproto.h>
#ifdef __linux__
#if defined(__linux__) || defined (__GLIBC__) || defined(__GNU__)
#include <byteswap.h>
#elif defined(__OpenBSD__)
#include <sys/endian.h>

View File

@ -46,7 +46,7 @@
#include "dispatch.h"
#include "glapioffsets.h"
#ifdef __linux__
#if defined(__linux__) || defined (__GLIBC__) || defined(__GNU__)
#include <byteswap.h>
#elif defined(__OpenBSD__)
#include <sys/endian.h>

View File

@ -39,7 +39,7 @@
#include "glthread.h"
#include "dispatch.h"
#ifdef __linux__
#if defined(__linux__) || defined (__GLIBC__) || defined(__GNU__)
#include <byteswap.h>
#elif defined(__OpenBSD__)
#include <sys/endian.h>

View File

@ -40,7 +40,7 @@
#include "dispatch.h"
#include "glapioffsets.h"
#ifdef __linux__
#if defined(__linux__) || defined (__GLIBC__) || defined(__GNU__)
#include <byteswap.h>
#elif defined(__OpenBSD__)
#include <sys/endian.h>

View File

@ -42,6 +42,12 @@ from The Open Group.
#include <X11/extensions/xcmiscstr.h>
#include "modinit.h"
#if HAVE_STDINT_H
#include <stdint.h>
#elif !defined(UINT32_MAX)
#define UINT32_MAX 0xffffffffU
#endif
#if 0
static unsigned char XCMiscCode;
#endif
@ -143,7 +149,10 @@ ProcXCMiscGetXIDList(client)
REQUEST_SIZE_MATCH(xXCMiscGetXIDListReq);
pids = (XID *)ALLOCATE_LOCAL(stuff->count * sizeof(XID));
if (stuff->count > UINT32_MAX / sizeof(XID))
return BadAlloc;
pids = (XID *)Xalloc(stuff->count * sizeof(XID));
if (!pids)
{
return BadAlloc;
@ -164,7 +173,7 @@ ProcXCMiscGetXIDList(client)
client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
WriteSwappedDataToClient(client, count * sizeof(XID), pids);
}
DEALLOCATE_LOCAL(pids);
Xfree(pids);
return(client->noClientException);
}

View File

@ -28,11 +28,25 @@ dnl Process this file with autoconf to create configure.
AC_PREREQ(2.57)
dnl This is the not the Xorg version number, it's the server version number.
dnl Yes, that's weird.
AC_INIT([xorg-server], 1.2a11, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
AC_INIT([xorg-server], 1.3a1, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
AC_CONFIG_SRCDIR([Makefile.am])
AM_INIT_AUTOMAKE([dist-bzip2 foreign])
AM_MAINTAINER_MODE
dnl
dnl Make sure these line up with the version number above. Automatically
dnl extracting them would be cool.
dnl
DEFAULT_VENDOR_NAME="The X.Org Foundation"
DEFAULT_VENDOR_NAME_SHORT="X.Org"
DEFAULT_VERSION_MAJOR=1
DEFAULT_VERSION_MINOR=3
DEFAULT_VERSION_PATCH=0
DEFAULT_VERSION_SNAP=0
DEFAULT_RELEASE_DATE="19 April 2007"
DEFAULT_VENDOR_WEB="http://wiki.x.org"
dnl this gets generated by autoheader, and thus contains all the defines. we
dnl don't ever actually use it, internally.
AC_CONFIG_HEADERS(include/do-not-use-config.h)
@ -360,14 +374,6 @@ OSNAME=`uname -srm`
AC_DEFINE_UNQUOTED(OSNAME, "$OSNAME",
[Define to OS Name string to display for build OS in Xorg log])
DEFAULT_VENDOR_NAME="The X.Org Foundation"
DEFAULT_VENDOR_NAME_SHORT="X.Org"
DEFAULT_VERSION_MAJOR=7
DEFAULT_VERSION_MINOR=2
DEFAULT_VERSION_PATCH=0
DEFAULT_VERSION_SNAP=0
DEFAULT_RELEASE_DATE="22 January 2007"
DEFAULT_VENDOR_WEB="http://wiki.x.org"
m4_ifdef([AS_HELP_STRING], , [m4_define([AS_HELP_STRING], m4_defn([AC_HELP_STRING]))])
@ -940,7 +946,7 @@ PKG_CHECK_MODULES([XSERVERCFLAGS], [$REQUIRED_MODULES $REQUIRED_LIBS])
PKG_CHECK_MODULES([XSERVERLIBS], [$REQUIRED_LIBS])
XSERVER_CFLAGS="${XSERVERCFLAGS_CFLAGS}"
XSERVER_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} -lm"
XSERVER_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} ${LIBS}"
AC_SUBST([SYS_LIBS])
AC_CHECK_FUNCS([clock_gettime], [have_clock_gettime=yes],
@ -951,9 +957,9 @@ AC_MSG_CHECKING([for a useful monotonic clock ...])
if ! test "x$have_clock_gettime" = xno; then
if ! test "x$have_clock_gettime" = xyes; then
LIBS="$have_clock_gettime"
CLOCK_LIBS="$have_clock_gettime"
else
LIBS=""
CLOCK_LIBS=""
fi
AC_RUN_IFELSE([
@ -978,7 +984,8 @@ AC_MSG_RESULT([$MONOTONIC_CLOCK])
if test "x$MONOTONIC_CLOCK" = xyes; then
AC_DEFINE(MONOTONIC_CLOCK, 1, [Have monotonic clock from clock_gettime()])
XSERVER_LIBS="$XSERVER_LIBS $LIBS"
XSERVER_LIBS="$XSERVER_LIBS $CLOCK_LIBS"
LIBS="$LIBS $CLOCK_LIBS"
fi
dnl Imake defines SVR4 on SVR4 systems, and many files check for it, so
@ -1068,7 +1075,7 @@ AC_MSG_RESULT([$XVFB])
AM_CONDITIONAL(XVFB, [test "x$XVFB" = xyes])
if test "x$XVFB" = xyes; then
XVFB_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $CWRAP_LIB $OS_LIB"
XVFB_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $CWRAP_LIB $OS_LIB $LIBS"
AC_SUBST([XVFB_LIBS])
fi
@ -1084,7 +1091,7 @@ AC_MSG_RESULT([$XNEST])
AM_CONDITIONAL(XNEST, [test "x$XNEST" = xyes])
if test "x$XNEST" = xyes; then
XNEST_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $CWRAP_LIB $OS_LIB"
XNEST_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $CWRAP_LIB $OS_LIB $LIBS"
AC_SUBST([XNEST_LIBS])
fi

View File

@ -75,7 +75,8 @@ Bool
ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv)
{
int width = 640, height = 480;
unsigned long redMask, greenMask, blueMask;
if (hostx_want_screen_size(&width, &height)
|| !screen->width || !screen->height)
{
@ -127,30 +128,24 @@ ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv)
{
screen->fb[0].depth = 15;
screen->fb[0].bitsPerPixel = 16;
hostx_get_visual_masks (&screen->fb[0].redMask,
&screen->fb[0].greenMask,
&screen->fb[0].blueMask);
}
else if (screen->fb[0].depth <= 16)
{
screen->fb[0].depth = 16;
screen->fb[0].bitsPerPixel = 16;
hostx_get_visual_masks (&screen->fb[0].redMask,
&screen->fb[0].greenMask,
&screen->fb[0].blueMask);
}
else
{
screen->fb[0].depth = 24;
screen->fb[0].bitsPerPixel = 32;
hostx_get_visual_masks (&screen->fb[0].redMask,
&screen->fb[0].greenMask,
&screen->fb[0].blueMask);
}
hostx_get_visual_masks (&redMask, &greenMask, &blueMask);
screen->fb[0].redMask = (Pixel) redMask;
screen->fb[0].greenMask = (Pixel) greenMask;
screen->fb[0].blueMask = (Pixel) blueMask;
}
scrpriv->randr = screen->randr;
@ -675,6 +670,8 @@ ephyrRestore (KdCardInfo *card)
void
ephyrScreenFini (KdScreenInfo *screen)
{
xfree(screen->driver);
screen->driver = NULL;
}
/*

View File

@ -40,6 +40,7 @@
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <X11/extensions/XShm.h>
#include <X11/Xmd.h>
/*
* All xlib calls go here, which gets built as its own .a .
@ -79,7 +80,7 @@ static int HostXWantDamageDebug = 0;
extern KeySym EphyrKeymap[];
extern KeySym kdKeymap[];
extern CARD32 kdKeymap[];
extern int kdMinScanCode;
extern int kdMaxScanCode;
extern int kdMinKeyCode;

View File

@ -48,6 +48,7 @@ XORG_LIBS = \
parser/libxf86config.a \
dixmods/libdixmods.la \
modes/libxf86modes.a \
ramdac/libramdac.a \
ddc/libddc.a \
i2c/libi2c.a \
@XORG_LIBS@

View File

@ -118,7 +118,7 @@ extern int ffs(unsigned long);
# if defined(NO_INLINE) || defined(DO_PROTOTYPES)
# if !defined(__arm__)
# if !defined(__sparc__) && !defined(__arm32__) \
# if !defined(__sparc__) && !defined(__sparc) && !defined(__arm32__) \
&& !(defined(__alpha__) && defined(linux)) \
&& !(defined(__ia64__) && defined(linux)) \
@ -1697,7 +1697,7 @@ static __inline__ void ppc_flush_icache(char *addr)
: : "r"(addr) : "memory");
}
# elif defined(__sparc__) || defined(sparc)
# elif defined(__sparc__) || defined(sparc) || defined(__sparc)
/*
* Like powerpc, we provide byteswapping and no byteswapping functions
* here with byteswapping as default, drivers that don't need byteswapping

View File

@ -64,7 +64,7 @@ extern ScrnInfoPtr xf86CurrentScreen;
extern Bool pciSlotClaimed;
extern Bool isaSlotClaimed;
extern Bool fbSlotClaimed;
#ifdef __sparc__
#if defined(__sparc__) || defined(__sparc)
extern Bool sbusSlotClaimed;
#endif
extern confDRIRec xf86ConfigDRI;

View File

@ -113,7 +113,7 @@ void
xf86BusProbe(void)
{
xf86PciProbe();
#if defined(__sparc__) && !defined(__OpenBSD__)
#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
xf86SbusProbe();
#endif
}
@ -2373,7 +2373,7 @@ xf86PostProbe(void)
if (fbSlotClaimed) {
if (pciSlotClaimed || isaSlotClaimed
#if defined(__sparc__) && !defined(__OpenBSD__)
#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
|| sbusSlotClaimed
#endif
) {
@ -3006,7 +3006,7 @@ xf86FindPrimaryDevice()
}
#if !defined(__sparc__) && !defined(__powerpc__) && !defined(__mips__)
#if !defined(__sparc) && !defined(__sparc__) && !defined(__powerpc__) && !defined(__mips__)
#include "vgaHW.h"
#include "compiler.h"
#endif
@ -3018,7 +3018,7 @@ static void
CheckGenericGA()
{
/* This needs to be changed for multiple domains */
#if !defined(__sparc__) && !defined(__powerpc__) && !defined(__mips__) && !defined(__ia64__) && !defined(__arm__) && !defined(__s390__)
#if !defined(__sparc__) && !defined(__sparc) && !defined(__powerpc__) && !defined(__mips__) && !defined(__ia64__) && !defined(__arm__) && !defined(__s390__)
IOADDRESS GenericIOBase = VGAHW_GET_IOBASE();
CARD8 CurrentValue, TestValue;

View File

@ -40,7 +40,7 @@
#define _XF86_BUS_H
#include "xf86pciBus.h"
#ifdef __sparc__
#if defined(__sparc__) || defined(__sparc)
#include "xf86sbusBus.h"
#endif

View File

@ -48,7 +48,7 @@
#include "Configint.h"
#include "vbe.h"
#include "xf86DDC.h"
#if defined(__sparc__) && !defined(__OpenBSD__)
#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
#include "xf86Bus.h"
#include "xf86Sbus.h"
#endif
@ -57,7 +57,7 @@
typedef struct _DevToConfig {
GDevRec GDev;
pciVideoPtr pVideo;
#if defined(__sparc__) && !defined(__OpenBSD__)
#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
sbusDevicePtr sVideo;
#endif
int iDriver;
@ -134,7 +134,7 @@ xf86AddBusDeviceToConfigure(const char *driver, BusType bus, void *busData, int
if (!DevToConfig[i].pVideo)
return NULL;
break;
#if defined(__sparc__) && !defined(__OpenBSD__)
#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
case BUS_SBUS:
for (i = 0; i < nDevToConfig; i++)
if (DevToConfig[i].sVideo &&
@ -213,7 +213,7 @@ xf86AddBusDeviceToConfigure(const char *driver, BusType bus, void *busData, int
NewDevice.GDev.identifier = "ISA Adapter";
NewDevice.GDev.busID = "ISA";
break;
#if defined(__sparc__) && !defined(__OpenBSD__)
#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
case BUS_SBUS: {
char *promPath = NULL;
NewDevice.sVideo = (sbusDevicePtr) busData;

View File

@ -84,7 +84,7 @@ typedef enum {
* mask is 0xFFFF0000.
*/
#define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 3)
#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(1, 1)
#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(1, 2)
#define ABI_XINPUT_VERSION SET_ABI_VERSION(0, 7)
#define ABI_EXTENSION_VERSION SET_ABI_VERSION(0, 3)
#define ABI_FONT_VERSION SET_ABI_VERSION(0, 5)

View File

@ -92,6 +92,7 @@
#define PCI_VENDOR_TRITECH 0x1292
#define PCI_VENDOR_NVIDIA_SGS 0x12D2
#define PCI_VENDOR_VMWARE 0x15AD
#define PCI_VENDOR_AST 0x1A03
#define PCI_VENDOR_3DLABS 0x3D3D
#define PCI_VENDOR_AVANCE_2 0x4005
#define PCI_VENDOR_HERCULES 0x4843
@ -358,6 +359,9 @@
#define PCI_CHIP_RS350_7834 0x7834
#define PCI_CHIP_RS350_7835 0x7835
/* ASPEED Technology (AST) */
#define PCI_CHIP_AST2000 0x2000
/* Avance Logic */
#define PCI_CHIP_ALG2064 0x2064
#define PCI_CHIP_ALG2301 0x2301

View File

@ -974,6 +974,7 @@ xf86XVEnlistPortInWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
if(!winPriv) {
winPriv = xalloc(sizeof(XF86XVWindowRec));
if(!winPriv) return BadAlloc;
memset(winPriv, 0, sizeof(XF86XVWindowRec));
winPriv->PortRec = portPriv;
winPriv->next = PrivRoot;
pWin->devPrivates[XF86XVWindowIndex].ptr = (pointer)winPriv;
@ -1026,6 +1027,9 @@ xf86XVDestroyWindow(WindowPtr pWin)
pPriv->pDraw = NULL;
tmp = WinPriv;
if(WinPriv->pGC) {
FreeGC(WinPriv->pGC, 0);
}
WinPriv = WinPriv->next;
xfree(tmp);
}
@ -1118,6 +1122,8 @@ xf86XVClipNotify(WindowPtr pWin, int dx, int dy)
while(WinPriv) {
pPriv = WinPriv->PortRec;
if(!pPriv) goto next;
if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
REGION_DESTROY(pScreen, pPriv->pCompositeClip);
@ -1148,6 +1154,7 @@ xf86XVClipNotify(WindowPtr pWin, int dx, int dy)
}
}
next:
pPrev = WinPriv;
WinPriv = WinPriv->next;
}
@ -1739,9 +1746,13 @@ xf86XVPutImage(
REGION_UNINIT(pScreen, &VPReg);
}
if(portPriv->pDraw) {
/* 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;
@ -1772,7 +1783,6 @@ xf86XVPutImage(
if((ret == Success) &&
(portPriv->AdaptorRec->flags & VIDEO_OVERLAID_IMAGES)) {
xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
portPriv->isOn = XV_ON;
portPriv->pDraw = pDraw;
portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
@ -1813,6 +1823,56 @@ xf86XVQueryImageAttributes(
format->id, width, height, pitches, offsets);
}
_X_EXPORT 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);
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 = ALLOCATE_LOCAL(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);
DEALLOCATE_LOCAL(rects);
}
_X_EXPORT void
xf86XVFillKeyHelper (ScreenPtr pScreen, CARD32 key, RegionPtr clipboxes)
{

View File

@ -232,6 +232,9 @@ void xf86XVFreeVideoAdaptorRec(XF86VideoAdaptorPtr ptr);
void
xf86XVFillKeyHelper (ScreenPtr pScreen, CARD32 key, RegionPtr clipboxes);
void
xf86XVFillKeyHelperDrawable (DrawablePtr pDraw, CARD32 key, RegionPtr clipboxes);
Bool
xf86XVClipVideoHelper(
BoxPtr dst,

View File

@ -80,6 +80,7 @@ typedef struct {
typedef struct _XF86XVWindowRec{
XvPortRecPrivatePtr PortRec;
struct _XF86XVWindowRec *next;
GCPtr pGC;
} XF86XVWindowRec, *XF86XVWindowPtr;
#endif /* _XF86XVPRIV_H_ */

View File

@ -337,6 +337,12 @@ DDCRead_DDC2(int scrnIndex, I2CBusPtr pBus, int start, int len)
unsigned char *R_Buffer;
int i;
/*
* Slow down the bus so that older monitors don't
* miss things.
*/
pBus->RiseFallTime = 20;
if (!(dev = xf86I2CFindDev(pBus, 0x00A0))) {
dev = xf86CreateI2CDevRec();
dev->DevName = "ddc2";
@ -344,7 +350,6 @@ DDCRead_DDC2(int scrnIndex, I2CBusPtr pBus, int start, int len)
dev->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */
dev->StartTimeout = 550;
dev->BitTimeout = 40;
dev->ByteTimeout = 40;
dev->AcknTimeout = 40;
dev->pI2CBus = pBus;

474
hw/xfree86/doc/README.modes Normal file
View File

@ -0,0 +1,474 @@
Multi-monitor Mode Setting APIs
Keith Packard, <keithp@keithp.com
6 March 2007
1. Introduction
This document describes a set of mode setting APIs added in X server version
1.3 that support multiple monitors per card. These interfaces expose the
underlying hardware CRTC and output concepts to the xf86 DDX layer so that
the implementation of initial server setup and mode changes through
extensions can be shared across drivers. In addition, these new interfaces
support a new configuration mechanism as well which allows each monitor to
be customized separately providing a consistent cross-driver configuration
mechanism that supports the full range of output features.
All of the code implementing this interface can be found in hw/xfree86/modes
in the X server sources.
2. Overview
This document describes both the driver API and the configuration data
placed in xorg.conf; these are entirely separate as the driver has no
interaction with the configuration information at all. Much of the structure
here is cloned from the RandR extension version 1.2 additions which deal
with the same kinds of information.
2.1 API overview
The mode setting API is expressed through two new driver-visible objects,
the 'CRTC' (xf86CrtcRec) and the 'Output' (xf86OutputRec). A CRTC refers to
hardware within the video system that can scan a subset of the framebuffer
and generate a video signal. An Output receives that signal and transmits it
to a monitor, projector or other device.
The xf86CrtcRec and xf86OutputRec contain a small amount of state data
related to the object along with a pointer to a set of functions provided by
the driver that manipulate the object in fairly simple ways.
To emulate older behaviour, one of the outputs is picked as the 'compat'
output; this output changes over time as outputs are detected and used, the
goal is to always have one 'special' output which is used for operations
which need a single defined monitor (like XFree86-VidModeExtension mode
setting, RandR 1.1 mode setting, DDC property setting, etc.).
2.1.1 Output overview
As outputs are connected to monitors, they hold a list of modes supported by
the monitor. If the monitor and output support DDC, then the list of modes
generally comes from the EDID data in the monitor. Otherwise, the server
uses the standard VESA modes, pruned by monitor timing. If the configuration
file doesn't contain monitor timing data, the server uses default timing
information which supports 640x480, 800x600 and 1024x768 all with a 60Hz
refresh rate.
As hardware often limits possible configuration combinations, each output
knows the set of CRTCs that it can be connected to as well as the set of
other outputs which can be simutaneously connected to a CRTC.
2.1.2 CRTC overview
CRTCs serve only to stream frame buffer data to outputs using a mode line.
Ideally, they would not be presented to the user at all, and in fact the
configuration file doesn't expose them. The RandR 1.2 protocol does, but the
hope there is that client-side applications will hide them carefully away.
Each crtc has an associated cursor, along with the current configuration.
All of the data needed to determine valid configurations is contained within
the Outputs.
2.2 Configuration overview
As outputs drive monitors, the "Monitor" section has been repurposed to
define their configuration. This provides for a bit more syntax than
the large list of driver-specific options that were used in the past for
similar configuration.
However, the existing "Monitor" section referenced by the active "Screen"
section no longer has any use at all; some sensible meaning for this
parameter is needed now that a Screen can have multiple Monitors.
3. Public Functions
3.1 PreInit functions
These functions should be used during the driver PreInit phase, they are
arranged in the order they should be invoked.
void
xf86CrtcConfigInit (ScrnInfoPtr scrn
const xf86CrtcConfigFuncsRec *funcs)
This function allocates and initializes structures needed to track CRTC and
Output state.
void
xf86CrtcSetSizeRange (ScrnInfoPtr scrn,
int minWidth, int minHeight,
int maxWidth, int maxHeight)
This sets the range of screen sizes supported by the driver.
xf86CrtcPtr
xf86CrtcCreate (ScrnInfoPtr scrn,
const xf86CrtcFuncsRec *funcs)
Create one CRTC object. See the discussion below for a description of the
contents of the xf86CrtcFuncsRec. Note that this is done in PreInit, so it
should not be re-invoked at each server generation. Create one of these for
each CRTC present in the hardware.
xf86OutputPtr
xf86OutputCreate (ScrnInfoPtr scrn,
const xf86OutputFuncsRec *funcs,
const char *name)
Create one Output object. See the discussion below for a description of the
contents of the xf86OutputFuncsRec. This is also called from PreInit and
need not be re-invoked at each ScreenInit time. An Output should be created
for every Output present in the hardware, not just for outputs which have
detected monitors.
Bool
xf86OutputRename (xf86OutputPtr output, const char *name)
If necessary, the name of an output can be changed after it is created using
this function.
Bool
xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
Using the resources provided, and the configuration specified by the user,
this function computes an initial configuration for the server. It tries to
enable as much hardware as possible using some fairly simple heuristics.
The 'canGrow' parameter indicates that the frame buffer does not have a fixed
size (fixed size frame buffers are required by XAA). When the frame buffer
has a fixed size, the configuration selects a 'reasonablely large' frame
buffer so that common reconfiguration options are possible. For resizable
frame buffers, the frame buffer is set to the smallest size that encloses
the desired configuration.
3.2 ScreenInit functions
These functions should be used during the driver ScreenInit phase.
Bool
xf86DiDGAInit (ScreenPtr screen, unsigned long dga_address)
This function provides driver-independent accelerated DGA support for some
of the DGA operations; using this, the driver can avoid needing to implement
any of the rest of DGA.
Bool
xf86SaveScreen(ScreenPtr pScreen, int mode)
Stick this in pScreen->SaveScreen and the core X screen saver will be
implemented by disabling outputs and crtcs using their dpms functions.
void
xf86DPMSSet(ScrnInfoPtr scrn, int mode, int flags)
Pass this function to xf86DPMSInit and all DPMS mode switching will be
managed by using the dpms functions provided by the Outputs and CRTCs.
Bool
xf86CrtcScreenInit (ScreenPtr screen)
This function completes the screen initialization process for the crtc and
output objects. Call it near the end of the ScreenInit function, after the
frame buffer and acceleration layers have been added.
3.3 EnterVT functions
Functions used during EnterVT, or whenever the current configuration needs
to be applied to the hardware.
Bool
xf86SetDesiredModes (ScrnInfoPtr scrn)
xf86InitialConfiguration selects the desired configuration at PreInit time;
when the server finally hits ScreenInit, xf86SetDesiredModes is used by the
driver to take that configuration and apply it to the hardware. In addition,
successful mode selection at other times updates the configuration that will
be used by this function, so LeaveVT/EnterVT pairs can simply invoke this
and return to the previous configuration.
3.4 SwitchMode functions
Functions called from the pScrn->SwitchMode hook, which is used by the
XFree86-VidModeExtension and the keypad mode switch commands.
Bool
xf86SetSingleMode (ScrnInfoPtr scrn,
DisplayModePtr desired,
Rotation rotation)
This function applies the specified mode to all active outputs. Which is to
say, it picks reasonable modes for all active outputs, attempting to get the
screen to the specified size while not breaking anything that is currently
working.
3.7 get_modes functions
Functions called during output->get_modes to help build lists of modes
xf86MonPtr
xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus)
This returns the EDID data structure for the 'output' using the I2C bus
'pDDCBus'. This has no effect on 'output' itself.
void
xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon)
Once the EDID data has been fetched, this call applies the EDID data to the
output object, setting the physical size and also various properties, like
the DDC root window property (when output is the 'compat' output), and the
RandR 1.2 EDID output properties.
DisplayModePtr
xf86OutputGetEDIDModes (xf86OutputPtr output)
Given an EDID data structure, this function computes a list of suitable
modes. This function also applies a sequence of 'quirks' during this process
so that the returned modes may not actually match the mode data present in
the EDID data.
3.6 Other functions
These remaining functions in the API can be used by the driver as needed.
Bool
xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
int x, int y)
Applies a mode to a CRTC. All of the outputs which are currently using the
specified CRTC are included in the mode setting process. 'x' and 'y' are the
offset within the frame buffer that the crtc is placed at. No checking is
done in this function to ensure that the mode is usable by the active
outputs.
void
xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY)
This discards the mode lists for all outputs, re-detects monitor presence
and then acquires new mode lists for all monitors which are not disconnected.
Monitor configuration data is used to modify the mode lists returned by the
outputs. 'maxX' and 'maxY' limit the maximum size modes that will be
returned.
void
xf86SetScrnInfoModes (ScrnInfoPtr pScrn)
This copies the 'compat' output mode list into the pScrn modes list which is
used by the XFree86-VidModeExtension and the keypad mode switching
operations. The current 'desired' mode for the CRTC associated with the
'compat' output is placed first in this list to indicate the current mode.
Usually, the driver won't need to call this function as
xf86InitialConfiguration will do so automatically, as well as any RandR
functions which reprobe for modes. However, if the driver reprobes for modes
at other times using xf86ProbeOutputModes, this function needs to be called.
Bool
xf86DiDGAReInit (ScreenPtr pScreen)
This is similar to xf86SetScrnInfoModes, but it applies the 'compat' output
mode list to the set of modes advertised by the DGA extension; it needs to
be called whenever xf86ProbeOutputModes is invoked.
void
xf86DisableUnusedFunctions(ScrnInfoPtr pScrn)
After any sequence of calls using xf86CrtcSetMode, this function cleans up
any leftover Output and CRTC objects by disabling them, saving power. It is
safe to call this whenever the server is running as it only disables objects
which are not currently in use.
4. CRTC operations
4.1 CRTC functions
These functions provide an abstract interface for the CRTC object; most
manipulation of the CRTC object is done through these functions.
void
crtc->funcs->dpms (xf86CrtcPtr crtc, int mode)
Where 'mode' is one of DPMSModeOff, DPMSModeSuspend, DPMSModeStandby or
DPMSModeOn. This requests that the crtc go to the specified power state.
When changing power states, the output dpms functions are invoked before the
crtc dpms functions.
void
crtc->funcs->save (xf86CrtcPtr crtc)
void
crtc->funcs->restore (xf86CrtcPtr crtc)
Preserve/restore any register contents related to the CRTC. These are
strictly a convenience for the driver writer; if the existing driver has
fully operation save/restore functions, you need not place any additional
code here. In particular, the server itself never uses this function.
Bool
crtc->funcs->lock (xf86CrtcPtr crtc)
void
crtc->funcs->unlock (xf86CrtcPtr crtc)
These functions are invoked around mode setting operations; the intent is
that DRI locking be done here to prevent DRI applications from manipulating
the hardware while the server is busy changing the output configuration. If
the lock function returns FALSE, the unlock function will not be invoked.
Bool
crtc->funcs->mode_fixup (xf86CrtcPtr crtc,
DisplayModePtr mode,
DisplayModePtr adjusted_mode)
This call gives the CRTC a chance to see what mode will be set and to
comment on the mode by changing 'adjusted_mode' as needed. This function
shall not modify the state of the crtc hardware at all. If the CRTC cannot
accept this mode, this function may return FALSE.
void
crtc->funcs->prepare (xf86CrtcPtr crtc)
This call is made just before the mode is set to make the hardware ready for
the operation. A usual function to perform here is to disable the crtc so
that mode setting can occur with clocks turned off and outputs deactivated.
void
crtc->funcs->mode_set (xf86CrtcPtr crtc,
DisplayModePtr mode,
DisplayModePtr adjusted_mode)
This function applies the specified mode (possibly adjusted by the CRTC
and/or Outputs).
void
crtc->funcs->commit (xf86CrtcPtr crtc)
Once the mode has been applied to the CRTC and Outputs, this function is
invoked to let the hardware turn things back on.
void
crtc->funcs->gamma_set (xf86CrtcPtr crtc, CARD16 *red,
CARD16 *green, CARD16 *blue, int size)
This function adjusts the gamma ramps for the specified crtc.
void *
crtc->funcs->shadow_allocate (xf86CrtcPtr crtc, int width, int height)
This function allocates frame buffer space for a shadow frame buffer. When
allocated, the crtc must scan from the shadow instead of the main frame
buffer. This is used for rotation. The address returned is passed to the
shadow_create function. This function should return NULL on failure.
PixmapPtr
crtc->funcs->shadow_create (xf86CrtcPtr crtc, void *data,
int width, int height)
This function creates a pixmap object that will be used as a shadow of the
main frame buffer for CRTCs which are rotated or reflected. 'data' is the
value returned by shadow_allocate.
void
crtc->funcs->shadow_destroy (xf86CrtcPtr crtc, PixmapPtr pPixmap,
void *data)
Destroys any associated shadow objects. If pPixmap is NULL, then a pixmap
was not created, but 'data' may still be non-NULL indicating that the shadow
had been allocated.
void
crtc->funcs->destroy (xf86CrtcPtr crtc)
When a CRTC is destroyed (which only happens in error cases), this function
can clean up any driver-specific data.
4.2 CRTC fields
The CRTC object is not opaque; there are several fields of interest to the
driver writer.
struct _xf86Crtc {
/**
* Associated ScrnInfo
*/
ScrnInfoPtr scrn;
/**
* Active state of this CRTC
*
* Set when this CRTC is driving one or more outputs
*/
Bool enabled;
/** Track whether cursor is within CRTC range */
Bool cursorInRange;
/** Track state of cursor associated with this CRTC */
Bool cursorShown;
/**
* Active mode
*
* This reflects the mode as set in the CRTC currently
* It will be cleared when the VT is not active or
* during server startup
*/
DisplayModeRec mode;
Rotation rotation;
PixmapPtr rotatedPixmap;
void *rotatedData;
/**
* Position on screen
*
* Locates this CRTC within the frame buffer
*/
int x, y;
/**
* Desired mode
*
* This is set to the requested mode, independent of
* whether the VT is active. In particular, it receives
* the startup configured mode and saves the active mode
* on VT switch.
*/
DisplayModeRec desiredMode;
Rotation desiredRotation;
int desiredX, desiredY;
/** crtc-specific functions */
const xf86CrtcFuncsRec *funcs;
/**
* Driver private
*
* Holds driver-private information
*/
void *driver_private;
#ifdef RANDR_12_INTERFACE
/**
* RandR crtc
*
* When RandR 1.2 is available, this
* points at the associated crtc object
*/
RRCrtcPtr randr_crtc;
#else
void *randr_crtc;
#endif
};
5. Output functions.
6. Configuration
Because the configuration file syntax is fixed,
this was done by creating new "Driver" section options that hook specific
outputs to specific "Monitor" sections in the file. The option:
section of the form:
Option "monitor-VGA" "My VGA Monitor"
connects the VGA output of this driver to the "Monitor" section with
Identifier "My VGA Monitor". All of the usual monitor options can now be
placed in that "Monitor" section and will be applied to the VGA output
configuration.

View File

@ -183,12 +183,20 @@ print_xfree_mode(char *txt, DisplayModePtr mode)
static void
xfree2fbdev_fblayout(ScrnInfoPtr pScrn, struct fb_var_screeninfo *var)
{
var->xres_virtual = pScrn->virtualX;
var->xres_virtual = pScrn->displayWidth ? pScrn->displayWidth :
pScrn->virtualX;
var->yres_virtual = pScrn->virtualY;
var->bits_per_pixel = pScrn->bitsPerPixel;
var->red.length = pScrn->weight.red;
var->green.length = pScrn->weight.green;
var->blue.length = pScrn->weight.blue;
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
@ -227,6 +235,26 @@ xfree2fbdev_timing(DisplayModePtr mode, struct fb_var_screeninfo *var)
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->pixclock == req->pixclock &&
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)
{
@ -470,13 +498,53 @@ fbdevHWGetVidmem(ScrnInfoPtr 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)
{
fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
int virtX = pScrn->display->virtualX;
int virtY = pScrn->display->virtualY;
struct fb_var_screeninfo var;
char **modename;
DisplayModePtr mode,this,last = pScrn->modes;
@ -484,6 +552,9 @@ fbdevHWSetVideoModes(ScrnInfoPtr pScrn)
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))
@ -493,27 +564,20 @@ fbdevHWSetVideoModes(ScrnInfoPtr pScrn)
"\tmode \"%s\" not found\n", *modename);
continue;
}
memset(&var,0,sizeof(var));
xfree2fbdev_timing(mode,&var);
var.xres_virtual = virtX;
var.yres_virtual = virtY;
var.bits_per_pixel = pScrn->bitsPerPixel;
var.red.length = pScrn->weight.red;
var.green.length = pScrn->weight.green;
var.blue.length = pScrn->weight.blue;
var.activate = FB_ACTIVATE_TEST;
if (var.xres_virtual < var.xres) var.xres_virtual = var.xres;
if (var.yres_virtual < var.yres) var.yres_virtual = var.yres;
if (-1 == ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&var))) {
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 (virtX < var.xres) virtX = var.xres;
if (virtY < var.yres) virtY = var.yres;
if (pScrn->virtualX < mode->HDisplay)
pScrn->virtualX = mode->HDisplay;
if (pScrn->virtualY < mode->VDisplay)
pScrn->virtualY = mode->VDisplay;
if (NULL == pScrn->modes) {
pScrn->modes = xnfalloc(sizeof(DisplayModeRec));
this = pScrn->modes;
@ -530,8 +594,6 @@ fbdevHWSetVideoModes(ScrnInfoPtr pScrn)
}
last = this;
}
pScrn->virtualX = virtX;
pScrn->virtualY = virtY;
}
DisplayModePtr
@ -673,21 +735,12 @@ fbdevHWModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
{
fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
TRACE_ENTER("ModeInit");
xfree2fbdev_fblayout(pScrn, &fPtr->var);
xfree2fbdev_timing(mode, &fPtr->var);
#if DEBUG
print_xfree_mode("init",mode);
print_fbdev_mode("init",&fPtr->var);
#endif
pScrn->vtSema = TRUE;
/* set */
if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
if (!fbdevHWSetMode(pScrn, mode, FALSE))
return FALSE;
}
/* read back */
if (0 != ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@ -699,6 +752,20 @@ fbdevHWModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
"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;
}
@ -767,18 +834,12 @@ ModeStatus
fbdevHWValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
struct fb_var_screeninfo var;
TRACE_ENTER("ValidMode");
memcpy(&var,&fPtr->var,sizeof(var));
xfree2fbdev_timing(mode, &var);
var.activate = FB_ACTIVATE_TEST;
if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) {
xf86DrvMsg(scrnIndex, X_ERROR,
"FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
if (!fbdevHWSetMode(pScrn, mode, TRUE))
return MODE_BAD;
}
return MODE_OK;
}
@ -786,15 +847,12 @@ Bool
fbdevHWSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
TRACE_ENTER("SwitchMode");
xfree2fbdev_timing(mode, &fPtr->var);
if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) {
xf86DrvMsg(scrnIndex, X_ERROR,
"FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
if (!fbdevHWSetMode(pScrn, mode, FALSE))
return FALSE;
}
return TRUE;
}

View File

@ -1,4 +1,4 @@
module_LIBRARIES = libi2c.a
noinst_LIBRARIES = libi2c.a
multimediadir = $(moduledir)/multimedia
multimedia_LTLIBRARIES = \

View File

@ -2,7 +2,8 @@ noinst_LIBRARIES = libloader.a
INCLUDES = $(XORG_INCS) -I$(srcdir)/../parser -I$(srcdir)/../dixmods/extmod \
-I$(srcdir)/../vbe -I$(top_srcdir)/miext/cw -I$(srcdir)/../int10 \
-I$(srcdir)/../ddc -I$(srcdir)/../i2c -I$(srcdir)/../modes
-I$(srcdir)/../ddc -I$(srcdir)/../i2c -I$(srcdir)/../modes \
-I$(srcdir)/../ramdac
#AM_LDFLAGS = -r
AM_CFLAGS = -DIN_LOADER $(XORG_CFLAGS)

View File

@ -841,6 +841,7 @@ DuplicateModule(ModuleDescPtr mod, ModuleDescPtr parent)
static const char *compiled_in_modules[] = {
"ddc",
"i2c",
"ramdac",
NULL
};
@ -861,14 +862,14 @@ doLoadModule(const char *module, const char *path, const char **subdirlist,
PatternPtr patterns = NULL;
int noncanonical = 0;
char *m = NULL;
char **cim;
const char **cim;
xf86MsgVerb(X_INFO, 3, "LoadModule: \"%s\"", module);
for (cim = compiled_in_modules; *cim; cim++)
if (!strcmp (module, *cim))
{
xf86MsgVerb(X_INFO, 3, "Module alread ybuilt-in");
xf86MsgVerb(X_INFO, 0, "Module already built-in\n");
return (ModuleDescPtr) 1;
}

View File

@ -510,7 +510,7 @@ _X_HIDDEN void *xfree86LookupTab[] = {
SYMFUNC(xf86AddModuleInfo)
SYMFUNC(xf86DeleteModuleInfo)
#if defined(__sparc__) && !defined(__OpenBSD__)
#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
/* xf86sbusBus.c */
SYMFUNC(xf86MatchSbusInstances)
SYMFUNC(xf86GetSbusInfoForEntity)
@ -632,6 +632,7 @@ _X_HIDDEN void *xfree86LookupTab[] = {
SYMFUNC(xf86XVAllocateVideoAdaptorRec)
SYMFUNC(xf86XVFreeVideoAdaptorRec)
SYMFUNC(xf86XVFillKeyHelper)
SYMFUNC(xf86XVFillKeyHelperDrawable)
SYMFUNC(xf86XVClipVideoHelper)
SYMFUNC(xf86XVCopyYUV12ToPacked)
SYMFUNC(xf86XVCopyPacked)
@ -1180,6 +1181,7 @@ _X_HIDDEN void *xfree86LookupTab[] = {
SYMVAR(pciNumBuses)
/* modes */
SYMVAR(xf86CrtcConfigPrivateIndex)
SYMFUNC(xf86CrtcConfigInit)
SYMFUNC(xf86CrtcConfigPrivateIndex)
SYMFUNC(xf86CrtcCreate)
@ -1230,6 +1232,11 @@ _X_HIDDEN void *xfree86LookupTab[] = {
SYMFUNC(xf86RandR12SetConfig)
SYMFUNC(xf86RandR12SetRotations)
#endif
SYMFUNC(xf86_cursors_init)
SYMFUNC(xf86_reload_cursors)
SYMFUNC(xf86_show_cursors)
SYMFUNC(xf86_hide_cursors)
SYMFUNC(xf86_cursors_fini)
SYMFUNC(xf86DoEDID_DDC1)
SYMFUNC(xf86DoEDID_DDC2)

View File

@ -3,6 +3,7 @@ noinst_LIBRARIES = libxf86modes.a
libxf86modes_a_SOURCES = \
xf86Crtc.c \
xf86Crtc.h \
xf86Cursors.c \
xf86cvt.c \
xf86DiDGA.c \
xf86EdidModes.c \
@ -16,7 +17,8 @@ libxf86modes_a_SOURCES = \
INCLUDES = $(XORG_INCS) -I$(srcdir)/../ddc -I$(srcdir)/../i2c \
-I$(srcdir)/../loader -I$(srcdir)/../rac -I$(srcdir)/../parser \
-I$(srcdir)/../scanpci -I$(srcdir)/../vbe -I$(srcdir)/../int10 \
-I$(srcdir)/../vgahw -I$(srcdir)/../dixmods/extmod
-I$(srcdir)/../vgahw -I$(srcdir)/../ramdac \
-I$(srcdir)/../dixmods/extmod
sdk_HEADERS = \
xf86Crtc.h \

View File

@ -22,6 +22,10 @@
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#else
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#endif
#include <stddef.h>
@ -37,6 +41,9 @@
#define DPMS_SERVER
#include "X11/extensions/dpms.h"
#include "X11/Xatom.h"
#ifdef RENDER
#include "picturestr.h"
#endif
/*
* Initialize xf86CrtcConfig structure
@ -45,13 +52,17 @@
int xf86CrtcConfigPrivateIndex = -1;
void
xf86CrtcConfigInit (ScrnInfoPtr scrn)
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;
}
@ -140,6 +151,71 @@ xf86CrtcInUse (xf86CrtcPtr crtc)
return FALSE;
}
void
xf86CrtcSetScreenSubpixelOrder (ScreenPtr pScreen)
{
#ifdef RENDER
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);
#endif
}
/**
* Sets the given video mode on the given crtc
*/
@ -157,8 +233,6 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
int saved_x, saved_y;
Rotation saved_rotation;
adjusted_mode = xf86DuplicateMode(mode);
crtc->enabled = xf86CrtcInUse (crtc);
if (!crtc->enabled)
@ -167,6 +241,8 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
return TRUE;
}
adjusted_mode = xf86DuplicateMode(mode);
didLock = crtc->funcs->lock (crtc);
saved_mode = crtc->mode;
@ -206,7 +282,7 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
goto done;
}
/* Disable the outputs and CRTCs before setting the mode. */
/* Prepare the outputs and CRTCs before setting the mode. */
for (i = 0; i < xf86_config->num_output; i++) {
xf86OutputPtr output = xf86_config->output[i];
@ -214,10 +290,10 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
continue;
/* Disable the output as the first thing we do. */
output->funcs->dpms(output, DPMSModeOff);
output->funcs->prepare(output);
}
crtc->funcs->dpms(crtc, DPMSModeOff);
crtc->funcs->prepare(crtc);
/* Set up the DPLL and any output state that needs to adjust or depend
* on the DPLL.
@ -231,16 +307,25 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
}
/* Now, enable the clocks, plane, pipe, and outputs that we set up. */
crtc->funcs->dpms(crtc, DPMSModeOn);
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->dpms(output, DPMSModeOn);
{
output->funcs->commit(output);
#ifdef RANDR_12_INTERFACE
if (output->randr_output)
RRPostPendingProperties (output->randr_output);
#endif
}
}
/* XXX free adjustedmode */
ret = TRUE;
if (scrn->pScreen)
xf86CrtcSetScreenSubpixelOrder (scrn->pScreen);
done:
if (!ret) {
crtc->x = saved_x;
@ -273,6 +358,7 @@ typedef enum {
OPTION_MIN_CLOCK,
OPTION_MAX_CLOCK,
OPTION_IGNORE,
OPTION_ROTATE,
} OutputOpts;
static OptionInfoRec xf86OutputOptions[] = {
@ -287,6 +373,7 @@ static OptionInfoRec xf86OutputOptions[] = {
{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 },
{-1, NULL, OPTV_NONE, {0}, FALSE },
};
@ -318,22 +405,51 @@ xf86OutputSetMonitor (xf86OutputPtr output)
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)
xf86OutputEnabled (xf86OutputPtr output)
{
/* Check to see if this output was disabled in the config file */
if (xf86ReturnOptValBool (output->options, OPTION_ENABLE, TRUE) == FALSE ||
xf86ReturnOptValBool (output->options, OPTION_DISABLE, FALSE) == TRUE)
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;
}
return TRUE;
/* otherwise, enable if it is not disconnected */
enable = output->status != XF86OutputStatusDisconnected;
xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
"Output %s %sconnected\n", output->name, enable ? "" : "dis");
return enable;
}
static Bool
@ -342,9 +458,32 @@ 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 xf86OutputFuncsRec *funcs,
const char *name)
{
xf86OutputPtr output, *outputs;
@ -367,6 +506,10 @@ xf86OutputCreate (ScrnInfoPtr scrn,
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
@ -417,6 +560,16 @@ xf86OutputRename (xf86OutputPtr output, const char *name)
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)
{
@ -441,6 +594,93 @@ xf86OutputDestroy (xf86OutputPtr output)
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
*/
Bool
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);
else
xf86RandR12SetRotations (screen, RR_Rotate_0);
/* Wrap CreateScreenResources so we can initialize the RandR code */
config->CreateScreenResources = screen->CreateScreenResources;
screen->CreateScreenResources = xf86CrtcCreateScreenResources;
config->CloseScreen = screen->CloseScreen;
screen->CloseScreen = xf86CrtcCloseScreen;
return TRUE;
}
static DisplayModePtr
xf86DefaultMode (xf86OutputPtr output, int width, int height)
{
@ -462,8 +702,12 @@ xf86DefaultMode (xf86OutputPtr output, int width, int height)
int preferred = (mode->type & M_T_PREFERRED) != 0;
int diff;
if (mode->HDisplay > width || mode->VDisplay > height) continue;
dpi = (mode->HDisplay * 254) / (mm_height * 10);
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 - 96;
diff = diff < 0 ? -diff : diff;
if (target_mode == NULL || (preferred > target_preferred) ||
@ -478,7 +722,8 @@ xf86DefaultMode (xf86OutputPtr output, int width, int height)
}
static DisplayModePtr
xf86ClosestMode (xf86OutputPtr output, DisplayModePtr match,
xf86ClosestMode (xf86OutputPtr output,
DisplayModePtr match, Rotation match_rotation,
int width, int height)
{
DisplayModePtr target_mode = NULL;
@ -493,14 +738,17 @@ xf86ClosestMode (xf86OutputPtr output, DisplayModePtr match,
int dx, dy;
int diff;
if (mode->HDisplay > width || mode->VDisplay > height) continue;
if (xf86ModeWidth (mode, output->initial_rotation) > width ||
xf86ModeHeight (mode, output->initial_rotation) > height)
continue;
/* exact matches are preferred */
if (xf86ModesEqual (mode, match))
if (output->initial_rotation == match_rotation &&
xf86ModesEqual (mode, match))
return mode;
dx = match->HDisplay - mode->HDisplay;
dy = match->VDisplay - mode->VDisplay;
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)
{
@ -518,7 +766,10 @@ xf86OutputHasPreferredMode (xf86OutputPtr output, int width, int height)
for (mode = output->probed_modes; mode; mode = mode->next)
{
if (mode->HDisplay > width || mode->VDisplay > height) continue;
if (xf86ModeWidth (mode, output->initial_rotation) > width ||
xf86ModeHeight (mode, output->initial_rotation) > height)
continue;
if (mode->type & M_T_PREFERRED)
return TRUE;
}
@ -534,7 +785,7 @@ xf86PickCrtcs (ScrnInfoPtr scrn,
int height)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int c, o, l;
int c, o;
xf86OutputPtr output;
xf86CrtcPtr crtc;
xf86CrtcPtr *crtcs;
@ -592,13 +843,11 @@ xf86PickCrtcs (ScrnInfoPtr scrn,
* see if they can be cloned
*/
if (xf86ModesEqual (modes[o], modes[n]) &&
config->output[0]->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)
{
for (l = 0; l < config->num_output; l++)
if (output->possible_clones & (1 << l))
break;
if (l == config->num_output)
if ((output->possible_clones & (1 << o)) == 0)
continue; /* nope, try next CRTC */
}
else
@ -621,12 +870,16 @@ xf86PickCrtcs (ScrnInfoPtr scrn,
/*
* Compute the virtual size necessary to place all of the available
* crtcs in the specified configuration and also large enough to
* resize any crtc to the largest available mode
* 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)
xf86DefaultScreenLimits (ScrnInfoPtr scrn, int *widthp, int *heightp,
Bool canGrow)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int width = 0, height = 0;
@ -641,25 +894,31 @@ xf86DefaultScreenLimits (ScrnInfoPtr scrn, int *widthp, int *heightp)
if (crtc->enabled)
{
crtc_width = crtc->x + crtc->desiredMode.HDisplay;
crtc_height = crtc->y + crtc->desiredMode.VDisplay;
crtc_width = crtc->x + xf86ModeWidth (&crtc->desiredMode, crtc->desiredRotation);
crtc_height = crtc->y + xf86ModeHeight (&crtc->desiredMode, crtc->desiredRotation);
}
for (o = 0; o < config->num_output; o++)
{
xf86OutputPtr output = config->output[o];
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)
for (s = 0; s < config->num_crtc; s++)
if (output->possible_crtcs & (1 << s))
{
if (mode->HDisplay > crtc_width)
crtc_width = mode->HDisplay;
if (mode->VDisplay > crtc_height)
crtc_height = mode->VDisplay;
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;
@ -756,13 +1015,17 @@ xf86InitialOutputPositions (ScrnInfoPtr scrn, DisplayModePtr *modes)
{
xf86OutputPtr out_rel = config->output[or];
XF86ConfMonitorPtr rel_mon = out_rel->conf_monitor;
char *name;
if (rel_mon)
name = rel_mon->mon_identifier;
else
name = out_rel->name;
if (!strcmp (relative_name, name))
{
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;
@ -787,16 +1050,16 @@ xf86InitialOutputPositions (ScrnInfoPtr scrn, DisplayModePtr *modes)
output->initial_y = relative->initial_y;
switch (relation) {
case OPTION_BELOW:
output->initial_y += modes[or]->VDisplay;
output->initial_y += xf86ModeHeight (modes[or], relative->initial_rotation);
break;
case OPTION_RIGHT_OF:
output->initial_x += modes[or]->HDisplay;
output->initial_x += xf86ModeWidth (modes[or], relative->initial_rotation);
break;
case OPTION_ABOVE:
output->initial_y -= modes[o]->VDisplay;
output->initial_y -= xf86ModeHeight (modes[or], relative->initial_rotation);
break;
case OPTION_LEFT_OF:
output->initial_x -= modes[o]->HDisplay;
output->initial_x -= xf86ModeWidth (modes[or], relative->initial_rotation);
break;
default:
break;
@ -976,8 +1239,11 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
*/
output->status = (*output->funcs->detect)(output);
if (output->status == XF86OutputStatusDisconnected)
if (!xf86OutputEnabled (output))
{
xf86OutputSetEDID (output, NULL);
continue;
}
memset (&mon_rec, '\0', sizeof (mon_rec));
@ -1137,6 +1403,8 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
}
}
output->initial_rotation = xf86OutputInitialRotation (output);
#ifdef DEBUG_REPROBE
if (output->probed_modes != NULL) {
xf86DrvMsg(scrn->scrnIndex, X_INFO,
@ -1231,14 +1499,22 @@ xf86SetScrnInfoModes (ScrnInfoPtr scrn)
*
* 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)
xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int o, c;
DisplayModePtr target_mode = NULL;
Rotation target_rotation = RR_Rotate_0;
xf86CrtcPtr *crtcs;
DisplayModePtr *modes;
Bool *enabled;
@ -1265,8 +1541,7 @@ xf86InitialConfiguration (ScrnInfoPtr scrn)
xf86OutputPtr output = config->output[o];
modes[o] = NULL;
enabled[o] = (xf86OutputEnabled (output) &&
output->status != XF86OutputStatusDisconnected);
enabled[o] = xf86OutputEnabled (output);
}
/*
@ -1280,6 +1555,7 @@ xf86InitialConfiguration (ScrnInfoPtr scrn)
xf86OutputHasPreferredMode (output, width, height))
{
target_mode = xf86DefaultMode (output, width, height);
target_rotation = output->initial_rotation;
if (target_mode)
{
modes[o] = target_mode;
@ -1296,6 +1572,7 @@ xf86InitialConfiguration (ScrnInfoPtr scrn)
if (enabled[o])
{
target_mode = xf86DefaultMode (output, width, height);
target_rotation = output->initial_rotation;
if (target_mode)
{
modes[o] = target_mode;
@ -1309,8 +1586,20 @@ xf86InitialConfiguration (ScrnInfoPtr scrn)
{
xf86OutputPtr output = config->output[o];
if (enabled[o] && !modes[o])
modes[o] = xf86ClosestMode (output, target_mode, width, height);
if (enabled[o])
{
if (!modes[o])
modes[o] = xf86ClosestMode (output, target_mode,
target_rotation, width, height);
if (!modes[o])
xf86DrvMsg (scrn->scrnIndex, X_ERROR,
"Output %s enabled but has no modes\n",
output->name);
else
xf86DrvMsg (scrn->scrnIndex, X_INFO,
"Output %s using initial mode %s\n",
output->name, modes[o]->name);
}
}
/*
@ -1358,6 +1647,9 @@ xf86InitialConfiguration (ScrnInfoPtr scrn)
if (mode && crtc)
{
crtc->desiredMode = *mode;
crtc->desiredRotation = output->initial_rotation;
crtc->desiredX = output->initial_x;
crtc->desiredY = output->initial_y;
crtc->enabled = TRUE;
crtc->x = output->initial_x;
crtc->y = output->initial_y;
@ -1368,9 +1660,10 @@ xf86InitialConfiguration (ScrnInfoPtr scrn)
if (scrn->display->virtualX == 0)
{
/*
* Expand virtual size to cover potential mode switches
* 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);
xf86DefaultScreenLimits (scrn, &width, &height, canGrow);
scrn->display->virtualX = width;
scrn->display->virtualY = height;
@ -1380,7 +1673,23 @@ xf86InitialConfiguration (ScrnInfoPtr scrn)
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);
@ -1389,6 +1698,202 @@ xf86InitialConfiguration (ScrnInfoPtr scrn)
return TRUE;
}
/*
* 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);
int c;
for (c = 0; c < config->num_crtc; c++)
{
xf86CrtcPtr crtc = config->crtc[c];
xf86OutputPtr output = NULL;
int o;
if (config->output[config->compat_output]->crtc == crtc)
output = config->output[config->compat_output];
else
{
for (o = 0; o < config->num_output; o++)
if (config->output[o]->crtc == crtc)
{
output = config->output[o];
break;
}
}
/*
* Skip disabled crtcs
*/
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->desiredX = 0;
crtc->desiredY = 0;
}
if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation,
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 = config->output[config->compat_output];
DisplayModePtr compat_mode;
int c;
/*
* Let the compat output drive the final mode selection
*/
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 (!xf86CrtcSetMode (crtc, crtc_mode, rotation, 0, 0))
ok = FALSE;
else
{
crtc->desiredMode = *crtc_mode;
crtc->desiredRotation = rotation;
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.
*
@ -1492,7 +1997,7 @@ xf86OutputSetEDIDProperty (xf86OutputPtr output, void *data, int data_len)
if (data_len != 0) {
RRChangeOutputProperty(output->randr_output, edid_atom, XA_INTEGER, 8,
PropModeReplace, data_len, data, FALSE);
PropModeReplace, data_len, data, FALSE, TRUE);
} else {
RRDeleteOutputProperty(output->randr_output, edid_atom);
}
@ -1585,3 +2090,12 @@ xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus)
return xf86DoEDID_DDC2 (scrn->scrnIndex, pDDCBus);
}
static char *_xf86ConnectorNames[] = { "None", "VGA", "DVI-I", "DVI-D",
"DVI-A", "Composite", "S-Video",
"Component", "LFP", "Proprietary" };
char *
xf86ConnectorGetName(xf86ConnectorType connector)
{
return _xf86ConnectorNames[connector];
}

View File

@ -28,7 +28,7 @@
#include "xf86Rename.h"
#endif
#include "xf86Modes.h"
#include "xf86Parser.h"
#include "xf86Cursor.h"
#include "damage.h"
/* Compat definitions for older X Servers. */
@ -38,10 +38,27 @@
#ifndef M_T_DRIVER
#define M_T_DRIVER 0x40
#endif
#ifndef HARDWARE_CURSOR_ARGB
#define HARDWARE_CURSOR_ARGB 0x00004000
#endif
typedef struct _xf86Crtc xf86CrtcRec, *xf86CrtcPtr;
typedef struct _xf86Output xf86OutputRec, *xf86OutputPtr;
/* define a standard for connector types */
typedef enum _xf86ConnectorType {
XF86ConnectorNone,
XF86ConnectorVGA,
XF86ConnectorDVI_I,
XF86ConnectorDVI_D,
XF86ConnectorDVI_A,
XF86ConnectorComposite,
XF86ConnectorSvideo,
XF86ConnectorComponent,
XF86ConnectorLFP,
XF86ConnectorProprietary,
} xf86ConnectorType;
typedef enum _xf86OutputStatus {
XF86OutputStatusConnected,
XF86OutputStatusDisconnected,
@ -97,6 +114,12 @@ typedef struct _xf86CrtcFuncs {
DisplayModePtr mode,
DisplayModePtr adjusted_mode);
/**
* Prepare CRTC for an upcoming mode set.
*/
void
(*prepare)(xf86CrtcPtr crtc);
/**
* Callback for setting up a video mode after fixups have been made.
*/
@ -106,23 +129,71 @@ typedef struct _xf86CrtcFuncs {
DisplayModePtr adjusted_mode,
int x, int y);
/**
* Commit mode changes to a CRTC
*/
void
(*commit)(xf86CrtcPtr crtc);
/* Set the color ramps for the CRTC to the given values. */
void
(*gamma_set)(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue,
int size);
/**
* Allocate the shadow area, delay the pixmap creation until needed
*/
void *
(*shadow_allocate) (xf86CrtcPtr crtc, int width, int height);
/**
* Create shadow pixmap for rotation support
*/
PixmapPtr
(*shadow_create) (xf86CrtcPtr crtc, int width, int height);
(*shadow_create) (xf86CrtcPtr crtc, void *data, int width, int height);
/**
* Destroy shadow pixmap
*/
void
(*shadow_destroy) (xf86CrtcPtr crtc, PixmapPtr pPixmap);
(*shadow_destroy) (xf86CrtcPtr crtc, PixmapPtr pPixmap, void *data);
/**
* Set cursor colors
*/
void
(*set_cursor_colors) (xf86CrtcPtr crtc, int bg, int fg);
/**
* Set cursor position
*/
void
(*set_cursor_position) (xf86CrtcPtr crtc, int x, int y);
/**
* Show cursor
*/
void
(*show_cursor) (xf86CrtcPtr crtc);
/**
* Hide cursor
*/
void
(*hide_cursor) (xf86CrtcPtr crtc);
/**
* Load monochrome image
*/
void
(*load_cursor_image) (xf86CrtcPtr crtc, CARD8 *image);
/**
* Load ARGB image
*/
void
(*load_cursor_argb) (xf86CrtcPtr crtc, CARD32 *image);
/**
* Clean up driver-specific bits of the crtc
*/
@ -143,12 +214,6 @@ struct _xf86Crtc {
*/
Bool enabled;
/** Track whether cursor is within CRTC range */
Bool cursorInRange;
/** Track state of cursor associated with this CRTC */
Bool cursorShown;
/**
* Active mode
*
@ -159,6 +224,8 @@ struct _xf86Crtc {
DisplayModeRec mode;
Rotation rotation;
PixmapPtr rotatedPixmap;
void *rotatedData;
/**
* Position on screen
*
@ -199,6 +266,19 @@ struct _xf86Crtc {
#else
void *randr_crtc;
#endif
/**
* Current cursor is ARGB
*/
Bool cursor_argb;
/**
* Track whether cursor is within CRTC range
*/
Bool cursor_in_range;
/**
* Track state of cursor associated with this CRTC
*/
Bool cursor_shown;
};
typedef struct _xf86OutputFuncs {
@ -256,6 +336,18 @@ typedef struct _xf86OutputFuncs {
DisplayModePtr mode,
DisplayModePtr adjusted_mode);
/**
* Callback for preparing mode changes on an output
*/
void
(*prepare)(xf86OutputPtr output);
/**
* Callback for committing mode changes on an output
*/
void
(*commit)(xf86OutputPtr output);
/**
* Callback for setting up a video mode after fixups have been made.
*
@ -356,6 +448,11 @@ struct _xf86Output {
*/
int initial_x, initial_y;
/**
* Desired initial rotation
*/
Rotation initial_rotation;
/**
* Current connection status
*
@ -382,6 +479,9 @@ struct _xf86Output {
/** driver private information */
void *driver_private;
/** Whether to use the old per-screen Monitor config section */
Bool use_screen_monitor;
#ifdef RANDR_12_INTERFACE
/**
* RandR 1.2 output structure.
@ -395,6 +495,25 @@ struct _xf86Output {
#endif
};
typedef struct _xf86CrtcConfigFuncs {
/**
* Requests that the driver resize the screen.
*
* The driver is responsible for updating scrn->virtualX and scrn->virtualY.
* If the requested size cannot be set, the driver should leave those values
* alone and return FALSE.
*
* A naive driver that cannot reallocate the screen may simply change
* virtual[XY]. A more advanced driver will want to also change the
* devPrivate.ptr and devKind of the screen pixmap, update any offscreen
* pixmaps it may have moved, and change pScrn->displayWidth.
*/
Bool
(*resize)(ScrnInfoPtr scrn,
int width,
int height);
} xf86CrtcConfigFuncsRec, *xf86CrtcConfigFuncsPtr;
typedef struct _xf86CrtcConfig {
int num_output;
xf86OutputPtr *output;
@ -413,7 +532,8 @@ typedef struct _xf86CrtcConfig {
int maxWidth, maxHeight;
/* For crtc-based rotation */
DamagePtr rotationDamage;
DamagePtr rotation_damage;
Bool rotation_damage_registered;
/* DGA */
unsigned int dga_flags;
@ -423,6 +543,18 @@ typedef struct _xf86CrtcConfig {
int dga_width, dga_height, dga_stride;
DisplayModePtr dga_save_mode;
const xf86CrtcConfigFuncsRec *funcs;
CreateScreenResourcesProcPtr CreateScreenResources;
CloseScreenProcPtr CloseScreen;
/* Cursor information */
xf86CursorInfoPtr cursor_info;
CursorPtr cursor;
CARD8 *cursor_image;
Bool cursor_on;
CARD32 cursor_fg, cursor_bg;
} xf86CrtcConfigRec, *xf86CrtcConfigPtr;
extern int xf86CrtcConfigPrivateIndex;
@ -434,7 +566,8 @@ extern int xf86CrtcConfigPrivateIndex;
*/
void
xf86CrtcConfigInit (ScrnInfoPtr scrn);
xf86CrtcConfigInit (ScrnInfoPtr scrn,
const xf86CrtcConfigFuncsRec *funcs);
void
xf86CrtcSetSizeRange (ScrnInfoPtr scrn,
@ -452,25 +585,6 @@ void
xf86CrtcDestroy (xf86CrtcPtr crtc);
/**
* Allocate a crtc for the specified output
*
* Find a currently unused CRTC which is suitable for
* the specified output
*/
xf86CrtcPtr
xf86AllocCrtc (xf86OutputPtr output);
/**
* Free a crtc
*
* Mark the crtc as unused by any outputs
*/
void
xf86FreeCrtc (xf86CrtcPtr crtc);
/**
* Sets the given video mode on the given crtc
*/
@ -484,6 +598,12 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
Bool
xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation);
/*
* Clean up rotation during CloseScreen
*/
void
xf86RotateCloseScreen (ScreenPtr pScreen);
/**
* Return whether any output is assigned to the crtc
*/
@ -494,9 +614,12 @@ xf86CrtcInUse (xf86CrtcPtr crtc);
* Output functions
*/
xf86OutputPtr
xf86OutputCreate (ScrnInfoPtr scrn,
const xf86OutputFuncsRec *funcs,
const char *name);
xf86OutputCreate (ScrnInfoPtr scrn,
const xf86OutputFuncsRec *funcs,
const char *name);
void
xf86OutputUseScreenMonitor (xf86OutputPtr output, Bool use_screen_monitor);
Bool
xf86OutputRename (xf86OutputPtr output, const char *name);
@ -511,7 +634,10 @@ void
xf86SetScrnInfoModes (ScrnInfoPtr pScrn);
Bool
xf86InitialConfiguration (ScrnInfoPtr pScrn);
xf86CrtcScreenInit (ScreenPtr pScreen);
Bool
xf86InitialConfiguration (ScrnInfoPtr pScrn, Bool canGrow);
void
xf86DPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags);
@ -522,6 +648,12 @@ xf86SaveScreen(ScreenPtr pScreen, int mode);
void
xf86DisableUnusedFunctions(ScrnInfoPtr pScrn);
DisplayModePtr
xf86OutputFindClosestMode (xf86OutputPtr output, DisplayModePtr desired);
Bool
xf86SetSingleMode (ScrnInfoPtr pScrn, DisplayModePtr desired, Rotation rotation);
/**
* Set the EDID information for the specified output
*/
@ -552,4 +684,63 @@ xf86DiDGAInit (ScreenPtr pScreen, unsigned long dga_address);
Bool
xf86DiDGAReInit (ScreenPtr pScreen);
/*
* Set the subpixel order reported for the screen using
* the information from the outputs
*/
void
xf86CrtcSetScreenSubpixelOrder (ScreenPtr pScreen);
/*
* Get a standard string name for a connector type
*/
char *
xf86ConnectorGetName(xf86ConnectorType connector);
/*
* Using the desired mode information in each crtc, set
* modes (used in EnterVT functions, or at server startup)
*/
Bool
xf86SetDesiredModes (ScrnInfoPtr pScrn);
/**
* Initialize the CRTC-based cursor code. CRTC function vectors must
* contain relevant cursor setting functions.
*
* Driver should call this from ScreenInit function
*/
Bool
xf86_cursors_init (ScreenPtr screen, int max_width, int max_height, int flags);
/**
* Called when anything on the screen is reconfigured.
*
* Reloads cursor images as needed, then adjusts cursor positions.
*
* Driver should call this from crtc commit function.
*/
void
xf86_reload_cursors (ScreenPtr screen);
/**
* Called from EnterVT to turn the cursors back on
*/
void
xf86_show_cursors (ScrnInfoPtr scrn);
/**
* Called by the driver to turn cursors off
*/
void
xf86_hide_cursors (ScrnInfoPtr scrn);
/**
* Clean up CRTC-based cursor code. Driver must call this at CloseScreen time.
*/
void
xf86_cursors_fini (ScreenPtr screen);
#endif /* _XF86CRTC_H_ */

View File

@ -0,0 +1,607 @@
/*
* Copyright © 2007 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 "xf86Crtc.h"
#include "xf86Modes.h"
#include "xf86RandR12.h"
#include "X11/extensions/render.h"
#define DPMS_SERVER
#include "X11/extensions/dpms.h"
#include "X11/Xatom.h"
#ifdef RENDER
#include "picturestr.h"
#endif
#include "cursorstr.h"
/*
* Given a screen coordinate, rotate back to a cursor source coordinate
*/
static void
xf86_crtc_rotate_coord (Rotation rotation,
int width,
int height,
int x_dst,
int y_dst,
int *x_src,
int *y_src)
{
if (rotation & RR_Reflect_X)
x_dst = width - x_dst - 1;
if (rotation & RR_Reflect_Y)
y_dst = height - y_dst - 1;
switch (rotation & 0xf) {
case RR_Rotate_0:
*x_src = x_dst;
*y_src = y_dst;
break;
case RR_Rotate_90:
*x_src = height - y_dst - 1;
*y_src = x_dst;
break;
case RR_Rotate_180:
*x_src = width - x_dst - 1;
*y_src = height - y_dst - 1;
break;
case RR_Rotate_270:
*x_src = y_dst;
*y_src = width - x_dst - 1;
break;
}
}
/*
* Convert an x coordinate to a position within the cursor bitmap
*/
static int
cursor_bitpos (int flags, int x, Bool mask)
{
if (flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK)
mask = !mask;
if (flags & HARDWARE_CURSOR_NIBBLE_SWAPPED)
x = (x & ~3) | (3 - (x & 3));
if (flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST)
x = (x & ~7) | (7 - (x & 7));
if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1)
x = (x << 1) + mask;
else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8)
x = ((x & ~7) << 1) | (mask << 3) | (x & 7);
else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16)
x = ((x & ~15) << 1) | (mask << 4) | (x & 15);
else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32)
x = ((x & ~31) << 1) | (mask << 5) | (x & 31);
else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64)
x = ((x & ~63) << 1) | (mask << 6) | (x & 63);
return x;
}
/*
* Fetch one bit from a cursor bitmap
*/
static CARD8
get_bit (CARD8 *image, int stride, int flags, int x, int y, Bool mask)
{
x = cursor_bitpos (flags, x, mask);
image += y * stride;
return (image[(x >> 3)] >> (x & 7)) & 1;
}
/*
* Set one bit in a cursor bitmap
*/
static void
set_bit (CARD8 *image, int stride, int flags, int x, int y, Bool mask)
{
x = cursor_bitpos (flags, x, mask);
image += y * stride;
image[(x >> 3)] |= 1 << (x & 7);
}
/*
* Load a two color cursor into a driver that supports only ARGB cursors
*/
static void
xf86_crtc_convert_cursor_to_argb (xf86CrtcPtr crtc, unsigned char *src)
{
ScrnInfoPtr scrn = crtc->scrn;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
CARD32 *cursor_image = (CARD32 *) xf86_config->cursor_image;
int x, y;
int xin, yin;
int stride = cursor_info->MaxWidth >> 2;
int flags = cursor_info->Flags;
CARD32 bits;
#ifdef ARGB_CURSOR
crtc->cursor_argb = FALSE;
#endif
for (y = 0; y < cursor_info->MaxHeight; y++)
for (x = 0; x < cursor_info->MaxWidth; x++)
{
xf86_crtc_rotate_coord (crtc->rotation,
cursor_info->MaxWidth,
cursor_info->MaxHeight,
x, y, &xin, &yin);
if (get_bit (src, stride, flags, xin, yin, TRUE) ==
((flags & HARDWARE_CURSOR_INVERT_MASK) == 0))
{
if (get_bit (src, stride, flags, xin, yin, FALSE))
bits = xf86_config->cursor_fg;
else
bits = xf86_config->cursor_bg;
}
else
bits = 0;
cursor_image[y * cursor_info->MaxWidth + x] = bits;
}
crtc->funcs->load_cursor_argb (crtc, cursor_image);
}
/*
* Set the colors for a two-color cursor (ignore for ARGB cursors)
*/
static void
xf86_set_cursor_colors (ScrnInfoPtr scrn, int bg, int fg)
{
ScreenPtr screen = scrn->pScreen;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
CursorPtr cursor = xf86_config->cursor;
int c;
CARD8 *bits = cursor ? cursor->devPriv[screen->myNum] : NULL;
/* Save ARGB versions of these colors */
xf86_config->cursor_fg = (CARD32) fg | 0xff000000;
xf86_config->cursor_bg = (CARD32) bg | 0xff000000;
for (c = 0; c < xf86_config->num_crtc; c++)
{
xf86CrtcPtr crtc = xf86_config->crtc[c];
if (crtc->enabled && !crtc->cursor_argb)
{
if (crtc->funcs->load_cursor_image)
crtc->funcs->set_cursor_colors (crtc, bg, fg);
else if (bits)
xf86_crtc_convert_cursor_to_argb (crtc, bits);
}
}
}
static void
xf86_crtc_hide_cursor (xf86CrtcPtr crtc)
{
if (crtc->cursor_shown)
{
crtc->funcs->hide_cursor (crtc);
crtc->cursor_shown = FALSE;
}
}
void
xf86_hide_cursors (ScrnInfoPtr scrn)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
int c;
xf86_config->cursor_on = FALSE;
for (c = 0; c < xf86_config->num_crtc; c++)
{
xf86CrtcPtr crtc = xf86_config->crtc[c];
if (crtc->enabled)
xf86_crtc_hide_cursor (crtc);
}
}
static void
xf86_crtc_show_cursor (xf86CrtcPtr crtc)
{
if (!crtc->cursor_shown && crtc->cursor_in_range)
{
crtc->funcs->show_cursor (crtc);
crtc->cursor_shown = TRUE;
}
}
void
xf86_show_cursors (ScrnInfoPtr scrn)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
int c;
xf86_config->cursor_on = TRUE;
for (c = 0; c < xf86_config->num_crtc; c++)
{
xf86CrtcPtr crtc = xf86_config->crtc[c];
if (crtc->enabled)
xf86_crtc_show_cursor (crtc);
}
}
static void
xf86_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
{
ScrnInfoPtr scrn = crtc->scrn;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
DisplayModePtr mode = &crtc->mode;
int x_temp;
int y_temp;
Bool in_range;
/*
* Move to crtc coordinate space
*/
x -= crtc->x;
y -= crtc->y;
/*
* Rotate
*/
switch ((crtc->rotation) & 0xf) {
case RR_Rotate_0:
break;
case RR_Rotate_90:
x_temp = y;
y_temp = mode->VDisplay - cursor_info->MaxWidth - x;
x = x_temp;
y = y_temp;
break;
case RR_Rotate_180:
x_temp = mode->HDisplay - cursor_info->MaxWidth - x;
y_temp = mode->VDisplay - cursor_info->MaxHeight - y;
x = x_temp;
y = y_temp;
break;
case RR_Rotate_270:
x_temp = mode->HDisplay - cursor_info->MaxHeight - y;
y_temp = x;
x = x_temp;
y = y_temp;
break;
}
/*
* Reflect
*/
if (crtc->rotation & RR_Reflect_X)
x = mode->HDisplay - cursor_info->MaxWidth - x;
if (crtc->rotation & RR_Reflect_Y)
y = mode->VDisplay - cursor_info->MaxHeight - y;
/*
* Disable the cursor when it is outside the viewport
*/
in_range = TRUE;
if (x >= mode->HDisplay || y >= mode->VDisplay ||
x <= -cursor_info->MaxWidth || y <= -cursor_info->MaxHeight)
{
in_range = FALSE;
x = 0;
y = 0;
}
crtc->cursor_in_range = in_range;
if (in_range)
{
crtc->funcs->set_cursor_position (crtc, x, y);
xf86_crtc_show_cursor (crtc);
}
else
xf86_crtc_hide_cursor (crtc);
}
static void
xf86_set_cursor_position (ScrnInfoPtr scrn, int x, int y)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
int c;
/* undo what xf86HWCurs did to the coordinates */
x += scrn->frameX0;
y += scrn->frameY0;
for (c = 0; c < xf86_config->num_crtc; c++)
{
xf86CrtcPtr crtc = xf86_config->crtc[c];
if (crtc->enabled)
xf86_crtc_set_cursor_position (crtc, x, y);
}
}
/*
* Load a two-color cursor into a crtc, performing rotation as needed
*/
static void
xf86_crtc_load_cursor_image (xf86CrtcPtr crtc, CARD8 *src)
{
ScrnInfoPtr scrn = crtc->scrn;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
CARD8 *cursor_image;
#ifdef ARGB_CURSOR
crtc->cursor_argb = FALSE;
#endif
if (crtc->rotation == RR_Rotate_0)
cursor_image = src;
else
{
int x, y;
int xin, yin;
int stride = cursor_info->MaxWidth >> 2;
int flags = cursor_info->Flags;
cursor_image = xf86_config->cursor_image;
memset(cursor_image, 0, cursor_info->MaxWidth * stride);
for (y = 0; y < cursor_info->MaxHeight; y++)
for (x = 0; x < cursor_info->MaxWidth; x++)
{
xf86_crtc_rotate_coord (crtc->rotation,
cursor_info->MaxWidth,
cursor_info->MaxHeight,
x, y, &xin, &yin);
if (get_bit(src, stride, flags, xin, yin, FALSE))
set_bit(cursor_image, stride, flags, x, y, FALSE);
if (get_bit(src, stride, flags, xin, yin, TRUE))
set_bit(cursor_image, stride, flags, x, y, TRUE);
}
}
crtc->funcs->load_cursor_image (crtc, cursor_image);
}
/*
* Load a cursor image into all active CRTCs
*/
static void
xf86_load_cursor_image (ScrnInfoPtr scrn, unsigned char *src)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
int c;
for (c = 0; c < xf86_config->num_crtc; c++)
{
xf86CrtcPtr crtc = xf86_config->crtc[c];
if (crtc->enabled)
{
if (crtc->funcs->load_cursor_image)
xf86_crtc_load_cursor_image (crtc, src);
else if (crtc->funcs->load_cursor_argb)
xf86_crtc_convert_cursor_to_argb (crtc, src);
}
}
}
static Bool
xf86_use_hw_cursor (ScreenPtr screen, CursorPtr cursor)
{
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
xf86_config->cursor = cursor;
if (cursor->bits->width > cursor_info->MaxWidth ||
cursor->bits->height> cursor_info->MaxHeight)
return FALSE;
return TRUE;
}
static Bool
xf86_use_hw_cursor_argb (ScreenPtr screen, CursorPtr cursor)
{
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
xf86_config->cursor = cursor;
/* Make sure ARGB support is available */
if ((cursor_info->Flags & HARDWARE_CURSOR_ARGB) == 0)
return FALSE;
if (cursor->bits->width > cursor_info->MaxWidth ||
cursor->bits->height> cursor_info->MaxHeight)
return FALSE;
return TRUE;
}
static void
xf86_crtc_load_cursor_argb (xf86CrtcPtr crtc, CursorPtr cursor)
{
ScrnInfoPtr scrn = crtc->scrn;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
CARD32 *cursor_image = (CARD32 *) xf86_config->cursor_image;
CARD32 *cursor_source = (CARD32 *) cursor->bits->argb;
int x, y;
int xin, yin;
CARD32 bits;
int source_width = cursor->bits->width;
int source_height = cursor->bits->height;
int image_width = cursor_info->MaxWidth;
int image_height = cursor_info->MaxHeight;
for (y = 0; y < image_height; y++)
for (x = 0; x < image_width; x++)
{
xf86_crtc_rotate_coord (crtc->rotation, image_width, image_height,
x, y, &xin, &yin);
if (xin < source_width && yin < source_height)
bits = cursor_source[yin * source_width + xin];
else
bits = 0;
cursor_image[y * image_width + x] = bits;
}
crtc->funcs->load_cursor_argb (crtc, cursor_image);
}
static void
xf86_load_cursor_argb (ScrnInfoPtr scrn, CursorPtr cursor)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
int c;
for (c = 0; c < xf86_config->num_crtc; c++)
{
xf86CrtcPtr crtc = xf86_config->crtc[c];
if (crtc->enabled)
xf86_crtc_load_cursor_argb (crtc, cursor);
}
}
Bool
xf86_cursors_init (ScreenPtr screen, int max_width, int max_height, int flags)
{
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
xf86CursorInfoPtr cursor_info;
cursor_info = xf86CreateCursorInfoRec();
if (!cursor_info)
return FALSE;
xf86_config->cursor_image = xalloc (max_width * max_height * 4);
if (!xf86_config->cursor_image)
{
xf86DestroyCursorInfoRec (cursor_info);
return FALSE;
}
xf86_config->cursor_info = cursor_info;
cursor_info->MaxWidth = max_width;
cursor_info->MaxHeight = max_height;
cursor_info->Flags = flags;
cursor_info->SetCursorColors = xf86_set_cursor_colors;
cursor_info->SetCursorPosition = xf86_set_cursor_position;
cursor_info->LoadCursorImage = xf86_load_cursor_image;
cursor_info->HideCursor = xf86_hide_cursors;
cursor_info->ShowCursor = xf86_show_cursors;
cursor_info->UseHWCursor = xf86_use_hw_cursor;
#ifdef ARGB_CURSOR
if (flags & HARDWARE_CURSOR_ARGB)
{
cursor_info->UseHWCursorARGB = xf86_use_hw_cursor_argb;
cursor_info->LoadCursorARGB = xf86_load_cursor_argb;
}
#endif
xf86_config->cursor = NULL;
xf86_hide_cursors (scrn);
return xf86InitCursor (screen, cursor_info);
}
/**
* Called when anything on the screen is reconfigured.
*
* Reloads cursor images as needed, then adjusts cursor positions
*/
void
xf86_reload_cursors (ScreenPtr screen)
{
ScrnInfoPtr scrn;
xf86CrtcConfigPtr xf86_config;
xf86CursorInfoPtr cursor_info;
CursorPtr cursor;
int x, y;
/* initial mode setting will not have set a screen yet */
if (!screen)
return;
scrn = xf86Screens[screen->myNum];
xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
/* make sure the cursor code has been initialized */
cursor_info = xf86_config->cursor_info;
if (!cursor_info)
return;
cursor = xf86_config->cursor;
GetSpritePosition (&x, &y);
if (!(cursor_info->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
(*cursor_info->HideCursor)(scrn);
if (cursor)
{
#ifdef ARGB_CURSOR
if (cursor->bits->argb && cursor_info->LoadCursorARGB)
(*cursor_info->LoadCursorARGB) (scrn, cursor);
else
#endif
(*cursor_info->LoadCursorImage)(cursor_info->pScrn,
cursor->devPriv[screen->myNum]);
(*cursor_info->SetCursorPosition)(cursor_info->pScrn, x, y);
(*cursor_info->ShowCursor)(cursor_info->pScrn);
}
}
/**
* Clean up CRTC-based cursor code
*/
void
xf86_cursors_fini (ScreenPtr screen)
{
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
if (xf86_config->cursor_info)
{
xf86DestroyCursorInfoRec (xf86_config->cursor_info);
xf86_config->cursor_info = NULL;
}
if (xf86_config->cursor_image)
{
xfree (xf86_config->cursor_image);
xf86_config->cursor_image = NULL;
}
}

View File

@ -22,6 +22,10 @@
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#else
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#endif
#include "xf86.h"
@ -31,6 +35,8 @@
#include "xf86Crtc.h"
#include "xf86Modes.h"
#include "gcstruct.h"
#include "scrnintstr.h"
#include "windowstr.h"
static Bool
xf86_dga_get_modes (ScreenPtr pScreen)

View File

@ -27,6 +27,10 @@
*/
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#else
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#endif
#include "xf86.h"
@ -78,6 +82,16 @@ static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
DDC->vendor.prod_id == 1516)
return TRUE;
/* Acer AL1706 */
if (memcmp (DDC->vendor.name, "ACR", 4) == 0 &&
DDC->vendor.prod_id == 44358)
return TRUE;
/* Samsung SyncMaster 226BW */
if (memcmp (DDC->vendor.name, "SAM", 4) == 0 &&
DDC->vendor.prod_id == 638)
return TRUE;
return FALSE;
}

View File

@ -30,13 +30,12 @@
#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 "xf86Modes.h"
#include "xf86Priv.h"
@ -90,6 +89,36 @@ xf86ModeVRefresh(DisplayModePtr mode)
return refresh;
}
int
xf86ModeWidth (DisplayModePtr 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 (DisplayModePtr 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;
}
}
/** Sets a default mode name of <width>x<height> on a mode. */
void
xf86SetModeDefaultName(DisplayModePtr mode)

View File

@ -25,17 +25,30 @@
*
*/
#ifndef _I830_XF86MODES_H_
#define _I830_XF86MODES_H_
#ifndef _XF86MODES_H_
#define _XF86MODES_H_
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include "xf86.h"
#include "xorgVersion.h"
#include "xf86Parser.h"
#include "edid.h"
#include "xf86Parser.h"
#if XF86_MODES_RENAME
#include "xf86Rename.h"
#endif
double xf86ModeHSync(DisplayModePtr mode);
double xf86ModeVRefresh(DisplayModePtr mode);
int
xf86ModeWidth (DisplayModePtr mode, Rotation rotation);
int
xf86ModeHeight (DisplayModePtr mode, Rotation rotation);
DisplayModePtr xf86DuplicateMode(DisplayModePtr pMode);
DisplayModePtr xf86DuplicateModes(ScrnInfoPtr pScrn,
DisplayModePtr modeList);
@ -82,4 +95,4 @@ xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor);
DisplayModePtr
xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed);
#endif /* _I830_XF86MODES_H_ */
#endif /* _XF86MODES_H_ */

View File

@ -25,6 +25,10 @@
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#else
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#endif
#include "xf86.h"
@ -331,8 +335,9 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen,
{
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
WindowPtr pRoot = WindowTable[pScreen->myNum];
Bool ret = TRUE;
Bool ret = FALSE;
if (randrp->virtualX == -1 || randrp->virtualY == -1)
{
@ -341,20 +346,26 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen,
}
if (pRoot)
(*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE);
pScrn->virtualX = width;
pScrn->virtualY = height;
pScreen->width = pScrn->virtualX;
pScreen->height = pScrn->virtualY;
/* Let the driver update virtualX and virtualY */
if (!(*config->funcs->resize)(pScrn, width, height))
goto finish;
ret = TRUE;
pScreen->width = width;
pScreen->height = height;
pScreen->mmWidth = mmWidth;
pScreen->mmHeight = mmHeight;
xf86SetViewport (pScreen, pScreen->width-1, pScreen->height-1);
xf86SetViewport (pScreen, 0, 0);
finish:
if (pRoot)
(*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE);
#if RANDR_12_INTERFACE
if (WindowTable[pScreen->myNum])
if (WindowTable[pScreen->myNum] && ret)
RRScreenSizeNotify (pScreen);
#endif
return ret;
@ -390,8 +401,8 @@ xf86RandR12CreateScreenResources (ScreenPtr pScreen)
for (c = 0; c < config->num_crtc; c++)
{
xf86CrtcPtr crtc = config->crtc[c];
int crtc_width = crtc->x + crtc->mode.HDisplay;
int crtc_height = crtc->y + crtc->mode.VDisplay;
int crtc_width = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation);
int crtc_height = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation);
if (crtc->enabled && crtc_width > width)
width = crtc_width;
@ -411,8 +422,28 @@ xf86RandR12CreateScreenResources (ScreenPtr pScreen)
}
else
{
mmWidth = pScreen->mmWidth;
mmHeight = pScreen->mmHeight;
xf86OutputPtr output = config->output[config->compat_output];
xf86CrtcPtr crtc = output->crtc;
if (crtc && crtc->mode.HDisplay &&
output->mm_width && output->mm_height)
{
/*
* If the output has a mode and a declared size, use that
* to scale the screen size
*/
DisplayModePtr mode = &crtc->mode;
mmWidth = output->mm_width * width / mode->HDisplay;
mmHeight = output->mm_height * height / mode->VDisplay;
}
else
{
/*
* Otherwise, just set the screen to 96dpi
*/
mmWidth = width * 25.4 / 96;
mmHeight = height * 25.4 / 96;
}
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Setting screen physical size to %d x %d\n",
@ -429,6 +460,7 @@ xf86RandR12CreateScreenResources (ScreenPtr pScreen)
randrp->virtualX = pScrn->virtualX;
randrp->virtualY = pScrn->virtualY;
}
xf86CrtcSetScreenSubpixelOrder (pScreen);
#if RANDR_12_INTERFACE
if (xf86RandR12CreateScreenResources12 (pScreen))
return TRUE;
@ -491,19 +523,18 @@ void
xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations)
{
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
int c;
randrp->supported_rotations = rotations;
#if RANDR_12_INTERFACE
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
int c;
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
for (c = 0; c < config->num_crtc; c++) {
xf86CrtcPtr crtc = config->crtc[c];
RRCrtcSetRotations (crtc->randr_crtc, rotations);
}
#endif
randrp->supported_rotations = rotations;
}
void
@ -525,6 +556,56 @@ xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y)
}
#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)
{
@ -563,12 +644,15 @@ xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
* We make copies of modes, so pointer equality
* isn't sufficient
*/
for (j = 0; j < randr_output->numModes; j++)
for (j = 0; j < randr_output->numModes + randr_output->numUserModes; j++)
{
DisplayModePtr outMode = randr_output->modes[j]->devPrivate;
if (xf86ModesEqual(mode, outMode))
RRModePtr m = (j < randr_output->numModes ?
randr_output->modes[j] :
randr_output->userModes[j-randr_output->numModes]);
if (xf86RandRModeMatches (m, mode))
{
randr_mode = randr_output->modes[j];
randr_mode = m;
break;
}
}
@ -580,6 +664,39 @@ xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
return ret;
}
/*
* Convert a RandR mode to a DisplayMode
*/
static void
xf86RandRModeConvert (ScrnInfoPtr scrn,
RRModePtr randr_mode,
DisplayModePtr mode)
{
mode->prev = NULL;
mode->next = NULL;
mode->name = NULL;
mode->status = MODE_OK;
mode->type = 0;
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,
@ -593,16 +710,15 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
xf86CrtcPtr crtc = randr_crtc->devPrivate;
DisplayModePtr mode = randr_mode ? randr_mode->devPrivate : NULL;
Bool changed = FALSE;
int o, ro;
xf86CrtcPtr *save_crtcs;
Bool save_enabled = crtc->enabled;
save_crtcs = ALLOCATE_LOCAL(config->num_crtc * sizeof (xf86CrtcPtr));
if ((mode != NULL) != crtc->enabled)
if ((randr_mode != NULL) != crtc->enabled)
changed = TRUE;
else if (mode && !xf86ModesEqual (&crtc->mode, mode))
else if (randr_mode && !xf86RandRModeMatches (randr_mode, &crtc->mode))
changed = TRUE;
if (rotation != crtc->rotation)
@ -636,11 +752,14 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
/* XXX need device-independent mode setting code through an API */
if (changed)
{
crtc->enabled = mode != NULL;
crtc->enabled = randr_mode != NULL;
if (mode)
if (randr_mode)
{
if (!xf86CrtcSetMode (crtc, mode, rotation, x, y))
DisplayModeRec mode;
xf86RandRModeConvert (pScrn, randr_mode, &mode);
if (!xf86CrtcSetMode (crtc, &mode, rotation, x, y))
{
crtc->enabled = save_enabled;
for (o = 0; o < config->num_output; o++)
@ -654,7 +773,7 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
/*
* Save the last successful setting for EnterVT
*/
crtc->desiredMode = *mode;
crtc->desiredMode = mode;
crtc->desiredRotation = rotation;
crtc->desiredX = x;
crtc->desiredY = y;
@ -697,6 +816,26 @@ xf86RandR12OutputSetProperty (ScreenPtr pScreen,
return output->funcs->set_property(output, property, value);
}
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);
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
@ -743,7 +882,6 @@ xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes)
rrmode = RRModeGet (&modeInfo, mode->name);
if (rrmode) {
rrmode->devPrivate = mode;
rrmodes[nmode++] = rrmode;
npreferred += pref;
}
@ -873,8 +1011,7 @@ xf86RandR12CreateObjects12 (ScreenPtr pScreen)
{
xf86CrtcPtr crtc = config->crtc[c];
crtc->randr_crtc = RRCrtcCreate (crtc);
RRCrtcAttachScreen (crtc->randr_crtc, pScreen);
crtc->randr_crtc = RRCrtcCreate (pScreen, crtc);
RRCrtcGammaSetSize (crtc->randr_crtc, 256);
}
/*
@ -884,13 +1021,13 @@ xf86RandR12CreateObjects12 (ScreenPtr pScreen)
{
xf86OutputPtr output = config->output[o];
output->randr_output = RROutputCreate (output->name,
output->randr_output = RROutputCreate (pScreen, output->name,
strlen (output->name),
output);
RROutputAttachScreen (output->randr_output, pScreen);
if (output->funcs->create_resources != NULL)
output->funcs->create_resources(output);
RRPostPendingProperties (output->randr_output);
}
return TRUE;
}
@ -900,18 +1037,39 @@ xf86RandR12CreateScreenResources12 (ScreenPtr pScreen)
{
int c;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
for (c = 0; c < config->num_crtc; c++)
xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
RRScreenSetSizeRange (pScreen, 320, 240,
randrp->virtualX, randrp->virtualY);
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);
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
int c;
if (!randrp)
return;
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)
{
@ -928,6 +1086,8 @@ xf86RandR12Init12 (ScreenPtr pScreen)
rp->rrCrtcSet = xf86RandR12CrtcSet;
rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma;
rp->rrOutputSetProperty = xf86RandR12OutputSetProperty;
rp->rrOutputValidateMode = xf86RandR12OutputValidateMode;
rp->rrModeDestroy = xf86RandR12ModeDestroy;
rp->rrSetConfig = NULL;
pScrn->PointerMoved = xf86RandR12PointerMoved;
if (!xf86RandR12CreateObjects12 (pScreen))

View File

@ -33,5 +33,6 @@ Bool xf86RandR12SetConfig(ScreenPtr pScreen, Rotation rotation, int rate,
Rotation xf86RandR12GetRotation(ScreenPtr pScreen);
void xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y);
Bool xf86RandR12PreInit (ScrnInfoPtr pScrn);
void xf86RandR12TellChanged (ScreenPtr pScreen);
#endif /* _XF86_RANDR_H_ */

View File

@ -31,6 +31,7 @@
#define xf86CrtcDestroy XF86NAME(xf86CrtcDestroy)
#define xf86CrtcInUse XF86NAME(xf86CrtcInUse)
#define xf86CrtcRotate XF86NAME(xf86CrtcRotate)
#define xf86CrtcScreenInit XF86NAME(xf86CrtcScreenInit)
#define xf86CrtcSetMode XF86NAME(xf86CrtcSetMode)
#define xf86CrtcSetSizeRange XF86NAME(xf86CrtcSetSizeRange)
#define xf86CVTMode XF86NAME(xf86CVTMode)
@ -73,5 +74,11 @@
#define xf86RandR12SetConfig XF86NAME(xf86RandR12SetConfig)
#define xf86RandR12SetRotations XF86NAME(xf86RandR12SetRotations)
#define xf86SaveScreen XF86NAME(xf86SaveScreen)
#define xf86CrtcSetScreenSubpixelOrder XF86NAME(xf86CrtcSetScreenSubpixelOrder)
#define xf86ModeWidth XF86NAME(xf86ModeWidth)
#define xf86ModeHeight XF86NAME(xf86ModeHeight)
#define xf86OutputFindClosestMode XF86NAME(xf86OutputFindClosestMode)
#define xf86SetSingleMode XF86NAME(xf86SetSingleMode)
#define xf86SetDesiredModes XF86NAME(xf86SetDesiredModes)
#endif /* _XF86RENAME_H_ */

View File

@ -22,6 +22,10 @@
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#else
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#endif
#include <stddef.h>
@ -40,36 +44,6 @@
#include "X11/extensions/dpms.h"
#include "X11/Xatom.h"
static int
mode_height (DisplayModePtr 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;
}
}
static int
mode_width (DisplayModePtr 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;
}
}
/* borrowed from composite extension, move to Render and publish? */
static VisualPtr
@ -95,31 +69,44 @@ compWindowFormat (WindowPtr pWin)
}
static void
xf86RotateBox (BoxPtr dst, BoxPtr src, Rotation rotation,
int dest_width, int dest_height)
xf86TranslateBox (BoxPtr b, int dx, int dy)
{
b->x1 += dx;
b->y1 += dy;
b->x2 += dx;
b->y2 += dy;
}
static void
xf86TransformBox (BoxPtr dst, BoxPtr src, Rotation rotation,
int xoff, int yoff,
int dest_width, int dest_height)
{
BoxRec stmp = *src;
xf86TranslateBox (&stmp, -xoff, -yoff);
switch (rotation & 0xf) {
default:
case RR_Rotate_0:
*dst = *src;
*dst = stmp;
break;
case RR_Rotate_90:
dst->x1 = src->y1;
dst->y1 = dest_height - src->x2;
dst->x2 = src->y2;
dst->y2 = dest_height - src->x1;
dst->x1 = stmp.y1;
dst->y1 = dest_height - stmp.x2;
dst->x2 = stmp.y2;
dst->y2 = dest_height - stmp.x1;
break;
case RR_Rotate_180:
dst->x1 = dest_width - src->x2;
dst->y1 = dest_height - src->y2;
dst->x2 = dest_width - src->x1;
dst->y2 = dest_height - src->y1;
dst->x1 = dest_width - stmp.x2;
dst->y1 = dest_height - stmp.y2;
dst->x2 = dest_width - stmp.x1;
dst->y2 = dest_height - stmp.y1;
break;
case RR_Rotate_270:
dst->x1 = dest_width - src->y2;
dst->y1 = src->x1;
dst->y2 = src->x2;
dst->x2 = dest_width - src->y1;
dst->x1 = dest_width - stmp.y2;
dst->y1 = stmp.x1;
dst->y2 = stmp.x2;
dst->x2 = dest_width - stmp.y1;
break;
}
if (rotation & RR_Reflect_X) {
@ -156,10 +143,9 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
&include_inferiors,
serverClient,
&error);
if (!src) {
ErrorF("couldn't create src pict\n");
if (!src)
return;
}
dst = CreatePicture (None,
&dst_pixmap->drawable,
format,
@ -167,10 +153,8 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
NULL,
serverClient,
&error);
if (!dst) {
ErrorF("couldn't create src pict\n");
if (!dst)
return;
}
memset (&transform, '\0', sizeof (transform));
transform.matrix[2][2] = IntToxFixed(1);
@ -211,17 +195,16 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
}
error = SetPictureTransform (src, &transform);
if (error) {
ErrorF("Couldn't set transform\n");
if (error)
return;
}
while (n--)
{
BoxRec dst_box;
xf86RotateBox (&dst_box, b, crtc->rotation,
crtc->mode.HDisplay, crtc->mode.VDisplay);
xf86TransformBox (&dst_box, b, crtc->rotation,
crtc->x, crtc->y,
crtc->mode.HDisplay, crtc->mode.VDisplay);
CompositePicture (PictOpSrc,
src, NULL, dst,
dst_box.x1, dst_box.y1, 0, 0, dst_box.x1, dst_box.y1,
@ -233,35 +216,94 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
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 = crtc->x;
damage_box.x2 = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation);
damage_box.y1 = crtc->y;
damage_box.y2 = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation);
REGION_INIT (pScreen, &damage_region, &damage_box, 1);
DamageDamageRegion (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
&damage_region);
REGION_UNINIT (pScreen, &damage_region);
}
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;
}
xf86CrtcDamageShadow (crtc);
}
}
}
static void
xf86RotateRedisplay(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
DamagePtr damage = xf86_config->rotationDamage;
DamagePtr damage = xf86_config->rotation_damage;
RegionPtr region;
if (!damage)
return;
xf86RotatePrepare (pScreen);
region = DamageRegion(damage);
if (REGION_NOTEMPTY(pScreen, region))
{
int c;
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->rotation != RR_Rotate_0)
if (crtc->rotation != RR_Rotate_0 && crtc->enabled)
{
BoxRec box;
RegionRec crtc_damage;
/* compute portion of damage that overlaps crtc */
box.x1 = crtc->x;
box.x2 = crtc->x + mode_width (&crtc->mode, crtc->rotation);
box.x2 = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation);
box.y1 = crtc->y;
box.y2 = crtc->y + mode_height (&crtc->mode, crtc->rotation);
box.y2 = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation);
REGION_INIT(pScreen, &crtc_damage, &box, 1);
REGION_INTERSECT (pScreen, &crtc_damage, &crtc_damage, region);
@ -272,6 +314,7 @@ xf86RotateRedisplay(ScreenPtr pScreen)
REGION_UNINIT (pScreen, &crtc_damage);
}
}
pScreen->SourceValidate = SourceValidate;
DamageEmpty(damage);
}
}
@ -289,6 +332,59 @@ xf86RotateWakeupHandler(pointer data, int i, pointer LastSelectMask)
{
}
static 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]->rotatedPixmap ||
xf86_config->crtc[c]->rotatedData)
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;
}
DamageDestroy (xf86_config->rotation_damage);
xf86_config->rotation_damage = NULL;
/* Free block/wakeup handler */
RemoveBlockAndWakeupHandlers (xf86RotateBlockHandler,
xf86RotateWakeupHandler,
(pointer) pScreen);
}
}
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]);
}
Bool
xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
{
@ -298,25 +394,7 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
if (rotation == RR_Rotate_0)
{
/* Free memory from rotation */
if (crtc->rotatedPixmap)
{
crtc->funcs->shadow_destroy (crtc, crtc->rotatedPixmap);
crtc->rotatedPixmap = NULL;
}
if (xf86_config->rotationDamage)
{
/* Free damage structure */
DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
xf86_config->rotationDamage);
DamageDestroy (xf86_config->rotationDamage);
xf86_config->rotationDamage = NULL;
/* Free block/wakeup handler */
RemoveBlockAndWakeupHandlers (xf86RotateBlockHandler,
xf86RotateWakeupHandler,
(pointer) pScreen);
}
xf86RotateDestroy (crtc);
}
else
{
@ -327,39 +405,41 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
*/
int width = mode->HDisplay;
int height = 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;
BoxRec damage_box;
RegionRec damage_region;
/* Allocate memory for rotation */
if (old_width != width || old_height != height)
{
if (shadow)
if (shadow || shadowData)
{
crtc->funcs->shadow_destroy (crtc, shadow);
crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
crtc->rotatedPixmap = NULL;
crtc->rotatedData = NULL;
}
shadow = crtc->funcs->shadow_create (crtc, width, height);
if (!shadow)
shadowData = crtc->funcs->shadow_allocate (crtc, width, height);
if (!shadowData)
goto bail1;
crtc->rotatedPixmap = shadow;
crtc->rotatedData = shadowData;
/* shadow will be damaged in xf86RotatePrepare */
}
else
{
/* mark shadowed area as damaged so it will be repainted */
xf86CrtcDamageShadow (crtc);
}
if (!xf86_config->rotationDamage)
if (!xf86_config->rotation_damage)
{
/* Create damage structure */
xf86_config->rotationDamage = DamageCreate (NULL, NULL,
xf86_config->rotation_damage = DamageCreate (NULL, NULL,
DamageReportNone,
TRUE, pScreen, pScreen);
if (!xf86_config->rotationDamage)
if (!xf86_config->rotation_damage)
goto bail2;
/* Hook damage to screen pixmap */
DamageRegister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
xf86_config->rotationDamage);
/* Assign block/wakeup handler */
if (!RegisterBlockAndWakeupHandlers (xf86RotateBlockHandler,
xf86RotateWakeupHandler,
@ -367,30 +447,24 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
{
goto bail3;
}
damage_box.x1 = 0;
damage_box.y1 = 0;
damage_box.x2 = mode_width (mode, rotation);
damage_box.y2 = mode_height (mode, rotation);
REGION_INIT (pScreen, &damage_region, &damage_box, 1);
DamageDamageRegion (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
&damage_region);
REGION_UNINIT (pScreen, &damage_region);
}
if (0)
{
bail3:
DamageDestroy (xf86_config->rotationDamage);
xf86_config->rotationDamage = NULL;
DamageDestroy (xf86_config->rotation_damage);
xf86_config->rotation_damage = NULL;
bail2:
if (shadow)
if (shadow || shadowData)
{
crtc->funcs->shadow_destroy (crtc, shadow);
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;

View File

@ -33,9 +33,14 @@
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#else
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#endif
#include "xf86.h"
#include "xf86Modes.h"
#include <string.h>

View File

@ -130,8 +130,8 @@ typedef signed long xf86ssize_t;
# include <errno.h>
# if defined(_NEED_SYSI86)
# include <sys/immu.h>
# if !(defined (sun) && defined (SVR4))
# include <sys/immu.h>
# include <sys/region.h>
# endif
# include <sys/proc.h>

View File

@ -37,4 +37,6 @@ EXTRA_DIST = \
cpconfig.c
sdk_HEADERS = \
$(LIBHEADERS)
$(LIBHEADERS) \
xf86Parser.h \
xf86Optrec.h

View File

@ -1,8 +1,6 @@
module_LTLIBRARIES = libramdac.la
noinst_LIBRARIES = libramdac.a
libramdac_la_LDFLAGS = -avoid-version
libramdac_la_SOURCES = xf86RamDacMod.c xf86RamDac.c xf86RamDacCmap.c \
libramdac_a_SOURCES = xf86RamDac.c xf86RamDacCmap.c \
xf86Cursor.c xf86HWCurs.c IBM.c BT.c TI.c \
xf86BitOrder.c

View File

@ -44,5 +44,8 @@ void xf86ForceHWCursor (ScreenPtr pScreen, Bool on);
#define HARDWARE_CURSOR_NIBBLE_SWAPPED 0x00000800
#define HARDWARE_CURSOR_SHOW_TRANSPARENT 0x00001000
#define HARDWARE_CURSOR_UPDATE_UNHIDDEN 0x00002000
#ifdef ARGB_CURSOR
#define HARDWARE_CURSOR_ARGB 0x00004000
#endif
#endif /* _XF86CURSOR_H */

View File

@ -181,7 +181,7 @@ LOOKUP xfree86LookupTab[] = {
SYMFUNC(xf86memchr)
SYMFUNC(xf86memcmp)
SYMFUNC(xf86memcpy)
#if (defined(__powerpc__) && (defined(Lynx) || defined(linux))) || defined(__sparc__) || defined(__ia64__) || defined (__amd64__)
#if (defined(__powerpc__) && (defined(Lynx) || defined(linux))) || defined(__sparc__) || defined(__sparc) || defined(__ia64__) || defined (__amd64__)
/*
* Some PPC, SPARC, and IA64 compilers generate calls to memcpy to handle
* structure copies. This causes a problem both here and in shared

View File

@ -1128,6 +1128,7 @@ CardConfig(void)
static char *xdrivers[] = {
"apm",
"ark",
"ast",
"ati",
"r128",
"radeon",

View File

@ -51,6 +51,11 @@ NAME ** Ark Logic (generic) [ark]
SERVER SVGA
DRIVER ark
NAME ** ASPEED Technology (generic) [ast]
#CHIPSET ast
SERVER SVGA
DRIVER ast
NAME ** ATI (generic) [ati]
#CHIPSET ati
SERVER SVGA

View File

@ -63,6 +63,40 @@ static void x86emuOp2_illegal_op(
#define xorl(a,b) ((a) && !(b)) || (!(a) && (b))
/****************************************************************************
REMARKS:
Handles opcode 0x0f,0x31
****************************************************************************/
static void x86emuOp2_rdtsc(u8 X86EMU_UNUSED(op2))
{
#ifdef __HAS_LONG_LONG__
static u64 counter = 0;
#else
static u32 counter = 0;
#endif
counter += 0x10000;
/* read timestamp counter */
/*
* Note that instead of actually trying to accurately measure this, we just
* increase the counter by a fixed amount every time we hit one of these
* instructions. Feel free to come up with a better method.
*/
START_OF_INSTR();
DECODE_PRINTF("RDTSC\n");
TRACE_AND_STEP();
#ifdef __HAS_LONG_LONG__
M.x86.R_EAX = counter & 0xffffffff;
M.x86.R_EDX = counter >> 32;
#else
M.x86.R_EAX = counter;
M.x86.R_EDX = 0;
#endif
DECODE_CLEAR_SEGOVR();
END_OF_INSTR();
}
/****************************************************************************
REMARKS:
Handles opcode 0x0f,0x80-0x8F
@ -2580,7 +2614,7 @@ void (*x86emu_optab2[256])(u8) =
/* 0x2f */ x86emuOp2_illegal_op,
/* 0x30 */ x86emuOp2_illegal_op,
/* 0x31 */ x86emuOp2_illegal_op,
/* 0x31 */ x86emuOp2_rdtsc,
/* 0x32 */ x86emuOp2_illegal_op,
/* 0x33 */ x86emuOp2_illegal_op,
/* 0x34 */ x86emuOp2_illegal_op,

View File

@ -1,6 +1,6 @@
xpcdir = @xpconfigdir@/C/print/models/CANONC3200-PS/fonts
parentdir = @xpconfigdir@/C/print/models/PSdefault/fonts
parentdir = ../../PSdefault/fonts
XPFONTS = \
AvantGarde-Book.pmf \
@ -19,10 +19,10 @@ XPFONTS = \
LubalinGraph-BookOblique.pmf \
LubalinGraph-Demi.pmf \
LubalinGraph-DemiOblique.pmf \
NewCenturySchlbk-Bold.pmf \
NewCenturySchlbk-BoldItalic.pmf \
NewCenturySchlbk-Italic.pmf \
NewCenturySchlbk-Roman.pmf \
NewCentSchlbk-Bold.pmf \
NewCentSchlbk-BoldItal.pmf \
NewCentSchlbk-Ital.pmf \
NewCentSchlbk-Roman.pmf \
Souvenir-Demi.pmf \
Souvenir-DemiItalic.pmf \
Souvenir-Light.pmf \

View File

@ -1,6 +1,6 @@
xpcdir = @xpconfigdir@/C/print/models/HPLJ4050-PS/fonts
parentdir = @xpconfigdir@/C/print/models/PSdefault/fonts
parentdir = ../../PSdefault/fonts
XPFONTS = \
AvantGarde-Book.pmf \
@ -19,10 +19,10 @@ XPFONTS = \
LubalinGraph-BookOblique.pmf \
LubalinGraph-Demi.pmf \
LubalinGraph-DemiOblique.pmf \
NewCenturySchlbk-Bold.pmf \
NewCenturySchlbk-BoldItalic.pmf \
NewCenturySchlbk-Italic.pmf \
NewCenturySchlbk-Roman.pmf \
NewCentSchlbk-Bold.pmf \
NewCentSchlbk-BoldItal.pmf \
NewCentSchlbk-Ital.pmf \
NewCentSchlbk-Roman.pmf \
Souvenir-Demi.pmf \
Souvenir-DemiItalic.pmf \
Souvenir-Light.pmf \

View File

@ -17,9 +17,10 @@ dist_xpc_DATA = \
LubalinGraph-Book.pmf \
LubalinGraph-DemiOblique.pmf \
LubalinGraph-Demi.pmf \
NewCenturySchlbk-Bold.pmf \
NewCenturySchlbk-Italic.pmf \
NewCenturySchlbk-Roman.pmf \
NewCentSchlbk-Bold.pmf \
NewCentSchlbk-BoldItal.pmf \
NewCentSchlbk-Ital.pmf \
NewCentSchlbk-Roman.pmf \
Souvenir-DemiItalic.pmf \
Souvenir-Demi.pmf \
Souvenir-LightItalic.pmf \

View File

@ -1,6 +1,6 @@
xpcdir = @xpconfigdir@/C/print/models/SPSPARC2/fonts
parentdir = @xpconfigdir@/C/print/models/PSdefault/fonts
parentdir = ../../PSdefault/fonts
XPFONTS = \
Courier-Bold.pmf \

View File

@ -125,7 +125,7 @@ struct _OsTimerRec {
};
static void DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev);
static void CheckAllTimers(CARD32 now);
static void CheckAllTimers(void);
static OsTimerPtr timers = NULL;
/*****************
@ -204,7 +204,7 @@ WaitForSomething(int *pClientsReady)
timeout = timers->expires - now;
if (timeout > 0 && timeout > timers->delta + 250) {
/* time has rewound. reset the timers. */
CheckAllTimers(now);
CheckAllTimers();
}
if (timers) {
@ -439,11 +439,14 @@ ANYSET(FdMask *src)
/* If time has rewound, re-run every affected timer.
* Timers might drop out of the list, so we have to restart every time. */
static void
CheckAllTimers(CARD32 now)
CheckAllTimers(void)
{
OsTimerPtr timer;
CARD32 now;
start:
now = GetTimeInMillis();
for (timer = timers; timer; timer = timer->next) {
if (timer->expires - now > timer->delta + 250) {
TimerForce(timer);

View File

@ -1050,6 +1050,8 @@ CloseDownConnection(ClientPtr client)
XdmcpCloseDisplay(oc->fd);
#endif
CloseDownFileDescriptor(oc);
FreeOsBuffers(oc);
xfree(client->osPrivate);
client->osPrivate = (pointer)NULL;
if (auditTrailLevel > 1)
AuditF("client %d disconnected\n", client->index);

View File

@ -73,6 +73,20 @@ miRROutputSetProperty (ScreenPtr pScreen,
return TRUE;
}
Bool
miRROutputValidateMode (ScreenPtr pScreen,
RROutputPtr output,
RRModePtr mode)
{
return FALSE;
}
void
miRRModeDestroy (ScreenPtr pScreen,
RRModePtr mode)
{
}
/*
* This function assumes that only a single depth can be
* displayed at a time, but that all visuals of that depth
@ -102,7 +116,8 @@ miRandRInit (ScreenPtr pScreen)
pScrPriv->rrCrtcSet = miRRCrtcSet;
pScrPriv->rrCrtcSetGamma = miRRCrtcSetGamma;
pScrPriv->rrOutputSetProperty = miRROutputSetProperty;
pScrPriv->rrOutputValidateMode = miRROutputValidateMode;
pScrPriv->rrModeDestroy = miRRModeDestroy;
RRScreenSetSizeRange (pScreen,
pScreen->width, pScreen->height,
@ -118,20 +133,13 @@ miRandRInit (ScreenPtr pScreen)
if (!mode)
return FALSE;
crtc = RRCrtcCreate (NULL);
crtc = RRCrtcCreate (pScreen, NULL);
if (!crtc)
return FALSE;
if (!RRCrtcAttachScreen (crtc, pScreen))
{
RRCrtcDestroy (crtc);
return FALSE;
}
output = RROutputCreate ("screen", 6, NULL);
output = RROutputCreate (pScreen, "screen", 6, NULL);
if (!output)
return FALSE;
if (!RROutputAttachScreen (output, pScreen))
return FALSE;
if (!RROutputSetClones (output, NULL, 0))
return FALSE;
if (!RROutputSetModes (output, &mode, 1, 0))

View File

@ -230,7 +230,7 @@ Bool RRScreenInit(ScreenPtr pScreen)
RRScreenGeneration = serverGeneration;
}
pScrPriv = (rrScrPrivPtr) xalloc (sizeof (rrScrPrivRec));
pScrPriv = (rrScrPrivPtr) xcalloc (1, sizeof (rrScrPrivRec));
if (!pScrPriv)
return FALSE;

View File

@ -79,8 +79,7 @@ struct _rrMode {
int refcnt;
xRRModeInfo mode;
char *name;
void *devPrivate;
Bool userDefined;
ScreenPtr userScreen;
};
struct _rrPropertyValue {
@ -135,8 +134,11 @@ struct _rrOutput {
int numModes;
int numPreferred;
RRModePtr *modes;
int numUserModes;
RRModePtr *userModes;
Bool changed;
RRPropertyPtr properties;
Bool pendingProperties;
void *devPrivate;
};
@ -164,6 +166,13 @@ typedef Bool (*RROutputSetPropertyProcPtr) (ScreenPtr pScreen,
Atom property,
RRPropertyValuePtr value);
typedef Bool (*RROutputValidateModeProcPtr) (ScreenPtr pScreen,
RROutputPtr output,
RRModePtr mode);
typedef void (*RRModeDestroyProcPtr) (ScreenPtr pScreen,
RRModePtr mode);
#endif
typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations);
@ -208,6 +217,8 @@ typedef struct _rrScrPriv {
RRCrtcSetProcPtr rrCrtcSet;
RRCrtcSetGammaProcPtr rrCrtcSetGamma;
RROutputSetPropertyProcPtr rrOutputSetProperty;
RROutputValidateModeProcPtr rrOutputValidateMode;
RRModeDestroyProcPtr rrModeDestroy;
#endif
/*
@ -394,6 +405,15 @@ miRROutputSetProperty (ScreenPtr pScreen,
Atom property,
RRPropertyValuePtr value);
Bool
miRROutputValidateMode (ScreenPtr pScreen,
RROutputPtr output,
RRModePtr mode);
void
miRRModeDestroy (ScreenPtr pScreen,
RRModePtr mode);
/* randr.c */
/*
* Send all pending events
@ -477,7 +497,7 @@ RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged);
* Create a CRTC
*/
RRCrtcPtr
RRCrtcCreate (void *devPrivate);
RRCrtcCreate (ScreenPtr pScreen, void *devPrivate);
/*
* Set the allowed rotations on a CRTC
@ -485,14 +505,6 @@ RRCrtcCreate (void *devPrivate);
void
RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations);
/*
* Attach a CRTC to a screen. Once done, this cannot be
* undone without destroying the CRTC; it is separate from Create
* only to allow an xf86-based driver to create objects in preinit
*/
Bool
RRCrtcAttachScreen (RRCrtcPtr crtc, ScreenPtr pScreen);
/*
* Notify the extension that the Crtc has been reconfigured,
* the driver calls this whenever it has updated the mode
@ -548,6 +560,10 @@ Bool
RRCrtcGammaSetSize (RRCrtcPtr crtc,
int size);
/*
* Return the area of the frame buffer scanned out by the crtc,
* taking into account the current mode and rotation
*/
void
RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height);
@ -645,18 +661,11 @@ RROutputChanged (RROutputPtr output, Bool configChanged);
*/
RROutputPtr
RROutputCreate (const char *name,
RROutputCreate (ScreenPtr pScreen,
const char *name,
int nameLength,
void *devPrivate);
/*
* Attach an output to a screen, again split from creation so
* xf86 DDXen can create randr resources before the ScreenRec
* exists
*/
Bool
RROutputAttachScreen (RROutputPtr output, ScreenPtr pScreen);
/*
* Notify extension that output parameters have been changed
*/
@ -671,6 +680,14 @@ RROutputSetModes (RROutputPtr output,
int numModes,
int numPreferred);
int
RROutputAddUserMode (RROutputPtr output,
RRModePtr mode);
int
RROutputDeleteUserMode (RROutputPtr output,
RRModePtr mode);
Bool
RROutputSetCrtcs (RROutputPtr output,
RRCrtcPtr *crtcs,
@ -728,10 +745,13 @@ RRQueryOutputProperty (RROutputPtr output, Atom property);
void
RRDeleteOutputProperty (RROutputPtr output, Atom property);
Bool
RRPostPendingProperties (RROutputPtr output);
int
RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
int format, int mode, unsigned long len,
pointer value, Bool sendevent);
pointer value, Bool sendevent, Bool pending);
int
RRConfigureOutputProperty (RROutputPtr output, Atom property,

View File

@ -51,17 +51,32 @@ RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged)
* Create a CRTC
*/
RRCrtcPtr
RRCrtcCreate (void *devPrivate)
RRCrtcCreate (ScreenPtr pScreen, void *devPrivate)
{
RRCrtcPtr crtc;
RRCrtcPtr crtc;
RRCrtcPtr *crtcs;
rrScrPrivPtr pScrPriv;
if (!RRInit())
return NULL;
pScrPriv = rrGetScrPriv(pScreen);
/* make space for the crtc pointer */
if (pScrPriv->numCrtcs)
crtcs = xrealloc (pScrPriv->crtcs,
(pScrPriv->numCrtcs + 1) * sizeof (RRCrtcPtr));
else
crtcs = xalloc (sizeof (RRCrtcPtr));
if (!crtcs)
return FALSE;
pScrPriv->crtcs = crtcs;
crtc = xalloc (sizeof (RRCrtcRec));
if (!crtc)
return NULL;
crtc->id = FakeClientID (0);
crtc->pScreen = NULL;
crtc->pScreen = pScreen;
crtc->mode = NULL;
crtc->x = 0;
crtc->y = 0;
@ -77,6 +92,10 @@ RRCrtcCreate (void *devPrivate)
if (!AddResource (crtc->id, RRCrtcType, (pointer) crtc))
return NULL;
/* attach the screen and crtc together */
crtc->pScreen = pScreen;
pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc;
return crtc;
}
@ -89,36 +108,6 @@ RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations)
crtc->rotations = rotations;
}
/*
* Attach a Crtc to a screen. This is done as a separate step
* so that an xf86-based driver can create CRTCs in PreInit
* before the Screen has been created
*/
Bool
RRCrtcAttachScreen (RRCrtcPtr crtc, ScreenPtr pScreen)
{
rrScrPriv (pScreen);
RRCrtcPtr *crtcs;
/* make space for the crtc pointer */
if (pScrPriv->numCrtcs)
crtcs = xrealloc (pScrPriv->crtcs,
(pScrPriv->numCrtcs + 1) * sizeof (RRCrtcPtr));
else
crtcs = xalloc (sizeof (RRCrtcPtr));
if (!crtcs)
return FALSE;
/* attach the screen and crtc together */
crtc->pScreen = pScreen;
pScrPriv->crtcs = crtcs;
pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc;
RRCrtcChanged (crtc, TRUE);
return TRUE;
}
/*
* Notify the extension that the Crtc has been reconfigured,
* the driver calls this whenever it has updated the mode
@ -258,6 +247,22 @@ RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc)
WriteEventsToClient (client, 1, (xEvent *) &ce);
}
static Bool
RRCrtcPendingProperties (RRCrtcPtr crtc)
{
ScreenPtr pScreen = crtc->pScreen;
rrScrPriv(pScreen);
int o;
for (o = 0; o < pScrPriv->numOutputs; o++)
{
RROutputPtr output = pScrPriv->outputs[o];
if (output->crtc == crtc && output->pendingProperties)
return TRUE;
}
return FALSE;
}
/*
* Request that the Crtc be reconfigured
*/
@ -271,6 +276,8 @@ RRCrtcSet (RRCrtcPtr crtc,
RROutputPtr *outputs)
{
ScreenPtr pScreen = crtc->pScreen;
Bool ret = FALSE;
rrScrPriv(pScreen);
/* See if nothing changed */
if (crtc->mode == mode &&
@ -278,54 +285,73 @@ RRCrtcSet (RRCrtcPtr crtc,
crtc->y == y &&
crtc->rotation == rotation &&
crtc->numOutputs == numOutputs &&
!memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)))
!memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)) &&
!RRCrtcPendingProperties (crtc))
{
return TRUE;
ret = TRUE;
}
if (pScreen)
else
{
#if RANDR_12_INTERFACE
rrScrPriv(pScreen);
if (pScrPriv->rrCrtcSet)
{
return (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y,
rotation, numOutputs, outputs);
ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y,
rotation, numOutputs, outputs);
}
else
#endif
#if RANDR_10_INTERFACE
if (pScrPriv->rrSetConfig)
{
RRScreenSize size;
RRScreenRate rate;
Bool ret;
#if RANDR_10_INTERFACE
if (pScrPriv->rrSetConfig)
{
RRScreenSize size;
RRScreenRate rate;
size.width = mode->mode.width;
size.height = mode->mode.height;
if (outputs[0]->mmWidth && outputs[0]->mmHeight)
{
size.mmWidth = outputs[0]->mmWidth;
size.mmHeight = outputs[0]->mmHeight;
if (!mode)
{
RRCrtcNotify (crtc, NULL, x, y, rotation, 0, NULL);
ret = TRUE;
}
else
{
size.width = mode->mode.width;
size.height = mode->mode.height;
if (outputs[0]->mmWidth && outputs[0]->mmHeight)
{
size.mmWidth = outputs[0]->mmWidth;
size.mmHeight = outputs[0]->mmHeight;
}
else
{
size.mmWidth = pScreen->mmWidth;
size.mmHeight = pScreen->mmHeight;
}
size.nRates = 1;
rate.rate = RRVerticalRefresh (&mode->mode);
size.pRates = &rate;
ret = (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate, &size);
/*
* Old 1.0 interface tied screen size to mode size
*/
if (ret)
{
RRCrtcNotify (crtc, mode, x, y, rotation, 1, outputs);
RRScreenSizeNotify (pScreen);
}
}
}
else
{
size.mmWidth = pScreen->mmWidth;
size.mmHeight = pScreen->mmHeight;
}
size.nRates = 1;
rate.rate = RRVerticalRefresh (&mode->mode);
size.pRates = &rate;
ret = (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate, &size);
/*
* Old 1.0 interface tied screen size to mode size
*/
if (ret)
RRCrtcNotify (crtc, mode, x, y, rotation, 1, outputs);
return ret;
}
#endif
RRTellChanged (pScreen);
}
if (ret)
{
int o;
RRTellChanged (pScreen);
for (o = 0; o < numOutputs; o++)
RRPostPendingProperties (outputs[o]);
}
}
return FALSE;
return ret;
}
/*
@ -361,6 +387,8 @@ RRCrtcDestroyResource (pointer value, XID pid)
}
if (crtc->gammaRed)
xfree (crtc->gammaRed);
if (crtc->mode)
RRModeDestroy (crtc->mode);
xfree (crtc);
return 1;
}
@ -490,6 +518,7 @@ ProcRRGetCrtcInfo (ClientPtr client)
RROutput *outputs;
RROutput *possible;
int i, j, k, n;
int width, height;
REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq);
crtc = LookupCrtc(client, stuff->crtc, SecurityReadAccess);
@ -512,8 +541,9 @@ ProcRRGetCrtcInfo (ClientPtr client)
rep.timestamp = pScrPriv->lastSetTime.milliseconds;
rep.x = crtc->x;
rep.y = crtc->y;
rep.width = mode ? mode->mode.width : 0;
rep.height = mode ? mode->mode.height : 0;
RRCrtcGetScanoutSize (crtc, &width, &height);
rep.width = width;
rep.height = height;
rep.mode = mode ? mode->mode.id : 0;
rep.rotation = crtc->rotation;
rep.rotations = crtc->rotations;
@ -655,16 +685,42 @@ ProcRRSetCrtcConfig (ClientPtr client)
return BadMatch;
}
/* validate mode for this output */
for (j = 0; j < outputs[i]->numModes; j++)
if (outputs[i]->modes[j] == mode)
for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++)
{
RRModePtr m = (j < outputs[i]->numModes ?
outputs[i]->modes[j] :
outputs[i]->userModes[j - outputs[i]->numModes]);
if (m == mode)
break;
if (j == outputs[i]->numModes)
}
if (j == outputs[i]->numModes + outputs[i]->numUserModes)
{
if (outputs)
xfree (outputs);
return BadMatch;
}
}
/* validate clones */
for (i = 0; i < numOutputs; i++)
{
for (j = 0; j < numOutputs; j++)
{
int k;
if (i == j)
continue;
for (k = 0; k < outputs[i]->numClones; k++)
{
if (outputs[i]->clones[k] == outputs[j])
break;
}
if (k == outputs[i]->numClones)
{
if (outputs)
xfree (outputs);
return BadMatch;
}
}
}
pScreen = crtc->pScreen;
pScrPriv = rrGetScrPriv(pScreen);
@ -679,6 +735,7 @@ ProcRRSetCrtcConfig (ClientPtr client)
goto sendReply;
}
#if 0
/*
* if the client's config timestamp is not the same as the last config
* timestamp, then the config information isn't up-to-date and
@ -689,6 +746,7 @@ ProcRRSetCrtcConfig (ClientPtr client)
rep.status = RRSetConfigInvalidConfigTime;
goto sendReply;
}
#endif
/*
* Validate requested rotation

View File

@ -91,19 +91,12 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations)
if (pScrPriv->numOutputs == 0 &&
pScrPriv->numCrtcs == 0)
{
crtc = RRCrtcCreate (NULL);
crtc = RRCrtcCreate (pScreen, NULL);
if (!crtc)
return;
if (!RRCrtcAttachScreen (crtc, pScreen))
{
RRCrtcDestroy (crtc);
return;
}
output = RROutputCreate ("default", 7, NULL);
output = RROutputCreate (pScreen, "default", 7, NULL);
if (!output)
return;
if (!RROutputAttachScreen (output, pScreen))
return;
RROutputSetCrtcs (output, &crtc, 1);
RROutputSetCrtc (output, crtc);
RROutputSetConnection (output, RR_Connected);
@ -157,9 +150,11 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations)
pScrPriv->nSizes = 0;
/* find size bounds */
for (i = 0; i < output->numModes; i++)
for (i = 0; i < output->numModes + output->numUserModes; i++)
{
RRModePtr mode = output->modes[i];
RRModePtr mode = (i < output->numModes ?
output->modes[i] :
output->userModes[i-output->numModes]);
CARD16 width = mode->mode.width;
CARD16 height = mode->mode.height;

View File

@ -48,25 +48,13 @@ RRModeEqual (xRRModeInfo *a, xRRModeInfo *b)
static int num_modes;
static RRModePtr *modes;
RRModePtr
RRModeGet (xRRModeInfo *modeInfo,
const char *name)
static RRModePtr
RRModeCreate (xRRModeInfo *modeInfo,
const char *name,
ScreenPtr userScreen)
{
int i;
RRModePtr mode;
RRModePtr *newModes;
for (i = 0; i < num_modes; i++)
{
mode = modes[i];
if (RRModeEqual (&mode->mode, modeInfo) &&
!memcmp (name, mode->name, modeInfo->nameLength))
{
++mode->refcnt;
return mode;
}
}
RRModePtr mode, *newModes;
if (!RRInit ())
return NULL;
@ -78,7 +66,7 @@ RRModeGet (xRRModeInfo *modeInfo,
mode->name = (char *) (mode + 1);
memcpy (mode->name, name, modeInfo->nameLength);
mode->name[modeInfo->nameLength] = '\0';
mode->userDefined = FALSE;
mode->userScreen = userScreen;
if (num_modes)
newModes = xrealloc (modes, (num_modes + 1) * sizeof (RRModePtr));
@ -104,11 +92,75 @@ RRModeGet (xRRModeInfo *modeInfo,
return mode;
}
static RRModePtr
RRModeFindByName (const char *name,
CARD16 nameLength)
{
int i;
RRModePtr mode;
for (i = 0; i < num_modes; i++)
{
mode = modes[i];
if (mode->mode.nameLength == nameLength &&
!memcmp (name, mode->name, nameLength))
{
return mode;
}
}
return NULL;
}
RRModePtr
RRModeGet (xRRModeInfo *modeInfo,
const char *name)
{
int i;
for (i = 0; i < num_modes; i++)
{
RRModePtr mode = modes[i];
if (RRModeEqual (&mode->mode, modeInfo) &&
!memcmp (name, mode->name, modeInfo->nameLength))
{
++mode->refcnt;
return mode;
}
}
return RRModeCreate (modeInfo, name, NULL);
}
static RRModePtr
RRModeCreateUser (ScreenPtr pScreen,
xRRModeInfo *modeInfo,
const char *name,
int *error)
{
RRModePtr mode;
mode = RRModeFindByName (name, modeInfo->nameLength);
if (mode)
{
*error = BadName;
return NULL;
}
mode = RRModeCreate (modeInfo, name, pScreen);
if (!mode)
{
*error = BadAlloc;
return NULL;
}
*error = Success;
return mode;
}
RRModePtr *
RRModesForScreen (ScreenPtr pScreen, int *num_ret)
{
rrScrPriv(pScreen);
int o, c;
int o, c, m;
RRModePtr *screen_modes;
int num_screen_modes = 0;
@ -122,9 +174,11 @@ RRModesForScreen (ScreenPtr pScreen, int *num_ret)
RROutputPtr output = pScrPriv->outputs[o];
int m, n;
for (m = 0; m < output->numModes; m++)
for (m = 0; m < output->numModes + output->numUserModes; m++)
{
RRModePtr mode = output->modes[m];
RRModePtr mode = (m < output->numModes ?
output->modes[m] :
output->userModes[m-output->numModes]);
for (n = 0; n < num_screen_modes; n++)
if (screen_modes[n] == mode)
break;
@ -150,6 +204,23 @@ RRModesForScreen (ScreenPtr pScreen, int *num_ret)
if (n == num_screen_modes)
screen_modes[num_screen_modes++] = mode;
}
/*
* Add all user modes for this screen
*/
for (m = 0; m < num_modes; m++)
{
RRModePtr mode = modes[m];
int n;
if (mode->userScreen != pScreen)
continue;
for (n = 0; n < num_screen_modes; n++)
if (screen_modes[n] == mode)
break;
if (n == num_screen_modes)
screen_modes[num_screen_modes++] = mode;
}
*num_ret = num_screen_modes;
return screen_modes;
}
@ -205,38 +276,123 @@ int
ProcRRCreateMode (ClientPtr client)
{
REQUEST(xRRCreateModeReq);
xRRCreateModeReply rep;
WindowPtr pWin;
ScreenPtr pScreen;
rrScrPrivPtr pScrPriv;
xRRModeInfo *modeInfo;
long units_after;
char *name;
int error;
RRModePtr mode;
REQUEST_SIZE_MATCH(xRRCreateModeReq);
(void) stuff;
return BadImplementation;
REQUEST_AT_LEAST_SIZE (xRRCreateModeReq);
pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
SecurityReadAccess);
if (!pWin)
return BadWindow;
pScreen = pWin->drawable.pScreen;
pScrPriv = rrGetScrPriv(pScreen);
modeInfo = &stuff->modeInfo;
name = (char *) (stuff + 1);
units_after = (stuff->length - (sizeof (xRRCreateModeReq) >> 2));
/* check to make sure requested name fits within the data provided */
if ((int) (modeInfo->nameLength + 3) >> 2 > units_after)
return BadLength;
mode = RRModeCreateUser (pScreen, modeInfo, name, &error);
if (!mode)
return error;
rep.type = X_Reply;
rep.pad0 = 0;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.mode = mode->mode.id;
if (client->swapped)
{
int n;
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.mode, n);
}
WriteToClient(client, sizeof(xRRCreateModeReply), (char *)&rep);
return client->noClientException;
}
int
ProcRRDestroyMode (ClientPtr client)
{
REQUEST(xRRDestroyModeReq);
RRModePtr mode;
REQUEST_SIZE_MATCH(xRRDestroyModeReq);
(void) stuff;
return BadImplementation;
mode = LookupIDByType (stuff->mode, RRModeType);
if (!mode)
{
client->errorValue = stuff->mode;
return RRErrorBase + BadRRMode;
}
if (!mode->userScreen)
return BadMatch;
if (mode->refcnt > 1)
return BadAccess;
FreeResource (stuff->mode, 0);
return Success;
}
int
ProcRRAddOutputMode (ClientPtr client)
{
REQUEST(xRRAddOutputModeReq);
RRModePtr mode;
RROutputPtr output;
REQUEST_SIZE_MATCH(xRRAddOutputModeReq);
(void) stuff;
return BadImplementation;
output = LookupOutput(client, stuff->output, SecurityReadAccess);
if (!output)
{
client->errorValue = stuff->output;
return RRErrorBase + BadRROutput;
}
mode = LookupIDByType (stuff->mode, RRModeType);
if (!mode)
{
client->errorValue = stuff->mode;
return RRErrorBase + BadRRMode;
}
return RROutputAddUserMode (output, mode);
}
int
ProcRRDeleteOutputMode (ClientPtr client)
{
REQUEST(xRRDeleteOutputModeReq);
RRModePtr mode;
RROutputPtr output;
REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq);
(void) stuff;
return BadImplementation;
output = LookupOutput(client, stuff->output, SecurityReadAccess);
if (!output)
{
client->errorValue = stuff->output;
return RRErrorBase + BadRROutput;
}
mode = LookupIDByType (stuff->mode, RRModeType);
if (!mode)
{
client->errorValue = stuff->mode;
return RRErrorBase + BadRRMode;
}
return RROutputDeleteUserMode (output, mode);
}

View File

@ -47,19 +47,35 @@ RROutputChanged (RROutputPtr output, Bool configChanged)
*/
RROutputPtr
RROutputCreate (const char *name,
RROutputCreate (ScreenPtr pScreen,
const char *name,
int nameLength,
void *devPrivate)
{
RROutputPtr output;
RROutputPtr output;
RROutputPtr *outputs;
rrScrPrivPtr pScrPriv;
if (!RRInit())
return NULL;
pScrPriv = rrGetScrPriv(pScreen);
if (pScrPriv->numOutputs)
outputs = xrealloc (pScrPriv->outputs,
(pScrPriv->numOutputs + 1) * sizeof (RROutputPtr));
else
outputs = xalloc (sizeof (RROutputPtr));
if (!outputs)
return FALSE;
pScrPriv->outputs = outputs;
output = xalloc (sizeof (RROutputRec) + nameLength + 1);
if (!output)
return NULL;
output->id = FakeClientID (0);
output->pScreen = NULL;
output->pScreen = pScreen;
output->name = (char *) (output + 1);
output->nameLength = nameLength;
memcpy (output->name, name, nameLength);
@ -76,6 +92,8 @@ RROutputCreate (const char *name,
output->numModes = 0;
output->numPreferred = 0;
output->modes = NULL;
output->numUserModes = 0;
output->userModes = NULL;
output->properties = NULL;
output->changed = FALSE;
output->devPrivate = devPrivate;
@ -83,35 +101,10 @@ RROutputCreate (const char *name,
if (!AddResource (output->id, RROutputType, (pointer) output))
return NULL;
pScrPriv->outputs[pScrPriv->numOutputs++] = output;
return output;
}
/*
* Attach an Output to a screen. This is done as a separate step
* so that an xf86-based driver can create Outputs in PreInit
* before the Screen has been created
*/
Bool
RROutputAttachScreen (RROutputPtr output, ScreenPtr pScreen)
{
rrScrPriv (pScreen);
RROutputPtr *outputs;
if (pScrPriv->numOutputs)
outputs = xrealloc (pScrPriv->outputs,
(pScrPriv->numOutputs + 1) * sizeof (RROutputPtr));
else
outputs = xalloc (sizeof (RROutputPtr));
if (!outputs)
return FALSE;
output->pScreen = pScreen;
pScrPriv->outputs = outputs;
pScrPriv->outputs[pScrPriv->numOutputs++] = output;
RROutputChanged (output, FALSE);
return TRUE;
}
/*
* Notify extension that output parameters have been changed
*/
@ -192,6 +185,74 @@ RROutputSetModes (RROutputPtr output,
return TRUE;
}
int
RROutputAddUserMode (RROutputPtr output,
RRModePtr mode)
{
int m;
ScreenPtr pScreen = output->pScreen;
rrScrPriv(pScreen);
RRModePtr *newModes;
/* Check to see if this mode is already listed for this output */
for (m = 0; m < output->numModes + output->numUserModes; m++)
{
RRModePtr e = (m < output->numModes ?
output->modes[m] :
output->userModes[m - output->numModes]);
if (mode == e)
return Success;
}
/* Check with the DDX to see if this mode is OK */
if (pScrPriv->rrOutputValidateMode)
if (!pScrPriv->rrOutputValidateMode (pScreen, output, mode))
return BadMatch;
if (output->userModes)
newModes = xrealloc (output->userModes,
(output->numUserModes + 1) * sizeof (RRModePtr));
else
newModes = xalloc (sizeof (RRModePtr));
if (!newModes)
return BadAlloc;
output->userModes = newModes;
output->userModes[output->numUserModes++] = mode;
++mode->refcnt;
RROutputChanged (output, TRUE);
RRTellChanged (pScreen);
return Success;
}
int
RROutputDeleteUserMode (RROutputPtr output,
RRModePtr mode)
{
int m;
/* Find this mode in the user mode list */
for (m = 0; m < output->numUserModes; m++)
{
RRModePtr e = output->userModes[m];
if (mode == e)
break;
}
/* Not there, access error */
if (m == output->numUserModes)
return BadAccess;
/* make sure the mode isn't active for this output */
if (output->crtc && output->crtc->mode == mode)
return BadMatch;
memmove (output->userModes + m, output->userModes + m + 1,
(output->numUserModes - m - 1) * sizeof (RRModePtr));
RRModeDestroy (mode);
return Success;
}
Bool
RROutputSetCrtcs (RROutputPtr output,
RRCrtcPtr *crtcs,
@ -308,9 +369,9 @@ RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output)
* Destroy a Output at shutdown
*/
void
RROutputDestroy (RROutputPtr crtc)
RROutputDestroy (RROutputPtr output)
{
FreeResource (crtc->id, 0);
FreeResource (output->id, 0);
}
static int
@ -318,6 +379,7 @@ RROutputDestroyResource (pointer value, XID pid)
{
RROutputPtr output = (RROutputPtr) value;
ScreenPtr pScreen = output->pScreen;
int m;
if (pScreen)
{
@ -336,7 +398,17 @@ RROutputDestroyResource (pointer value, XID pid)
}
}
if (output->modes)
{
for (m = 0; m < output->numModes; m++)
RRModeDestroy (output->modes[m]);
xfree (output->modes);
}
for (m = 0; m < output->numUserModes; m++)
RRModeDestroy (output->userModes[m]);
if (output->userModes)
xfree (output->userModes);
if (output->crtcs)
xfree (output->crtcs);
if (output->clones)
@ -383,7 +455,10 @@ ProcRRGetOutputInfo (ClientPtr client)
output = LookupOutput(client, stuff->output, SecurityReadAccess);
if (!output)
{
client->errorValue = stuff->output;
return RRErrorBase + BadRROutput;
}
pScreen = output->pScreen;
pScrPriv = rrGetScrPriv(pScreen);
@ -398,13 +473,13 @@ ProcRRGetOutputInfo (ClientPtr client)
rep.connection = output->connection;
rep.subpixelOrder = output->subpixelOrder;
rep.nCrtcs = output->numCrtcs;
rep.nModes = output->numModes;
rep.nModes = output->numModes + output->numUserModes;
rep.nPreferred = output->numPreferred;
rep.nClones = output->numClones;
rep.nameLength = output->nameLength;
extraLen = ((output->numCrtcs +
output->numModes +
output->numModes + output->numUserModes +
output->numClones +
((rep.nameLength + 3) >> 2)) << 2);
@ -420,7 +495,7 @@ ProcRRGetOutputInfo (ClientPtr client)
crtcs = (RRCrtc *) extra;
modes = (RRMode *) (crtcs + output->numCrtcs);
clones = (RROutput *) (modes + output->numModes);
clones = (RROutput *) (modes + output->numModes + output->numUserModes);
name = (char *) (clones + output->numClones);
for (i = 0; i < output->numCrtcs; i++)
@ -429,9 +504,12 @@ ProcRRGetOutputInfo (ClientPtr client)
if (client->swapped)
swapl (&crtcs[i], n);
}
for (i = 0; i < output->numModes; i++)
for (i = 0; i < output->numModes + output->numUserModes; i++)
{
modes[i] = output->modes[i]->mode.id;
if (i < output->numModes)
modes[i] = output->modes[i]->mode.id;
else
modes[i] = output->userModes[i - output->numModes]->mode.id;
if (client->swapped)
swapl (&modes[i], n);
}

View File

@ -27,7 +27,7 @@
static void
RRDeliverEvent (ScreenPtr pScreen, xEvent *event, CARD32 mask)
{
}
void
@ -50,7 +50,7 @@ RRDeleteAllOutputProperties (RROutputPtr output)
xfree(prop->current.data);
if (prop->pending.data)
xfree(prop->pending.data);
xfree(prop);
xfree(prop);
}
}
@ -67,7 +67,7 @@ static RRPropertyPtr
RRCreateOutputProperty (Atom property)
{
RRPropertyPtr prop;
prop = (RRPropertyPtr)xalloc(sizeof(RRPropertyRec));
if (!prop)
return NULL;
@ -121,105 +121,114 @@ RRDeleteOutputProperty (RROutputPtr output, Atom property)
int
RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
int format, int mode, unsigned long len,
pointer value, Bool sendevent)
pointer value, Bool sendevent, Bool pending)
{
RRPropertyPtr prop;
xRROutputPropertyNotifyEvent event;
rrScrPrivPtr pScrPriv = rrGetScrPriv(output->pScreen);
int sizeInBytes;
int totalSize;
pointer data;
int size_in_bytes;
int total_size;
unsigned long total_len;
RRPropertyValuePtr prop_value;
RRPropertyValueRec new_value;
Bool add = FALSE;
sizeInBytes = format >> 3;
totalSize = len * sizeInBytes;
size_in_bytes = format >> 3;
/* first see if property already exists */
prop = RRQueryOutputProperty (output, property);
if (!prop) /* just add to list */
{
prop = RRCreateOutputProperty (property);
prop = RRCreateOutputProperty (property);
if (!prop)
return(BadAlloc);
add = TRUE;
mode = PropModeReplace;
}
if (prop->is_pending)
if (pending && prop->is_pending)
prop_value = &prop->pending;
else
prop_value = &prop->current;
/* To append or prepend to a property the request format and type
must match those of the already defined property. The
existing format and type are irrelevant when using the mode
"PropModeReplace" since they will be written over. */
must match those of the already defined property. The
existing format and type are irrelevant when using the mode
"PropModeReplace" since they will be written over. */
if ((format != prop_value->format) && (mode != PropModeReplace))
return(BadMatch);
if ((prop_value->type != type) && (mode != PropModeReplace))
return(BadMatch);
new_value = *prop_value;
if (mode == PropModeReplace)
total_len = len;
else
total_len = prop_value->size + len;
if (mode == PropModeReplace || len > 0)
{
if (totalSize != prop_value->size * (prop_value->format >> 3))
pointer new_data = NULL, old_data = NULL;
total_size = total_len * size_in_bytes;
new_value.data = (pointer)xalloc (total_size);
if (!new_value.data && total_size)
{
if (prop_value->data)
data = (pointer)xrealloc(prop_value->data, totalSize);
else
data = (pointer)xalloc (totalSize);
if (!data && len)
{
if (add)
RRDestroyOutputProperty (prop);
return(BadAlloc);
}
prop_value->data = data;
if (add)
RRDestroyOutputProperty (prop);
return BadAlloc;
}
if (len)
memmove((char *)prop_value->data, (char *)value, totalSize);
prop_value->size = len;
prop_value->type = type;
prop_value->format = format;
new_value.size = len;
new_value.type = type;
new_value.format = format;
switch (mode) {
case PropModeReplace:
new_data = new_value.data;
old_data = NULL;
break;
case PropModeAppend:
new_data = (pointer) (((char *) new_value.data) +
(prop_value->size * size_in_bytes));
old_data = new_value.data;
break;
case PropModePrepend:
new_data = new_value.data;
old_data = (pointer) (((char *) new_value.data) +
(prop_value->size * size_in_bytes));
break;
}
if (new_data)
memcpy ((char *) new_data, (char *) value, len * size_in_bytes);
if (old_data)
memcpy ((char *) old_data, (char *) prop_value->data,
prop_value->size * size_in_bytes);
if (pending && pScrPriv->rrOutputSetProperty &&
!pScrPriv->rrOutputSetProperty(output->pScreen, output,
prop->propertyName, &new_value))
{
if (new_value.data)
xfree (new_value.data);
return (BadValue);
}
if (prop_value->data)
xfree (prop_value->data);
*prop_value = new_value;
}
else if (len == 0)
{
/* do nothing */
}
else if (mode == PropModeAppend)
{
data = (pointer)xrealloc(prop_value->data,
sizeInBytes * (len + prop_value->size));
if (!data)
return(BadAlloc);
prop_value->data = data;
memmove(&((char *)data)[prop_value->size * sizeInBytes],
(char *)value,
totalSize);
prop_value->size += len;
}
else if (mode == PropModePrepend)
{
data = (pointer)xalloc(sizeInBytes * (len + prop_value->size));
if (!data)
return(BadAlloc);
memmove(&((char *)data)[totalSize], (char *)prop_value->data,
(int)(prop_value->size * sizeInBytes));
memmove((char *)data, (char *)value, totalSize);
xfree(prop_value->data);
prop_value->data = data;
prop_value->size += len;
}
if (add)
{
prop->next = output->properties;
output->properties = prop;
}
if (!prop->is_pending && pScrPriv->rrOutputSetProperty) {
/* What should we do in case of failure? */
pScrPriv->rrOutputSetProperty(output->pScreen, output,
prop->propertyName, prop_value);
}
if (pending && prop->is_pending)
output->pendingProperties = TRUE;
if (sendevent)
{
@ -234,6 +243,48 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
return(Success);
}
Bool
RRPostPendingProperties (RROutputPtr output)
{
RRPropertyValuePtr pending_value;
RRPropertyValuePtr current_value;
RRPropertyPtr property;
Bool ret = TRUE;
if (!output->pendingProperties)
return TRUE;
output->pendingProperties = FALSE;
for (property = output->properties; property; property = property->next)
{
/* Skip non-pending properties */
if (!property->is_pending)
continue;
pending_value = &property->pending;
current_value = &property->current;
/*
* If the pending and current values are equal, don't mark it
* as changed (which would deliver an event)
*/
if (pending_value->type == current_value->type &&
pending_value->format == current_value->format &&
pending_value->size == current_value->size &&
!memcmp (pending_value->data, current_value->data,
pending_value->size))
continue;
if (RRChangeOutputProperty (output, property->propertyName,
pending_value->type, pending_value->format,
PropModeReplace, pending_value->size,
pending_value->data, TRUE,
FALSE) != Success)
ret = FALSE;
}
return ret;
}
RRPropertyPtr
RRQueryOutputProperty (RROutputPtr output, Atom property)
{
@ -410,7 +461,7 @@ ProcRRConfigureOutputProperty (ClientPtr client)
RROutputPtr output;
int num_valid;
REQUEST_SIZE_MATCH(xRRConfigureOutputPropertyReq);
REQUEST_AT_LEAST_SIZE(xRRConfigureOutputPropertyReq);
output = LookupOutput (client, stuff->output, SecurityReadAccess);
@ -474,7 +525,7 @@ ProcRRChangeOutputProperty (ClientPtr client)
err = RRChangeOutputProperty(output, stuff->property,
stuff->type, (int)format,
(int)mode, len, (pointer)&stuff[1], TRUE);
(int)mode, len, (pointer)&stuff[1], TRUE, TRUE);
if (err != Success)
return err;
else
@ -508,8 +559,8 @@ int
ProcRRGetOutputProperty (ClientPtr client)
{
REQUEST(xRRGetOutputPropertyReq);
RRPropertyPtr prop, *prev;
RRPropertyValuePtr prop_value;
RRPropertyPtr prop, *prev;
RRPropertyValuePtr prop_value;
unsigned long n, len, ind;
RROutputPtr output;
xRRGetOutputPropertyReply reply;
@ -600,7 +651,10 @@ ProcRRGetOutputProperty (ClientPtr client)
reply.bytesAfter = n - (ind + len);
reply.format = prop_value->format;
reply.length = (len + 3) >> 2;
reply.nItems = len / (prop_value->format / 8 );
if (prop_value->format)
reply.nItems = len / (prop_value->format / 8);
else
reply.nItems = 0;
reply.propertyType = prop_value->type;
if (stuff->delete && (reply.bytesAfter == 0))

View File

@ -26,6 +26,9 @@ extern char *ConnectionInfo;
static int padlength[4] = {0, 3, 2, 1};
static CARD16
RR10CurrentSizeID (ScreenPtr pScreen);
/*
* Edit connection information block so that new clients
* see the current screen size on connect
@ -96,10 +99,7 @@ RRDeliverScreenEvent (ClientPtr client, WindowPtr pWin, ScreenPtr pScreen)
rrScrPriv (pScreen);
xRRScreenChangeNotifyEvent se;
RRCrtcPtr crtc = pScrPriv->numCrtcs ? pScrPriv->crtcs[0] : NULL;
RROutputPtr output = pScrPriv->numOutputs ? pScrPriv->outputs[0] : NULL;
RRModePtr mode = crtc ? crtc->mode : NULL;
WindowPtr pRoot = WindowTable[pScreen->myNum];
int i;
se.type = RRScreenChangeNotify + RREventBase;
se.rotation = (CARD8) (crtc ? crtc->rotation : RR_Rotate_0);
@ -115,32 +115,12 @@ RRDeliverScreenEvent (ClientPtr client, WindowPtr pWin, ScreenPtr pScreen)
#endif
se.sequenceNumber = client->sequence;
if (mode)
{
se.sizeID = -1;
for (i = 0; i < output->numModes; i++)
if (mode == output->modes[i])
{
se.sizeID = i;
break;
}
se.widthInPixels = mode->mode.width;
se.heightInPixels = mode->mode.height;
se.widthInMillimeters = pScreen->mmWidth;
se.heightInMillimeters = pScreen->mmHeight;
}
else
{
/*
* This "shouldn't happen", but a broken DDX can
* forget to set the current configuration on GetInfo
*/
se.sizeID = 0xffff;
se.widthInPixels = 0;
se.heightInPixels = 0;
se.widthInMillimeters = 0;
se.heightInMillimeters = 0;
}
se.sizeID = RR10CurrentSizeID (pScreen);
se.widthInPixels = pScreen->width;
se.heightInPixels = pScreen->height;
se.widthInMillimeters = pScreen->mmWidth;
se.heightInMillimeters = pScreen->mmHeight;
WriteEventsToClient (client, 1, (xEvent *) &se);
}
@ -499,7 +479,7 @@ RR10GetData (ScreenPtr pScreen, RROutputPtr output)
{
RR10DataPtr data;
RRScreenSizePtr size;
int nmode = output->numModes;
int nmode = output->numModes + output->numUserModes;
int o, os, l, r;
RRScreenRatePtr refresh;
CARD16 vRefresh;
@ -526,11 +506,14 @@ RR10GetData (ScreenPtr pScreen, RROutputPtr output)
/*
* find modes not yet listed
*/
for (o = 0; o < output->numModes; o++)
for (o = 0; o < output->numModes + output->numUserModes; o++)
{
if (used[o]) continue;
mode = output->modes[o];
if (o < output->numModes)
mode = output->modes[o];
else
mode = output->userModes[o - output->numModes];
l = data->nsize;
size[l].id = data->nsize;
@ -550,9 +533,12 @@ RR10GetData (ScreenPtr pScreen, RROutputPtr output)
/*
* Find all modes with matching size
*/
for (os = o; os < output->numModes; os++)
for (os = o; os < output->numModes + output->numUserModes; os++)
{
mode = output->modes[os];
if (os < output->numModes)
mode = output->modes[os];
else
mode = output->userModes[os - output->numModes];
if (mode->mode.width == size[l].width &&
mode->mode.height == size[l].height)
{
@ -755,6 +741,7 @@ ProcRRSetScreenConfig (ClientPtr client)
RRModePtr mode;
RR10DataPtr pData = NULL;
RRScreenSizePtr pSize;
int width, height;
UpdateCurrentTime ();
@ -896,8 +883,14 @@ ProcRRSetScreenConfig (ClientPtr client)
* If the screen size is changing, adjust all of the other outputs
* to fit the new size, mirroring as much as possible
*/
if (mode->mode.width != pScreen->width ||
mode->mode.height != pScreen->height)
width = mode->mode.width;
height = mode->mode.height;
if (rotation & (RR_Rotate_90|RR_Rotate_270))
{
width = mode->mode.height;
height = mode->mode.width;
}
if (width != pScreen->width || height != pScreen->height)
{
int c;
@ -911,7 +904,7 @@ ProcRRSetScreenConfig (ClientPtr client)
goto sendReply;
}
}
if (!RRScreenSizeSet (pScreen, mode->mode.width, mode->mode.height,
if (!RRScreenSizeSet (pScreen, width, height,
pScreen->mmWidth, pScreen->mmHeight))
{
rep.status = RRSetConfigFailed;
@ -956,3 +949,27 @@ sendReply:
return (client->noClientException);
}
static CARD16
RR10CurrentSizeID (ScreenPtr pScreen)
{
CARD16 sizeID = 0xffff;
RROutputPtr output = RRFirstOutput (pScreen);
if (output)
{
RR10DataPtr data = RR10GetData (pScreen, output);
if (data)
{
int i;
for (i = 0; i < data->nsize; i++)
if (data->sizes[i].width == pScreen->width &&
data->sizes[i].height == pScreen->height)
{
sizeID = (CARD16) i;
break;
}
xfree (data);
}
}
return sizeID;
}

View File

@ -143,7 +143,8 @@ CursorDisplayCursor (ScreenPtr pScreen,
CursorCurrent = pCursor;
for (e = cursorEvents; e; e = e->next)
{
if (e->eventMask & XFixesDisplayCursorNotifyMask)
if ((e->eventMask & XFixesDisplayCursorNotifyMask) &&
!e->pClient->clientGone)
{
xXFixesCursorNotifyEvent ev;
ev.type = XFixesEventBase + XFixesCursorNotify;

View File

@ -78,7 +78,9 @@ XFixesSelectionCallback (CallbackListPtr *callbacks, pointer data, pointer args)
}
for (e = selectionEvents; e; e = e->next)
{
if (e->selection == selection->selection && (e->eventMask & eventMask))
if (e->selection == selection->selection &&
(e->eventMask & eventMask) &&
!e->pClient->clientGone)
{
xXFixesSelectionNotifyEvent ev;