XIHierarchy.c revision 44584a44
1/************************************************************
2
3Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au>
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25*/
26
27/***********************************************************************
28 *
29 * XIChangeHierarchy - change the device hierarchy, i.e. which slave
30 * device is attached to which master, etc.
31 */
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
36#include <stdint.h>
37#include <X11/extensions/XI2proto.h>
38#include <X11/Xlibint.h>
39#include <X11/extensions/XInput2.h>
40#include <X11/extensions/extutil.h>
41#include "XIint.h"
42
43int
44XIChangeHierarchy(Display* dpy,
45                        XIAnyHierarchyChangeInfo* changes,
46                        int num_changes)
47{
48    XIAnyHierarchyChangeInfo* any;
49    xXIChangeHierarchyReq *req;
50    XExtDisplayInfo *info = XInput_find_display(dpy);
51    char *data = NULL, *dptr;
52    int dlen = 0, i, ret = Success;
53
54    LockDisplay(dpy);
55    if (_XiCheckExtInit(dpy, XInput_2_0, info) == -1)
56	return (NoSuchExtension);
57
58    if (num_changes <= 0)
59        goto out;
60
61    GetReq(XIChangeHierarchy, req);
62    req->reqType = info->codes->major_opcode;
63    req->ReqType = X_XIChangeHierarchy;
64    req->num_changes = num_changes;
65
66    /* alloc required memory */
67    for (i = 0, any = changes; i < num_changes; i++, any++)
68    {
69        switch(any->type)
70        {
71            case XIAddMaster:
72                {
73                    int slen = (strlen(any->add.name));
74                    dlen += sizeof(xXIAddMasterInfo) +
75                        slen + (4 - (slen % 4));
76                }
77                break;
78            case XIRemoveMaster:
79                dlen += sizeof(xXIRemoveMasterInfo);
80                break;
81            case XIAttachSlave:
82                dlen += sizeof(xXIAttachSlaveInfo);
83                break;
84            case XIDetachSlave:
85                dlen += sizeof(xXIDetachSlaveInfo);
86                break;
87            default:
88                return BadValue;
89        }
90    }
91
92    req->length += dlen / 4; /* dlen is 4-byte aligned */
93    data = Xmalloc(dlen);
94    if (!data) {
95        ret = BadAlloc;
96        goto out;
97    }
98
99    dptr = data;
100    for (i = 0, any = changes; i < num_changes; i++, any++)
101    {
102        switch(any->type)
103        {
104                case XIAddMaster:
105                {
106                    XIAddMasterInfo* C = &any->add;
107                    xXIAddMasterInfo* c = (xXIAddMasterInfo*)dptr;
108                    c->type = C->type;
109                    c->send_core = C->send_core;
110                    c->enable = C->enable;
111                    c->name_len = strlen(C->name);
112                    c->length = (sizeof(xXIAddMasterInfo) + c->name_len + 3)/4;
113                    strncpy((char*)&c[1], C->name, c->name_len);
114                    dptr += 4 * c->length;
115                }
116                break;
117            case XIRemoveMaster:
118                {
119                    XIRemoveMasterInfo* R = &any->remove;
120                    xXIRemoveMasterInfo* r = (xXIRemoveMasterInfo*)dptr;
121                    r->type = R->type;
122                    r->return_mode = R->return_mode;
123                    r->deviceid = R->deviceid;
124                    r->length = sizeof(xXIRemoveMasterInfo)/4;
125                    if (r->return_mode == XIAttachToMaster)
126                    {
127                        r->return_pointer = R->return_pointer;
128                        r->return_keyboard = R->return_keyboard;
129                    }
130                    dptr += sizeof(xXIRemoveMasterInfo);
131                }
132                break;
133            case XIAttachSlave:
134                {
135                    XIAttachSlaveInfo* C = &any->attach;
136                    xXIAttachSlaveInfo* c = (xXIAttachSlaveInfo*)dptr;
137
138                    c->type = C->type;
139                    c->deviceid = C->deviceid;
140                    c->length = sizeof(xXIAttachSlaveInfo)/4;
141                    c->new_master = C->new_master;
142
143                    dptr += sizeof(xXIAttachSlaveInfo);
144                }
145                break;
146            case XIDetachSlave:
147                {
148                    XIDetachSlaveInfo *D = &any->detach;
149                    xXIDetachSlaveInfo *d = (xXIDetachSlaveInfo*)dptr;
150
151                    d->type = D->type;
152                    d->deviceid = D->deviceid;
153                    d->length = sizeof(xXIDetachSlaveInfo)/4;
154                    dptr += sizeof(xXIDetachSlaveInfo);
155                }
156        }
157    }
158
159    Data(dpy, data, dlen);
160
161out:
162    Xfree(data);
163    UnlockDisplay(dpy);
164    SyncHandle();
165    return ret;
166}
167