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