xiwarppointer.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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. * Request to Warp the pointer location of an extension input device.
  28. *
  29. */
  30. #ifdef HAVE_DIX_CONFIG_H
  31. #include <dix-config.h>
  32. #endif
  33. #include <X11/X.h> /* for inputstr.h */
  34. #include <X11/Xproto.h> /* Request macro */
  35. #include "inputstr.h" /* DeviceIntPtr */
  36. #include "windowstr.h" /* window structure */
  37. #include "scrnintstr.h" /* screen structure */
  38. #include <X11/extensions/XI.h>
  39. #include <X11/extensions/XI2proto.h>
  40. #include "extnsionst.h"
  41. #include "exevents.h"
  42. #include "exglobals.h"
  43. #include "mipointer.h" /* for miPointerUpdateSprite */
  44. #include "xiwarppointer.h"
  45. /***********************************************************************
  46. *
  47. * This procedure allows a client to warp the pointer of a device.
  48. *
  49. */
  50. int
  51. SProcXIWarpPointer(ClientPtr client)
  52. {
  53. REQUEST(xXIWarpPointerReq);
  54. REQUEST_SIZE_MATCH(xXIWarpPointerReq);
  55. swaps(&stuff->length);
  56. swapl(&stuff->src_win);
  57. swapl(&stuff->dst_win);
  58. swapl(&stuff->src_x);
  59. swapl(&stuff->src_y);
  60. swaps(&stuff->src_width);
  61. swaps(&stuff->src_height);
  62. swapl(&stuff->dst_x);
  63. swapl(&stuff->dst_y);
  64. swaps(&stuff->deviceid);
  65. return (ProcXIWarpPointer(client));
  66. }
  67. int
  68. ProcXIWarpPointer(ClientPtr client)
  69. {
  70. int rc;
  71. int x, y;
  72. WindowPtr dest = NULL;
  73. DeviceIntPtr pDev;
  74. SpritePtr pSprite;
  75. ScreenPtr newScreen;
  76. int src_x, src_y;
  77. int dst_x, dst_y;
  78. REQUEST(xXIWarpPointerReq);
  79. REQUEST_SIZE_MATCH(xXIWarpPointerReq);
  80. /* FIXME: panoramix stuff is missing, look at ProcWarpPointer */
  81. rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixWriteAccess);
  82. if (rc != Success) {
  83. client->errorValue = stuff->deviceid;
  84. return rc;
  85. }
  86. if ((!IsMaster(pDev) && !IsFloating(pDev)) ||
  87. (IsMaster(pDev) && !IsPointerDevice(pDev))) {
  88. client->errorValue = stuff->deviceid;
  89. return BadDevice;
  90. }
  91. if (stuff->dst_win != None) {
  92. rc = dixLookupWindow(&dest, stuff->dst_win, client, DixGetAttrAccess);
  93. if (rc != Success) {
  94. client->errorValue = stuff->dst_win;
  95. return rc;
  96. }
  97. }
  98. pSprite = pDev->spriteInfo->sprite;
  99. x = pSprite->hotPhys.x;
  100. y = pSprite->hotPhys.y;
  101. src_x = stuff->src_x / (double) (1 << 16);
  102. src_y = stuff->src_y / (double) (1 << 16);
  103. dst_x = stuff->dst_x / (double) (1 << 16);
  104. dst_y = stuff->dst_y / (double) (1 << 16);
  105. if (stuff->src_win != None) {
  106. int winX, winY;
  107. WindowPtr src;
  108. rc = dixLookupWindow(&src, stuff->src_win, client, DixGetAttrAccess);
  109. if (rc != Success) {
  110. client->errorValue = stuff->src_win;
  111. return rc;
  112. }
  113. winX = src->drawable.x;
  114. winY = src->drawable.y;
  115. if (src->drawable.pScreen != pSprite->hotPhys.pScreen ||
  116. x < winX + src_x ||
  117. y < winY + src_y ||
  118. (stuff->src_width != 0 &&
  119. winX + src_x + (int) stuff->src_width < 0) ||
  120. (stuff->src_height != 0 &&
  121. winY + src_y + (int) stuff->src_height < y) ||
  122. !PointInWindowIsVisible(src, x, y))
  123. return Success;
  124. }
  125. if (dest) {
  126. x = dest->drawable.x;
  127. y = dest->drawable.y;
  128. newScreen = dest->drawable.pScreen;
  129. }
  130. else
  131. newScreen = pSprite->hotPhys.pScreen;
  132. x += dst_x;
  133. y += dst_y;
  134. if (x < 0)
  135. x = 0;
  136. else if (x > newScreen->width)
  137. x = newScreen->width - 1;
  138. if (y < 0)
  139. y = 0;
  140. else if (y > newScreen->height)
  141. y = newScreen->height - 1;
  142. if (newScreen == pSprite->hotPhys.pScreen) {
  143. if (x < pSprite->physLimits.x1)
  144. x = pSprite->physLimits.x1;
  145. else if (x >= pSprite->physLimits.x2)
  146. x = pSprite->physLimits.x2 - 1;
  147. if (y < pSprite->physLimits.y1)
  148. y = pSprite->physLimits.y1;
  149. else if (y >= pSprite->physLimits.y2)
  150. y = pSprite->physLimits.y2 - 1;
  151. if (pSprite->hotShape)
  152. ConfineToShape(pDev, pSprite->hotShape, &x, &y);
  153. (*newScreen->SetCursorPosition) (pDev, newScreen, x, y, TRUE);
  154. }
  155. else if (!PointerConfinedToScreen(pDev)) {
  156. NewCurrentScreen(pDev, newScreen, x, y);
  157. }
  158. /* if we don't update the device, we get a jump next time it moves */
  159. pDev->last.valuators[0] = x;
  160. pDev->last.valuators[1] = y;
  161. miPointerUpdateSprite(pDev);
  162. /* FIXME: XWarpPointer is supposed to generate an event. It doesn't do it
  163. here though. */
  164. return Success;
  165. }