xigrabdev.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * Copyright © 2009 Red Hat, Inc.
  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
  24. */
  25. /***********************************************************************
  26. *
  27. * Request to grab or ungrab input device.
  28. *
  29. */
  30. #ifdef HAVE_DIX_CONFIG_H
  31. #include <dix-config.h>
  32. #endif
  33. #include "inputstr.h" /* DeviceIntPtr */
  34. #include "windowstr.h" /* window structure */
  35. #include <X11/extensions/XI2.h>
  36. #include <X11/extensions/XI2proto.h>
  37. #include "exglobals.h" /* BadDevice */
  38. #include "exevents.h"
  39. #include "xigrabdev.h"
  40. #include "inpututils.h"
  41. int
  42. SProcXIGrabDevice(ClientPtr client)
  43. {
  44. REQUEST(xXIGrabDeviceReq);
  45. /*
  46. * Check here for at least the length of the struct we swap, then
  47. * let ProcXIGrabDevice check the full size after we swap mask_len.
  48. */
  49. REQUEST_AT_LEAST_SIZE(xXIGrabDeviceReq);
  50. swaps(&stuff->length);
  51. swaps(&stuff->deviceid);
  52. swapl(&stuff->grab_window);
  53. swapl(&stuff->cursor);
  54. swapl(&stuff->time);
  55. swaps(&stuff->mask_len);
  56. return ProcXIGrabDevice(client);
  57. }
  58. int
  59. ProcXIGrabDevice(ClientPtr client)
  60. {
  61. DeviceIntPtr dev;
  62. xXIGrabDeviceReply rep;
  63. int ret = Success;
  64. uint8_t status;
  65. GrabMask mask = { 0 };
  66. int mask_len;
  67. unsigned int keyboard_mode;
  68. unsigned int pointer_mode;
  69. REQUEST(xXIGrabDeviceReq);
  70. REQUEST_FIXED_SIZE(xXIGrabDeviceReq, ((size_t) stuff->mask_len) * 4);
  71. ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
  72. if (ret != Success)
  73. return ret;
  74. if (!IsMaster(dev))
  75. stuff->paired_device_mode = GrabModeAsync;
  76. if (IsKeyboardDevice(dev)) {
  77. keyboard_mode = stuff->grab_mode;
  78. pointer_mode = stuff->paired_device_mode;
  79. }
  80. else {
  81. keyboard_mode = stuff->paired_device_mode;
  82. pointer_mode = stuff->grab_mode;
  83. }
  84. if (XICheckInvalidMaskBits(client, (unsigned char *) &stuff[1],
  85. stuff->mask_len * 4) != Success)
  86. return BadValue;
  87. mask.xi2mask = xi2mask_new();
  88. if (!mask.xi2mask)
  89. return BadAlloc;
  90. mask_len = min(xi2mask_mask_size(mask.xi2mask), stuff->mask_len * 4);
  91. /* FIXME: I think the old code was broken here */
  92. xi2mask_set_one_mask(mask.xi2mask, dev->id, (unsigned char *) &stuff[1],
  93. mask_len);
  94. ret = GrabDevice(client, dev, pointer_mode,
  95. keyboard_mode,
  96. stuff->grab_window,
  97. stuff->owner_events,
  98. stuff->time,
  99. &mask, XI2, stuff->cursor, None /* confineTo */ ,
  100. &status);
  101. xi2mask_free(&mask.xi2mask);
  102. if (ret != Success)
  103. return ret;
  104. rep = (xXIGrabDeviceReply) {
  105. .repType = X_Reply,
  106. .RepType = X_XIGrabDevice,
  107. .sequenceNumber = client->sequence,
  108. .length = 0,
  109. .status = status
  110. };
  111. WriteReplyToClient(client, sizeof(rep), &rep);
  112. return ret;
  113. }
  114. int
  115. SProcXIUngrabDevice(ClientPtr client)
  116. {
  117. REQUEST(xXIUngrabDeviceReq);
  118. REQUEST_SIZE_MATCH(xXIUngrabDeviceReq);
  119. swaps(&stuff->length);
  120. swaps(&stuff->deviceid);
  121. swapl(&stuff->time);
  122. return ProcXIUngrabDevice(client);
  123. }
  124. int
  125. ProcXIUngrabDevice(ClientPtr client)
  126. {
  127. DeviceIntPtr dev;
  128. GrabPtr grab;
  129. int ret = Success;
  130. TimeStamp time;
  131. REQUEST(xXIUngrabDeviceReq);
  132. REQUEST_SIZE_MATCH(xXIUngrabDeviceReq);
  133. ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
  134. if (ret != Success)
  135. return ret;
  136. grab = dev->deviceGrab.grab;
  137. time = ClientTimeToServerTime(stuff->time);
  138. if ((CompareTimeStamps(time, currentTime) != LATER) &&
  139. (CompareTimeStamps(time, dev->deviceGrab.grabTime) != EARLIER) &&
  140. (grab) && SameClient(grab, client) && grab->grabtype == XI2)
  141. (*dev->deviceGrab.DeactivateGrab) (dev);
  142. return Success;
  143. }
  144. void
  145. SRepXIGrabDevice(ClientPtr client, int size, xXIGrabDeviceReply * rep)
  146. {
  147. swaps(&rep->sequenceNumber);
  148. swapl(&rep->length);
  149. WriteToClient(client, size, rep);
  150. }