Events.c revision 6747b715
105b261ecSmrg/*
205b261ecSmrg
305b261ecSmrgCopyright 1993 by Davor Matic
405b261ecSmrg
505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software
605b261ecSmrgand its documentation for any purpose is hereby granted without fee,
705b261ecSmrgprovided that the above copyright notice appear in all copies and that
805b261ecSmrgboth that copyright notice and this permission notice appear in
905b261ecSmrgsupporting documentation.  Davor Matic makes no representations about
1005b261ecSmrgthe suitability of this software for any purpose.  It is provided "as
1105b261ecSmrgis" without express or implied warranty.
1205b261ecSmrg
1305b261ecSmrg*/
1405b261ecSmrg
1505b261ecSmrg#ifdef HAVE_XNEST_CONFIG_H
1605b261ecSmrg#include <xnest-config.h>
1705b261ecSmrg#endif
1805b261ecSmrg
1905b261ecSmrg#include <X11/X.h>
2005b261ecSmrg#include <X11/Xproto.h>
2105b261ecSmrg#include "screenint.h"
2205b261ecSmrg#include "input.h"
2305b261ecSmrg#include "misc.h"
2405b261ecSmrg#include "scrnintstr.h"
2505b261ecSmrg#include "windowstr.h"
2605b261ecSmrg#include "servermd.h"
274642e01fSmrg#include "inputstr.h"
2805b261ecSmrg
2905b261ecSmrg#include "mi.h"
3005b261ecSmrg
3105b261ecSmrg#include "Xnest.h"
3205b261ecSmrg
3305b261ecSmrg#include "Args.h"
3405b261ecSmrg#include "Color.h"
3505b261ecSmrg#include "Display.h"
3605b261ecSmrg#include "Screen.h"
3705b261ecSmrg#include "XNWindow.h"
3805b261ecSmrg#include "Events.h"
3905b261ecSmrg#include "Keyboard.h"
4005b261ecSmrg#include "Pointer.h"
4105b261ecSmrg#include "mipointer.h"
4205b261ecSmrg
4305b261ecSmrgCARD32 lastEventTime = 0;
4405b261ecSmrg
454642e01fSmrgextern EventList *xnestEvents;
4605b261ecSmrg
4705b261ecSmrgvoid
486747b715SmrgProcessInputEvents(void)
4905b261ecSmrg{
5005b261ecSmrg  mieqProcessInputEvents();
5105b261ecSmrg}
5205b261ecSmrg
5305b261ecSmrgint
5405b261ecSmrgTimeSinceLastInputEvent(void)
5505b261ecSmrg{
5605b261ecSmrg    if (lastEventTime == 0)
5705b261ecSmrg        lastEventTime = GetTimeInMillis();
5805b261ecSmrg    return GetTimeInMillis() - lastEventTime;
5905b261ecSmrg}
6005b261ecSmrg
6105b261ecSmrgvoid
6205b261ecSmrgSetTimeSinceLastInputEvent(void)
6305b261ecSmrg{
6405b261ecSmrg  lastEventTime = GetTimeInMillis();
6505b261ecSmrg}
6605b261ecSmrg
6705b261ecSmrgstatic Bool
6805b261ecSmrgxnestExposurePredicate(Display *display, XEvent *event, char *args)
6905b261ecSmrg{
706747b715Smrg  return event->type == Expose || event->type == ProcessedExpose;
7105b261ecSmrg}
7205b261ecSmrg
7305b261ecSmrgstatic Bool
7405b261ecSmrgxnestNotExposurePredicate(Display *display, XEvent *event, char *args)
7505b261ecSmrg{
7605b261ecSmrg  return !xnestExposurePredicate(display, event, args);
7705b261ecSmrg}
7805b261ecSmrg
7905b261ecSmrgvoid
8005b261ecSmrgxnestCollectExposures(void)
8105b261ecSmrg{
8205b261ecSmrg  XEvent X;
8305b261ecSmrg  WindowPtr pWin;
8405b261ecSmrg  RegionRec Rgn;
8505b261ecSmrg  BoxRec Box;
8605b261ecSmrg
8705b261ecSmrg  while (XCheckIfEvent(xnestDisplay, &X, xnestExposurePredicate, NULL)) {
8805b261ecSmrg    pWin = xnestWindowPtr(X.xexpose.window);
8905b261ecSmrg
904642e01fSmrg    if (pWin && X.xexpose.width && X.xexpose.height) {
9105b261ecSmrg      Box.x1 = pWin->drawable.x + wBorderWidth(pWin) + X.xexpose.x;
9205b261ecSmrg      Box.y1 = pWin->drawable.y + wBorderWidth(pWin) + X.xexpose.y;
9305b261ecSmrg      Box.x2 = Box.x1 + X.xexpose.width;
9405b261ecSmrg      Box.y2 = Box.y1 + X.xexpose.height;
9505b261ecSmrg
966747b715Smrg      RegionInit(&Rgn, &Box, 1);
9705b261ecSmrg
984642e01fSmrg      miSendExposures(pWin, &Rgn, Box.x2, Box.y2);
9905b261ecSmrg    }
10005b261ecSmrg  }
10105b261ecSmrg}
10205b261ecSmrg
10305b261ecSmrgvoid
10405b261ecSmrgxnestQueueKeyEvent(int type, unsigned int keycode)
10505b261ecSmrg{
10605b261ecSmrg  int i, n;
10705b261ecSmrg
1084642e01fSmrg  GetEventList(&xnestEvents);
10905b261ecSmrg  lastEventTime = GetTimeInMillis();
11005b261ecSmrg  n = GetKeyboardEvents(xnestEvents, xnestKeyboardDevice, type, keycode);
11105b261ecSmrg  for (i = 0; i < n; i++)
1126747b715Smrg    mieqEnqueue(xnestKeyboardDevice, (InternalEvent*)(xnestEvents + i)->event);
11305b261ecSmrg}
11405b261ecSmrg
11505b261ecSmrgvoid
11605b261ecSmrgxnestCollectEvents(void)
11705b261ecSmrg{
11805b261ecSmrg  XEvent X;
11905b261ecSmrg  int i, n, valuators[2];
12005b261ecSmrg  ScreenPtr pScreen;
1214642e01fSmrg  GetEventList(&xnestEvents);
12205b261ecSmrg
12305b261ecSmrg  while (XCheckIfEvent(xnestDisplay, &X, xnestNotExposurePredicate, NULL)) {
12405b261ecSmrg    switch (X.type) {
12505b261ecSmrg    case KeyPress:
12605b261ecSmrg      xnestUpdateModifierState(X.xkey.state);
12705b261ecSmrg      xnestQueueKeyEvent(KeyPress, X.xkey.keycode);
12805b261ecSmrg      break;
12905b261ecSmrg
13005b261ecSmrg    case KeyRelease:
13105b261ecSmrg      xnestUpdateModifierState(X.xkey.state);
13205b261ecSmrg      xnestQueueKeyEvent(KeyRelease, X.xkey.keycode);
13305b261ecSmrg      break;
13405b261ecSmrg
13505b261ecSmrg    case ButtonPress:
13605b261ecSmrg      xnestUpdateModifierState(X.xkey.state);
13705b261ecSmrg      lastEventTime = GetTimeInMillis();
13805b261ecSmrg      n = GetPointerEvents(xnestEvents, xnestPointerDevice, ButtonPress,
13905b261ecSmrg                           X.xbutton.button, POINTER_RELATIVE, 0, 0, NULL);
14005b261ecSmrg      for (i = 0; i < n; i++)
1416747b715Smrg        mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
14205b261ecSmrg      break;
14305b261ecSmrg
14405b261ecSmrg    case ButtonRelease:
14505b261ecSmrg      xnestUpdateModifierState(X.xkey.state);
14605b261ecSmrg      lastEventTime = GetTimeInMillis();
14705b261ecSmrg      n = GetPointerEvents(xnestEvents, xnestPointerDevice, ButtonRelease,
14805b261ecSmrg                           X.xbutton.button, POINTER_RELATIVE, 0, 0, NULL);
14905b261ecSmrg      for (i = 0; i < n; i++)
1506747b715Smrg        mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
15105b261ecSmrg      break;
15205b261ecSmrg
15305b261ecSmrg    case MotionNotify:
15405b261ecSmrg      valuators[0] = X.xmotion.x;
15505b261ecSmrg      valuators[1] = X.xmotion.y;
15605b261ecSmrg      lastEventTime = GetTimeInMillis();
15705b261ecSmrg      n = GetPointerEvents(xnestEvents, xnestPointerDevice, MotionNotify,
15805b261ecSmrg                           0, POINTER_ABSOLUTE, 0, 2, valuators);
15905b261ecSmrg      for (i = 0; i < n; i++)
1606747b715Smrg        mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
16105b261ecSmrg      break;
16205b261ecSmrg
16305b261ecSmrg    case FocusIn:
16405b261ecSmrg      if (X.xfocus.detail != NotifyInferior) {
16505b261ecSmrg	pScreen = xnestScreen(X.xfocus.window);
16605b261ecSmrg	if (pScreen)
16705b261ecSmrg	  xnestDirectInstallColormaps(pScreen);
16805b261ecSmrg      }
16905b261ecSmrg      break;
17005b261ecSmrg
17105b261ecSmrg    case FocusOut:
17205b261ecSmrg      if (X.xfocus.detail != NotifyInferior) {
17305b261ecSmrg	pScreen = xnestScreen(X.xfocus.window);
17405b261ecSmrg	if (pScreen)
17505b261ecSmrg	  xnestDirectUninstallColormaps(pScreen);
17605b261ecSmrg      }
17705b261ecSmrg      break;
17805b261ecSmrg
17905b261ecSmrg    case KeymapNotify:
18005b261ecSmrg      break;
18105b261ecSmrg
18205b261ecSmrg    case EnterNotify:
18305b261ecSmrg      if (X.xcrossing.detail != NotifyInferior) {
18405b261ecSmrg	pScreen = xnestScreen(X.xcrossing.window);
18505b261ecSmrg	if (pScreen) {
1864642e01fSmrg	  NewCurrentScreen(inputInfo.pointer, pScreen, X.xcrossing.x, X.xcrossing.y);
18705b261ecSmrg          valuators[0] = X.xcrossing.x;
18805b261ecSmrg          valuators[1] = X.xcrossing.y;
18905b261ecSmrg          lastEventTime = GetTimeInMillis();
19005b261ecSmrg          n = GetPointerEvents(xnestEvents, xnestPointerDevice, MotionNotify,
19105b261ecSmrg                               0, POINTER_ABSOLUTE, 0, 2, valuators);
19205b261ecSmrg          for (i = 0; i < n; i++)
1936747b715Smrg            mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
19405b261ecSmrg	  xnestDirectInstallColormaps(pScreen);
19505b261ecSmrg	}
19605b261ecSmrg      }
19705b261ecSmrg      break;
19805b261ecSmrg
19905b261ecSmrg    case LeaveNotify:
20005b261ecSmrg      if (X.xcrossing.detail != NotifyInferior) {
20105b261ecSmrg	pScreen = xnestScreen(X.xcrossing.window);
20205b261ecSmrg	if (pScreen) {
20305b261ecSmrg	  xnestDirectUninstallColormaps(pScreen);
20405b261ecSmrg	}
20505b261ecSmrg      }
20605b261ecSmrg      break;
20705b261ecSmrg
20805b261ecSmrg    case DestroyNotify:
20905b261ecSmrg      if (xnestParentWindow != (Window) 0 &&
21005b261ecSmrg	  X.xdestroywindow.window == xnestParentWindow)
21105b261ecSmrg	exit (0);
21205b261ecSmrg      break;
21305b261ecSmrg
21405b261ecSmrg    case CirculateNotify:
21505b261ecSmrg    case ConfigureNotify:
21605b261ecSmrg    case GravityNotify:
21705b261ecSmrg    case MapNotify:
21805b261ecSmrg    case ReparentNotify:
21905b261ecSmrg    case UnmapNotify:
22005b261ecSmrg      break;
22105b261ecSmrg
22205b261ecSmrg    default:
22305b261ecSmrg      ErrorF("xnest warning: unhandled event\n");
22405b261ecSmrg      break;
22505b261ecSmrg    }
22605b261ecSmrg  }
22705b261ecSmrg}
228