xiquerypointer.c revision 0b0d8713
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 "xiquerypointer.h" 54 55/*********************************************************************** 56 * 57 * This procedure allows a client to query the pointer of a device. 58 * 59 */ 60 61int 62SProcXIQueryPointer(ClientPtr client) 63{ 64 char n; 65 66 REQUEST(xXIQueryPointerReq); 67 REQUEST_SIZE_MATCH(xXIQueryPointerReq); 68 69 swaps(&stuff->length, n); 70 swaps(&stuff->deviceid, n); 71 swapl(&stuff->win, n); 72 return (ProcXIQueryPointer(client)); 73} 74 75int 76ProcXIQueryPointer(ClientPtr client) 77{ 78 int rc; 79 xXIQueryPointerReply rep; 80 DeviceIntPtr pDev, kbd; 81 WindowPtr pWin, t; 82 SpritePtr pSprite; 83 XkbStatePtr state; 84 char *buttons = NULL; 85 int buttons_size = 0; /* size of buttons array */ 86 87 REQUEST(xXIQueryPointerReq); 88 REQUEST_SIZE_MATCH(xXIQueryPointerReq); 89 90 rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixReadAccess); 91 if (rc != Success) 92 { 93 client->errorValue = stuff->deviceid; 94 return rc; 95 } 96 97 if (pDev->valuator == NULL || IsKeyboardDevice(pDev) || 98 (!IsMaster(pDev) && pDev->u.master)) /* no attached devices */ 99 { 100 client->errorValue = stuff->deviceid; 101 return BadDevice; 102 } 103 104 rc = dixLookupWindow(&pWin, stuff->win, client, DixGetAttrAccess); 105 if (rc != Success) 106 { 107 SendErrorToClient(client, IReqCode, X_XIQueryPointer, 108 stuff->win, rc); 109 return Success; 110 } 111 112 if (pDev->valuator->motionHintWindow) 113 MaybeStopHint(pDev, client); 114 115 if (IsMaster(pDev)) 116 kbd = GetPairedDevice(pDev); 117 else 118 kbd = (pDev->key) ? pDev : NULL; 119 120 pSprite = pDev->spriteInfo->sprite; 121 122 memset(&rep, 0, sizeof(rep)); 123 rep.repType = X_Reply; 124 rep.RepType = X_XIQueryPointer; 125 rep.length = 6; 126 rep.sequenceNumber = client->sequence; 127 rep.root = (GetCurrentRootWindow(pDev))->drawable.id; 128 rep.root_x = FP1616(pSprite->hot.x, 0); 129 rep.root_y = FP1616(pSprite->hot.y, 0); 130 rep.child = None; 131 132 if (kbd) 133 { 134 state = &kbd->key->xkbInfo->state; 135 rep.mods.base_mods = state->base_mods; 136 rep.mods.latched_mods = state->latched_mods; 137 rep.mods.locked_mods = state->locked_mods; 138 139 rep.group.base_group = state->base_group; 140 rep.group.latched_group = state->latched_group; 141 rep.group.locked_group = state->locked_group; 142 } 143 144 if (pDev->button) 145 { 146 int i, down; 147 rep.buttons_len = bytes_to_int32(bits_to_bytes(pDev->button->numButtons)); 148 rep.length += rep.buttons_len; 149 buttons_size = rep.buttons_len * 4; 150 buttons = calloc(1, buttons_size); 151 if (!buttons) 152 return BadAlloc; 153 154 down = pDev->button->buttonsDown; 155 156 for (i = 0; i < pDev->button->numButtons && down; i++) 157 { 158 if (BitIsOn(pDev->button->down, i)) 159 { 160 SetBit(buttons, i); 161 down--; 162 } 163 } 164 } else 165 rep.buttons_len = 0; 166 167 if (pSprite->hot.pScreen == pWin->drawable.pScreen) 168 { 169 rep.same_screen = xTrue; 170 rep.win_x = FP1616(pSprite->hot.x - pWin->drawable.x, 0); 171 rep.win_y = FP1616(pSprite->hot.y - pWin->drawable.y, 0); 172 for (t = pSprite->win; t; t = t->parent) 173 if (t->parent == pWin) 174 { 175 rep.child = t->drawable.id; 176 break; 177 } 178 } else 179 { 180 rep.same_screen = xFalse; 181 rep.win_x = 0; 182 rep.win_y = 0; 183 } 184 185#ifdef PANORAMIX 186 if(!noPanoramiXExtension) { 187 rep.root_x += FP1616(screenInfo.screens[0]->x, 0); 188 rep.root_y += FP1616(screenInfo.screens[0]->y, 0); 189 if (stuff->win == rep.root) 190 { 191 rep.win_x += FP1616(screenInfo.screens[0]->x, 0); 192 rep.win_y += FP1616(screenInfo.screens[0]->y, 0); 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 213void 214SRepXIQueryPointer(ClientPtr client, int size, 215 xXIQueryPointerReply * rep) 216{ 217 char n; 218 219 swaps(&rep->sequenceNumber, n); 220 swapl(&rep->length, n); 221 swapl(&rep->root, n); 222 swapl(&rep->child, n); 223 swapl(&rep->root_x, n); 224 swapl(&rep->root_y, n); 225 swapl(&rep->win_x, n); 226 swapl(&rep->win_y, n); 227 swaps(&rep->buttons_len, n); 228 229 WriteToClient(client, size, (char *)rep); 230} 231 232