2 * Copyright © 2006 Keith Packard
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. The copyright holders make no representations
11 * about the suitability of this software for any purpose. It is provided "as
12 * is" without express or implied warranty.
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
25 #define SERVER_RANDR_MAJOR 1
26 #define SERVER_RANDR_MINOR 2
29 RRClientKnowsRates (ClientPtr pClient
)
31 rrClientPriv(pClient
);
33 return (pRRClient
->major_version
> 1 ||
34 (pRRClient
->major_version
== 1 && pRRClient
->minor_version
>= 1));
38 ProcRRQueryVersion (ClientPtr client
)
40 xRRQueryVersionReply rep
;
42 REQUEST(xRRQueryVersionReq
);
45 REQUEST_SIZE_MATCH(xRRQueryVersionReq
);
46 pRRClient
->major_version
= stuff
->majorVersion
;
47 pRRClient
->minor_version
= stuff
->minorVersion
;
50 rep
.sequenceNumber
= client
->sequence
;
52 * Report the current version; the current
53 * spec says they're all compatible after 1.0
55 rep
.majorVersion
= SERVER_RANDR_MAJOR
;
56 rep
.minorVersion
= SERVER_RANDR_MINOR
;
57 if (client
->swapped
) {
58 swaps(&rep
.sequenceNumber
, n
);
59 swapl(&rep
.length
, n
);
60 swapl(&rep
.majorVersion
, n
);
61 swapl(&rep
.minorVersion
, n
);
63 WriteToClient(client
, sizeof(xRRQueryVersionReply
), (char *)&rep
);
64 return (client
->noClientException
);
68 ProcRRSelectInput (ClientPtr client
)
70 REQUEST(xRRSelectInputReq
);
74 RREventPtr pRREvent
, *pHead
;
78 REQUEST_SIZE_MATCH(xRRSelectInputReq
);
79 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixWriteAccess
);
82 pHead
= (RREventPtr
*)SecurityLookupIDByType(client
,
83 pWin
->drawable
.id
, RREventType
,
86 if (stuff
->enable
& (RRScreenChangeNotifyMask
|
87 RRCrtcChangeNotifyMask
|
88 RROutputChangeNotifyMask
))
90 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
96 /* check for existing entry. */
97 for (pRREvent
= *pHead
; pRREvent
; pRREvent
= pRREvent
->next
)
98 if (pRREvent
->client
== client
)
104 /* build the entry */
105 pRREvent
= (RREventPtr
) xalloc (sizeof (RREventRec
));
109 pRREvent
->client
= client
;
110 pRREvent
->window
= pWin
;
111 pRREvent
->mask
= stuff
->enable
;
113 * add a resource that will be deleted when
114 * the client goes away
116 clientResource
= FakeClientID (client
->index
);
117 pRREvent
->clientResource
= clientResource
;
118 if (!AddResource (clientResource
, RRClientType
, (pointer
)pRREvent
))
121 * create a resource to contain a pointer to the list
122 * of clients selecting input. This must be indirect as
123 * the list may be arbitrarily rearranged which cannot be
124 * done through the resource database.
128 pHead
= (RREventPtr
*) xalloc (sizeof (RREventPtr
));
130 !AddResource (pWin
->drawable
.id
, RREventType
, (pointer
)pHead
))
132 FreeResource (clientResource
, RT_NONE
);
137 pRREvent
->next
= *pHead
;
141 * Now see if the client needs an event
143 if (pScrPriv
&& (pRREvent
->mask
& RRScreenChangeNotifyMask
))
145 pTimes
= &((RRTimesPtr
) (pRRClient
+ 1))[pScreen
->myNum
];
146 if (CompareTimeStamps (pTimes
->setTime
,
147 pScrPriv
->lastSetTime
) != 0 ||
148 CompareTimeStamps (pTimes
->configTime
,
149 pScrPriv
->lastConfigTime
) != 0)
151 RRDeliverScreenEvent (client
, pWin
, pScreen
);
155 else if (stuff
->enable
== 0)
157 /* delete the interest */
159 RREventPtr pNewRREvent
= 0;
160 for (pRREvent
= *pHead
; pRREvent
; pRREvent
= pRREvent
->next
) {
161 if (pRREvent
->client
== client
)
163 pNewRREvent
= pRREvent
;
166 FreeResource (pRREvent
->clientResource
, RRClientType
);
168 pNewRREvent
->next
= pRREvent
->next
;
170 *pHead
= pRREvent
->next
;
177 client
->errorValue
= stuff
->enable
;
183 int (*ProcRandrVector
[RRNumberRequests
])(ClientPtr
) = {
184 ProcRRQueryVersion
, /* 0 */
185 /* we skip 1 to make old clients fail pretty immediately */
186 NULL
, /* 1 ProcRandrOldGetScreenInfo */
187 /* V1.0 apps share the same set screen config request id */
188 ProcRRSetScreenConfig
, /* 2 */
189 NULL
, /* 3 ProcRandrOldScreenChangeSelectInput */
190 /* 3 used to be ScreenChangeSelectInput; deprecated */
191 ProcRRSelectInput
, /* 4 */
192 ProcRRGetScreenInfo
, /* 5 */
194 ProcRRGetScreenSizeRange
, /* 6 */
195 ProcRRSetScreenSize
, /* 7 */
196 ProcRRGetScreenResources
, /* 8 */
197 ProcRRGetOutputInfo
, /* 9 */
198 ProcRRListOutputProperties
, /* 10 */
199 ProcRRQueryOutputProperty
, /* 11 */
200 ProcRRConfigureOutputProperty
, /* 12 */
201 ProcRRChangeOutputProperty
, /* 13 */
202 ProcRRDeleteOutputProperty
, /* 14 */
203 ProcRRGetOutputProperty
, /* 15 */
204 ProcRRCreateMode
, /* 16 */
205 ProcRRDestroyMode
, /* 17 */
206 ProcRRAddOutputMode
, /* 18 */
207 ProcRRDeleteOutputMode
, /* 19 */
208 ProcRRGetCrtcInfo
, /* 20 */
209 ProcRRSetCrtcConfig
, /* 21 */
210 ProcRRGetCrtcGammaSize
, /* 22 */
211 ProcRRGetCrtcGamma
, /* 23 */
212 ProcRRSetCrtcGamma
, /* 24 */