mieq.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /*
  2. *
  3. Copyright 1990, 1998 The Open Group
  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
  7. copyright notice and this permission notice appear in supporting
  8. documentation.
  9. The above copyright notice and this permission notice shall be included in
  10. all copies or substantial portions of the Software.
  11. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  15. AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  16. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  17. Except as contained in this notice, the name of The Open Group shall not be
  18. used in advertising or otherwise to promote the sale, use or other dealings
  19. in this Software without prior written authorization from The Open Group.
  20. *
  21. * Author: Keith Packard, MIT X Consortium
  22. */
  23. /*
  24. * mieq.c
  25. *
  26. * Machine independent event queue
  27. *
  28. */
  29. #if HAVE_DIX_CONFIG_H
  30. #include <dix-config.h>
  31. #endif
  32. # include <X11/X.h>
  33. # include <X11/Xmd.h>
  34. # include <X11/Xproto.h>
  35. # include "misc.h"
  36. # include "windowstr.h"
  37. # include "pixmapstr.h"
  38. # include "inputstr.h"
  39. # include "mi.h"
  40. # include "scrnintstr.h"
  41. #define QUEUE_SIZE 256
  42. typedef struct _Event {
  43. xEvent event;
  44. ScreenPtr pScreen;
  45. } EventRec, *EventPtr;
  46. typedef struct _EventQueue {
  47. HWEventQueueType head, tail; /* long for SetInputCheck */
  48. CARD32 lastEventTime; /* to avoid time running backwards */
  49. Bool lastMotion;
  50. EventRec events[QUEUE_SIZE]; /* static allocation for signals */
  51. DevicePtr pKbd, pPtr; /* device pointer, to get funcs */
  52. ScreenPtr pEnqueueScreen; /* screen events are being delivered to */
  53. ScreenPtr pDequeueScreen; /* screen events are being dispatched to */
  54. } EventQueueRec, *EventQueuePtr;
  55. static EventQueueRec miEventQueue;
  56. Bool
  57. mieqInit (pKbd, pPtr)
  58. DevicePtr pKbd, pPtr;
  59. {
  60. miEventQueue.head = miEventQueue.tail = 0;
  61. miEventQueue.lastEventTime = GetTimeInMillis ();
  62. miEventQueue.pKbd = pKbd;
  63. miEventQueue.pPtr = pPtr;
  64. miEventQueue.lastMotion = FALSE;
  65. miEventQueue.pEnqueueScreen = screenInfo.screens[0];
  66. miEventQueue.pDequeueScreen = miEventQueue.pEnqueueScreen;
  67. SetInputCheck (&miEventQueue.head, &miEventQueue.tail);
  68. return TRUE;
  69. }
  70. /*
  71. * Must be reentrant with ProcessInputEvents. Assumption: mieqEnqueue
  72. * will never be interrupted. If this is called from both signal
  73. * handlers and regular code, make sure the signal is suspended when
  74. * called from regular code.
  75. */
  76. void
  77. mieqEnqueue (e)
  78. xEvent *e;
  79. {
  80. HWEventQueueType oldtail, newtail;
  81. Bool isMotion;
  82. oldtail = miEventQueue.tail;
  83. isMotion = e->u.u.type == MotionNotify;
  84. if (isMotion && miEventQueue.lastMotion && oldtail != miEventQueue.head)
  85. {
  86. if (oldtail == 0)
  87. oldtail = QUEUE_SIZE;
  88. oldtail = oldtail - 1;
  89. }
  90. else
  91. {
  92. newtail = oldtail + 1;
  93. if (newtail == QUEUE_SIZE)
  94. newtail = 0;
  95. /* Toss events which come in late */
  96. if (newtail == miEventQueue.head)
  97. return;
  98. miEventQueue.tail = newtail;
  99. }
  100. miEventQueue.lastMotion = isMotion;
  101. miEventQueue.events[oldtail].event = *e;
  102. /*
  103. * Make sure that event times don't go backwards - this
  104. * is "unnecessary", but very useful
  105. */
  106. if (e->u.keyButtonPointer.time < miEventQueue.lastEventTime &&
  107. miEventQueue.lastEventTime - e->u.keyButtonPointer.time < 10000)
  108. {
  109. miEventQueue.events[oldtail].event.u.keyButtonPointer.time =
  110. miEventQueue.lastEventTime;
  111. }
  112. miEventQueue.lastEventTime =
  113. miEventQueue.events[oldtail].event.u.keyButtonPointer.time;
  114. miEventQueue.events[oldtail].pScreen = miEventQueue.pEnqueueScreen;
  115. }
  116. void
  117. mieqSwitchScreen (pScreen, fromDIX)
  118. ScreenPtr pScreen;
  119. Bool fromDIX;
  120. {
  121. miEventQueue.pEnqueueScreen = pScreen;
  122. if (fromDIX)
  123. miEventQueue.pDequeueScreen = pScreen;
  124. }
  125. /*
  126. * Call this from ProcessInputEvents()
  127. */
  128. void mieqProcessInputEvents ()
  129. {
  130. EventRec *e;
  131. int x, y;
  132. xEvent xe;
  133. while (miEventQueue.head != miEventQueue.tail)
  134. {
  135. if (screenIsSaved == SCREEN_SAVER_ON)
  136. SaveScreens (SCREEN_SAVER_OFF, ScreenSaverReset);
  137. e = &miEventQueue.events[miEventQueue.head];
  138. /*
  139. * Assumption - screen switching can only occur on motion events
  140. */
  141. if (e->pScreen != miEventQueue.pDequeueScreen)
  142. {
  143. miEventQueue.pDequeueScreen = e->pScreen;
  144. x = e->event.u.keyButtonPointer.rootX;
  145. y = e->event.u.keyButtonPointer.rootY;
  146. if (miEventQueue.head == QUEUE_SIZE - 1)
  147. miEventQueue.head = 0;
  148. else
  149. ++miEventQueue.head;
  150. NewCurrentScreen (miEventQueue.pDequeueScreen, x, y);
  151. }
  152. else
  153. {
  154. xe = e->event;
  155. if (miEventQueue.head == QUEUE_SIZE - 1)
  156. miEventQueue.head = 0;
  157. else
  158. ++miEventQueue.head;
  159. switch (xe.u.u.type)
  160. {
  161. case KeyPress:
  162. case KeyRelease:
  163. (*miEventQueue.pKbd->processInputProc)
  164. (&xe, (DeviceIntPtr)miEventQueue.pKbd, 1);
  165. break;
  166. default:
  167. (*miEventQueue.pPtr->processInputProc)
  168. (&xe, (DeviceIntPtr)miEventQueue.pPtr, 1);
  169. break;
  170. }
  171. }
  172. }
  173. }