~ubuntu-branches/ubuntu/natty/libxi/natty-201011191114

« back to all changes in this revision

Viewing changes to src/XISelEv.c

  • Committer: Bazaar Package Importer
  • Author(s): Julien Cristau
  • Date: 2009-11-21 18:39:28 UTC
  • mfrom: (1.1.10 upstream) (0.1.6 experimental)
  • Revision ID: james.westby@ubuntu.com-20091121183928-ek2jwqx3rmhv3zjz
Tags: 2:1.3-1
* Bump Standards-Version to 3.8.3.
* Add build-deps on xmlto and asciidoc to build the manpages.
* New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/************************************************************
 
2
 
 
3
Copyright 2009 Red Hat, Inc.
 
4
 
 
5
Permission to use, copy, modify, distribute, and sell this software and its
 
6
documentation for any purpose is hereby granted without fee, provided that
 
7
the above copyright notice appear in all copies and that both that
 
8
copyright notice and this permission notice appear in supporting
 
9
documentation.
 
10
 
 
11
The above copyright notice and this permission notice shall be included in
 
12
all copies or substantial portions of the Software.
 
13
 
 
14
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
15
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
16
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
17
AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
18
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
19
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
20
 
 
21
Except as contained in this notice, the name of the author shall not be
 
22
used in advertising or otherwise to promote the sale, use or other dealings
 
23
in this Software without prior written authorization from the author.
 
24
 
 
25
*/
 
26
 
 
27
/***********************************************************************
 
28
 *
 
29
 * XISelectEvent - Select for XI2 events.
 
30
 *
 
31
 */
 
32
 
 
33
 
 
34
#include <stdint.h>
 
35
#include <X11/Xlibint.h>
 
36
#include <X11/extensions/XI2proto.h>
 
37
#include <X11/extensions/XInput2.h>
 
38
#include <X11/extensions/extutil.h>
 
39
#include <X11/extensions/ge.h>
 
40
#include <X11/extensions/geproto.h>
 
41
#include "XIint.h"
 
42
 
 
43
int
 
44
XISelectEvents(Display* dpy, Window win, XIEventMask* masks, int num_masks)
 
45
{
 
46
    XIEventMask  *current;
 
47
    xXISelectEventsReq  *req;
 
48
    xXIEventMask mask;
 
49
    int i;
 
50
    int len = 0;
 
51
 
 
52
    XExtDisplayInfo *info = XInput_find_display(dpy);
 
53
    LockDisplay(dpy);
 
54
    if (_XiCheckExtInit(dpy, Dont_Check, info) == -1)
 
55
        return (NoSuchExtension);
 
56
    GetReq(XISelectEvents, req);
 
57
 
 
58
    req->reqType = info->codes->major_opcode;
 
59
    req->ReqType = X_XISelectEvents;
 
60
    req->win = win;
 
61
    req->num_masks = num_masks;
 
62
 
 
63
    /* get the right length */
 
64
    for (i = 0; i < num_masks; i++)
 
65
    {
 
66
        len++;
 
67
        current = &masks[i];
 
68
        len += (current->mask_len + 3)/4;
 
69
    }
 
70
 
 
71
    SetReqLen(req, len, len);
 
72
 
 
73
    for (i = 0; i < num_masks; i++)
 
74
    {
 
75
        char *buff;
 
76
        current = &masks[i];
 
77
        mask.deviceid = current->deviceid;
 
78
        mask.mask_len = (current->mask_len + 3)/4;
 
79
        /* masks.mask_len is in bytes, but we need 4-byte units on the wire,
 
80
         * and they need to be padded with 0 */
 
81
        buff = calloc(1, mask.mask_len * 4);
 
82
        memcpy(buff, current->mask, current->mask_len);
 
83
        Data32(dpy, &mask, sizeof(xXIEventMask));
 
84
        Data(dpy, buff, mask.mask_len * 4);
 
85
        free(buff);
 
86
    }
 
87
 
 
88
    UnlockDisplay(dpy);
 
89
    SyncHandle();
 
90
    return Success;
 
91
 
 
92
}
 
93
 
 
94
XIEventMask*
 
95
XIGetSelectedEvents(Display* dpy, Window win, int *num_masks_return)
 
96
{
 
97
    int i, len = 0;
 
98
    unsigned char *mask;
 
99
    XIEventMask *mask_out = NULL;
 
100
    xXIEventMask *mask_in = NULL, *mi;
 
101
    xXIGetSelectedEventsReq *req;
 
102
    xXIGetSelectedEventsReply reply;
 
103
 
 
104
    XExtDisplayInfo *info = XInput_find_display(dpy);
 
105
    LockDisplay(dpy);
 
106
    if (_XiCheckExtInit(dpy, Dont_Check, info) == -1)
 
107
    {
 
108
        *num_masks_return = -1;
 
109
        return NULL;
 
110
    }
 
111
 
 
112
    GetReq(XIGetSelectedEvents, req);
 
113
 
 
114
    req->reqType = info->codes->major_opcode;
 
115
    req->ReqType = X_XIGetSelectedEvents;
 
116
    req->win = win;
 
117
 
 
118
    if (!_XReply(dpy, (xReply *) &reply, 0, xFalse))
 
119
        goto error;
 
120
 
 
121
    if (reply.num_masks == 0)
 
122
    {
 
123
        *num_masks_return = 0;
 
124
        return NULL;
 
125
    }
 
126
 
 
127
    mask_in = Xmalloc(reply.length * 4);
 
128
    if (!mask_in)
 
129
        goto error;
 
130
 
 
131
    _XRead(dpy, (char*)mask_in, reply.length * 4);
 
132
 
 
133
    /* Memory layout of the XIEventMask for a 3 mask reply:
 
134
     * [struct a][struct b][struct c][masks a][masks b][masks c]
 
135
     */
 
136
    len = reply.num_masks * sizeof(XIEventMask);
 
137
 
 
138
    for (i = 0, mi = mask_in; i < reply.num_masks; i++)
 
139
    {
 
140
        len += mi->mask_len * 4;
 
141
        mi = (xXIEventMask*)((char*)mi + mi->mask_len * 4);
 
142
        mi++;
 
143
    }
 
144
 
 
145
    mask_out = Xmalloc(len);
 
146
    if (!mask_out)
 
147
        goto error;
 
148
 
 
149
    mi = mask_in;
 
150
    mask = (unsigned char*)&mask_out[reply.num_masks];
 
151
    for (i = 0; i < reply.num_masks; i++)
 
152
    {
 
153
        mask_out[i].deviceid = mi->deviceid;
 
154
        mask_out[i].mask_len = mi->mask_len * 4;
 
155
        mask_out[i].mask = mask;
 
156
        memcpy(mask_out[i].mask, &mi[1], mask_out[i].mask_len);
 
157
        mask += mask_out[i].mask_len;
 
158
        mi = (xXIEventMask*)((char*)mi + mi->mask_len * 4);
 
159
        mi++;
 
160
    }
 
161
 
 
162
    *num_masks_return = reply.num_masks;
 
163
 
 
164
    return mask_out;
 
165
 
 
166
error:
 
167
    if (mask_in)
 
168
        Xfree(mask_in);
 
169
    *num_masks_return = -1;
 
170
    UnlockDisplay(dpy);
 
171
    SyncHandle();
 
172
    return NULL;
 
173
 
 
174
}