Commit c2b1f489 authored by Mike Gabriel's avatar Mike Gabriel

Backport RANDR proto version 1.5 to nx-X11's Xserver.

Backported to X.org's /xorg/xserver Git hash level: a6b6e8ba026acedef6336b17adf06aebddd5f22f.
parent 2e5b9898
...@@ -35,6 +35,32 @@ static int nxagentRandRScreenSetSize(ScreenPtr pScreen, CARD16 width, ...@@ -35,6 +35,32 @@ static int nxagentRandRScreenSetSize(ScreenPtr pScreen, CARD16 width,
static int nxagentRandRInitSizes(ScreenPtr pScreen); static int nxagentRandRInitSizes(ScreenPtr pScreen);
#if RANDR_14_INTERFACE
static Bool
nxagentRandRReplaceScanoutPixmap(DrawablePtr pDrawable,
PixmapPtr pPixmap,
Bool enable);
#endif
#if RANDR_13_INTERFACE
static Bool
nxagentRandROutputGetProperty(ScreenPtr pScreen,
RROutputPtr output,
Atom property);
static Bool
nxagentRandRGetPanning(ScreenPtr pScrn,
RRCrtcPtr crtc,
BoxPtr totalArea,
BoxPtr trackingArea,
INT16 *border);
static Bool
nxagentRandRSetPanning(ScreenPtr pScrn,
RRCrtcPtr crtc,
BoxPtr totalArea,
BoxPtr trackingArea,
INT16 *border);
#endif
#if RANDR_12_INTERFACE #if RANDR_12_INTERFACE
static Bool nxagentRandRCrtcSet (ScreenPtr pScreen, RRCrtcPtr crtc, static Bool nxagentRandRCrtcSet (ScreenPtr pScreen, RRCrtcPtr crtc,
RRModePtr mode, int x, int y, RRModePtr mode, int x, int y,
...@@ -104,6 +130,29 @@ void nxagentInitRandRExtension(ScreenPtr pScreen) ...@@ -104,6 +130,29 @@ void nxagentInitRandRExtension(ScreenPtr pScreen)
pRandRScrPriv -> rrGetInfo = nxagentRandRGetInfo; pRandRScrPriv -> rrGetInfo = nxagentRandRGetInfo;
#if RANDR_15_INTERFACE
/* nothing to be assigned here, so far */
#endif
#if RANDR_14_INTERFACE
/* no pixmap sharing in nx-X11 */
pScreen->ReplaceScanoutPixmap = nxagentRandRReplaceScanoutPixmap;
pRandRScrPriv -> rrCrtcSetScanoutPixmap = NULL;
/* only fake provider support in nx-X11, so far */
pRandRScrPriv -> provider = RRProviderCreate(pScreen, "default", 7);
pRandRScrPriv -> rrProviderSetOutputSource = NULL;
pRandRScrPriv -> rrProviderSetOffloadSink;
pRandRScrPriv -> rrProviderGetProperty;
pRandRScrPriv -> rrProviderSetProperty;
#endif
#if RANDR_13_INTERFACE
pRandRScrPriv -> rrOutputGetProperty = nxagentRandROutputGetProperty;
pRandRScrPriv -> rrGetPanning = nxagentRandRGetPanning;
pRandRScrPriv -> rrSetPanning = nxagentRandRSetPanning;
#endif
#if RANDR_12_INTERFACE #if RANDR_12_INTERFACE
pRandRScrPriv -> rrScreenSetSize = nxagentRandRScreenSetSize; pRandRScrPriv -> rrScreenSetSize = nxagentRandRScreenSetSize;
pRandRScrPriv -> rrCrtcSet = nxagentRandRCrtcSet; pRandRScrPriv -> rrCrtcSet = nxagentRandRCrtcSet;
...@@ -114,13 +163,70 @@ void nxagentInitRandRExtension(ScreenPtr pScreen) ...@@ -114,13 +163,70 @@ void nxagentInitRandRExtension(ScreenPtr pScreen)
#endif #endif
} }
void #if RANDR_14_INTERFACE
RRResetProc (ExtensionEntry *extEntry) static Bool
nxagentRandRReplaceScanoutPixmap(DrawablePtr pDrawable,
PixmapPtr pPixmap,
Bool enable)
{
/* FALSE means: not supported */
#ifdef DEBUG
fprintf(stderr, "nxagentRandRReplaceScanoutPixmap: NX's RANDR does not support scan-out pixmaps.\n");
#endif
return FALSE;
}
#endif
#if RANDR_13_INTERFACE
static Bool
nxagentRandROutputGetProperty(ScreenPtr pScreen,
RROutputPtr output,
Atom property)
{ {
fprintf(stderr, "RANDR going down - NX version\n"); /* FALSE means: no property required to be modified on the fly here */
return FALSE;
} }
static Bool
nxagentRandRGetPanning(ScreenPtr pScrn,
RRCrtcPtr crtc,
BoxPtr totalArea,
BoxPtr trackingArea,
INT16 *border)
{
/* FALSE means: no, panning is not supported at the moment...
* Panning requires several modes to be available for
* the NX<n> output(s).
*
* FIXME: Add more modes per output than the current window size.
* At least when in fullscreen mode.
*/
#ifdef DEBUG
fprintf(stderr, "nxagentRandRGetPanning: RANDR Panning is currently not supported.\n");
#endif
return FALSE;
}
static Bool
nxagentRandRSetPanning(ScreenPtr pScrn,
RRCrtcPtr crtc,
BoxPtr totalArea,
BoxPtr trackingArea,
INT16 *border)
{
/* FALSE means: no, panning is not supported at the moment...
* Panning requires several modes to be available for
* the NX<n> output(s).
*
* FIXME: Add more modes per output than the current window size.
* At least when in fullscreen mode.
*/
#ifdef DEBUG
fprintf(stderr, "nxagentRandRSetPanning: RANDR Panning is currently not supported.\n");
#endif
return FALSE;
}
#endif
#if RANDR_12_INTERFACE #if RANDR_12_INTERFACE
/* /*
...@@ -137,7 +243,7 @@ nxagentRandRCrtcSet (ScreenPtr pScreen, ...@@ -137,7 +243,7 @@ nxagentRandRCrtcSet (ScreenPtr pScreen,
int numOutputs, int numOutputs,
RROutputPtr *outputs) RROutputPtr *outputs)
{ {
return RRCrtcNotify(crtc, mode, x, y, rotation, numOutputs, outputs); return RRCrtcNotify(crtc, mode, x, y, rotation, NULL, numOutputs, outputs);
} }
#endif #endif
......
...@@ -209,8 +209,11 @@ DEFINES = -g $(OS_DEFINES) $(EXT_DEFINES) $(NX_DEFINES) \ ...@@ -209,8 +209,11 @@ DEFINES = -g $(OS_DEFINES) $(EXT_DEFINES) $(NX_DEFINES) \
-DNXAGENT_ARTSD \ -DNXAGENT_ARTSD \
-DNXAGENT_RANDR_MODE_PREFIX \ -DNXAGENT_RANDR_MODE_PREFIX \
-UNX_DEBUG_INPUT \ -UNX_DEBUG_INPUT \
-DRANDR_10_INTERFACE \ -DRANDR_10_INTERFACE=1 \
-DRANDR_12_INTERFACE \ -DRANDR_12_INTERFACE=1 \
-DRANDR_13_INTERFACE=1 \
-DRANDR_14_INTERFACE=1 \
-DRANDR_15_INTERFACE=1 \
-DPANORAMIX \ -DPANORAMIX \
-UDEBUG_TREE -UDEBUG_TREE
......
...@@ -3793,7 +3793,7 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen) ...@@ -3793,7 +3793,7 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen)
* do this here it will be done implicitely later and add mode(s) to * do this here it will be done implicitely later and add mode(s) to
* our crtc(s)! * our crtc(s)!
*/ */
rrgetinfo = RRGetInfo(pScreen); rrgetinfo = RRGetInfo(pScreen, FALSE);
fprintf(stderr, "nxagentAdjustRandRXinerama: RRGetInfo returned [%d]\n", rrgetinfo); fprintf(stderr, "nxagentAdjustRandRXinerama: RRGetInfo returned [%d]\n", rrgetinfo);
} }
......
...@@ -24,11 +24,15 @@ XCOMM $XFree86: xc/programs/Xserver/randr/Imakefile,v 1.1 2001/05/23 03:29:44 ke ...@@ -24,11 +24,15 @@ XCOMM $XFree86: xc/programs/Xserver/randr/Imakefile,v 1.1 2001/05/23 03:29:44 ke
rrdispatch.c \ rrdispatch.c \
rrinfo.c \ rrinfo.c \
rrmode.c \ rrmode.c \
rrmonitor.c \
rroutput.c \ rroutput.c \
rrpointer.c \ rrpointer.c \
rrproperty.c \ rrproperty.c \
rrprovider.c \
rrproviderproperty.c \
rrscreen.c \ rrscreen.c \
rrsdispatch.c \ rrsdispatch.c \
rrtransform.c \
rrxinerama.c \ rrxinerama.c \
$(NULL) $(NULL)
...@@ -37,11 +41,15 @@ XCOMM $XFree86: xc/programs/Xserver/randr/Imakefile,v 1.1 2001/05/23 03:29:44 ke ...@@ -37,11 +41,15 @@ XCOMM $XFree86: xc/programs/Xserver/randr/Imakefile,v 1.1 2001/05/23 03:29:44 ke
rrdispatch.o \ rrdispatch.o \
rrinfo.o \ rrinfo.o \
rrmode.o \ rrmode.o \
rrmonitor.o \
rroutput.o \ rroutput.o \
rrpointer.o \ rrpointer.o \
rrproperty.o \ rrproperty.o \
rrprovider.o \
rrproviderproperty.o \
rrscreen.o \ rrscreen.o \
rrsdispatch.o \ rrsdispatch.o \
rrtransform.o \
rrxinerama.o \ rrxinerama.o \
$(NULL) $(NULL)
...@@ -50,9 +58,20 @@ XCOMM $XFree86: xc/programs/Xserver/randr/Imakefile,v 1.1 2001/05/23 03:29:44 ke ...@@ -50,9 +58,20 @@ XCOMM $XFree86: xc/programs/Xserver/randr/Imakefile,v 1.1 2001/05/23 03:29:44 ke
-I../render \ -I../render \
`pkg-config --cflags-only-I pixman-1` `pkg-config --cflags-only-I pixman-1`
#if defined(BuildXinerama)
PNRX_DEFINES = -DXINERAMA -DPANORAMIX
#endif
#if defined(NXAgentServer)
NX_DEFINES = -DNXAGENT_SERVER
#endif
LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln
DEFINES = -DNXAGENT_SERVER DEFINES = \
$(PNRX_DEFINES) \
$(NX_DEFINES) \
$(NULL)
NormalLibraryTarget(randr,$(OBJS)) NormalLibraryTarget(randr,$(OBJS))
NormalLibraryObjectRule() NormalLibraryObjectRule()
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* Copyright © 2000 Compaq Computer Corporation * Copyright © 2000 Compaq Computer Corporation
* Copyright © 2002 Hewlett Packard Company * Copyright © 2002 Hewlett Packard Company
* Copyright © 2006 Intel Corporation * Copyright © 2006 Intel Corporation
* Copyright © 2008 Red Hat, Inc.
* *
* Permission to use, copy, modify, distribute, and sell this software and its * Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that * documentation for any purpose is hereby granted without fee, provided that
...@@ -39,11 +40,11 @@ typedef unsigned long XRandrModeFlags; ...@@ -39,11 +40,11 @@ typedef unsigned long XRandrModeFlags;
#define RANDR_NAME "RANDR" #define RANDR_NAME "RANDR"
#define RANDR_MAJOR 1 #define RANDR_MAJOR 1
#define RANDR_MINOR 2 #define RANDR_MINOR 5
#define RRNumberErrors 3 #define RRNumberErrors 4
#define RRNumberEvents 2 #define RRNumberEvents 2
#define RRNumberRequests 25 #define RRNumberRequests 45
#define X_RRQueryVersion 0 #define X_RRQueryVersion 0
/* we skip 1 to make old clients fail pretty immediately */ /* we skip 1 to make old clients fail pretty immediately */
...@@ -77,12 +78,47 @@ typedef unsigned long XRandrModeFlags; ...@@ -77,12 +78,47 @@ typedef unsigned long XRandrModeFlags;
#define X_RRGetCrtcGamma 23 #define X_RRGetCrtcGamma 23
#define X_RRSetCrtcGamma 24 #define X_RRSetCrtcGamma 24
/* V1.3 additions */
#define X_RRGetScreenResourcesCurrent 25
#define X_RRSetCrtcTransform 26
#define X_RRGetCrtcTransform 27
#define X_RRGetPanning 28
#define X_RRSetPanning 29
#define X_RRSetOutputPrimary 30
#define X_RRGetOutputPrimary 31
#define RRTransformUnit (1L << 0)
#define RRTransformScaleUp (1L << 1)
#define RRTransformScaleDown (1L << 2)
#define RRTransformProjective (1L << 3)
/* v1.4 */
#define X_RRGetProviders 32
#define X_RRGetProviderInfo 33
#define X_RRSetProviderOffloadSink 34
#define X_RRSetProviderOutputSource 35
#define X_RRListProviderProperties 36
#define X_RRQueryProviderProperty 37
#define X_RRConfigureProviderProperty 38
#define X_RRChangeProviderProperty 39
#define X_RRDeleteProviderProperty 40
#define X_RRGetProviderProperty 41
/* v1.5 */
#define X_RRGetMonitors 42
#define X_RRSetMonitor 43
#define X_RRDeleteMonitor 44
/* Event selection bits */ /* Event selection bits */
#define RRScreenChangeNotifyMask (1L << 0) #define RRScreenChangeNotifyMask (1L << 0)
/* V1.2 additions */ /* V1.2 additions */
#define RRCrtcChangeNotifyMask (1L << 1) #define RRCrtcChangeNotifyMask (1L << 1)
#define RROutputChangeNotifyMask (1L << 2) #define RROutputChangeNotifyMask (1L << 2)
#define RROutputPropertyNotifyMask (1L << 3) #define RROutputPropertyNotifyMask (1L << 3)
/* V1.4 additions */
#define RRProviderChangeNotifyMask (1L << 4)
#define RRProviderPropertyNotifyMask (1L << 5)
#define RRResourceChangeNotifyMask (1L << 6)
/* Event codes */ /* Event codes */
#define RRScreenChangeNotify 0 #define RRScreenChangeNotify 0
...@@ -92,7 +128,9 @@ typedef unsigned long XRandrModeFlags; ...@@ -92,7 +128,9 @@ typedef unsigned long XRandrModeFlags;
#define RRNotify_CrtcChange 0 #define RRNotify_CrtcChange 0
#define RRNotify_OutputChange 1 #define RRNotify_OutputChange 1
#define RRNotify_OutputProperty 2 #define RRNotify_OutputProperty 2
#define RRNotify_ProviderChange 3
#define RRNotify_ProviderProperty 4
#define RRNotify_ResourceChange 5
/* used in the rotation field; rotation and reflection in 0.1 proto. */ /* used in the rotation field; rotation and reflection in 0.1 proto. */
#define RR_Rotate_0 1 #define RR_Rotate_0 1
#define RR_Rotate_90 2 #define RR_Rotate_90 2
...@@ -133,9 +171,28 @@ typedef unsigned long XRandrModeFlags; ...@@ -133,9 +171,28 @@ typedef unsigned long XRandrModeFlags;
#define BadRROutput 0 #define BadRROutput 0
#define BadRRCrtc 1 #define BadRRCrtc 1
#define BadRRMode 2 #define BadRRMode 2
#define BadRRProvider 3
/* Conventional RandR output properties */ /* Conventional RandR output properties */
#define RR_PROPERTY_RANDR_EDID "RANDR_EDID" #define RR_PROPERTY_BACKLIGHT "Backlight"
#define RR_PROPERTY_RANDR_EDID "EDID"
#define RR_PROPERTY_SIGNAL_FORMAT "SignalFormat"
#define RR_PROPERTY_SIGNAL_PROPERTIES "SignalProperties"
#define RR_PROPERTY_CONNECTOR_TYPE "ConnectorType"
#define RR_PROPERTY_CONNECTOR_NUMBER "ConnectorNumber"
#define RR_PROPERTY_COMPATIBILITY_LIST "CompatibilityList"
#define RR_PROPERTY_CLONE_LIST "CloneList"
#define RR_PROPERTY_BORDER "Border"
#define RR_PROPERTY_BORDER_DIMENSIONS "BorderDimensions"
#define RR_PROPERTY_GUID "GUID"
#define RR_PROPERTY_RANDR_TILE "TILE"
/* roles this device can carry out */
#define RR_Capability_None 0
#define RR_Capability_SourceOutput 1
#define RR_Capability_SinkOutput 2
#define RR_Capability_SourceOffload 4
#define RR_Capability_SinkOffload 8
#endif /* _RANDR_H_ */ #endif /* _RANDR_H_ */
...@@ -21,48 +21,62 @@ ...@@ -21,48 +21,62 @@
*/ */
#include "randrstr.h" #include "randrstr.h"
#ifndef NXAGENT_SERVER
#define SERVER_RANDR_MAJOR 1 #include "protocol-versions.h"
#define SERVER_RANDR_MINOR 2 #else
#define SERVER_RANDR_MAJOR_VERSION 1
#define SERVER_RANDR_MINOR_VERSION 5
#endif
Bool Bool
RRClientKnowsRates(ClientPtr pClient) RRClientKnowsRates(ClientPtr pClient)
{ {
rrClientPriv(pClient); rrClientPriv(pClient);
return (pRRClient->major_version > 1 || return version_compare(pRRClient->major_version, pRRClient->minor_version,
(pRRClient->major_version == 1 && pRRClient->minor_version >= 1)); 1, 1) >= 0;
} }
static int static int
ProcRRQueryVersion(ClientPtr client) ProcRRQueryVersion(ClientPtr client)
{ {
xRRQueryVersionReply rep; int n;
register int n;
xRRQueryVersionReply rep = {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length = 0
};
REQUEST(xRRQueryVersionReq); REQUEST(xRRQueryVersionReq);
rrClientPriv(client); rrClientPriv(client);
REQUEST_SIZE_MATCH(xRRQueryVersionReq); REQUEST_SIZE_MATCH(xRRQueryVersionReq);
pRRClient->major_version = stuff->majorVersion; pRRClient->major_version = stuff->majorVersion;
pRRClient->minor_version = stuff->minorVersion; pRRClient->minor_version = stuff->minorVersion;
rep.type = X_Reply;
rep.length = 0; if (version_compare(stuff->majorVersion, stuff->minorVersion,
rep.sequenceNumber = client->sequence; SERVER_RANDR_MAJOR_VERSION,
/* SERVER_RANDR_MINOR_VERSION) < 0) {
* Report the current version; the current rep.majorVersion = stuff->majorVersion;
* spec says they're all compatible after 1.0 rep.minorVersion = stuff->minorVersion;
*/ }
rep.majorVersion = SERVER_RANDR_MAJOR; else {
rep.minorVersion = SERVER_RANDR_MINOR; rep.majorVersion = SERVER_RANDR_MAJOR_VERSION;
rep.minorVersion = SERVER_RANDR_MINOR_VERSION;
}
if (client->swapped) { if (client->swapped) {
swaps(&rep.sequenceNumber, n); swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n); swapl(&rep.length, n);
swapl(&rep.majorVersion, n); swapl(&rep.majorVersion, n);
swapl(&rep.minorVersion, n); swapl(&rep.minorVersion, n);
} }
#ifndef NXAGENT_SERVER
WriteToClient(client, sizeof(xRRQueryVersionReply), &rep);
#else
WriteToClient(client, sizeof(xRRQueryVersionReply), (char *) &rep); WriteToClient(client, sizeof(xRRQueryVersionReply), (char *) &rep);
return (client->noClientException); #endif
return Success;
} }
static int static int
...@@ -78,19 +92,30 @@ ProcRRSelectInput(ClientPtr client) ...@@ -78,19 +92,30 @@ ProcRRSelectInput(ClientPtr client)
REQUEST_SIZE_MATCH(xRRSelectInputReq); REQUEST_SIZE_MATCH(xRRSelectInputReq);
#ifndef NXAGENT_SERVER #ifndef NXAGENT_SERVER
rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess); rc = dixLookupWindow(&pWin, stuff->window, client, DixReceiveAccess);
#else #else
pWin = SecurityLookupWindow(stuff->window, client, SecurityWriteAccess); pWin = SecurityLookupWindow(stuff->window, client, SecurityWriteAccess);
rc = pWin ? Success : BadWindow; rc = pWin ? Success : BadWindow;
#endif #endif
if (rc != Success) if (rc != Success)
return rc; return rc;
pHead = (RREventPtr *) SecurityLookupIDByType(client, #ifndef NXAGENT_SERVER
pWin->drawable.id, rc = dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
RREventType, DixWriteAccess); RREventType, client, DixWriteAccess);
#else /* !defined(NXAGENT_SERVER) */
pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, RREventType);
#endif /* !defined(NXAGENT_SERVER) */
if (rc != Success && rc != BadValue)
return rc;
if (stuff->enable & (RRScreenChangeNotifyMask | if (stuff->enable & (RRScreenChangeNotifyMask |
RRCrtcChangeNotifyMask | RROutputChangeNotifyMask)) { RRCrtcChangeNotifyMask |
RROutputChangeNotifyMask |
RROutputPropertyNotifyMask |
RRProviderChangeNotifyMask |
RRProviderPropertyNotifyMask |
RRResourceChangeNotifyMask)) {
ScreenPtr pScreen = pWin->drawable.pScreen; ScreenPtr pScreen = pWin->drawable.pScreen;
rrScrPriv(pScreen); rrScrPriv(pScreen);
...@@ -142,14 +167,38 @@ ProcRRSelectInput(ClientPtr client) ...@@ -142,14 +167,38 @@ ProcRRSelectInput(ClientPtr client)
/* /*
* Now see if the client needs an event * Now see if the client needs an event
*/ */
if (pScrPriv && (pRREvent->mask & RRScreenChangeNotifyMask)) { if (pScrPriv) {
pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum]; pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum];
if (CompareTimeStamps(pTimes->setTime, if (CompareTimeStamps(pTimes->setTime,
pScrPriv->lastSetTime) != 0 || pScrPriv->lastSetTime) != 0 ||
CompareTimeStamps(pTimes->configTime, CompareTimeStamps(pTimes->configTime,
pScrPriv->lastConfigTime) != 0) { pScrPriv->lastConfigTime) != 0) {
if (pRREvent->mask & RRScreenChangeNotifyMask) {
RRDeliverScreenEvent(client, pWin, pScreen); RRDeliverScreenEvent(client, pWin, pScreen);
} }
if (pRREvent->mask & RRCrtcChangeNotifyMask) {
int i;
for (i = 0; i < pScrPriv->numCrtcs; i++) {
RRDeliverCrtcEvent(client, pWin, pScrPriv->crtcs[i]);
}
}
if (pRREvent->mask & RROutputChangeNotifyMask) {
int i;
for (i = 0; i < pScrPriv->numOutputs; i++) {
RRDeliverOutputEvent(client, pWin,
pScrPriv->outputs[i]);
}
}
/* We don't check for RROutputPropertyNotifyMask, as randrproto.txt doesn't
* say if there ought to be notifications of changes to output properties
* if those changes occurred before the time RRSelectInput is called.
*/
}
} }
} }
else if (stuff->enable == 0) { else if (stuff->enable == 0) {
...@@ -209,4 +258,26 @@ int (*ProcRandrVector[RRNumberRequests]) (ClientPtr) = { ...@@ -209,4 +258,26 @@ int (*ProcRandrVector[RRNumberRequests]) (ClientPtr) = {
ProcRRGetCrtcGammaSize, /* 22 */ ProcRRGetCrtcGammaSize, /* 22 */
ProcRRGetCrtcGamma, /* 23 */ ProcRRGetCrtcGamma, /* 23 */
ProcRRSetCrtcGamma, /* 24 */ ProcRRSetCrtcGamma, /* 24 */
/* V1.3 additions */
ProcRRGetScreenResourcesCurrent, /* 25 */
ProcRRSetCrtcTransform, /* 26 */
ProcRRGetCrtcTransform, /* 27 */
ProcRRGetPanning, /* 28 */
ProcRRSetPanning, /* 29 */
ProcRRSetOutputPrimary, /* 30 */
ProcRRGetOutputPrimary, /* 31 */
/* V1.4 additions */
ProcRRGetProviders, /* 32 */
ProcRRGetProviderInfo, /* 33 */
ProcRRSetProviderOffloadSink, /* 34 */
ProcRRSetProviderOutputSource, /* 35 */
ProcRRListProviderProperties, /* 36 */
ProcRRQueryProviderProperty, /* 37 */
ProcRRConfigureProviderProperty, /* 38 */
ProcRRChangeProviderProperty, /* 39 */
ProcRRDeleteProviderProperty, /* 40 */
ProcRRGetProviderProperty, /* 41 */
ProcRRGetMonitors, /* 42 */
ProcRRSetMonitor, /* 43 */
ProcRRDeleteMonitor, /* 44 */
}; };
...@@ -36,7 +36,7 @@ RROldModeAdd(RROutputPtr output, RRScreenSizePtr size, int refresh) ...@@ -36,7 +36,7 @@ RROldModeAdd(RROutputPtr output, RRScreenSizePtr size, int refresh)
RRModePtr *modes; RRModePtr *modes;
memset(&modeInfo, '\0', sizeof(modeInfo)); memset(&modeInfo, '\0', sizeof(modeInfo));
sprintf(name, "%dx%d", size->width, size->height); snprintf(name, sizeof(name), "%dx%d", size->width, size->height);
modeInfo.width = size->width; modeInfo.width = size->width;
modeInfo.height = size->height; modeInfo.height = size->height;
...@@ -55,8 +55,13 @@ RROldModeAdd(RROutputPtr output, RRScreenSizePtr size, int refresh) ...@@ -55,8 +55,13 @@ RROldModeAdd(RROutputPtr output, RRScreenSizePtr size, int refresh)
} }
if (output->numModes) if (output->numModes)
#ifndef NXAGENT_SERVER
modes = reallocarray(output->modes,
output->numModes + 1, sizeof(RRModePtr));
#else /* !defined(NXAGENT_SERVER) */
modes = xrealloc(output->modes, modes = xrealloc(output->modes,
(output->numModes + 1) * sizeof(RRModePtr)); (output->numModes + 1) * sizeof(RRModePtr));
#endif /* !defined(NXAGENT_SERVER) */
else else
modes = xalloc(sizeof(RRModePtr)); modes = xalloc(sizeof(RRModePtr));
if (!modes) { if (!modes) {
...@@ -97,9 +102,7 @@ RRScanOldConfig(ScreenPtr pScreen, Rotation rotations) ...@@ -97,9 +102,7 @@ RRScanOldConfig(ScreenPtr pScreen, Rotation rotations)
return; return;
RROutputSetCrtcs(output, &crtc, 1); RROutputSetCrtcs(output, &crtc, 1);
RROutputSetConnection(output, RR_Connected); RROutputSetConnection(output, RR_Connected);
#ifdef RENDER
RROutputSetSubpixelOrder(output, PictureGetSubpixelOrder(pScreen)); RROutputSetSubpixelOrder(output, PictureGetSubpixelOrder(pScreen));
#endif
} }
output = pScrPriv->outputs[0]; output = pScrPriv->outputs[0];
...@@ -145,7 +148,8 @@ RRScanOldConfig(ScreenPtr pScreen, Rotation rotations) ...@@ -145,7 +148,8 @@ RRScanOldConfig(ScreenPtr pScreen, Rotation rotations)
/* find size bounds */ /* find size bounds */
for (i = 0; i < output->numModes + output->numUserModes; i++) { for (i = 0; i < output->numModes + output->numUserModes; i++) {
mode = (i < output->numModes ? mode = (i < output->numModes ?
output->modes[i] : output->userModes[i - output->numModes]); output->modes[i] :
output->userModes[i - output->numModes]);
width = mode->mode.width; width = mode->mode.width;
height = mode->mode.height; height = mode->mode.height;
...@@ -163,7 +167,7 @@ RRScanOldConfig(ScreenPtr pScreen, Rotation rotations) ...@@ -163,7 +167,7 @@ RRScanOldConfig(ScreenPtr pScreen, Rotation rotations)
/* notice current mode */ /* notice current mode */
if (newMode) if (newMode)
RRCrtcNotify(crtc, newMode, 0, 0, pScrPriv->rotation, 1, &output); RRCrtcNotify(crtc, newMode, 0, 0, pScrPriv->rotation, NULL, 1, &output);
} }
#endif #endif
...@@ -171,12 +175,20 @@ RRScanOldConfig(ScreenPtr pScreen, Rotation rotations) ...@@ -171,12 +175,20 @@ RRScanOldConfig(ScreenPtr pScreen, Rotation rotations)
* Poll the driver for changed information * Poll the driver for changed information
*/ */
Bool Bool
RRGetInfo(ScreenPtr pScreen) RRGetInfo(ScreenPtr pScreen, Bool force_query)
{ {
rrScrPriv(pScreen); rrScrPriv(pScreen);
Rotation rotations; Rotation rotations;
int i; int i;
/* Return immediately if we don't need to re-query and we already have the
* information.
*/
if (!force_query) {
if (pScrPriv->numCrtcs != 0 || pScrPriv->numOutputs != 0)
return TRUE;
}
for (i = 0; i < pScrPriv->numOutputs; i++) for (i = 0; i < pScrPriv->numOutputs; i++)
pScrPriv->outputs[i]->changed = FALSE; pScrPriv->outputs[i]->changed = FALSE;
for (i = 0; i < pScrPriv->numCrtcs; i++) for (i = 0; i < pScrPriv->numCrtcs; i++)
...@@ -218,7 +230,7 @@ RRScreenSetSizeRange(ScreenPtr pScreen, ...@@ -218,7 +230,7 @@ RRScreenSetSizeRange(ScreenPtr pScreen,
pScrPriv->minHeight = minHeight; pScrPriv->minHeight = minHeight;
pScrPriv->maxWidth = maxWidth; pScrPriv->maxWidth = maxWidth;
pScrPriv->maxHeight = maxHeight; pScrPriv->maxHeight = maxHeight;
pScrPriv->changed = TRUE; RRSetChanged(pScreen);
pScrPriv->configChanged = TRUE; pScrPriv->configChanged = TRUE;
} }
...@@ -259,8 +271,13 @@ RRRegisterSize(ScreenPtr pScreen, ...@@ -259,8 +271,13 @@ RRRegisterSize(ScreenPtr pScreen,
for (i = 0; i < pScrPriv->nSizes; i++) for (i = 0; i < pScrPriv->nSizes; i++)
if (RRScreenSizeMatches(&tmp, &pScrPriv->pSizes[i])) if (RRScreenSizeMatches(&tmp, &pScrPriv->pSizes[i]))
return &pScrPriv->pSizes[i]; return &pScrPriv->pSizes[i];
#ifndef NXAGENT_SERVER
pNew = reallocarray(pScrPriv->pSizes,
pScrPriv->nSizes + 1, sizeof(RRScreenSize));
#else /* !defined(NXAGENT_SERVER) */
pNew = xrealloc(pScrPriv->pSizes, pNew = xrealloc(pScrPriv->pSizes,
(pScrPriv->nSizes + 1) * sizeof(RRScreenSize)); (pScrPriv->nSizes + 1) * sizeof(RRScreenSize));
#endif /* !defined(NXAGENT_SERVER) */
if (!pNew) if (!pNew)
return 0; return 0;
pNew[pScrPriv->nSizes++] = tmp; pNew[pScrPriv->nSizes++] = tmp;
...@@ -282,7 +299,11 @@ RRRegisterRate(ScreenPtr pScreen, RRScreenSizePtr pSize, int rate) ...@@ -282,7 +299,11 @@ RRRegisterRate(ScreenPtr pScreen, RRScreenSizePtr pSize, int rate)
if (pSize->pRates[i].rate == rate) if (pSize->pRates[i].rate == rate)
return TRUE; return TRUE;
#ifndef NXAGENT_SERVER
pNew = reallocarray(pSize->pRates, pSize->nRates + 1, sizeof(RRScreenRate));
#else /* !defined(NXAGENT_SERVER) */
pNew = xrealloc(pSize->pRates, (pSize->nRates + 1) * sizeof(RRScreenRate)); pNew = xrealloc(pSize->pRates, (pSize->nRates + 1) * sizeof(RRScreenRate));
#endif /* !defined(NXAGENT_SERVER) */
if (!pNew) if (!pNew)
return FALSE; return FALSE;
pRate = &pNew[pSize->nRates++]; pRate = &pNew[pSize->nRates++];
......
...@@ -38,7 +38,6 @@ ...@@ -38,7 +38,6 @@
/**************************************************************************/ /**************************************************************************/
#include "randrstr.h" #include "randrstr.h"
#include "registry.h"
RESTYPE RRModeType; RESTYPE RRModeType;
...@@ -97,7 +96,12 @@ RRModeCreate(xRRModeInfo * modeInfo, const char *name, ScreenPtr userScreen) ...@@ -97,7 +96,12 @@ RRModeCreate(xRRModeInfo * modeInfo, const char *name, ScreenPtr userScreen)
mode->userScreen = userScreen; mode->userScreen = userScreen;
if (num_modes) if (num_modes)
#ifndef NXAGENT_SERVER
newModes = reallocarray(modes, num_modes + 1, sizeof(RRModePtr));
#else /* !defined(NXAGENT_SERVER) */
newModes = xrealloc(modes, (num_modes + 1) * sizeof(RRModePtr)); newModes = xrealloc(modes, (num_modes + 1) * sizeof(RRModePtr));
#endif /* !defined(NXAGENT_SERVER) */
else else
newModes = xalloc(sizeof(RRModePtr)); newModes = xalloc(sizeof(RRModePtr));
...@@ -113,6 +117,7 @@ RRModeCreate(xRRModeInfo * modeInfo, const char *name, ScreenPtr userScreen) ...@@ -113,6 +117,7 @@ RRModeCreate(xRRModeInfo * modeInfo, const char *name, ScreenPtr userScreen)
} }
modes = newModes; modes = newModes;
modes[num_modes++] = mode; modes[num_modes++] = mode;
/* /*
* give the caller a reference to this mode * give the caller a reference to this mode
*/ */
...@@ -203,7 +208,11 @@ RRModesForScreen(ScreenPtr pScreen, int *num_ret) ...@@ -203,7 +208,11 @@ RRModesForScreen(ScreenPtr pScreen, int *num_ret)
RRModePtr *screen_modes; RRModePtr *screen_modes;
int num_screen_modes = 0; int num_screen_modes = 0;
#ifndef NXAGENT_SERVER
screen_modes = xallocarray((num_modes ? num_modes : 1), sizeof(RRModePtr));
#else /* !defined(NXAGENT_SERVER) */
screen_modes = xalloc((num_modes ? num_modes : 1) * sizeof(RRModePtr)); screen_modes = xalloc((num_modes ? num_modes : 1) * sizeof(RRModePtr));
#endif /* !defined(NXAGENT_SERVER) */
if (!screen_modes) if (!screen_modes)
return NULL; return NULL;
...@@ -268,13 +277,8 @@ RRModeDestroy(RRModePtr mode) ...@@ -268,13 +277,8 @@ RRModeDestroy(RRModePtr mode)
{ {
int m; int m;
if (--mode->refcnt > 0) { if (--mode->refcnt > 0)
#ifdef DEBUG
fprintf(stderr, "RRModeDestroy: mode [%s] ([%p]) refcnt [%d -> %d]\n",
mode->name, mode, mode->refcnt + 1, mode->refcnt);
#endif
return; return;
}
for (m = 0; m < num_modes; m++) { for (m = 0; m < num_modes; m++) {
if (modes[m] == mode) { if (modes[m] == mode) {
memmove(modes + m, modes + m + 1, memmove(modes + m, modes + m + 1,
...@@ -288,37 +292,46 @@ RRModeDestroy(RRModePtr mode) ...@@ -288,37 +292,46 @@ RRModeDestroy(RRModePtr mode)
} }
} }
#ifdef DEBUG
fprintf(stderr, "RRModeDestroy: destroyed mode [%s] ([%p])\n", mode->name,
mode);
#endif
xfree(mode); xfree(mode);
} }
static int static int
RRModeDestroyResource(void *value, XID pid) RRModeDestroyResource(void *value, XID pid)
{ {
#ifdef DEBUG
fprintf(stderr, "RRModeDestroyResource: mode [%s] ([%p]) refcnt [%d]\n",
((RRModePtr) value)->name, (RRModePtr) value,
((RRModePtr) value)->refcnt);
#endif
RRModeDestroy((RRModePtr) value); RRModeDestroy((RRModePtr) value);
return 1; return 1;
} }
/*
* Initialize mode type
*/
Bool Bool
RRModeInit(void) RRModeInit(void)
{ {
assert(num_modes == 0); assert(num_modes == 0);
assert(modes == NULL); assert(modes == NULL);
RRModeType = CreateNewResourceType(RRModeDestroyResource); RRModeType = CreateNewResourceType(RRModeDestroyResource
#ifndef NXAGENT_SERVER
, "MODE"
#endif
);
if (!RRModeType) if (!RRModeType)
return FALSE; return FALSE;
RegisterResourceName(RRModeType, "MODE");
return TRUE; return TRUE;
} }
/*
* Initialize mode type error value
*/
void
RRModeInitErrorValue(void)
{
#ifndef NXAGENT_SERVER
SetResourceTypeErrorValue(RRModeType, RRErrorBase + BadRRMode);
#endif
}
int int
ProcRRCreateMode(ClientPtr client) ProcRRCreateMode(ClientPtr client)
{ {
...@@ -331,10 +344,11 @@ ProcRRCreateMode(ClientPtr client) ...@@ -331,10 +344,11 @@ ProcRRCreateMode(ClientPtr client)
char *name; char *name;
int error, rc; int error, rc;
RRModePtr mode; RRModePtr mode;
int n;
REQUEST_AT_LEAST_SIZE(xRRCreateModeReq); REQUEST_AT_LEAST_SIZE(xRRCreateModeReq);
#ifndef NXAGENT_SERVER #ifndef NXAGENT_SERVER
rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
#else #else
pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess); pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
rc = pWin ? Success : BadWindow; rc = pWin ? Success : BadWindow;
...@@ -346,24 +360,23 @@ ProcRRCreateMode(ClientPtr client) ...@@ -346,24 +360,23 @@ ProcRRCreateMode(ClientPtr client)
modeInfo = &stuff->modeInfo; modeInfo = &stuff->modeInfo;
name = (char *) (stuff + 1); name = (char *) (stuff + 1);
units_after = (stuff->length - (sizeof(xRRCreateModeReq) >> 2)); units_after = (stuff->length - bytes_to_int32(sizeof(xRRCreateModeReq)));
/* check to make sure requested name fits within the data provided */ /* check to make sure requested name fits within the data provided */
if ((int) (modeInfo->nameLength + 3) >> 2 > units_after) if (bytes_to_int32(modeInfo->nameLength) > units_after)
return BadLength; return BadLength;
mode = RRModeCreateUser(pScreen, modeInfo, name, &error); mode = RRModeCreateUser(pScreen, modeInfo, name, &error);
if (!mode) if (!mode)
return error; return error;
rep.type = X_Reply; rep = (xRRCreateModeReply) {
rep.pad0 = 0; .type = X_Reply,
rep.sequenceNumber = client->sequence; .sequenceNumber = client->sequence,
rep.length = 0; .length = 0,
rep.mode = mode->mode.id; .mode = mode->mode.id
};
if (client->swapped) { if (client->swapped) {
int n;
swaps(&rep.sequenceNumber, n); swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n); swapl(&rep.length, n);
swapl(&rep.mode, n); swapl(&rep.mode, n);
...@@ -371,7 +384,7 @@ ProcRRCreateMode(ClientPtr client) ...@@ -371,7 +384,7 @@ ProcRRCreateMode(ClientPtr client)
WriteToClient(client, sizeof(xRRCreateModeReply), (char *) &rep); WriteToClient(client, sizeof(xRRCreateModeReply), (char *) &rep);
/* Drop out reference to this mode */ /* Drop out reference to this mode */
RRModeDestroy(mode); RRModeDestroy(mode);
return client->noClientException; return Success;
} }
int int
...@@ -381,11 +394,8 @@ ProcRRDestroyMode(ClientPtr client) ...@@ -381,11 +394,8 @@ ProcRRDestroyMode(ClientPtr client)
RRModePtr mode; RRModePtr mode;
REQUEST_SIZE_MATCH(xRRDestroyModeReq); REQUEST_SIZE_MATCH(xRRDestroyModeReq);
mode = LookupIDByType(stuff->mode, RRModeType); VERIFY_RR_MODE(stuff->mode, mode, DixDestroyAccess);
if (!mode) {
client->errorValue = stuff->mode;
return RRErrorBase + BadRRMode;
}
if (!mode->userScreen) if (!mode->userScreen)
return BadMatch; return BadMatch;
if (mode->refcnt > 1) if (mode->refcnt > 1)
...@@ -402,18 +412,8 @@ ProcRRAddOutputMode(ClientPtr client) ...@@ -402,18 +412,8 @@ ProcRRAddOutputMode(ClientPtr client)
RROutputPtr output; RROutputPtr output;
REQUEST_SIZE_MATCH(xRRAddOutputModeReq); REQUEST_SIZE_MATCH(xRRAddOutputModeReq);
output = LookupOutput(client, stuff->output, DixReadAccess); VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
VERIFY_RR_MODE(stuff->mode, mode, DixUseAccess);
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); return RROutputAddUserMode(output, mode);
} }
...@@ -426,18 +426,8 @@ ProcRRDeleteOutputMode(ClientPtr client) ...@@ -426,18 +426,8 @@ ProcRRDeleteOutputMode(ClientPtr client)
RROutputPtr output; RROutputPtr output;
REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq); REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq);
output = LookupOutput(client, stuff->output, DixReadAccess); VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
VERIFY_RR_MODE(stuff->mode, mode, DixUseAccess);
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); return RROutputDeleteUserMode(output, mode);
} }
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
*/ */
#include "randrstr.h" #include "randrstr.h"
#include "inputstr.h"
/* /*
* When the pointer moves, check to see if the specified position is outside * When the pointer moves, check to see if the specified position is outside
...@@ -51,7 +52,11 @@ RRCrtcContainsPosition(RRCrtcPtr crtc, int x, int y) ...@@ -51,7 +52,11 @@ RRCrtcContainsPosition(RRCrtcPtr crtc, int x, int y)
* Find the CRTC nearest the specified position, ignoring 'skip' * Find the CRTC nearest the specified position, ignoring 'skip'
*/ */
static void static void
RRPointerToNearestCrtc(ScreenPtr pScreen, int x, int y, RRCrtcPtr skip) RRPointerToNearestCrtc(
#ifndef NXAGENT_SERVER
DeviceIntPtr pDev,
#endif /* !defined(NXAGENT_SERVER) */
ScreenPtr pScreen, int x, int y, RRCrtcPtr skip)
{ {
rrScrPriv(pScreen); rrScrPriv(pScreen);
int c; int c;
...@@ -75,25 +80,31 @@ RRPointerToNearestCrtc(ScreenPtr pScreen, int x, int y, RRCrtcPtr skip) ...@@ -75,25 +80,31 @@ RRPointerToNearestCrtc(ScreenPtr pScreen, int x, int y, RRCrtcPtr skip)
if (x < crtc->x) if (x < crtc->x)
dx = crtc->x - x; dx = crtc->x - x;
else if (x > crtc->x + scan_width) else if (x > crtc->x + scan_width - 1)
dx = x - (crtc->x + scan_width); dx = crtc->x + (scan_width - 1) - x;
else else
dx = 0; dx = 0;
if (y < crtc->y) if (y < crtc->y)
dy = crtc->y - x; dy = crtc->y - y;
else if (y > crtc->y + scan_height) else if (y > crtc->y + scan_height - 1)
dy = y - (crtc->y + scan_height); dy = crtc->y + (scan_height - 1) - y;
else else
dy = 0; dy = 0;
dist = dx + dy; dist = dx * dx + dy * dy;
if (!nearest || dist < best) { if (!nearest || dist < best) {
nearest = crtc; nearest = crtc;
best_dx = dx; best_dx = dx;
best_dy = dy; best_dy = dy;
best = dist;
} }
} }
if (best_dx || best_dy) if (best_dx || best_dy)
(*pScreen->SetCursorPosition) (pScreen, x + best_dx, y + best_dy, TRUE); (*pScreen->SetCursorPosition) (
#ifndef NXAGENT_SERVER
pDev,
#endif /* !defined(NXAGENT_SERVER) */
pScreen, x + best_dx, y + best_dy,
TRUE);
pScrPriv->pointerCrtc = nearest; pScrPriv->pointerCrtc = nearest;
} }
...@@ -120,22 +131,52 @@ RRPointerMoved(ScreenPtr pScreen, int x, int y) ...@@ -120,22 +131,52 @@ RRPointerMoved(ScreenPtr pScreen, int x, int y)
} }
/* None contain pointer, find nearest */ /* None contain pointer, find nearest */
RRPointerToNearestCrtc(pScreen, x, y, pointerCrtc); ErrorF("RRPointerMoved: Untested, may cause \"bogus pointer event\"\n");
RRPointerToNearestCrtc(
#ifndef NXAGENT_SERVER
inputInfo.pointer,
#endif /* !defined(NXAGENT_SERVER) */
pScreen, x, y, pointerCrtc);
} }
/* /*
* When the screen is reconfigured, move the pointer to the nearest * When the screen is reconfigured, move all pointers to the nearest
* CRTC * CRTC
*/ */
void void
RRPointerScreenConfigured(ScreenPtr pScreen) RRPointerScreenConfigured(ScreenPtr pScreen)
{ {
WindowPtr pRoot = GetCurrentRootWindow(); WindowPtr pRoot;
ScreenPtr pCurrentScreen = pRoot ? pRoot->drawable.pScreen : NULL; ScreenPtr pCurrentScreen;
int x, y; int x, y;
if (pScreen != pCurrentScreen) #ifndef NXAGENT_SERVER
return; DeviceIntPtr pDev;
GetSpritePosition(&x, &y);
RRPointerToNearestCrtc(pScreen, x, y, NULL); for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
if (IsPointerDevice(pDev)) {
#endif /* NXAGENT_SERVER */
pRoot = GetCurrentRootWindow(
#ifndef NXAGENT_SERVER
pDev
#endif /* NXAGENT_SERVER */
);
pCurrentScreen = pRoot ? pRoot->drawable.pScreen : NULL;
if (pScreen == pCurrentScreen) {
GetSpritePosition(
#ifndef NXAGENT_SERVER
pDev,
#endif /* NXAGENT_SERVER */
&x, &y);
RRPointerToNearestCrtc(
#ifndef NXAGENT_SERVER
pDev,
#endif /* NXAGENT_SERVER */
pScreen, x, y, NULL);
#ifndef NXAGENT_SERVER
}
}
#endif /* NXAGENT_SERVER */
}
} }
/*
* 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.
*/
#include "randrstr.h"
#include "rrtransform.h"
void
RRTransformInit(RRTransformPtr transform)
{
pixman_transform_init_identity(&transform->transform);
pixman_f_transform_init_identity(&transform->f_transform);
pixman_f_transform_init_identity(&transform->f_inverse);
transform->filter = NULL;
transform->params = NULL;
transform->nparams = 0;
}
void
RRTransformFini(RRTransformPtr transform)
{
xfree(transform->params);
}
Bool
RRTransformEqual(RRTransformPtr a, RRTransformPtr b)
{
if (a && pixman_transform_is_identity(&a->transform))
a = NULL;
if (b && pixman_transform_is_identity(&b->transform))
b = NULL;
if (a == NULL && b == NULL)
return TRUE;
if (a == NULL || b == NULL)
return FALSE;
if (memcmp(&a->transform, &b->transform, sizeof(a->transform)) != 0)
return FALSE;
if (a->filter != b->filter)
return FALSE;
if (a->nparams != b->nparams)
return FALSE;
if (memcmp(a->params, b->params, a->nparams * sizeof(xFixed)) != 0)
return FALSE;
return TRUE;
}
Bool
RRTransformSetFilter(RRTransformPtr dst,
PictFilterPtr filter,
xFixed * params, int nparams, int width, int height)
{
xFixed *new_params;
if (nparams) {
#ifndef NXAGENT_SERVER
new_params = xallocarray(nparams, sizeof(xFixed));
#else /* !defined(NXAGENT_SERVER) */
new_params = xalloc(nparams * sizeof(xFixed));
#endif /* !defined(NXAGENT_SERVER) */
if (!new_params)
return FALSE;
memcpy(new_params, params, nparams * sizeof(xFixed));
}
else
new_params = NULL;
xfree(dst->params);
dst->filter = filter;
dst->params = new_params;
dst->nparams = nparams;
dst->width = width;
dst->height = height;
return TRUE;
}
Bool
RRTransformCopy(RRTransformPtr dst, RRTransformPtr src)
{
if (src && pixman_transform_is_identity(&src->transform))
src = NULL;
if (src) {
if (!RRTransformSetFilter(dst, src->filter,
src->params, src->nparams, src->width,
src->height))
return FALSE;
dst->transform = src->transform;
dst->f_transform = src->f_transform;
dst->f_inverse = src->f_inverse;
}
else {
if (!RRTransformSetFilter(dst, NULL, NULL, 0, 0, 0))
return FALSE;
pixman_transform_init_identity(&dst->transform);
pixman_f_transform_init_identity(&dst->f_transform);
pixman_f_transform_init_identity(&dst->f_inverse);
}
return TRUE;
}
#define F(x) IntToxFixed(x)
static void
RRTransformRescale(struct pixman_f_transform *f_transform, double limit)
{
double max = 0, v, scale;
int i, j;
for (j = 0; j < 3; j++)
for (i = 0; i < 3; i++)
if ((v = fabs(f_transform->m[j][i])) > max)
max = v;
scale = limit / max;
for (j = 0; j < 3; j++)
for (i = 0; i < 3; i++)
f_transform->m[j][i] *= scale;
}
/*
* Compute the complete transformation matrix including
* client-specified transform, rotation/reflection values and the crtc
* offset.
*
* Return TRUE if the resulting transform is not a simple translation.
*/
Bool
RRTransformCompute(int x,
int y,
int width,
int height,
Rotation rotation,
RRTransformPtr rr_transform,
PictTransformPtr transform,
struct pixman_f_transform *f_transform,
struct pixman_f_transform *f_inverse)
{
PictTransform t_transform, inverse;
struct pixman_f_transform tf_transform, tf_inverse;
Bool overflow = FALSE;
if (!transform)
transform = &t_transform;
if (!f_transform)
f_transform = &tf_transform;
if (!f_inverse)
f_inverse = &tf_inverse;
pixman_transform_init_identity(transform);
pixman_transform_init_identity(&inverse);
pixman_f_transform_init_identity(f_transform);
pixman_f_transform_init_identity(f_inverse);
if (rotation != RR_Rotate_0) {
double f_rot_cos, f_rot_sin, f_rot_dx, f_rot_dy;
double f_scale_x, f_scale_y, f_scale_dx, f_scale_dy;
xFixed rot_cos, rot_sin, rot_dx, rot_dy;
xFixed scale_x, scale_y, scale_dx, scale_dy;
/* rotation */
switch (rotation & 0xf) {
default:
case RR_Rotate_0:
f_rot_cos = 1;
f_rot_sin = 0;
f_rot_dx = 0;
f_rot_dy = 0;
rot_cos = F(1);
rot_sin = F(0);
rot_dx = F(0);
rot_dy = F(0);
break;
case RR_Rotate_90:
f_rot_cos = 0;
f_rot_sin = 1;
f_rot_dx = height;
f_rot_dy = 0;
rot_cos = F(0);
rot_sin = F(1);
rot_dx = F(height);
rot_dy = F(0);
break;
case RR_Rotate_180:
f_rot_cos = -1;
f_rot_sin = 0;
f_rot_dx = width;
f_rot_dy = height;
rot_cos = F(~0u);
rot_sin = F(0);
rot_dx = F(width);
rot_dy = F(height);
break;
case RR_Rotate_270:
f_rot_cos = 0;
f_rot_sin = -1;
f_rot_dx = 0;
f_rot_dy = width;
rot_cos = F(0);
rot_sin = F(~0u);
rot_dx = F(0);
rot_dy = F(width);
break;
}
pixman_transform_rotate(transform, &inverse, rot_cos, rot_sin);
pixman_transform_translate(transform, &inverse, rot_dx, rot_dy);
pixman_f_transform_rotate(f_transform, f_inverse, f_rot_cos, f_rot_sin);
pixman_f_transform_translate(f_transform, f_inverse, f_rot_dx,
f_rot_dy);
/* reflection */
f_scale_x = 1;
f_scale_dx = 0;
f_scale_y = 1;
f_scale_dy = 0;
scale_x = F(1);
scale_dx = 0;
scale_y = F(1);
scale_dy = 0;
if (rotation & RR_Reflect_X) {
f_scale_x = -1;
scale_x = F(~0u);
if (rotation & (RR_Rotate_0 | RR_Rotate_180)) {
f_scale_dx = width;
scale_dx = F(width);
}
else {
f_scale_dx = height;
scale_dx = F(height);
}
}
if (rotation & RR_Reflect_Y) {
f_scale_y = -1;
scale_y = F(~0u);
if (rotation & (RR_Rotate_0 | RR_Rotate_180)) {
f_scale_dy = height;
scale_dy = F(height);
}
else {
f_scale_dy = width;
scale_dy = F(width);
}
}
pixman_transform_scale(transform, &inverse, scale_x, scale_y);
pixman_f_transform_scale(f_transform, f_inverse, f_scale_x, f_scale_y);
pixman_transform_translate(transform, &inverse, scale_dx, scale_dy);
pixman_f_transform_translate(f_transform, f_inverse, f_scale_dx,
f_scale_dy);
}
#ifdef RANDR_12_INTERFACE
if (rr_transform) {
if (!pixman_transform_multiply
(transform, &rr_transform->transform, transform))
overflow = TRUE;
pixman_f_transform_multiply(f_transform, &rr_transform->f_transform,
f_transform);
pixman_f_transform_multiply(f_inverse, f_inverse,
&rr_transform->f_inverse);
}
#endif
/*
* Compute the class of the resulting transform
*/
if (!overflow && pixman_transform_is_identity(transform)) {
pixman_transform_init_translate(transform, F(x), F(y));
pixman_f_transform_init_translate(f_transform, x, y);
pixman_f_transform_init_translate(f_inverse, -x, -y);
return FALSE;
}
else {
pixman_f_transform_translate(f_transform, f_inverse, x, y);
if (!pixman_transform_translate(transform, &inverse, F(x), F(y)))
overflow = TRUE;
if (overflow) {
struct pixman_f_transform f_scaled;
f_scaled = *f_transform;
RRTransformRescale(&f_scaled, 16384.0);
pixman_transform_from_pixman_f_transform(transform, &f_scaled);
}
return TRUE;
}
}
/*
* 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.
*/
#ifndef _RRTRANSFORM_H_
#define _RRTRANSFORM_H_
#include "randr.h"
#include "picturestr.h"
typedef struct _rrTransform RRTransformRec, *RRTransformPtr;
struct _rrTransform {
PictTransform transform;
struct pict_f_transform f_transform;
struct pict_f_transform f_inverse;
PictFilterPtr filter;
xFixed *params;
int nparams;
int width;
int height;
};
extern _X_EXPORT void
RRTransformInit(RRTransformPtr transform);
extern _X_EXPORT void
RRTransformFini(RRTransformPtr transform);
extern _X_EXPORT Bool
RRTransformEqual(RRTransformPtr a, RRTransformPtr b);
extern _X_EXPORT Bool
RRTransformSetFilter(RRTransformPtr dst,
PictFilterPtr filter,
xFixed * params, int nparams, int width, int height);
extern _X_EXPORT Bool
RRTransformCopy(RRTransformPtr dst, RRTransformPtr src);
/*
* Compute the complete transformation matrix including
* client-specified transform, rotation/reflection values and the crtc
* offset.
*
* Return TRUE if the resulting transform is not a simple translation.
*/
extern _X_EXPORT Bool
RRTransformCompute(int x,
int y,
int width,
int height,
Rotation rotation,
RRTransformPtr rr_transform,
PictTransformPtr transform,
struct pict_f_transform *f_transform,
struct pict_f_transform *f_inverse);
#endif /* _RRTRANSFORM_H_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment