xserver

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

xiquerypointer.c (7072B)


      1 /*
      2  * Copyright 2007-2008 Peter Hutterer
      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, University of South Australia, NICTA
     24  */
     25 
     26 /***********************************************************************
     27  *
     28  * Request to query the pointer location of an extension input device.
     29  *
     30  */
     31 
     32 #ifdef HAVE_DIX_CONFIG_H
     33 #include <dix-config.h>
     34 #endif
     35 
     36 #include <X11/X.h>              /* for inputstr.h    */
     37 #include <X11/Xproto.h>         /* Request macro     */
     38 #include "inputstr.h"           /* DeviceIntPtr      */
     39 #include "windowstr.h"          /* window structure  */
     40 #include <X11/extensions/XI.h>
     41 #include <X11/extensions/XI2proto.h>
     42 #include "extnsionst.h"
     43 #include "exevents.h"
     44 #include "exglobals.h"
     45 #include "eventconvert.h"
     46 #include "scrnintstr.h"
     47 #include "xkbsrv.h"
     48 
     49 #ifdef PANORAMIX
     50 #include "panoramiXsrv.h"
     51 #endif
     52 
     53 #include "inpututils.h"
     54 #include "xiquerypointer.h"
     55 
     56 /***********************************************************************
     57  *
     58  * This procedure allows a client to query the pointer of a device.
     59  *
     60  */
     61 
     62 int _X_COLD
     63 SProcXIQueryPointer(ClientPtr client)
     64 {
     65     REQUEST(xXIQueryPointerReq);
     66     REQUEST_SIZE_MATCH(xXIQueryPointerReq);
     67 
     68     swaps(&stuff->length);
     69     swaps(&stuff->deviceid);
     70     swapl(&stuff->win);
     71     return (ProcXIQueryPointer(client));
     72 }
     73 
     74 int
     75 ProcXIQueryPointer(ClientPtr client)
     76 {
     77     int rc;
     78     xXIQueryPointerReply rep;
     79     DeviceIntPtr pDev, kbd;
     80     WindowPtr pWin, t;
     81     SpritePtr pSprite;
     82     XkbStatePtr state;
     83     char *buttons = NULL;
     84     int buttons_size = 0;       /* size of buttons array */
     85     XIClientPtr xi_client;
     86     Bool have_xi22 = FALSE;
     87 
     88     REQUEST(xXIQueryPointerReq);
     89     REQUEST_SIZE_MATCH(xXIQueryPointerReq);
     90 
     91     /* Check if client is compliant with XInput 2.2 or later. Earlier clients
     92      * do not know about touches, so we must report emulated button presses. 2.2
     93      * and later clients are aware of touches, so we don't include emulated
     94      * button presses in the reply. */
     95     xi_client = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
     96     if (version_compare(xi_client->major_version,
     97                         xi_client->minor_version, 2, 2) >= 0)
     98         have_xi22 = TRUE;
     99 
    100     rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixReadAccess);
    101     if (rc != Success) {
    102         client->errorValue = stuff->deviceid;
    103         return rc;
    104     }
    105 
    106     if (pDev->valuator == NULL || IsKeyboardDevice(pDev) || (!IsMaster(pDev) && !IsFloating(pDev))) {   /* no attached devices */
    107         client->errorValue = stuff->deviceid;
    108         return BadDevice;
    109     }
    110 
    111     rc = dixLookupWindow(&pWin, stuff->win, client, DixGetAttrAccess);
    112     if (rc != Success) {
    113         client->errorValue = stuff->win;
    114         return rc;
    115     }
    116 
    117     if (pDev->valuator->motionHintWindow)
    118         MaybeStopHint(pDev, client);
    119 
    120     if (IsMaster(pDev))
    121         kbd = GetMaster(pDev, MASTER_KEYBOARD);
    122     else
    123         kbd = (pDev->key) ? pDev : NULL;
    124 
    125     pSprite = pDev->spriteInfo->sprite;
    126 
    127     rep = (xXIQueryPointerReply) {
    128         .repType = X_Reply,
    129         .RepType = X_XIQueryPointer,
    130         .sequenceNumber = client->sequence,
    131         .length = 6,
    132         .root = (GetCurrentRootWindow(pDev))->drawable.id,
    133         .root_x = double_to_fp1616(pSprite->hot.x),
    134         .root_y = double_to_fp1616(pSprite->hot.y),
    135         .child = None
    136     };
    137 
    138     if (kbd) {
    139         state = &kbd->key->xkbInfo->state;
    140         rep.mods.base_mods = state->base_mods;
    141         rep.mods.latched_mods = state->latched_mods;
    142         rep.mods.locked_mods = state->locked_mods;
    143 
    144         rep.group.base_group = state->base_group;
    145         rep.group.latched_group = state->latched_group;
    146         rep.group.locked_group = state->locked_group;
    147     }
    148 
    149     if (pDev->button) {
    150         int i;
    151 
    152         rep.buttons_len =
    153             bytes_to_int32(bits_to_bytes(pDev->button->numButtons));
    154         rep.length += rep.buttons_len;
    155         buttons = calloc(rep.buttons_len, 4);
    156         if (!buttons)
    157             return BadAlloc;
    158         buttons_size = rep.buttons_len * 4;
    159 
    160         for (i = 1; i < pDev->button->numButtons; i++)
    161             if (BitIsOn(pDev->button->down, i))
    162                 SetBit(buttons, pDev->button->map[i]);
    163 
    164         if (!have_xi22 && pDev->touch && pDev->touch->buttonsDown > 0)
    165             SetBit(buttons, pDev->button->map[1]);
    166     }
    167     else
    168         rep.buttons_len = 0;
    169 
    170     if (pSprite->hot.pScreen == pWin->drawable.pScreen) {
    171         rep.same_screen = xTrue;
    172         rep.win_x = double_to_fp1616(pSprite->hot.x - pWin->drawable.x);
    173         rep.win_y = double_to_fp1616(pSprite->hot.y - pWin->drawable.y);
    174         for (t = pSprite->win; t; t = t->parent)
    175             if (t->parent == pWin) {
    176                 rep.child = t->drawable.id;
    177                 break;
    178             }
    179     }
    180     else {
    181         rep.same_screen = xFalse;
    182         rep.win_x = 0;
    183         rep.win_y = 0;
    184     }
    185 
    186 #ifdef PANORAMIX
    187     if (!noPanoramiXExtension) {
    188         rep.root_x += double_to_fp1616(screenInfo.screens[0]->x);
    189         rep.root_y += double_to_fp1616(screenInfo.screens[0]->y);
    190         if (stuff->win == rep.root) {
    191             rep.win_x += double_to_fp1616(screenInfo.screens[0]->x);
    192             rep.win_y += double_to_fp1616(screenInfo.screens[0]->y);
    193         }
    194     }
    195 #endif
    196 
    197     WriteReplyToClient(client, sizeof(xXIQueryPointerReply), &rep);
    198     if (buttons)
    199         WriteToClient(client, buttons_size, buttons);
    200 
    201     free(buttons);
    202 
    203     return Success;
    204 }
    205 
    206 /***********************************************************************
    207  *
    208  * This procedure writes the reply for the XIQueryPointer function,
    209  * if the client and server have a different byte ordering.
    210  *
    211  */
    212 
    213 void
    214 SRepXIQueryPointer(ClientPtr client, int size, xXIQueryPointerReply * rep)
    215 {
    216     swaps(&rep->sequenceNumber);
    217     swapl(&rep->length);
    218     swapl(&rep->root);
    219     swapl(&rep->child);
    220     swapl(&rep->root_x);
    221     swapl(&rep->root_y);
    222     swapl(&rep->win_x);
    223     swapl(&rep->win_y);
    224     swaps(&rep->buttons_len);
    225 
    226     WriteToClient(client, size, rep);
    227 }