xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

present_request.c (11116B)


      1 /*
      2  * Copyright © 2013 Keith Packard
      3  *
      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.
     13  *
     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
     20  * OF THIS SOFTWARE.
     21  */
     22 
     23 #include "present_priv.h"
     24 #include "randrstr.h"
     25 #include <protocol-versions.h>
     26 
     27 static int
     28 proc_present_query_version(ClientPtr client)
     29 {
     30     REQUEST(xPresentQueryVersionReq);
     31     xPresentQueryVersionReply rep = {
     32         .type = X_Reply,
     33         .sequenceNumber = client->sequence,
     34         .length = 0,
     35         .majorVersion = SERVER_PRESENT_MAJOR_VERSION,
     36         .minorVersion = SERVER_PRESENT_MINOR_VERSION
     37     };
     38 
     39     REQUEST_SIZE_MATCH(xPresentQueryVersionReq);
     40     /* From presentproto:
     41      *
     42      * The client sends the highest supported version to the server
     43      * and the server sends the highest version it supports, but no
     44      * higher than the requested version.
     45      */
     46 
     47     if (rep.majorVersion > stuff->majorVersion ||
     48         rep.minorVersion > stuff->minorVersion) {
     49         rep.majorVersion = stuff->majorVersion;
     50         rep.minorVersion = stuff->minorVersion;
     51     }
     52 
     53     if (client->swapped) {
     54         swaps(&rep.sequenceNumber);
     55         swapl(&rep.length);
     56         swapl(&rep.majorVersion);
     57         swapl(&rep.minorVersion);
     58     }
     59     WriteToClient(client, sizeof(rep), &rep);
     60     return Success;
     61 }
     62 
     63 #define VERIFY_FENCE_OR_NONE(fence_ptr, fence_id, client, access) do {  \
     64         if ((fence_id) == None)                                         \
     65             (fence_ptr) = NULL;                                         \
     66         else {                                                          \
     67             int __rc__ = SyncVerifyFence(&fence_ptr, fence_id, client, access); \
     68             if (__rc__ != Success)                                      \
     69                 return __rc__;                                          \
     70         }                                                               \
     71     } while (0)
     72 
     73 #define VERIFY_CRTC_OR_NONE(crtc_ptr, crtc_id, client, access) do {     \
     74         if ((crtc_id) == None)                                          \
     75             (crtc_ptr) = NULL;                                          \
     76         else {                                                          \
     77             VERIFY_RR_CRTC(crtc_id, crtc_ptr, access);                  \
     78         }                                                               \
     79     } while (0)
     80 
     81 static int
     82 proc_present_pixmap(ClientPtr client)
     83 {
     84     REQUEST(xPresentPixmapReq);
     85     WindowPtr           window;
     86     PixmapPtr           pixmap;
     87     RegionPtr           valid = NULL;
     88     RegionPtr           update = NULL;
     89     SyncFence           *wait_fence;
     90     SyncFence           *idle_fence;
     91     RRCrtcPtr           target_crtc;
     92     int                 ret;
     93     int                 nnotifies;
     94     present_notify_ptr  notifies = NULL;
     95 
     96     REQUEST_AT_LEAST_SIZE(xPresentPixmapReq);
     97     ret = dixLookupWindow(&window, stuff->window, client, DixWriteAccess);
     98     if (ret != Success)
     99         return ret;
    100     ret = dixLookupResourceByType((void **) &pixmap, stuff->pixmap, RT_PIXMAP, client, DixReadAccess);
    101     if (ret != Success)
    102         return ret;
    103 
    104     if (window->drawable.depth != pixmap->drawable.depth)
    105         return BadMatch;
    106 
    107     VERIFY_REGION_OR_NONE(valid, stuff->valid, client, DixReadAccess);
    108     VERIFY_REGION_OR_NONE(update, stuff->update, client, DixReadAccess);
    109 
    110     VERIFY_CRTC_OR_NONE(target_crtc, stuff->target_crtc, client, DixReadAccess);
    111 
    112     VERIFY_FENCE_OR_NONE(wait_fence, stuff->wait_fence, client, DixReadAccess);
    113     VERIFY_FENCE_OR_NONE(idle_fence, stuff->idle_fence, client, DixWriteAccess);
    114 
    115     if (stuff->options & ~(PresentAllOptions)) {
    116         client->errorValue = stuff->options;
    117         return BadValue;
    118     }
    119 
    120     /*
    121      * Check to see if remainder is sane
    122      */
    123     if (stuff->divisor == 0) {
    124         if (stuff->remainder != 0) {
    125             client->errorValue = (CARD32) stuff->remainder;
    126             return BadValue;
    127         }
    128     } else {
    129         if (stuff->remainder >= stuff->divisor) {
    130             client->errorValue = (CARD32) stuff->remainder;
    131             return BadValue;
    132         }
    133     }
    134 
    135     nnotifies = (client->req_len << 2) - sizeof (xPresentPixmapReq);
    136     if (nnotifies % sizeof (xPresentNotify))
    137         return BadLength;
    138 
    139     nnotifies /= sizeof (xPresentNotify);
    140     if (nnotifies) {
    141         ret = present_create_notifies(client, nnotifies, (xPresentNotify *) (stuff + 1), &notifies);
    142         if (ret != Success)
    143             return ret;
    144     }
    145 
    146     ret = present_pixmap(window, pixmap, stuff->serial, valid, update,
    147                          stuff->x_off, stuff->y_off, target_crtc,
    148                          wait_fence, idle_fence, stuff->options,
    149                          stuff->target_msc, stuff->divisor, stuff->remainder, notifies, nnotifies);
    150     if (ret != Success)
    151         present_destroy_notifies(notifies, nnotifies);
    152     return ret;
    153 }
    154 
    155 static int
    156 proc_present_notify_msc(ClientPtr client)
    157 {
    158     REQUEST(xPresentNotifyMSCReq);
    159     WindowPtr   window;
    160     int         rc;
    161 
    162     REQUEST_SIZE_MATCH(xPresentNotifyMSCReq);
    163     rc = dixLookupWindow(&window, stuff->window, client, DixReadAccess);
    164     if (rc != Success)
    165         return rc;
    166 
    167     /*
    168      * Check to see if remainder is sane
    169      */
    170     if (stuff->divisor == 0) {
    171         if (stuff->remainder != 0) {
    172             client->errorValue = (CARD32) stuff->remainder;
    173             return BadValue;
    174         }
    175     } else {
    176         if (stuff->remainder >= stuff->divisor) {
    177             client->errorValue = (CARD32) stuff->remainder;
    178             return BadValue;
    179         }
    180     }
    181 
    182     return present_notify_msc(window, stuff->serial,
    183                               stuff->target_msc, stuff->divisor, stuff->remainder);
    184 }
    185 
    186 static int
    187 proc_present_select_input (ClientPtr client)
    188 {
    189     REQUEST(xPresentSelectInputReq);
    190     WindowPtr window;
    191     int rc;
    192 
    193     REQUEST_SIZE_MATCH(xPresentSelectInputReq);
    194 
    195     rc = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
    196     if (rc != Success)
    197         return rc;
    198 
    199     if (stuff->eventMask & ~PresentAllEvents) {
    200         client->errorValue = stuff->eventMask;
    201         return BadValue;
    202     }
    203     return present_select_input(client, stuff->eid, window, stuff->eventMask);
    204 }
    205 
    206 static int
    207 proc_present_query_capabilities (ClientPtr client)
    208 {
    209     REQUEST(xPresentQueryCapabilitiesReq);
    210     xPresentQueryCapabilitiesReply rep = {
    211         .type = X_Reply,
    212         .sequenceNumber = client->sequence,
    213         .length = 0,
    214     };
    215     WindowPtr   window;
    216     RRCrtcPtr   crtc = NULL;
    217     int         r;
    218 
    219     REQUEST_SIZE_MATCH(xPresentQueryCapabilitiesReq);
    220     r = dixLookupWindow(&window, stuff->target, client, DixGetAttrAccess);
    221     switch (r) {
    222     case Success:
    223         crtc = present_get_crtc(window);
    224         break;
    225     case BadWindow:
    226         VERIFY_RR_CRTC(stuff->target, crtc, DixGetAttrAccess);
    227         break;
    228     default:
    229         return r;
    230     }
    231 
    232     rep.capabilities = present_query_capabilities(crtc);
    233 
    234     if (client->swapped) {
    235         swaps(&rep.sequenceNumber);
    236         swapl(&rep.length);
    237         swapl(&rep.capabilities);
    238     }
    239     WriteToClient(client, sizeof(rep), &rep);
    240     return Success;
    241 }
    242 
    243 static int (*proc_present_vector[PresentNumberRequests]) (ClientPtr) = {
    244     proc_present_query_version,            /* 0 */
    245     proc_present_pixmap,                   /* 1 */
    246     proc_present_notify_msc,               /* 2 */
    247     proc_present_select_input,             /* 3 */
    248     proc_present_query_capabilities,       /* 4 */
    249 };
    250 
    251 int
    252 proc_present_dispatch(ClientPtr client)
    253 {
    254     REQUEST(xReq);
    255     if (stuff->data >= PresentNumberRequests || !proc_present_vector[stuff->data])
    256         return BadRequest;
    257     return (*proc_present_vector[stuff->data]) (client);
    258 }
    259 
    260 static int _X_COLD
    261 sproc_present_query_version(ClientPtr client)
    262 {
    263     REQUEST(xPresentQueryVersionReq);
    264     REQUEST_SIZE_MATCH(xPresentQueryVersionReq);
    265 
    266     swaps(&stuff->length);
    267     swapl(&stuff->majorVersion);
    268     swapl(&stuff->minorVersion);
    269     return (*proc_present_vector[stuff->presentReqType]) (client);
    270 }
    271 
    272 static int _X_COLD
    273 sproc_present_pixmap(ClientPtr client)
    274 {
    275     REQUEST(xPresentPixmapReq);
    276     REQUEST_AT_LEAST_SIZE(xPresentPixmapReq);
    277 
    278     swaps(&stuff->length);
    279     swapl(&stuff->window);
    280     swapl(&stuff->pixmap);
    281     swapl(&stuff->valid);
    282     swapl(&stuff->update);
    283     swaps(&stuff->x_off);
    284     swaps(&stuff->y_off);
    285     swapll(&stuff->target_msc);
    286     swapll(&stuff->divisor);
    287     swapll(&stuff->remainder);
    288     swapl(&stuff->idle_fence);
    289     return (*proc_present_vector[stuff->presentReqType]) (client);
    290 }
    291 
    292 static int _X_COLD
    293 sproc_present_notify_msc(ClientPtr client)
    294 {
    295     REQUEST(xPresentNotifyMSCReq);
    296     REQUEST_SIZE_MATCH(xPresentNotifyMSCReq);
    297 
    298     swaps(&stuff->length);
    299     swapl(&stuff->window);
    300     swapll(&stuff->target_msc);
    301     swapll(&stuff->divisor);
    302     swapll(&stuff->remainder);
    303     return (*proc_present_vector[stuff->presentReqType]) (client);
    304 }
    305 
    306 static int _X_COLD
    307 sproc_present_select_input (ClientPtr client)
    308 {
    309     REQUEST(xPresentSelectInputReq);
    310     REQUEST_SIZE_MATCH(xPresentSelectInputReq);
    311 
    312     swaps(&stuff->length);
    313     swapl(&stuff->window);
    314     swapl(&stuff->eventMask);
    315     return (*proc_present_vector[stuff->presentReqType]) (client);
    316 }
    317 
    318 static int _X_COLD
    319 sproc_present_query_capabilities (ClientPtr client)
    320 {
    321     REQUEST(xPresentQueryCapabilitiesReq);
    322     REQUEST_SIZE_MATCH(xPresentQueryCapabilitiesReq);
    323     swaps(&stuff->length);
    324     swapl(&stuff->target);
    325     return (*proc_present_vector[stuff->presentReqType]) (client);
    326 }
    327 
    328 static int (*sproc_present_vector[PresentNumberRequests]) (ClientPtr) = {
    329     sproc_present_query_version,           /* 0 */
    330     sproc_present_pixmap,                  /* 1 */
    331     sproc_present_notify_msc,              /* 2 */
    332     sproc_present_select_input,            /* 3 */
    333     sproc_present_query_capabilities,      /* 4 */
    334 };
    335 
    336 int _X_COLD
    337 sproc_present_dispatch(ClientPtr client)
    338 {
    339     REQUEST(xReq);
    340     if (stuff->data >= PresentNumberRequests || !sproc_present_vector[stuff->data])
    341         return BadRequest;
    342     return (*sproc_present_vector[stuff->data]) (client);
    343 }