Events.c revision 706f2543
1/*
2
3Copyright 1993 by Davor Matic
4
5Permission to use, copy, modify, distribute, and sell this software
6and its documentation for any purpose is hereby granted without fee,
7provided that the above copyright notice appear in all copies and that
8both that copyright notice and this permission notice appear in
9supporting documentation.  Davor Matic makes no representations about
10the suitability of this software for any purpose.  It is provided "as
11is" without express or implied warranty.
12
13*/
14
15#ifdef HAVE_XNEST_CONFIG_H
16#include <xnest-config.h>
17#endif
18
19#include <X11/X.h>
20#include <X11/Xproto.h>
21#include "screenint.h"
22#include "input.h"
23#include "misc.h"
24#include "scrnintstr.h"
25#include "windowstr.h"
26#include "servermd.h"
27#include "inputstr.h"
28#include "inpututils.h"
29
30#include "mi.h"
31
32#include "Xnest.h"
33
34#include "Args.h"
35#include "Color.h"
36#include "Display.h"
37#include "Screen.h"
38#include "XNWindow.h"
39#include "Events.h"
40#include "Keyboard.h"
41#include "Pointer.h"
42#include "mipointer.h"
43
44CARD32 lastEventTime = 0;
45
46extern EventList *xnestEvents;
47
48void
49ProcessInputEvents(void)
50{
51  mieqProcessInputEvents();
52}
53
54int
55TimeSinceLastInputEvent(void)
56{
57    if (lastEventTime == 0)
58        lastEventTime = GetTimeInMillis();
59    return GetTimeInMillis() - lastEventTime;
60}
61
62void
63SetTimeSinceLastInputEvent(void)
64{
65  lastEventTime = GetTimeInMillis();
66}
67
68static Bool
69xnestExposurePredicate(Display *display, XEvent *event, char *args)
70{
71  return event->type == Expose || event->type == ProcessedExpose;
72}
73
74static Bool
75xnestNotExposurePredicate(Display *display, XEvent *event, char *args)
76{
77  return !xnestExposurePredicate(display, event, args);
78}
79
80void
81xnestCollectExposures(void)
82{
83  XEvent X;
84  WindowPtr pWin;
85  RegionRec Rgn;
86  BoxRec Box;
87
88  while (XCheckIfEvent(xnestDisplay, &X, xnestExposurePredicate, NULL)) {
89    pWin = xnestWindowPtr(X.xexpose.window);
90
91    if (pWin && X.xexpose.width && X.xexpose.height) {
92      Box.x1 = pWin->drawable.x + wBorderWidth(pWin) + X.xexpose.x;
93      Box.y1 = pWin->drawable.y + wBorderWidth(pWin) + X.xexpose.y;
94      Box.x2 = Box.x1 + X.xexpose.width;
95      Box.y2 = Box.y1 + X.xexpose.height;
96
97      RegionInit(&Rgn, &Box, 1);
98
99      miSendExposures(pWin, &Rgn, Box.x2, Box.y2);
100    }
101  }
102}
103
104void
105xnestQueueKeyEvent(int type, unsigned int keycode)
106{
107  int i, n;
108
109  GetEventList(&xnestEvents);
110  lastEventTime = GetTimeInMillis();
111  n = GetKeyboardEvents(xnestEvents, xnestKeyboardDevice, type, keycode);
112  for (i = 0; i < n; i++)
113    mieqEnqueue(xnestKeyboardDevice, (InternalEvent*)(xnestEvents + i)->event);
114}
115
116void
117xnestCollectEvents(void)
118{
119  XEvent X;
120  int i, n, valuators[2];
121  ValuatorMask mask;
122  ScreenPtr pScreen;
123  GetEventList(&xnestEvents);
124
125  while (XCheckIfEvent(xnestDisplay, &X, xnestNotExposurePredicate, NULL)) {
126    switch (X.type) {
127    case KeyPress:
128      xnestUpdateModifierState(X.xkey.state);
129      xnestQueueKeyEvent(KeyPress, X.xkey.keycode);
130      break;
131
132    case KeyRelease:
133      xnestUpdateModifierState(X.xkey.state);
134      xnestQueueKeyEvent(KeyRelease, X.xkey.keycode);
135      break;
136
137    case ButtonPress:
138      valuator_mask_set_range(&mask, 0, 0, NULL);
139      xnestUpdateModifierState(X.xkey.state);
140      lastEventTime = GetTimeInMillis();
141      n = GetPointerEvents(xnestEvents, xnestPointerDevice, ButtonPress,
142                           X.xbutton.button, POINTER_RELATIVE, &mask);
143      for (i = 0; i < n; i++)
144        mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
145      break;
146
147    case ButtonRelease:
148      valuator_mask_set_range(&mask, 0, 0, NULL);
149      xnestUpdateModifierState(X.xkey.state);
150      lastEventTime = GetTimeInMillis();
151      n = GetPointerEvents(xnestEvents, xnestPointerDevice, ButtonRelease,
152                           X.xbutton.button, POINTER_RELATIVE, &mask);
153      for (i = 0; i < n; i++)
154        mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
155      break;
156
157    case MotionNotify:
158      valuators[0] = X.xmotion.x;
159      valuators[1] = X.xmotion.y;
160      valuator_mask_set_range(&mask, 0, 2, valuators);
161      lastEventTime = GetTimeInMillis();
162      n = GetPointerEvents(xnestEvents, xnestPointerDevice, MotionNotify,
163                           0, POINTER_ABSOLUTE, &mask);
164      for (i = 0; i < n; i++)
165        mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
166      break;
167
168    case FocusIn:
169      if (X.xfocus.detail != NotifyInferior) {
170	pScreen = xnestScreen(X.xfocus.window);
171	if (pScreen)
172	  xnestDirectInstallColormaps(pScreen);
173      }
174      break;
175
176    case FocusOut:
177      if (X.xfocus.detail != NotifyInferior) {
178	pScreen = xnestScreen(X.xfocus.window);
179	if (pScreen)
180	  xnestDirectUninstallColormaps(pScreen);
181      }
182      break;
183
184    case KeymapNotify:
185      break;
186
187    case EnterNotify:
188      if (X.xcrossing.detail != NotifyInferior) {
189	pScreen = xnestScreen(X.xcrossing.window);
190	if (pScreen) {
191	  NewCurrentScreen(inputInfo.pointer, pScreen, X.xcrossing.x, X.xcrossing.y);
192          valuators[0] = X.xcrossing.x;
193          valuators[1] = X.xcrossing.y;
194          valuator_mask_set_range(&mask, 0, 2, valuators);
195          lastEventTime = GetTimeInMillis();
196          n = GetPointerEvents(xnestEvents, xnestPointerDevice, MotionNotify,
197                               0, POINTER_ABSOLUTE, &mask);
198          for (i = 0; i < n; i++)
199            mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
200	  xnestDirectInstallColormaps(pScreen);
201	}
202      }
203      break;
204
205    case LeaveNotify:
206      if (X.xcrossing.detail != NotifyInferior) {
207	pScreen = xnestScreen(X.xcrossing.window);
208	if (pScreen) {
209	  xnestDirectUninstallColormaps(pScreen);
210	}
211      }
212      break;
213
214    case DestroyNotify:
215      if (xnestParentWindow != (Window) 0 &&
216	  X.xdestroywindow.window == xnestParentWindow)
217	exit (0);
218      break;
219
220    case CirculateNotify:
221    case ConfigureNotify:
222    case GravityNotify:
223    case MapNotify:
224    case ReparentNotify:
225    case UnmapNotify:
226      break;
227
228    default:
229      ErrorF("xnest warning: unhandled event\n");
230      break;
231    }
232  }
233}
234