123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- /*
- * Copyright © 2013 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>
- #endif
- #include "present_priv.h"
- #include "randrstr.h"
- #include <protocol-versions.h>
- static int
- proc_present_query_version(ClientPtr client)
- {
- REQUEST(xPresentQueryVersionReq);
- xPresentQueryVersionReply rep = {
- .type = X_Reply,
- .sequenceNumber = client->sequence,
- .length = 0,
- .majorVersion = SERVER_PRESENT_MAJOR_VERSION,
- .minorVersion = SERVER_PRESENT_MINOR_VERSION
- };
- REQUEST_SIZE_MATCH(xPresentQueryVersionReq);
- (void) stuff;
- if (client->swapped) {
- swaps(&rep.sequenceNumber);
- swapl(&rep.length);
- swapl(&rep.majorVersion);
- swapl(&rep.minorVersion);
- }
- WriteToClient(client, sizeof(rep), &rep);
- return Success;
- }
- #define VERIFY_FENCE_OR_NONE(fence_ptr, fence_id, client, access) do { \
- if ((fence_id) == None) \
- (fence_ptr) = NULL; \
- else { \
- int __rc__ = SyncVerifyFence(&fence_ptr, fence_id, client, access); \
- if (__rc__ != Success) \
- return __rc__; \
- } \
- } while (0)
- #define VERIFY_CRTC_OR_NONE(crtc_ptr, crtc_id, client, access) do { \
- if ((crtc_id) == None) \
- (crtc_ptr) = NULL; \
- else { \
- VERIFY_RR_CRTC(crtc_id, crtc_ptr, access); \
- } \
- } while (0)
- static int
- proc_present_pixmap(ClientPtr client)
- {
- REQUEST(xPresentPixmapReq);
- WindowPtr window;
- PixmapPtr pixmap;
- RegionPtr valid = NULL;
- RegionPtr update = NULL;
- SyncFence *wait_fence;
- SyncFence *idle_fence;
- RRCrtcPtr target_crtc;
- int ret;
- int nnotifies;
- present_notify_ptr notifies = NULL;
- REQUEST_AT_LEAST_SIZE(xPresentPixmapReq);
- ret = dixLookupWindow(&window, stuff->window, client, DixWriteAccess);
- if (ret != Success)
- return ret;
- ret = dixLookupResourceByType((void **) &pixmap, stuff->pixmap, RT_PIXMAP, client, DixReadAccess);
- if (ret != Success)
- return ret;
- if (window->drawable.depth != pixmap->drawable.depth)
- return BadMatch;
- VERIFY_REGION_OR_NONE(valid, stuff->valid, client, DixReadAccess);
- VERIFY_REGION_OR_NONE(update, stuff->update, client, DixReadAccess);
- VERIFY_CRTC_OR_NONE(target_crtc, stuff->target_crtc, client, DixReadAccess);
- VERIFY_FENCE_OR_NONE(wait_fence, stuff->wait_fence, client, DixReadAccess);
- VERIFY_FENCE_OR_NONE(idle_fence, stuff->idle_fence, client, DixWriteAccess);
- if (stuff->options & ~(PresentAllOptions)) {
- client->errorValue = stuff->options;
- return BadValue;
- }
- /*
- * Check to see if remainder is sane
- */
- if (stuff->divisor == 0) {
- if (stuff->remainder != 0) {
- client->errorValue = (CARD32) stuff->remainder;
- return BadValue;
- }
- } else {
- if (stuff->remainder >= stuff->divisor) {
- client->errorValue = (CARD32) stuff->remainder;
- return BadValue;
- }
- }
- nnotifies = (client->req_len << 2) - sizeof (xPresentPixmapReq);
- if (nnotifies % sizeof (xPresentNotify))
- return BadLength;
- nnotifies /= sizeof (xPresentNotify);
- if (nnotifies) {
- ret = present_create_notifies(client, nnotifies, (xPresentNotify *) (stuff + 1), ¬ifies);
- if (ret != Success)
- return ret;
- }
- ret = present_pixmap(window, pixmap, stuff->serial, valid, update,
- stuff->x_off, stuff->y_off, target_crtc,
- wait_fence, idle_fence, stuff->options,
- stuff->target_msc, stuff->divisor, stuff->remainder, notifies, nnotifies);
- if (ret != Success)
- present_destroy_notifies(notifies, nnotifies);
- return ret;
- }
- static int
- proc_present_notify_msc(ClientPtr client)
- {
- REQUEST(xPresentNotifyMSCReq);
- WindowPtr window;
- int rc;
- REQUEST_SIZE_MATCH(xPresentNotifyMSCReq);
- rc = dixLookupWindow(&window, stuff->window, client, DixReadAccess);
- if (rc != Success)
- return rc;
- /*
- * Check to see if remainder is sane
- */
- if (stuff->divisor == 0) {
- if (stuff->remainder != 0) {
- client->errorValue = (CARD32) stuff->remainder;
- return BadValue;
- }
- } else {
- if (stuff->remainder >= stuff->divisor) {
- client->errorValue = (CARD32) stuff->remainder;
- return BadValue;
- }
- }
- return present_notify_msc(window, stuff->serial,
- stuff->target_msc, stuff->divisor, stuff->remainder);
- }
- static int
- proc_present_select_input (ClientPtr client)
- {
- REQUEST(xPresentSelectInputReq);
- WindowPtr window;
- int rc;
- REQUEST_SIZE_MATCH(xPresentSelectInputReq);
- LEGAL_NEW_RESOURCE(stuff->eid, client);
- rc = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
- if (stuff->eventMask & ~PresentAllEvents) {
- client->errorValue = stuff->eventMask;
- return BadValue;
- }
- return present_select_input(client, stuff->eid, window, stuff->eventMask);
- }
- static int
- proc_present_query_capabilities (ClientPtr client)
- {
- REQUEST(xPresentQueryCapabilitiesReq);
- xPresentQueryCapabilitiesReply rep = {
- .type = X_Reply,
- .sequenceNumber = client->sequence,
- .length = 0,
- };
- WindowPtr window;
- RRCrtcPtr crtc = NULL;
- int r;
- REQUEST_SIZE_MATCH(xPresentQueryCapabilitiesReq);
- r = dixLookupWindow(&window, stuff->target, client, DixGetAttrAccess);
- switch (r) {
- case Success:
- crtc = present_get_crtc(window);
- break;
- case BadWindow:
- VERIFY_RR_CRTC(stuff->target, crtc, DixGetAttrAccess);
- break;
- default:
- return r;
- }
- rep.capabilities = present_query_capabilities(crtc);
- if (client->swapped) {
- swaps(&rep.sequenceNumber);
- swapl(&rep.length);
- swapl(&rep.capabilities);
- }
- WriteToClient(client, sizeof(rep), &rep);
- return Success;
- }
- int (*proc_present_vector[PresentNumberRequests]) (ClientPtr) = {
- proc_present_query_version, /* 0 */
- proc_present_pixmap, /* 1 */
- proc_present_notify_msc, /* 2 */
- proc_present_select_input, /* 3 */
- proc_present_query_capabilities, /* 4 */
- };
- int
- proc_present_dispatch(ClientPtr client)
- {
- REQUEST(xReq);
- if (stuff->data >= PresentNumberRequests || !proc_present_vector[stuff->data])
- return BadRequest;
- return (*proc_present_vector[stuff->data]) (client);
- }
- static int
- sproc_present_query_version(ClientPtr client)
- {
- REQUEST(xPresentQueryVersionReq);
- REQUEST_SIZE_MATCH(xPresentQueryVersionReq);
- swaps(&stuff->length);
- swapl(&stuff->majorVersion);
- swapl(&stuff->minorVersion);
- return (*proc_present_vector[stuff->presentReqType]) (client);
- }
- static int
- sproc_present_pixmap(ClientPtr client)
- {
- REQUEST(xPresentPixmapReq);
- REQUEST_AT_LEAST_SIZE(xPresentPixmapReq);
- swaps(&stuff->length);
- swapl(&stuff->window);
- swapl(&stuff->pixmap);
- swapl(&stuff->valid);
- swapl(&stuff->update);
- swaps(&stuff->x_off);
- swaps(&stuff->y_off);
- swapll(&stuff->target_msc);
- swapll(&stuff->divisor);
- swapll(&stuff->remainder);
- swapl(&stuff->idle_fence);
- return (*proc_present_vector[stuff->presentReqType]) (client);
- }
- static int
- sproc_present_notify_msc(ClientPtr client)
- {
- REQUEST(xPresentNotifyMSCReq);
- REQUEST_SIZE_MATCH(xPresentNotifyMSCReq);
- swaps(&stuff->length);
- swapl(&stuff->window);
- swapll(&stuff->target_msc);
- swapll(&stuff->divisor);
- swapll(&stuff->remainder);
- return (*proc_present_vector[stuff->presentReqType]) (client);
- }
- static int
- sproc_present_select_input (ClientPtr client)
- {
- REQUEST(xPresentSelectInputReq);
- REQUEST_SIZE_MATCH(xPresentSelectInputReq);
- swaps(&stuff->length);
- swapl(&stuff->window);
- swapl(&stuff->eventMask);
- return (*proc_present_vector[stuff->presentReqType]) (client);
- }
- static int
- sproc_present_query_capabilities (ClientPtr client)
- {
- REQUEST(xPresentQueryCapabilitiesReq);
- REQUEST_SIZE_MATCH(xPresentQueryCapabilitiesReq);
- swaps(&stuff->length);
- swapl(&stuff->target);
- return (*proc_present_vector[stuff->presentReqType]) (client);
- }
- int (*sproc_present_vector[PresentNumberRequests]) (ClientPtr) = {
- sproc_present_query_version, /* 0 */
- sproc_present_pixmap, /* 1 */
- sproc_present_notify_msc, /* 2 */
- sproc_present_select_input, /* 3 */
- sproc_present_query_capabilities, /* 4 */
- };
- int
- sproc_present_dispatch(ClientPtr client)
- {
- REQUEST(xReq);
- if (stuff->data >= PresentNumberRequests || !sproc_present_vector[stuff->data])
- return BadRequest;
- return (*sproc_present_vector[stuff->data]) (client);
- }
|