Events.c revision 6747b715
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
29#include "mi.h"
30
31#include "Xnest.h"
32
33#include "Args.h"
34#include "Color.h"
35#include "Display.h"
36#include "Screen.h"
37#include "XNWindow.h"
38#include "Events.h"
39#include "Keyboard.h"
40#include "Pointer.h"
41#include "mipointer.h"
42
43CARD32 lastEventTime = 0;
44
45extern EventList *xnestEvents;
46
47void
48ProcessInputEvents(void)
49{
50  mieqProcessInputEvents();
51}
52
53int
54TimeSinceLastInputEvent(void)
55{
56    if (lastEventTime == 0)
57        lastEventTime = GetTimeInMillis();
58    return GetTimeInMillis() - lastEventTime;
59}
60
61void
62SetTimeSinceLastInputEvent(void)
63{
64  lastEventTime = GetTimeInMillis();
65}
66
67static Bool
68xnestExposurePredicate(Display *display, XEvent *event, char *args)
69{
70  return event->type == Expose || event->type == ProcessedExpose;
71}
72
73static Bool
74xnestNotExposurePredicate(Display *display, XEvent *event, char *args)
75{
76  return !xnestExposurePredicate(display, event, args);
77}
78
79void
80xnestCollectExposures(void)
81{
82  XEvent X;
83  WindowPtr pWin;
84  RegionRec Rgn;
85  BoxRec Box;
86
87  while (XCheckIfEvent(xnestDisplay, &X, xnestExposurePredicate, NULL)) {
88    pWin = xnestWindowPtr(X.xexpose.window);
89
90    if (pWin && X.xexpose.width && X.xexpose.height) {
91      Box.x1 = pWin->drawable.x + wBorderWidth(pWin) + X.xexpose.x;
92      Box.y1 = pWin->drawable.y + wBorderWidth(pWin) + X.xexpose.y;
93      Box.x2 = Box.x1 + X.xexpose.width;
94      Box.y2 = Box.y1 + X.xexpose.height;
95
96      RegionInit(&Rgn, &Box, 1);
97
98      miSendExposures(pWin, &Rgn, Box.x2, Box.y2);
99    }
100  }
101}
102
103void
104xnestQueueKeyEvent(int type, unsigned int keycode)
105{
106  int i, n;
107
108  GetEventList(&xnestEvents);
109  lastEventTime = GetTimeInMillis();
110  n = GetKeyboardEvents(xnestEvents, xnestKeyboardDevice, type, keycode);
111  for (i = 0; i < n; i++)
112    mieqEnqueue(xnestKeyboardDevice, (InternalEvent*)(xnestEvents + i)->event);
113}
114
115void
116xnestCollectEvents(void)
117{
118  XEvent X;
119  int i, n, valuators[2];
120  ScreenPtr pScreen;
121  GetEventList(&xnestEvents);
122
123  while (XCheckIfEvent(xnestDisplay, &X, xnestNotExposurePredicate, NULL)) {
124    switch (X.type) {
125    case KeyPress:
126      xnestUpdateModifierState(X.xkey.state);
127      xnestQueueKeyEvent(KeyPress, X.xkey.keycode);
128      break;
129
130    case KeyRelease:
131      xnestUpdateModifierState(X.xkey.state);
132      xnestQueueKeyEvent(KeyRelease, X.xkey.keycode);
133      break;
134
135    case ButtonPress:
136      xnestUpdateModifierState(X.xkey.state);
137      lastEventTime = GetTimeInMillis();
138      n = GetPointerEvents(xnestEvents, xnestPointerDevice, ButtonPress,
139                           X.xbutton.button, POINTER_RELATIVE, 0, 0, NULL);
140      for (i = 0; i < n; i++)
141        mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
142      break;
143
144    case ButtonRelease:
145      xnestUpdateModifierState(X.xkey.state);
146      lastEventTime = GetTimeInMillis();
147      n = GetPointerEvents(xnestEvents, xnestPointerDevice, ButtonRelease,
148                           X.xbutton.button, POINTER_RELATIVE, 0, 0, NULL);
149      for (i = 0; i < n; i++)
150        mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
151      break;
152
153    case MotionNotify:
154      valuators[0] = X.xmotion.x;
155      valuators[1] = X.xmotion.y;
156      lastEventTime = GetTimeInMillis();
157      n = GetPointerEvents(xnestEvents, xnestPointerDevice, MotionNotify,
158                           0, POINTER_ABSOLUTE, 0, 2, valuators);
159      for (i = 0; i < n; i++)
160        mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
161      break;
162
163    case FocusIn:
164      if (X.xfocus.detail != NotifyInferior) {
165	pScreen = xnestScreen(X.xfocus.window);
166	if (pScreen)
167	  xnestDirectInstallColormaps(pScreen);
168      }
169      break;
170
171    case FocusOut:
172      if (X.xfocus.detail != NotifyInferior) {
173	pScreen = xnestScreen(X.xfocus.window);
174	if (pScreen)
175	  xnestDirectUninstallColormaps(pScreen);
176      }
177      break;
178
179    case KeymapNotify:
180      break;
181
182    case EnterNotify:
183      if (X.xcrossing.detail != NotifyInferior) {
184	pScreen = xnestScreen(X.xcrossing.window);
185	if (pScreen) {
186	  NewCurrentScreen(inputInfo.pointer, pScreen, X.xcrossing.x, X.xcrossing.y);
187          valuators[0] = X.xcrossing.x;
188          valuators[1] = X.xcrossing.y;
189          lastEventTime = GetTimeInMillis();
190          n = GetPointerEvents(xnestEvents, xnestPointerDevice, MotionNotify,
191                               0, POINTER_ABSOLUTE, 0, 2, valuators);
192          for (i = 0; i < n; i++)
193            mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
194	  xnestDirectInstallColormaps(pScreen);
195	}
196      }
197      break;
198
199    case LeaveNotify:
200      if (X.xcrossing.detail != NotifyInferior) {
201	pScreen = xnestScreen(X.xcrossing.window);
202	if (pScreen) {
203	  xnestDirectUninstallColormaps(pScreen);
204	}
205      }
206      break;
207
208    case DestroyNotify:
209      if (xnestParentWindow != (Window) 0 &&
210	  X.xdestroywindow.window == xnestParentWindow)
211	exit (0);
212      break;
213
214    case CirculateNotify:
215    case ConfigureNotify:
216    case GravityNotify:
217    case MapNotify:
218    case ReparentNotify:
219    case UnmapNotify:
220      break;
221
222    default:
223      ErrorF("xnest warning: unhandled event\n");
224      break;
225    }
226  }
227}
228