present_event.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /*
  2. * Copyright © 2013 Keith Packard
  3. *
  4. * Permission to use, copy, modify, distribute, and sell this software and its
  5. * documentation for any purpose is hereby granted without fee, provided that
  6. * the above copyright notice appear in all copies and that both that copyright
  7. * notice and this permission notice appear in supporting documentation, and
  8. * that the name of the copyright holders not be used in advertising or
  9. * publicity pertaining to distribution of the software without specific,
  10. * written prior permission. The copyright holders make no representations
  11. * about the suitability of this software for any purpose. It is provided "as
  12. * is" without express or implied warranty.
  13. *
  14. * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  15. * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  16. * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  17. * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  18. * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  19. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  20. * OF THIS SOFTWARE.
  21. */
  22. #ifdef HAVE_XORG_CONFIG_H
  23. #include <xorg-config.h>
  24. #endif
  25. #include "present_priv.h"
  26. RESTYPE present_event_type;
  27. static int
  28. present_free_event(void *data, XID id)
  29. {
  30. present_event_ptr present_event = (present_event_ptr) data;
  31. present_window_priv_ptr window_priv = present_window_priv(present_event->window);
  32. present_event_ptr *previous, current;
  33. for (previous = &window_priv->events; (current = *previous); previous = &current->next) {
  34. if (current == present_event) {
  35. *previous = present_event->next;
  36. break;
  37. }
  38. }
  39. free((void *) present_event);
  40. return 1;
  41. }
  42. void
  43. present_free_events(WindowPtr window)
  44. {
  45. present_window_priv_ptr window_priv = present_window_priv(window);
  46. present_event_ptr event;
  47. if (!window_priv)
  48. return;
  49. while ((event = window_priv->events))
  50. FreeResource(event->id, RT_NONE);
  51. }
  52. static void
  53. present_event_swap(xGenericEvent *from, xGenericEvent *to)
  54. {
  55. *to = *from;
  56. swaps(&to->sequenceNumber);
  57. swapl(&to->length);
  58. swaps(&to->evtype);
  59. switch (from->evtype) {
  60. case PresentConfigureNotify: {
  61. xPresentConfigureNotify *c = (xPresentConfigureNotify *) to;
  62. swapl(&c->eid);
  63. swapl(&c->window);
  64. swaps(&c->x);
  65. swaps(&c->y);
  66. swaps(&c->width);
  67. swaps(&c->height);
  68. swaps(&c->off_x);
  69. swaps(&c->off_y);
  70. swaps(&c->pixmap_width);
  71. swaps(&c->pixmap_height);
  72. swapl(&c->pixmap_flags);
  73. break;
  74. }
  75. case PresentCompleteNotify:
  76. {
  77. xPresentCompleteNotify *c = (xPresentCompleteNotify *) to;
  78. swapl(&c->eid);
  79. swapl(&c->window);
  80. swapl(&c->serial);
  81. swapll(&c->ust);
  82. swapll(&c->msc);
  83. }
  84. case PresentIdleNotify:
  85. {
  86. xPresentIdleNotify *c = (xPresentIdleNotify *) to;
  87. swapl(&c->eid);
  88. swapl(&c->window);
  89. swapl(&c->serial);
  90. swapl(&c->idle_fence);
  91. }
  92. }
  93. }
  94. void
  95. present_send_config_notify(WindowPtr window, int x, int y, int w, int h, int bw, WindowPtr sibling)
  96. {
  97. present_window_priv_ptr window_priv = present_window_priv(window);
  98. if (window_priv) {
  99. xPresentConfigureNotify cn = {
  100. .type = GenericEvent,
  101. .extension = present_request,
  102. .length = (sizeof(xPresentConfigureNotify) - 32) >> 2,
  103. .evtype = PresentConfigureNotify,
  104. .eid = 0,
  105. .window = window->drawable.id,
  106. .x = x,
  107. .y = y,
  108. .width = w,
  109. .height = h,
  110. .off_x = 0,
  111. .off_y = 0,
  112. .pixmap_width = w,
  113. .pixmap_height = h,
  114. .pixmap_flags = 0
  115. };
  116. present_event_ptr event;
  117. for (event = window_priv->events; event; event = event->next) {
  118. if (event->mask & (1 << PresentConfigureNotify)) {
  119. cn.eid = event->id;
  120. WriteEventsToClient(event->client, 1, (xEvent *) &cn);
  121. }
  122. }
  123. }
  124. }
  125. static present_complete_notify_proc complete_notify;
  126. void
  127. present_register_complete_notify(present_complete_notify_proc proc)
  128. {
  129. complete_notify = proc;
  130. }
  131. void
  132. present_send_complete_notify(WindowPtr window, CARD8 kind, CARD8 mode, CARD32 serial, uint64_t ust, uint64_t msc)
  133. {
  134. present_window_priv_ptr window_priv = present_window_priv(window);
  135. if (window_priv) {
  136. xPresentCompleteNotify cn = {
  137. .type = GenericEvent,
  138. .extension = present_request,
  139. .length = (sizeof(xPresentCompleteNotify) - 32) >> 2,
  140. .evtype = PresentCompleteNotify,
  141. .kind = kind,
  142. .mode = mode,
  143. .eid = 0,
  144. .window = window->drawable.id,
  145. .serial = serial,
  146. .ust = ust,
  147. .msc = msc,
  148. };
  149. present_event_ptr event;
  150. for (event = window_priv->events; event; event = event->next) {
  151. if (event->mask & PresentCompleteNotifyMask) {
  152. cn.eid = event->id;
  153. WriteEventsToClient(event->client, 1, (xEvent *) &cn);
  154. }
  155. }
  156. }
  157. if (complete_notify && kind == PresentCompleteKindPixmap)
  158. (*complete_notify)(window, mode, serial, ust, msc);
  159. }
  160. void
  161. present_send_idle_notify(WindowPtr window, CARD32 serial, PixmapPtr pixmap, struct present_fence *idle_fence)
  162. {
  163. present_window_priv_ptr window_priv = present_window_priv(window);
  164. if (window_priv) {
  165. xPresentIdleNotify in = {
  166. .type = GenericEvent,
  167. .extension = present_request,
  168. .length = (sizeof(xPresentIdleNotify) - 32) >> 2,
  169. .evtype = PresentIdleNotify,
  170. .eid = 0,
  171. .window = window->drawable.id,
  172. .serial = serial,
  173. .pixmap = pixmap->drawable.id,
  174. .idle_fence = present_fence_id(idle_fence)
  175. };
  176. present_event_ptr event;
  177. for (event = window_priv->events; event; event = event->next) {
  178. if (event->mask & PresentIdleNotifyMask) {
  179. in.eid = event->id;
  180. WriteEventsToClient(event->client, 1, (xEvent *) &in);
  181. }
  182. }
  183. }
  184. }
  185. int
  186. present_select_input(ClientPtr client, XID eid, WindowPtr window, CARD32 mask)
  187. {
  188. present_window_priv_ptr window_priv = present_get_window_priv(window, mask != 0);
  189. present_event_ptr event;
  190. if (!window_priv) {
  191. if (mask)
  192. return BadAlloc;
  193. return Success;
  194. }
  195. event = calloc (1, sizeof (present_event_rec));
  196. if (!event)
  197. return BadAlloc;
  198. event->client = client;
  199. event->window = window;
  200. event->id = eid;
  201. event->mask = mask;
  202. event->next = window_priv->events;
  203. window_priv->events = event;
  204. if (!AddResource(event->id, present_event_type, (void *) event))
  205. return BadAlloc;
  206. return Success;
  207. }
  208. Bool
  209. present_event_init(void)
  210. {
  211. present_event_type = CreateNewResourceType(present_free_event, "PresentEvent");
  212. if (!present_event_type)
  213. return FALSE;
  214. GERegisterExtension(present_request, present_event_swap);
  215. return TRUE;
  216. }