Events.c revision 4642e01f
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#define NEED_EVENTS
21#include <X11/Xproto.h>
22#include "screenint.h"
23#include "input.h"
24#include "misc.h"
25#include "scrnintstr.h"
26#include "windowstr.h"
27#include "servermd.h"
28#include "inputstr.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()
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      REGION_INIT(pWin->drawable.pScreen, &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, (xnestEvents + i)->event);
114}
115
116void
117xnestCollectEvents(void)
118{
119  XEvent X;
120  int i, n, valuators[2];
121  ScreenPtr pScreen;
122  GetEventList(&xnestEvents);
123
124  while (XCheckIfEvent(xnestDisplay, &X, xnestNotExposurePredicate, NULL)) {
125    switch (X.type) {
126    case KeyPress:
127      xnestUpdateModifierState(X.xkey.state);
128      xnestQueueKeyEvent(KeyPress, X.xkey.keycode);
129      break;
130
131    case KeyRelease:
132      xnestUpdateModifierState(X.xkey.state);
133      xnestQueueKeyEvent(KeyRelease, X.xkey.keycode);
134      break;
135
136    case ButtonPress:
137      xnestUpdateModifierState(X.xkey.state);
138      lastEventTime = GetTimeInMillis();
139      n = GetPointerEvents(xnestEvents, xnestPointerDevice, ButtonPress,
140                           X.xbutton.button, POINTER_RELATIVE, 0, 0, NULL);
141      for (i = 0; i < n; i++)
142        mieqEnqueue(xnestPointerDevice, (xnestEvents + i)->event);
143      break;
144
145    case ButtonRelease:
146      xnestUpdateModifierState(X.xkey.state);
147      lastEventTime = GetTimeInMillis();
148      n = GetPointerEvents(xnestEvents, xnestPointerDevice, ButtonRelease,
149                           X.xbutton.button, POINTER_RELATIVE, 0, 0, NULL);
150      for (i = 0; i < n; i++)
151        mieqEnqueue(xnestPointerDevice, (xnestEvents + i)->event);
152      break;
153
154    case MotionNotify:
155      valuators[0] = X.xmotion.x;
156      valuators[1] = X.xmotion.y;
157      lastEventTime = GetTimeInMillis();
158      n = GetPointerEvents(xnestEvents, xnestPointerDevice, MotionNotify,
159                           0, POINTER_ABSOLUTE, 0, 2, valuators);
160      for (i = 0; i < n; i++)
161        mieqEnqueue(xnestPointerDevice, (xnestEvents + i)->event);
162      break;
163
164    case FocusIn:
165      if (X.xfocus.detail != NotifyInferior) {
166	pScreen = xnestScreen(X.xfocus.window);
167	if (pScreen)
168	  xnestDirectInstallColormaps(pScreen);
169      }
170      break;
171
172    case FocusOut:
173      if (X.xfocus.detail != NotifyInferior) {
174	pScreen = xnestScreen(X.xfocus.window);
175	if (pScreen)
176	  xnestDirectUninstallColormaps(pScreen);
177      }
178      break;
179
180    case KeymapNotify:
181      break;
182
183    case EnterNotify:
184      if (X.xcrossing.detail != NotifyInferior) {
185	pScreen = xnestScreen(X.xcrossing.window);
186	if (pScreen) {
187	  NewCurrentScreen(inputInfo.pointer, pScreen, X.xcrossing.x, X.xcrossing.y);
188          valuators[0] = X.xcrossing.x;
189          valuators[1] = X.xcrossing.y;
190          lastEventTime = GetTimeInMillis();
191          n = GetPointerEvents(xnestEvents, xnestPointerDevice, MotionNotify,
192                               0, POINTER_ABSOLUTE, 0, 2, valuators);
193          for (i = 0; i < n; i++)
194            mieqEnqueue(xnestPointerDevice, (xnestEvents + i)->event);
195	  xnestDirectInstallColormaps(pScreen);
196	}
197      }
198      break;
199
200    case LeaveNotify:
201      if (X.xcrossing.detail != NotifyInferior) {
202	pScreen = xnestScreen(X.xcrossing.window);
203	if (pScreen) {
204	  xnestDirectUninstallColormaps(pScreen);
205	}
206      }
207      break;
208
209    case DestroyNotify:
210      if (xnestParentWindow != (Window) 0 &&
211	  X.xdestroywindow.window == xnestParentWindow)
212	exit (0);
213      break;
214
215    case CirculateNotify:
216    case ConfigureNotify:
217    case GravityNotify:
218    case MapNotify:
219    case ReparentNotify:
220    case UnmapNotify:
221      break;
222
223    default:
224      ErrorF("xnest warning: unhandled event\n");
225      break;
226    }
227  }
228}
229