mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2025-12-20 04:40:02 +01:00
Since we already had to rename some of them, in order to fix name clashes on win32, it's now time to rename all the remaining ones. The old ones are still present as define's to the new ones, just for backwards compatibility. Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net> Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1355>
462 lines
15 KiB
C
462 lines
15 KiB
C
/*
|
|
* 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.
|
|
*/
|
|
#include <dix-config.h>
|
|
|
|
#include "dix/dix_priv.h"
|
|
|
|
#include "present_priv.h"
|
|
#include "randrstr_priv.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);
|
|
/* From presentproto:
|
|
*
|
|
* The client sends the highest supported version to the server
|
|
* and the server sends the highest version it supports, but no
|
|
* higher than the requested version.
|
|
*/
|
|
|
|
if (rep.majorVersion > stuff->majorVersion ||
|
|
rep.minorVersion > stuff->minorVersion) {
|
|
rep.majorVersion = stuff->majorVersion;
|
|
rep.minorVersion = stuff->minorVersion;
|
|
}
|
|
|
|
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_common(ClientPtr client,
|
|
Window req_window,
|
|
Pixmap req_pixmap,
|
|
CARD32 req_serial,
|
|
CARD32 req_valid,
|
|
CARD32 req_update,
|
|
INT16 req_x_off,
|
|
INT16 req_y_off,
|
|
CARD32 req_target_crtc,
|
|
XSyncFence req_wait_fence,
|
|
XSyncFence req_idle_fence,
|
|
#ifdef DRI3
|
|
struct dri3_syncobj *acquire_syncobj,
|
|
struct dri3_syncobj *release_syncobj,
|
|
CARD64 req_acquire_point,
|
|
CARD64 req_release_point,
|
|
#endif /* DRI3 */
|
|
CARD32 req_options,
|
|
CARD64 req_target_msc,
|
|
CARD64 req_divisor,
|
|
CARD64 req_remainder,
|
|
size_t base_req_size,
|
|
xPresentNotify *req_notifies)
|
|
{
|
|
WindowPtr window;
|
|
PixmapPtr pixmap;
|
|
RegionPtr valid = NULL;
|
|
RegionPtr update = NULL;
|
|
RRCrtcPtr target_crtc;
|
|
SyncFence *wait_fence;
|
|
SyncFence *idle_fence;
|
|
int nnotifies;
|
|
present_notify_ptr notifies = NULL;
|
|
int ret;
|
|
|
|
ret = dixLookupWindow(&window, req_window, client, DixWriteAccess);
|
|
if (ret != Success)
|
|
return ret;
|
|
ret = dixLookupResourceByType((void **) &pixmap, req_pixmap, X11_RESTYPE_PIXMAP, client, DixReadAccess);
|
|
if (ret != Success)
|
|
return ret;
|
|
|
|
if (window->drawable.depth != pixmap->drawable.depth)
|
|
return BadMatch;
|
|
|
|
VERIFY_REGION_OR_NONE(valid, req_valid, client, DixReadAccess);
|
|
VERIFY_REGION_OR_NONE(update, req_update, client, DixReadAccess);
|
|
|
|
VERIFY_CRTC_OR_NONE(target_crtc, req_target_crtc, client, DixReadAccess);
|
|
|
|
VERIFY_FENCE_OR_NONE(wait_fence, req_wait_fence, client, DixReadAccess);
|
|
VERIFY_FENCE_OR_NONE(idle_fence, req_idle_fence, client, DixWriteAccess);
|
|
|
|
if (req_options & ~(PresentAllOptions)) {
|
|
client->errorValue = req_options;
|
|
return BadValue;
|
|
}
|
|
|
|
/*
|
|
* Check to see if remainder is sane
|
|
*/
|
|
if (req_divisor == 0) {
|
|
if (req_remainder != 0) {
|
|
client->errorValue = (CARD32)req_remainder;
|
|
return BadValue;
|
|
}
|
|
} else {
|
|
if (req_remainder >= req_divisor) {
|
|
client->errorValue = (CARD32)req_remainder;
|
|
return BadValue;
|
|
}
|
|
}
|
|
|
|
nnotifies = (client->req_len << 2) - base_req_size;
|
|
if (nnotifies % sizeof (xPresentNotify))
|
|
return BadLength;
|
|
|
|
nnotifies /= sizeof (xPresentNotify);
|
|
if (nnotifies) {
|
|
ret = present_create_notifies(client, nnotifies, req_notifies, ¬ifies);
|
|
if (ret != Success)
|
|
return ret;
|
|
}
|
|
|
|
ret = present_pixmap(window, pixmap, req_serial,
|
|
valid, update, req_x_off, req_y_off, target_crtc,
|
|
wait_fence, idle_fence,
|
|
#ifdef DRI3
|
|
acquire_syncobj, release_syncobj,
|
|
req_acquire_point, req_release_point,
|
|
#endif /* DRI3 */
|
|
req_options, req_target_msc, req_divisor, req_remainder,
|
|
notifies, nnotifies);
|
|
|
|
if (ret != Success)
|
|
present_destroy_notifies(notifies, nnotifies);
|
|
return ret;
|
|
}
|
|
|
|
static int
|
|
proc_present_pixmap(ClientPtr client)
|
|
{
|
|
REQUEST(xPresentPixmapReq);
|
|
REQUEST_AT_LEAST_SIZE(xPresentPixmapReq);
|
|
return proc_present_pixmap_common(client, stuff->window, stuff->pixmap, stuff->serial,
|
|
stuff->valid, stuff->update, stuff->x_off, stuff->y_off,
|
|
stuff->target_crtc,
|
|
stuff->wait_fence, stuff->idle_fence,
|
|
#ifdef DRI3
|
|
None, None, 0, 0,
|
|
#endif /* DRI3 */
|
|
stuff->options, stuff->target_msc,
|
|
stuff->divisor, stuff->remainder,
|
|
sizeof (xPresentPixmapReq),
|
|
(xPresentNotify *)(stuff + 1));
|
|
}
|
|
|
|
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);
|
|
|
|
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;
|
|
}
|
|
|
|
#ifdef DRI3
|
|
static int
|
|
proc_present_pixmap_synced (ClientPtr client)
|
|
{
|
|
REQUEST(xPresentPixmapSyncedReq);
|
|
struct dri3_syncobj *acquire_syncobj;
|
|
struct dri3_syncobj *release_syncobj;
|
|
|
|
REQUEST_AT_LEAST_SIZE(xPresentPixmapSyncedReq);
|
|
VERIFY_DRI3_SYNCOBJ(stuff->acquire_syncobj, acquire_syncobj, DixWriteAccess);
|
|
VERIFY_DRI3_SYNCOBJ(stuff->release_syncobj, release_syncobj, DixWriteAccess);
|
|
|
|
if (stuff->acquire_point == 0 || stuff->release_point == 0 ||
|
|
(stuff->acquire_syncobj == stuff->release_syncobj &&
|
|
stuff->acquire_point >= stuff->release_point))
|
|
return BadValue;
|
|
|
|
return proc_present_pixmap_common(client, stuff->window, stuff->pixmap, stuff->serial,
|
|
stuff->valid, stuff->update, stuff->x_off, stuff->y_off,
|
|
stuff->target_crtc,
|
|
None, None,
|
|
acquire_syncobj, release_syncobj,
|
|
stuff->acquire_point, stuff->release_point,
|
|
stuff->options, stuff->target_msc,
|
|
stuff->divisor, stuff->remainder,
|
|
sizeof (xPresentPixmapSyncedReq),
|
|
(xPresentNotify *)(stuff + 1));
|
|
}
|
|
#endif /* DRI3 */
|
|
|
|
static 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 */
|
|
#ifdef DRI3
|
|
proc_present_pixmap_synced, /* 5 */
|
|
#endif /* DRI3 */
|
|
};
|
|
|
|
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 _X_COLD
|
|
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 _X_COLD
|
|
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 _X_COLD
|
|
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 _X_COLD
|
|
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 _X_COLD
|
|
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);
|
|
}
|
|
|
|
|
|
#ifdef DRI3
|
|
static int _X_COLD
|
|
sproc_present_pixmap_synced(ClientPtr client)
|
|
{
|
|
REQUEST(xPresentPixmapSyncedReq);
|
|
REQUEST_AT_LEAST_SIZE(xPresentPixmapSyncedReq);
|
|
|
|
swaps(&stuff->length);
|
|
|
|
swapl(&stuff->window);
|
|
|
|
swapl(&stuff->pixmap);
|
|
swapl(&stuff->serial);
|
|
|
|
swapl(&stuff->valid);
|
|
swapl(&stuff->update);
|
|
|
|
swaps(&stuff->x_off);
|
|
swaps(&stuff->y_off);
|
|
swapl(&stuff->target_crtc);
|
|
|
|
swapl(&stuff->acquire_syncobj);
|
|
swapl(&stuff->release_syncobj);
|
|
swapll(&stuff->acquire_point);
|
|
swapll(&stuff->release_point);
|
|
|
|
swapl(&stuff->options);
|
|
|
|
swapll(&stuff->target_msc);
|
|
swapll(&stuff->divisor);
|
|
swapll(&stuff->remainder);
|
|
return (*proc_present_vector[stuff->presentReqType]) (client);
|
|
}
|
|
#endif /* DRI3 */
|
|
|
|
static 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 */
|
|
#ifdef DRI3
|
|
sproc_present_pixmap_synced, /* 5 */
|
|
#endif /* DRI3 */
|
|
};
|
|
|
|
int _X_COLD
|
|
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);
|
|
}
|