xserver

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

xipassivegrab.c (12205B)


      1 /*
      2  * Copyright © 2009 Red Hat, Inc.
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     21  * DEALINGS IN THE SOFTWARE.
     22  *
     23  * Author: Peter Hutterer
     24  */
     25 
     26 /***********************************************************************
     27  *
     28  * Request to grab or ungrab input device.
     29  *
     30  */
     31 
     32 #ifdef HAVE_DIX_CONFIG_H
     33 #include <dix-config.h>
     34 #endif
     35 
     36 #include "inputstr.h"           /* DeviceIntPtr      */
     37 #include "windowstr.h"          /* window structure  */
     38 #include <X11/extensions/XI2.h>
     39 #include <X11/extensions/XI2proto.h>
     40 #include "swaprep.h"
     41 
     42 #include "exglobals.h"          /* BadDevice */
     43 #include "exevents.h"
     44 #include "xipassivegrab.h"
     45 #include "dixgrabs.h"
     46 #include "misc.h"
     47 #include "inpututils.h"
     48 
     49 int _X_COLD
     50 SProcXIPassiveGrabDevice(ClientPtr client)
     51 {
     52     int i;
     53     uint32_t *mods;
     54 
     55     REQUEST(xXIPassiveGrabDeviceReq);
     56     REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq);
     57 
     58     swaps(&stuff->length);
     59     swaps(&stuff->deviceid);
     60     swapl(&stuff->grab_window);
     61     swapl(&stuff->cursor);
     62     swapl(&stuff->time);
     63     swapl(&stuff->detail);
     64     swaps(&stuff->mask_len);
     65     swaps(&stuff->num_modifiers);
     66 
     67     REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq,
     68         ((uint32_t) stuff->mask_len + stuff->num_modifiers) *4);
     69     mods = (uint32_t *) &stuff[1] + stuff->mask_len;
     70 
     71     for (i = 0; i < stuff->num_modifiers; i++, mods++) {
     72         swapl(mods);
     73     }
     74 
     75     return ProcXIPassiveGrabDevice(client);
     76 }
     77 
     78 int
     79 ProcXIPassiveGrabDevice(ClientPtr client)
     80 {
     81     DeviceIntPtr dev, mod_dev;
     82     xXIPassiveGrabDeviceReply rep = {
     83         .repType = X_Reply,
     84         .RepType = X_XIPassiveGrabDevice,
     85         .sequenceNumber = client->sequence,
     86         .length = 0,
     87         .num_modifiers = 0
     88     };
     89     int i, ret = Success;
     90     uint32_t *modifiers;
     91     xXIGrabModifierInfo *modifiers_failed = NULL;
     92     GrabMask mask = { 0 };
     93     GrabParameters param;
     94     void *tmp;
     95     int mask_len;
     96 
     97     REQUEST(xXIPassiveGrabDeviceReq);
     98     REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq,
     99         ((uint32_t) stuff->mask_len + stuff->num_modifiers) * 4);
    100 
    101     if (stuff->deviceid == XIAllDevices)
    102         dev = inputInfo.all_devices;
    103     else if (stuff->deviceid == XIAllMasterDevices)
    104         dev = inputInfo.all_master_devices;
    105     else {
    106         ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
    107         if (ret != Success) {
    108             client->errorValue = stuff->deviceid;
    109             return ret;
    110         }
    111     }
    112 
    113     if (stuff->grab_type != XIGrabtypeButton &&
    114         stuff->grab_type != XIGrabtypeKeycode &&
    115         stuff->grab_type != XIGrabtypeEnter &&
    116         stuff->grab_type != XIGrabtypeFocusIn &&
    117         stuff->grab_type != XIGrabtypeTouchBegin &&
    118         stuff->grab_type != XIGrabtypeGesturePinchBegin &&
    119         stuff->grab_type != XIGrabtypeGestureSwipeBegin) {
    120         client->errorValue = stuff->grab_type;
    121         return BadValue;
    122     }
    123 
    124     if ((stuff->grab_type == XIGrabtypeEnter ||
    125          stuff->grab_type == XIGrabtypeFocusIn ||
    126          stuff->grab_type == XIGrabtypeTouchBegin ||
    127          stuff->grab_type == XIGrabtypeGesturePinchBegin ||
    128          stuff->grab_type == XIGrabtypeGestureSwipeBegin) && stuff->detail != 0) {
    129         client->errorValue = stuff->detail;
    130         return BadValue;
    131     }
    132 
    133     if (stuff->grab_type == XIGrabtypeTouchBegin &&
    134         (stuff->grab_mode != XIGrabModeTouch ||
    135          stuff->paired_device_mode != GrabModeAsync)) {
    136         client->errorValue = stuff->grab_mode;
    137         return BadValue;
    138     }
    139 
    140     if (XICheckInvalidMaskBits(client, (unsigned char *) &stuff[1],
    141                                stuff->mask_len * 4) != Success)
    142         return BadValue;
    143 
    144     mask.xi2mask = xi2mask_new();
    145     if (!mask.xi2mask)
    146         return BadAlloc;
    147 
    148     mask_len = min(xi2mask_mask_size(mask.xi2mask), stuff->mask_len * 4);
    149     xi2mask_set_one_mask(mask.xi2mask, stuff->deviceid,
    150                          (unsigned char *) &stuff[1], mask_len * 4);
    151 
    152     memset(&param, 0, sizeof(param));
    153     param.grabtype = XI2;
    154     param.ownerEvents = stuff->owner_events;
    155     param.grabWindow = stuff->grab_window;
    156     param.cursor = stuff->cursor;
    157 
    158     if (IsKeyboardDevice(dev)) {
    159         param.this_device_mode = stuff->grab_mode;
    160         param.other_devices_mode = stuff->paired_device_mode;
    161     }
    162     else {
    163         param.this_device_mode = stuff->paired_device_mode;
    164         param.other_devices_mode = stuff->grab_mode;
    165     }
    166 
    167     if (stuff->cursor != None) {
    168         ret = dixLookupResourceByType(&tmp, stuff->cursor,
    169                                       RT_CURSOR, client, DixUseAccess);
    170         if (ret != Success) {
    171             client->errorValue = stuff->cursor;
    172             goto out;
    173         }
    174     }
    175 
    176     ret =
    177         dixLookupWindow((WindowPtr *) &tmp, stuff->grab_window, client,
    178                         DixSetAttrAccess);
    179     if (ret != Success)
    180         goto out;
    181 
    182     ret = CheckGrabValues(client, &param);
    183     if (ret != Success)
    184         goto out;
    185 
    186     modifiers = (uint32_t *) &stuff[1] + stuff->mask_len;
    187     modifiers_failed =
    188         calloc(stuff->num_modifiers, sizeof(xXIGrabModifierInfo));
    189     if (!modifiers_failed) {
    190         ret = BadAlloc;
    191         goto out;
    192     }
    193 
    194     mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD);
    195 
    196     for (i = 0; i < stuff->num_modifiers; i++, modifiers++) {
    197         uint8_t status = Success;
    198 
    199         param.modifiers = *modifiers;
    200         ret = CheckGrabValues(client, &param);
    201         if (ret != Success)
    202             goto out;
    203 
    204         switch (stuff->grab_type) {
    205         case XIGrabtypeButton:
    206             status = GrabButton(client, dev, mod_dev, stuff->detail,
    207                                 &param, XI2, &mask);
    208             break;
    209         case XIGrabtypeKeycode:
    210             /* XI2 allows 32-bit keycodes but thanks to XKB we can never
    211              * implement this. Just return an error for all keycodes that
    212              * cannot work anyway */
    213             if (stuff->detail > 255)
    214                 status = XIAlreadyGrabbed;
    215             else
    216                 status = GrabKey(client, dev, mod_dev, stuff->detail,
    217                                  &param, XI2, &mask);
    218             break;
    219         case XIGrabtypeEnter:
    220         case XIGrabtypeFocusIn:
    221             status = GrabWindow(client, dev, stuff->grab_type, &param, &mask);
    222             break;
    223         case XIGrabtypeTouchBegin:
    224             status = GrabTouchOrGesture(client, dev, mod_dev, XI_TouchBegin,
    225                                         &param, &mask);
    226             break;
    227         case XIGrabtypeGesturePinchBegin:
    228             status = GrabTouchOrGesture(client, dev, mod_dev,
    229                                         XI_GesturePinchBegin, &param, &mask);
    230             break;
    231         case XIGrabtypeGestureSwipeBegin:
    232             status = GrabTouchOrGesture(client, dev, mod_dev,
    233                                         XI_GestureSwipeBegin, &param, &mask);
    234             break;
    235         }
    236 
    237         if (status != GrabSuccess) {
    238             xXIGrabModifierInfo *info = modifiers_failed + rep.num_modifiers;
    239 
    240             info->status = status;
    241             info->modifiers = *modifiers;
    242             if (client->swapped)
    243                 swapl(&info->modifiers);
    244 
    245             rep.num_modifiers++;
    246             rep.length += bytes_to_int32(sizeof(xXIGrabModifierInfo));
    247         }
    248     }
    249 
    250     WriteReplyToClient(client, sizeof(rep), &rep);
    251     if (rep.num_modifiers)
    252         WriteToClient(client, rep.length * 4, modifiers_failed);
    253 
    254  out:
    255     free(modifiers_failed);
    256     xi2mask_free(&mask.xi2mask);
    257     return ret;
    258 }
    259 
    260 void _X_COLD
    261 SRepXIPassiveGrabDevice(ClientPtr client, int size,
    262                         xXIPassiveGrabDeviceReply * rep)
    263 {
    264     swaps(&rep->sequenceNumber);
    265     swapl(&rep->length);
    266     swaps(&rep->num_modifiers);
    267 
    268     WriteToClient(client, size, rep);
    269 }
    270 
    271 int _X_COLD
    272 SProcXIPassiveUngrabDevice(ClientPtr client)
    273 {
    274     int i;
    275     uint32_t *modifiers;
    276 
    277     REQUEST(xXIPassiveUngrabDeviceReq);
    278     REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq);
    279 
    280     swaps(&stuff->length);
    281     swapl(&stuff->grab_window);
    282     swaps(&stuff->deviceid);
    283     swapl(&stuff->detail);
    284     swaps(&stuff->num_modifiers);
    285 
    286     REQUEST_FIXED_SIZE(xXIPassiveUngrabDeviceReq,
    287                        ((uint32_t) stuff->num_modifiers) << 2);
    288     modifiers = (uint32_t *) &stuff[1];
    289 
    290     for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
    291         swapl(modifiers);
    292 
    293     return ProcXIPassiveUngrabDevice(client);
    294 }
    295 
    296 int
    297 ProcXIPassiveUngrabDevice(ClientPtr client)
    298 {
    299     DeviceIntPtr dev, mod_dev;
    300     WindowPtr win;
    301     GrabPtr tempGrab;
    302     uint32_t *modifiers;
    303     int i, rc;
    304 
    305     REQUEST(xXIPassiveUngrabDeviceReq);
    306     REQUEST_FIXED_SIZE(xXIPassiveUngrabDeviceReq,
    307                        ((uint32_t) stuff->num_modifiers) << 2);
    308 
    309     if (stuff->deviceid == XIAllDevices)
    310         dev = inputInfo.all_devices;
    311     else if (stuff->deviceid == XIAllMasterDevices)
    312         dev = inputInfo.all_master_devices;
    313     else {
    314         rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
    315         if (rc != Success)
    316             return rc;
    317     }
    318 
    319     if (stuff->grab_type != XIGrabtypeButton &&
    320         stuff->grab_type != XIGrabtypeKeycode &&
    321         stuff->grab_type != XIGrabtypeEnter &&
    322         stuff->grab_type != XIGrabtypeFocusIn &&
    323         stuff->grab_type != XIGrabtypeTouchBegin &&
    324         stuff->grab_type != XIGrabtypeGesturePinchBegin &&
    325         stuff->grab_type != XIGrabtypeGestureSwipeBegin) {
    326         client->errorValue = stuff->grab_type;
    327         return BadValue;
    328     }
    329 
    330     if ((stuff->grab_type == XIGrabtypeEnter ||
    331          stuff->grab_type == XIGrabtypeFocusIn ||
    332          stuff->grab_type == XIGrabtypeTouchBegin) && stuff->detail != 0) {
    333         client->errorValue = stuff->detail;
    334         return BadValue;
    335     }
    336 
    337     rc = dixLookupWindow(&win, stuff->grab_window, client, DixSetAttrAccess);
    338     if (rc != Success)
    339         return rc;
    340 
    341     mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD);
    342 
    343     tempGrab = AllocGrab(NULL);
    344     if (!tempGrab)
    345         return BadAlloc;
    346 
    347     tempGrab->resource = client->clientAsMask;
    348     tempGrab->device = dev;
    349     tempGrab->window = win;
    350     switch (stuff->grab_type) {
    351     case XIGrabtypeButton:
    352         tempGrab->type = XI_ButtonPress;
    353         break;
    354     case XIGrabtypeKeycode:
    355         tempGrab->type = XI_KeyPress;
    356         break;
    357     case XIGrabtypeEnter:
    358         tempGrab->type = XI_Enter;
    359         break;
    360     case XIGrabtypeFocusIn:
    361         tempGrab->type = XI_FocusIn;
    362         break;
    363     case XIGrabtypeTouchBegin:
    364         tempGrab->type = XI_TouchBegin;
    365         break;
    366     case XIGrabtypeGesturePinchBegin:
    367         tempGrab->type = XI_GesturePinchBegin;
    368         break;
    369     case XIGrabtypeGestureSwipeBegin:
    370         tempGrab->type = XI_GestureSwipeBegin;
    371         break;
    372     }
    373     tempGrab->grabtype = XI2;
    374     tempGrab->modifierDevice = mod_dev;
    375     tempGrab->modifiersDetail.pMask = NULL;
    376     tempGrab->detail.exact = stuff->detail;
    377     tempGrab->detail.pMask = NULL;
    378 
    379     modifiers = (uint32_t *) &stuff[1];
    380 
    381     for (i = 0; i < stuff->num_modifiers; i++, modifiers++) {
    382         tempGrab->modifiersDetail.exact = *modifiers;
    383         DeletePassiveGrabFromList(tempGrab);
    384     }
    385 
    386     FreeGrab(tempGrab);
    387 
    388     return Success;
    389 }