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"
289ace9065Smrg#include "inpututils.h"
2905b261ecSmrg
3005b261ecSmrg#include "mi.h"
3105b261ecSmrg
3205b261ecSmrg#include "Xnest.h"
3305b261ecSmrg
3405b261ecSmrg#include "Args.h"
3505b261ecSmrg#include "Color.h"
3605b261ecSmrg#include "Display.h"
3705b261ecSmrg#include "Screen.h"
3805b261ecSmrg#include "XNWindow.h"
3905b261ecSmrg#include "Events.h"
4005b261ecSmrg#include "Keyboard.h"
4105b261ecSmrg#include "Pointer.h"
4205b261ecSmrg#include "mipointer.h"
4305b261ecSmrg
4405b261ecSmrgCARD32 lastEventTime = 0;
4505b261ecSmrg
4605b261ecSmrgvoid
476747b715SmrgProcessInputEvents(void)
4805b261ecSmrg{
4935c4bbdfSmrg    mieqProcessInputEvents();
5005b261ecSmrg}
5105b261ecSmrg
5205b261ecSmrgint
5305b261ecSmrgTimeSinceLastInputEvent(void)
5405b261ecSmrg{
5505b261ecSmrg    if (lastEventTime == 0)
5605b261ecSmrg        lastEventTime = GetTimeInMillis();
5705b261ecSmrg    return GetTimeInMillis() - lastEventTime;
5805b261ecSmrg}
5905b261ecSmrg
6005b261ecSmrgvoid
6105b261ecSmrgSetTimeSinceLastInputEvent(void)
6205b261ecSmrg{
6335c4bbdfSmrg    lastEventTime = GetTimeInMillis();
6405b261ecSmrg}
6505b261ecSmrg
6605b261ecSmrgstatic Bool
6735c4bbdfSmrgxnestExposurePredicate(Display * dpy, XEvent * event, char *args)
6805b261ecSmrg{
6935c4bbdfSmrg    return event->type == Expose || event->type == ProcessedExpose;
7005b261ecSmrg}
7105b261ecSmrg
7205b261ecSmrgstatic Bool
7335c4bbdfSmrgxnestNotExposurePredicate(Display * dpy, XEvent * event, char *args)
7405b261ecSmrg{
7535c4bbdfSmrg    return !xnestExposurePredicate(dpy, event, args);
7605b261ecSmrg}
7705b261ecSmrg
7805b261ecSmrgvoid
7905b261ecSmrgxnestCollectExposures(void)
8005b261ecSmrg{
8135c4bbdfSmrg    XEvent X;
8235c4bbdfSmrg    WindowPtr pWin;
8335c4bbdfSmrg    RegionRec Rgn;
8435c4bbdfSmrg    BoxRec Box;
8535c4bbdfSmrg
8635c4bbdfSmrg    while (XCheckIfEvent(xnestDisplay, &X, xnestExposurePredicate, NULL)) {
8735c4bbdfSmrg        pWin = xnestWindowPtr(X.xexpose.window);
8835c4bbdfSmrg
8935c4bbdfSmrg        if (pWin && X.xexpose.width && X.xexpose.height) {
9035c4bbdfSmrg            Box.x1 = pWin->drawable.x + wBorderWidth(pWin) + X.xexpose.x;
9135c4bbdfSmrg            Box.y1 = pWin->drawable.y + wBorderWidth(pWin) + X.xexpose.y;
9235c4bbdfSmrg            Box.x2 = Box.x1 + X.xexpose.width;
9335c4bbdfSmrg            Box.y2 = Box.y1 + X.xexpose.height;
9435c4bbdfSmrg
9535c4bbdfSmrg            RegionInit(&Rgn, &Box, 1);
9635c4bbdfSmrg
9758cf2af7Smrg            miSendExposures(pWin, &Rgn, Box.x1, Box.y1);
9835c4bbdfSmrg        }
9905b261ecSmrg    }
10005b261ecSmrg}
10105b261ecSmrg
10205b261ecSmrgvoid
10305b261ecSmrgxnestQueueKeyEvent(int type, unsigned int keycode)
10405b261ecSmrg{
10535c4bbdfSmrg    lastEventTime = GetTimeInMillis();
10635c4bbdfSmrg    QueueKeyboardEvents(xnestKeyboardDevice, type, keycode);
10705b261ecSmrg}
10805b261ecSmrg
10905b261ecSmrgvoid
11005b261ecSmrgxnestCollectEvents(void)
11105b261ecSmrg{
11235c4bbdfSmrg    XEvent X;
11335c4bbdfSmrg    int valuators[2];
11435c4bbdfSmrg    ValuatorMask mask;
11535c4bbdfSmrg    ScreenPtr pScreen;
11635c4bbdfSmrg
11735c4bbdfSmrg    while (XCheckIfEvent(xnestDisplay, &X, xnestNotExposurePredicate, NULL)) {
11835c4bbdfSmrg        switch (X.type) {
11935c4bbdfSmrg        case KeyPress:
12035c4bbdfSmrg            xnestUpdateModifierState(X.xkey.state);
12135c4bbdfSmrg            xnestQueueKeyEvent(KeyPress, X.xkey.keycode);
12235c4bbdfSmrg            break;
12335c4bbdfSmrg
12435c4bbdfSmrg        case KeyRelease:
12535c4bbdfSmrg            xnestUpdateModifierState(X.xkey.state);
12635c4bbdfSmrg            xnestQueueKeyEvent(KeyRelease, X.xkey.keycode);
12735c4bbdfSmrg            break;
12835c4bbdfSmrg
12935c4bbdfSmrg        case ButtonPress:
13035c4bbdfSmrg            valuator_mask_set_range(&mask, 0, 0, NULL);
13135c4bbdfSmrg            xnestUpdateModifierState(X.xkey.state);
13235c4bbdfSmrg            lastEventTime = GetTimeInMillis();
13335c4bbdfSmrg            QueuePointerEvents(xnestPointerDevice, ButtonPress,
13435c4bbdfSmrg                               X.xbutton.button, POINTER_RELATIVE, &mask);
13535c4bbdfSmrg            break;
13635c4bbdfSmrg
13735c4bbdfSmrg        case ButtonRelease:
13835c4bbdfSmrg            valuator_mask_set_range(&mask, 0, 0, NULL);
13935c4bbdfSmrg            xnestUpdateModifierState(X.xkey.state);
14035c4bbdfSmrg            lastEventTime = GetTimeInMillis();
14135c4bbdfSmrg            QueuePointerEvents(xnestPointerDevice, ButtonRelease,
14235c4bbdfSmrg                               X.xbutton.button, POINTER_RELATIVE, &mask);
14335c4bbdfSmrg            break;
14435c4bbdfSmrg
14535c4bbdfSmrg        case MotionNotify:
14635c4bbdfSmrg            valuators[0] = X.xmotion.x;
14735c4bbdfSmrg            valuators[1] = X.xmotion.y;
14835c4bbdfSmrg            valuator_mask_set_range(&mask, 0, 2, valuators);
14935c4bbdfSmrg            lastEventTime = GetTimeInMillis();
15035c4bbdfSmrg            QueuePointerEvents(xnestPointerDevice, MotionNotify,
1519ace9065Smrg                               0, POINTER_ABSOLUTE, &mask);
15235c4bbdfSmrg            break;
15335c4bbdfSmrg
15435c4bbdfSmrg        case FocusIn:
15535c4bbdfSmrg            if (X.xfocus.detail != NotifyInferior) {
15635c4bbdfSmrg                pScreen = xnestScreen(X.xfocus.window);
15735c4bbdfSmrg                if (pScreen)
15835c4bbdfSmrg                    xnestDirectInstallColormaps(pScreen);
15935c4bbdfSmrg            }
16035c4bbdfSmrg            break;
16135c4bbdfSmrg
16235c4bbdfSmrg        case FocusOut:
16335c4bbdfSmrg            if (X.xfocus.detail != NotifyInferior) {
16435c4bbdfSmrg                pScreen = xnestScreen(X.xfocus.window);
16535c4bbdfSmrg                if (pScreen)
16635c4bbdfSmrg                    xnestDirectUninstallColormaps(pScreen);
16735c4bbdfSmrg            }
16835c4bbdfSmrg            break;
16935c4bbdfSmrg
17035c4bbdfSmrg        case KeymapNotify:
17135c4bbdfSmrg            break;
17235c4bbdfSmrg
17335c4bbdfSmrg        case EnterNotify:
17435c4bbdfSmrg            if (X.xcrossing.detail != NotifyInferior) {
17535c4bbdfSmrg                pScreen = xnestScreen(X.xcrossing.window);
17635c4bbdfSmrg                if (pScreen) {
17735c4bbdfSmrg                    NewCurrentScreen(inputInfo.pointer, pScreen, X.xcrossing.x,
17835c4bbdfSmrg                                     X.xcrossing.y);
17935c4bbdfSmrg                    valuators[0] = X.xcrossing.x;
18035c4bbdfSmrg                    valuators[1] = X.xcrossing.y;
18135c4bbdfSmrg                    valuator_mask_set_range(&mask, 0, 2, valuators);
18235c4bbdfSmrg                    lastEventTime = GetTimeInMillis();
18335c4bbdfSmrg                    QueuePointerEvents(xnestPointerDevice, MotionNotify,
18435c4bbdfSmrg                                       0, POINTER_ABSOLUTE, &mask);
18535c4bbdfSmrg                    xnestDirectInstallColormaps(pScreen);
18635c4bbdfSmrg                }
18735c4bbdfSmrg            }
18835c4bbdfSmrg            break;
18935c4bbdfSmrg
19035c4bbdfSmrg        case LeaveNotify:
19135c4bbdfSmrg            if (X.xcrossing.detail != NotifyInferior) {
19235c4bbdfSmrg                pScreen = xnestScreen(X.xcrossing.window);
19335c4bbdfSmrg                if (pScreen) {
19435c4bbdfSmrg                    xnestDirectUninstallColormaps(pScreen);
19535c4bbdfSmrg                }
19635c4bbdfSmrg            }
19735c4bbdfSmrg            break;
19835c4bbdfSmrg
19935c4bbdfSmrg        case DestroyNotify:
20035c4bbdfSmrg            if (xnestParentWindow != (Window) 0 &&
20135c4bbdfSmrg                X.xdestroywindow.window == xnestParentWindow)
20235c4bbdfSmrg                exit(0);
20335c4bbdfSmrg            break;
20435c4bbdfSmrg
20535c4bbdfSmrg        case CirculateNotify:
20635c4bbdfSmrg        case ConfigureNotify:
20735c4bbdfSmrg        case GravityNotify:
20835c4bbdfSmrg        case MapNotify:
20935c4bbdfSmrg        case ReparentNotify:
21035c4bbdfSmrg        case UnmapNotify:
21135c4bbdfSmrg            break;
21235c4bbdfSmrg
21335c4bbdfSmrg        default:
21435c4bbdfSmrg            ErrorF("xnest warning: unhandled event\n");
21535c4bbdfSmrg            break;
21635c4bbdfSmrg        }
21705b261ecSmrg    }
21805b261ecSmrg}
219