hierarchy.c revision 53719b08
1/*
2 * Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au>
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation.
9 *
10 * The above copyright notice and this permission notice shall be included
11 * in all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
17 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
19 * OTHER DEALINGS IN THE SOFTWARE.
20 *
21 * Except as contained in this notice, the name of the author shall
22 * not be used in advertising or otherwise to promote the sale, use or
23 * other dealings in this Software without prior written authorization
24 * from the author.
25 *
26 */
27
28#include "xinput.h"
29#include <string.h>
30
31#define Error(error, ...) \
32{ \
33    fprintf(stderr, __VA_ARGS__); \
34    return error;\
35}
36/**
37 * Create a new master device. Name must be supplied, other values are
38 * optional.
39 */
40int
41create_master(Display* dpy, int argc, char** argv, char* name, char *desc)
42{
43    XIAddMasterInfo c;
44
45    if (argc == 0)
46    {
47        fprintf(stderr, "Usage: xinput %s %s\n", name, desc);
48        return EXIT_FAILURE;
49    }
50
51    c.type = XIAddMaster;
52    c.name = argv[0];
53    c.send_core = (argc >= 2) ? atoi(argv[1]) : 1;
54    c.enable = (argc >= 3) ? atoi(argv[2]) : 1;
55
56    return XIChangeHierarchy(dpy, (XIAnyHierarchyChangeInfo*)&c, 1);
57}
58
59/**
60 * Remove a master device.
61 * By default, all attached devices are set to Floating, unless parameters are
62 * given.
63 */
64int
65remove_master(Display* dpy, int argc, char** argv, char *name, char *desc)
66{
67    XIRemoveMasterInfo r;
68    XIDeviceInfo *info;
69    int ret;
70
71    if (argc == 0)
72    {
73        fprintf(stderr, "usage: xinput %s %s\n", name, desc);
74        return EXIT_FAILURE;
75    }
76
77    info = xi2_find_device_info(dpy, argv[0]);
78
79    if (!info) {
80	fprintf(stderr, "unable to find device %s\n", argv[0]);
81	return EXIT_FAILURE;
82    }
83
84    r.type = XIRemoveMaster;
85    r.deviceid = info->deviceid;
86    if (argc >= 2)
87    {
88        if (!strcmp(argv[1], "Floating"))
89            r.return_mode = XIFloating;
90        else if (!strcmp(argv[1], "AttachToMaster"))
91            r.return_mode = XIAttachToMaster;
92        else
93            Error(BadValue, "Invalid return_mode.\n");
94    } else
95        r.return_mode = XIFloating;
96
97    if (r.return_mode == XIAttachToMaster)
98    {
99        r.return_pointer = 0;
100        if (argc >= 3) {
101            info = xi2_find_device_info(dpy, argv[2]);
102            if (!info) {
103                fprintf(stderr, "unable to find device %s\n", argv[2]);
104                return EXIT_FAILURE;
105            }
106
107            r.return_pointer = info->deviceid;
108        }
109
110        r.return_keyboard = 0;
111        if (argc >= 4) {
112            info = xi2_find_device_info(dpy, argv[3]);
113            if (!info) {
114                fprintf(stderr, "unable to find device %s\n", argv[3]);
115                return EXIT_FAILURE;
116            }
117
118            r.return_keyboard = info->deviceid;
119        }
120
121        if (!r.return_pointer || !r.return_keyboard) {
122            int i, ndevices;
123            info = XIQueryDevice(dpy, XIAllMasterDevices, &ndevices);
124            for(i = 0; i < ndevices; i++) {
125                if (info[i].use == XIMasterPointer && !r.return_pointer)
126                    r.return_pointer = info[i].deviceid;
127                if (info[i].use == XIMasterKeyboard && !r.return_keyboard)
128                    r.return_keyboard = info[i].deviceid;
129                if (r.return_pointer && r.return_keyboard)
130                    break;
131            }
132
133            XIFreeDeviceInfo(info);
134        }
135    }
136
137    ret = XIChangeHierarchy(dpy, (XIAnyHierarchyChangeInfo*)&r, 1);
138    return ret;
139}
140
141/**
142 * Swap a device from one master to another.
143 */
144int
145change_attachment(Display* dpy, int argc, char** argv, char *name, char* desc)
146{
147    XIDeviceInfo *sd_info, *md_info;
148    XIAttachSlaveInfo c;
149    int ret;
150
151    if (argc < 2)
152    {
153        fprintf(stderr, "usage: xinput %s %s\n", name, desc);
154        return EXIT_FAILURE;
155    }
156
157    sd_info = xi2_find_device_info(dpy, argv[0]);
158    md_info= xi2_find_device_info(dpy, argv[1]);
159
160    if (!sd_info) {
161	fprintf(stderr, "unable to find device %s\n", argv[0]);
162	return EXIT_FAILURE;
163    }
164
165    if (!md_info) {
166	fprintf(stderr, "unable to find device %s\n", argv[1]);
167	return EXIT_FAILURE;
168    }
169
170    c.type = XIAttachSlave;
171    c.deviceid = sd_info->deviceid;
172    c.new_master = md_info->deviceid;
173
174    ret = XIChangeHierarchy(dpy, (XIAnyHierarchyChangeInfo*)&c, 1);
175    return ret;
176}
177
178/**
179 * Set a device floating.
180 */
181int
182float_device(Display* dpy, int argc, char** argv, char* name, char* desc)
183{
184    XIDeviceInfo *info;
185    XIDetachSlaveInfo c;
186    int ret;
187
188    if (argc < 1)
189    {
190        fprintf(stderr, "usage: xinput %s %s\n", name, desc);
191        return EXIT_FAILURE;
192    }
193
194    info = xi2_find_device_info(dpy, argv[0]);
195
196    if (!info) {
197	fprintf(stderr, "unable to find device %s\n", argv[0]);
198	return EXIT_FAILURE;
199    }
200
201    c.type = XIDetachSlave;
202    c.deviceid = info->deviceid;
203
204    ret = XIChangeHierarchy(dpy, (XIAnyHierarchyChangeInfo*)&c, 1);
205    return ret;
206}
207
208
209