123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- /*
- * Copyright 2007-2008 Peter Hutterer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Author: Peter Hutterer, University of South Australia, NICTA
- */
- /***********************************************************************
- *
- * Request to Warp the pointer location of an extension input device.
- *
- */
- #ifdef HAVE_DIX_CONFIG_H
- #include <dix-config.h>
- #endif
- #include <X11/X.h> /* for inputstr.h */
- #include <X11/Xproto.h> /* Request macro */
- #include "inputstr.h" /* DeviceIntPtr */
- #include "windowstr.h" /* window structure */
- #include "scrnintstr.h" /* screen structure */
- #include <X11/extensions/XI.h>
- #include <X11/extensions/XI2proto.h>
- #include "extnsionst.h"
- #include "exevents.h"
- #include "exglobals.h"
- #include "mipointer.h" /* for miPointerUpdateSprite */
- #include "xiwarppointer.h"
- /***********************************************************************
- *
- * This procedure allows a client to warp the pointer of a device.
- *
- */
- int
- SProcXIWarpPointer(ClientPtr client)
- {
- REQUEST(xXIWarpPointerReq);
- REQUEST_SIZE_MATCH(xXIWarpPointerReq);
- swaps(&stuff->length);
- swapl(&stuff->src_win);
- swapl(&stuff->dst_win);
- swapl(&stuff->src_x);
- swapl(&stuff->src_y);
- swaps(&stuff->src_width);
- swaps(&stuff->src_height);
- swapl(&stuff->dst_x);
- swapl(&stuff->dst_y);
- swaps(&stuff->deviceid);
- return (ProcXIWarpPointer(client));
- }
- int
- ProcXIWarpPointer(ClientPtr client)
- {
- int rc;
- int x, y;
- WindowPtr dest = NULL;
- DeviceIntPtr pDev;
- SpritePtr pSprite;
- ScreenPtr newScreen;
- int src_x, src_y;
- int dst_x, dst_y;
- REQUEST(xXIWarpPointerReq);
- REQUEST_SIZE_MATCH(xXIWarpPointerReq);
- /* FIXME: panoramix stuff is missing, look at ProcWarpPointer */
- rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixWriteAccess);
- if (rc != Success) {
- client->errorValue = stuff->deviceid;
- return rc;
- }
- if ((!IsMaster(pDev) && !IsFloating(pDev)) ||
- (IsMaster(pDev) && !IsPointerDevice(pDev))) {
- client->errorValue = stuff->deviceid;
- return BadDevice;
- }
- if (stuff->dst_win != None) {
- rc = dixLookupWindow(&dest, stuff->dst_win, client, DixGetAttrAccess);
- if (rc != Success) {
- client->errorValue = stuff->dst_win;
- return rc;
- }
- }
- pSprite = pDev->spriteInfo->sprite;
- x = pSprite->hotPhys.x;
- y = pSprite->hotPhys.y;
- src_x = stuff->src_x / (double) (1 << 16);
- src_y = stuff->src_y / (double) (1 << 16);
- dst_x = stuff->dst_x / (double) (1 << 16);
- dst_y = stuff->dst_y / (double) (1 << 16);
- if (stuff->src_win != None) {
- int winX, winY;
- WindowPtr src;
- rc = dixLookupWindow(&src, stuff->src_win, client, DixGetAttrAccess);
- if (rc != Success) {
- client->errorValue = stuff->src_win;
- return rc;
- }
- winX = src->drawable.x;
- winY = src->drawable.y;
- if (src->drawable.pScreen != pSprite->hotPhys.pScreen ||
- x < winX + src_x ||
- y < winY + src_y ||
- (stuff->src_width != 0 &&
- winX + src_x + (int) stuff->src_width < 0) ||
- (stuff->src_height != 0 &&
- winY + src_y + (int) stuff->src_height < y) ||
- !PointInWindowIsVisible(src, x, y))
- return Success;
- }
- if (dest) {
- x = dest->drawable.x;
- y = dest->drawable.y;
- newScreen = dest->drawable.pScreen;
- }
- else
- newScreen = pSprite->hotPhys.pScreen;
- x += dst_x;
- y += dst_y;
- if (x < 0)
- x = 0;
- else if (x > newScreen->width)
- x = newScreen->width - 1;
- if (y < 0)
- y = 0;
- else if (y > newScreen->height)
- y = newScreen->height - 1;
- if (newScreen == pSprite->hotPhys.pScreen) {
- if (x < pSprite->physLimits.x1)
- x = pSprite->physLimits.x1;
- else if (x >= pSprite->physLimits.x2)
- x = pSprite->physLimits.x2 - 1;
- if (y < pSprite->physLimits.y1)
- y = pSprite->physLimits.y1;
- else if (y >= pSprite->physLimits.y2)
- y = pSprite->physLimits.y2 - 1;
- if (pSprite->hotShape)
- ConfineToShape(pDev, pSprite->hotShape, &x, &y);
- (*newScreen->SetCursorPosition) (pDev, newScreen, x, y, TRUE);
- }
- else if (!PointerConfinedToScreen(pDev)) {
- NewCurrentScreen(pDev, newScreen, x, y);
- }
- /* if we don't update the device, we get a jump next time it moves */
- pDev->last.valuators[0] = x;
- pDev->last.valuators[1] = y;
- miPointerUpdateSprite(pDev);
- /* FIXME: XWarpPointer is supposed to generate an event. It doesn't do it
- here though. */
- return Success;
- }
|