3f051f759a65b7aece5205b369810486610b2bb3
2 * Copyright 2007-2008 Peter Hutterer
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:
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
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.
23 * Author: Peter Hutterer, University of South Australia, NICTA
26 /***********************************************************************
28 * Request to Warp the pointer location of an extension input device.
32 #ifdef HAVE_DIX_CONFIG_H
33 #include <dix-config.h>
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 "scrnintstr.h" /* screen structure */
41 #include <X11/extensions/XI.h>
42 #include <X11/extensions/XI2proto.h>
43 #include "extnsionst.h"
45 #include "exglobals.h"
46 #include "mipointer.h" /* for miPointerUpdateSprite */
48 #include "xiwarppointer.h"
49 /***********************************************************************
51 * This procedure allows a client to warp the pointer of a device.
56 SProcXIWarpPointer(ClientPtr client
)
58 REQUEST(xXIWarpPointerReq
);
59 swaps(&stuff
->length
);
60 swapl(&stuff
->src_win
);
61 swapl(&stuff
->dst_win
);
64 swaps(&stuff
->src_width
);
65 swaps(&stuff
->src_height
);
68 swaps(&stuff
->deviceid
);
69 return (ProcXIWarpPointer(client
));
73 ProcXIWarpPointer(ClientPtr client
)
77 WindowPtr dest
= NULL
;
84 REQUEST(xXIWarpPointerReq
);
85 REQUEST_SIZE_MATCH(xXIWarpPointerReq
);
87 /* FIXME: panoramix stuff is missing, look at ProcWarpPointer */
89 rc
= dixLookupDevice(&pDev
, stuff
->deviceid
, client
, DixWriteAccess
);
92 client
->errorValue
= stuff
->deviceid
;
96 if ((!IsMaster(pDev
) && !IsFloating(pDev
)) ||
97 (IsMaster(pDev
) && !IsPointerDevice(pDev
))) {
98 client
->errorValue
= stuff
->deviceid
;
102 if (stuff
->dst_win
!= None
) {
103 rc
= dixLookupWindow(&dest
, stuff
->dst_win
, client
, DixGetAttrAccess
);
105 client
->errorValue
= stuff
->dst_win
;
110 pSprite
= pDev
->spriteInfo
->sprite
;
111 x
= pSprite
->hotPhys
.x
;
112 y
= pSprite
->hotPhys
.y
;
114 src_x
= stuff
->src_x
/ (double) (1 << 16);
115 src_y
= stuff
->src_y
/ (double) (1 << 16);
116 dst_x
= stuff
->dst_x
/ (double) (1 << 16);
117 dst_y
= stuff
->dst_y
/ (double) (1 << 16);
119 if (stuff
->src_win
!= None
) {
123 rc
= dixLookupWindow(&src
, stuff
->src_win
, client
, DixGetAttrAccess
);
125 client
->errorValue
= stuff
->src_win
;
129 winX
= src
->drawable
.x
;
130 winY
= src
->drawable
.y
;
131 if (src
->drawable
.pScreen
!= pSprite
->hotPhys
.pScreen
||
134 (stuff
->src_width
!= 0 &&
135 winX
+ src_x
+ (int) stuff
->src_width
< 0) ||
136 (stuff
->src_height
!= 0 &&
137 winY
+ src_y
+ (int) stuff
->src_height
< y
) ||
138 !PointInWindowIsVisible(src
, x
, y
))
143 x
= dest
->drawable
.x
;
144 y
= dest
->drawable
.y
;
145 newScreen
= dest
->drawable
.pScreen
;
148 newScreen
= pSprite
->hotPhys
.pScreen
;
155 else if (x
> newScreen
->width
)
156 x
= newScreen
->width
- 1;
160 else if (y
> newScreen
->height
)
161 y
= newScreen
->height
- 1;
163 if (newScreen
== pSprite
->hotPhys
.pScreen
) {
164 if (x
< pSprite
->physLimits
.x1
)
165 x
= pSprite
->physLimits
.x1
;
166 else if (x
>= pSprite
->physLimits
.x2
)
167 x
= pSprite
->physLimits
.x2
- 1;
169 if (y
< pSprite
->physLimits
.y1
)
170 y
= pSprite
->physLimits
.y1
;
171 else if (y
>= pSprite
->physLimits
.y2
)
172 y
= pSprite
->physLimits
.y2
- 1;
174 if (pSprite
->hotShape
)
175 ConfineToShape(pDev
, pSprite
->hotShape
, &x
, &y
);
176 (*newScreen
->SetCursorPosition
) (pDev
, newScreen
, x
, y
, TRUE
);
178 else if (!PointerConfinedToScreen(pDev
)) {
179 NewCurrentScreen(pDev
, newScreen
, x
, y
);
182 /* if we don't update the device, we get a jump next time it moves */
183 pDev
->last
.valuators
[0] = x
;
184 pDev
->last
.valuators
[1] = y
;
185 miPointerUpdateSprite(pDev
);
187 /* FIXME: XWarpPointer is supposed to generate an event. It doesn't do it