1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
/* Copyright 2006 by Peter Hutterer <peter@cs.unisa.edu.au> */
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <X11/X.h> /* for inputstr.h */
#include <X11/Xproto.h> /* Request macro */
#include "inputstr.h" /* DeviceIntPtr */
#include "windowstr.h" /* window structure */
#include <X11/extensions/MPX.h>
#include <X11/extensions/MPXproto.h>
#include "extnsionst.h"
#include "mpxextinit.h" /* LookupDeviceIntRec */
#include "mpxglobals.h"
#include "mpxevents.h"
#include "selectev.h"
/* functions borrowed from XI */
extern void RecalculateDeviceDeliverableEvents(
WindowPtr /* pWin */);
extern int AddExtensionClient (
WindowPtr /* pWin */,
ClientPtr /* client */,
Mask /* mask */,
int /* mskidx */);
extern Bool
ShouldFreeInputMasks(WindowPtr /* pWin */,
Bool /* ignoreSelectedEvents */);
/***********************************************************************
*
* Handle requests from clients with a different byte order.
*
*/
int
SProcMPXSelectEvents(register ClientPtr client)
{
register char n;
REQUEST(xMPXSelectEventsReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xMPXSelectEventsReq);
swapl(&stuff->window, n);
return (ProcMPXSelectEvents(client));
}
/***********************************************************************
*
* This procedure selects input from an extension device.
*
*/
int
ProcMPXSelectEvents(register ClientPtr client)
{
int ret;
WindowPtr pWin;
REQUEST(xMPXSelectEventsReq);
REQUEST_SIZE_MATCH(xMPXSelectEventsReq);
if (stuff->length != (sizeof(xMPXSelectEventsReq) >> 2))
{
SendErrorToClient(client, MPXReqCode, X_MPXSelectEvents, 0,
BadLength);
return Success;
}
pWin = (WindowPtr) LookupWindow(stuff->window, client);
if (!pWin)
{
client->errorValue = stuff->window;
SendErrorToClient(client, MPXReqCode, X_MPXSelectEvents, 0,
BadWindow);
return Success;
}
if (stuff->mask >= MPXHighestMask)
{
client->errorValue = stuff->mask;
SendErrorToClient(client, MPXReqCode, X_MPXSelectEvents, 0,
BadValue);
}
if ((ret = MPXSelectForWindow(pWin, client, stuff->mask)) != Success)
{
SendErrorToClient(client, MPXReqCode, X_MPXSelectEvents, 0, ret);
return Success;
}
return Success;
}
/**
* Selects a set of events for a given window.
* Different to XI, MPX is not device dependent. Either the client gets events
* from all devices or none.
*
* This method borrows some functions from XI, due to the piggyback on the
* core pointer (see comment in extinit.c)
*/
int
MPXSelectForWindow(WindowPtr pWin, ClientPtr client, int mask)
{
InputClientsPtr others;
int ret;
if (mask >= MPXHighestMask)
{
client->errorValue = mask;
return BadValue;
}
if (wOtherInputMasks(pWin))
{
for (others = wOtherInputMasks(pWin)->inputClients; others;
others = others->next)
{
if (SameClient(others, client)) {
others->mask[MPXmskidx] = mask;
if (mask == 0)
{
/* clean up stuff */
RecalculateDeviceDeliverableEvents(pWin);
if (ShouldFreeInputMasks(pWin, FALSE))
FreeResource(others->resource, RT_NONE);
return Success;
}
goto maskSet;
}
}
}
/* borrow from XI here */
if ((ret = AddExtensionClient(pWin, client, mask, MPXmskidx)) != Success)
return ret;
maskSet:
RecalculateDeviceDeliverableEvents(pWin);
return Success;
}
|