2 * Copyright © 2013 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
23 #ifdef HAVE_XORG_CONFIG_H
24 #include <xorg-config.h>
27 #include "present_priv.h"
29 #include <protocol-versions.h>
32 proc_present_query_version(ClientPtr client
)
34 REQUEST(xPresentQueryVersionReq
);
35 xPresentQueryVersionReply rep
= {
37 .sequenceNumber
= client
->sequence
,
39 .majorVersion
= SERVER_PRESENT_MAJOR_VERSION
,
40 .minorVersion
= SERVER_PRESENT_MINOR_VERSION
43 REQUEST_SIZE_MATCH(xPresentQueryVersionReq
);
45 if (client
->swapped
) {
46 swaps(&rep
.sequenceNumber
);
48 swapl(&rep
.majorVersion
);
49 swapl(&rep
.minorVersion
);
51 WriteToClient(client
, sizeof(rep
), &rep
);
55 #define VERIFY_FENCE_OR_NONE(fence_ptr, fence_id, client, access) do { \
56 if ((fence_id) == None) \
59 int __rc__ = SyncVerifyFence(&fence_ptr, fence_id, client, access); \
60 if (__rc__ != Success) \
65 #define VERIFY_CRTC_OR_NONE(crtc_ptr, crtc_id, client, access) do { \
66 if ((crtc_id) == None) \
69 VERIFY_RR_CRTC(crtc_id, crtc_ptr, access); \
74 proc_present_pixmap(ClientPtr client
)
76 REQUEST(xPresentPixmapReq
);
79 RegionPtr valid
= NULL
;
80 RegionPtr update
= NULL
;
81 SyncFence
*wait_fence
;
82 SyncFence
*idle_fence
;
83 RRCrtcPtr target_crtc
;
86 present_notify_ptr notifies
= NULL
;
88 REQUEST_AT_LEAST_SIZE(xPresentPixmapReq
);
89 ret
= dixLookupWindow(&window
, stuff
->window
, client
, DixWriteAccess
);
92 ret
= dixLookupResourceByType((pointer
*) &pixmap
, stuff
->pixmap
, RT_PIXMAP
, client
, DixReadAccess
);
96 if (window
->drawable
.depth
!= pixmap
->drawable
.depth
)
99 VERIFY_REGION_OR_NONE(valid
, stuff
->valid
, client
, DixReadAccess
);
100 VERIFY_REGION_OR_NONE(update
, stuff
->update
, client
, DixReadAccess
);
102 VERIFY_CRTC_OR_NONE(target_crtc
, stuff
->target_crtc
, client
, DixReadAccess
);
104 VERIFY_FENCE_OR_NONE(wait_fence
, stuff
->wait_fence
, client
, DixReadAccess
);
105 VERIFY_FENCE_OR_NONE(idle_fence
, stuff
->idle_fence
, client
, DixWriteAccess
);
107 if (stuff
->options
& ~(PresentAllOptions
)) {
108 client
->errorValue
= stuff
->options
;
113 * Check to see if remainder is sane
115 if (stuff
->divisor
== 0) {
116 if (stuff
->remainder
!= 0) {
117 client
->errorValue
= (CARD32
) stuff
->remainder
;
121 if (stuff
->remainder
>= stuff
->divisor
) {
122 client
->errorValue
= (CARD32
) stuff
->remainder
;
127 nnotifies
= (client
->req_len
<< 2) - sizeof (xPresentPixmapReq
);
128 if (nnotifies
% sizeof (xPresentNotify
))
131 nnotifies
/= sizeof (xPresentNotify
);
133 ret
= present_create_notifies(client
, nnotifies
, (xPresentNotify
*) (stuff
+ 1), ¬ifies
);
138 ret
= present_pixmap(window
, pixmap
, stuff
->serial
, valid
, update
,
139 stuff
->x_off
, stuff
->y_off
, target_crtc
,
140 wait_fence
, idle_fence
, stuff
->options
,
141 stuff
->target_msc
, stuff
->divisor
, stuff
->remainder
, notifies
, nnotifies
);
143 present_destroy_notifies(notifies
, nnotifies
);
148 proc_present_notify_msc(ClientPtr client
)
150 REQUEST(xPresentNotifyMSCReq
);
154 REQUEST_SIZE_MATCH(xPresentNotifyMSCReq
);
155 rc
= dixLookupWindow(&window
, stuff
->window
, client
, DixReadAccess
);
160 * Check to see if remainder is sane
162 if (stuff
->divisor
== 0) {
163 if (stuff
->remainder
!= 0) {
164 client
->errorValue
= (CARD32
) stuff
->remainder
;
168 if (stuff
->remainder
>= stuff
->divisor
) {
169 client
->errorValue
= (CARD32
) stuff
->remainder
;
174 return present_notify_msc(window
, stuff
->serial
,
175 stuff
->target_msc
, stuff
->divisor
, stuff
->remainder
);
179 proc_present_select_input (ClientPtr client
)
181 REQUEST(xPresentSelectInputReq
);
185 REQUEST_SIZE_MATCH(xPresentSelectInputReq
);
187 LEGAL_NEW_RESOURCE(stuff
->eid
, client
);
189 rc
= dixLookupWindow(&window
, stuff
->window
, client
, DixGetAttrAccess
);
193 if (stuff
->eventMask
& ~PresentAllEvents
) {
194 client
->errorValue
= stuff
->eventMask
;
197 return present_select_input(client
, stuff
->eid
, window
, stuff
->eventMask
);
201 proc_present_query_capabilities (ClientPtr client
)
203 REQUEST(xPresentQueryCapabilitiesReq
);
204 xPresentQueryCapabilitiesReply rep
= {
206 .sequenceNumber
= client
->sequence
,
210 RRCrtcPtr crtc
= NULL
;
213 r
= dixLookupWindow(&window
, stuff
->target
, client
, DixGetAttrAccess
);
216 crtc
= present_get_crtc(window
);
219 VERIFY_RR_CRTC(stuff
->target
, crtc
, DixGetAttrAccess
);
225 rep
.capabilities
= present_query_capabilities(crtc
);
227 if (client
->swapped
) {
228 swaps(&rep
.sequenceNumber
);
230 swapl(&rep
.capabilities
);
232 WriteToClient(client
, sizeof(rep
), &rep
);
236 int (*proc_present_vector
[PresentNumberRequests
]) (ClientPtr
) = {
237 proc_present_query_version
, /* 0 */
238 proc_present_pixmap
, /* 1 */
239 proc_present_notify_msc
, /* 2 */
240 proc_present_select_input
, /* 3 */
241 proc_present_query_capabilities
, /* 4 */
245 proc_present_dispatch(ClientPtr client
)
248 if (stuff
->data
>= PresentNumberRequests
|| !proc_present_vector
[stuff
->data
])
250 return (*proc_present_vector
[stuff
->data
]) (client
);
254 sproc_present_query_version(ClientPtr client
)
256 REQUEST(xPresentQueryVersionReq
);
258 swaps(&stuff
->length
);
259 swapl(&stuff
->majorVersion
);
260 swapl(&stuff
->minorVersion
);
261 return (*proc_present_vector
[stuff
->presentReqType
]) (client
);
265 sproc_present_pixmap(ClientPtr client
)
267 REQUEST(xPresentPixmapReq
);
269 swaps(&stuff
->length
);
270 swapl(&stuff
->window
);
271 swapl(&stuff
->pixmap
);
272 swapl(&stuff
->valid
);
273 swapl(&stuff
->update
);
274 swaps(&stuff
->x_off
);
275 swaps(&stuff
->y_off
);
276 swapll(&stuff
->target_msc
);
277 swapll(&stuff
->divisor
);
278 swapll(&stuff
->remainder
);
279 swapl(&stuff
->idle_fence
);
280 return (*proc_present_vector
[stuff
->presentReqType
]) (client
);
284 sproc_present_notify_msc(ClientPtr client
)
286 REQUEST(xPresentNotifyMSCReq
);
288 swaps(&stuff
->length
);
289 swapl(&stuff
->window
);
290 swapll(&stuff
->target_msc
);
291 swapll(&stuff
->divisor
);
292 swapll(&stuff
->remainder
);
293 return (*proc_present_vector
[stuff
->presentReqType
]) (client
);
297 sproc_present_select_input (ClientPtr client
)
299 REQUEST(xPresentSelectInputReq
);
301 swaps(&stuff
->length
);
302 swapl(&stuff
->window
);
303 swapl(&stuff
->eventMask
);
304 return (*proc_present_vector
[stuff
->presentReqType
]) (client
);
308 sproc_present_query_capabilities (ClientPtr client
)
310 REQUEST(xPresentQueryCapabilitiesReq
);
311 swaps(&stuff
->length
);
312 swapl(&stuff
->target
);
313 return (*proc_present_vector
[stuff
->presentReqType
]) (client
);
316 int (*sproc_present_vector
[PresentNumberRequests
]) (ClientPtr
) = {
317 sproc_present_query_version
, /* 0 */
318 sproc_present_pixmap
, /* 1 */
319 sproc_present_notify_msc
, /* 2 */
320 sproc_present_select_input
, /* 3 */
321 sproc_present_query_capabilities
, /* 4 */
325 sproc_present_dispatch(ClientPtr client
)
328 if (stuff
->data
>= PresentNumberRequests
|| !sproc_present_vector
[stuff
->data
])
330 return (*sproc_present_vector
[stuff
->data
]) (client
);