hierarchy.c revision 53719b08
15b944e2aSmrg/*
25b944e2aSmrg * Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au>
35b944e2aSmrg *
45b944e2aSmrg * Permission to use, copy, modify, distribute, and sell this software and its
55b944e2aSmrg * documentation for any purpose is hereby granted without fee, provided that
65b944e2aSmrg * the above copyright notice appear in all copies and that both that
75b944e2aSmrg * copyright notice and this permission notice appear in supporting
85b944e2aSmrg * documentation.
95b944e2aSmrg *
105b944e2aSmrg * The above copyright notice and this permission notice shall be included
115b944e2aSmrg * in all copies or substantial portions of the Software.
125b944e2aSmrg *
135b944e2aSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
145b944e2aSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
155b944e2aSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
165b944e2aSmrg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
175b944e2aSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
185b944e2aSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
195b944e2aSmrg * OTHER DEALINGS IN THE SOFTWARE.
205b944e2aSmrg *
215b944e2aSmrg * Except as contained in this notice, the name of the author shall
225b944e2aSmrg * not be used in advertising or otherwise to promote the sale, use or
235b944e2aSmrg * other dealings in this Software without prior written authorization
245b944e2aSmrg * from the author.
255b944e2aSmrg *
265b944e2aSmrg */
275b944e2aSmrg
285b944e2aSmrg#include "xinput.h"
295b944e2aSmrg#include <string.h>
305b944e2aSmrg
315b944e2aSmrg#define Error(error, ...) \
325b944e2aSmrg{ \
335b944e2aSmrg    fprintf(stderr, __VA_ARGS__); \
345b944e2aSmrg    return error;\
355b944e2aSmrg}
365b944e2aSmrg/**
375b944e2aSmrg * Create a new master device. Name must be supplied, other values are
385b944e2aSmrg * optional.
395b944e2aSmrg */
405b944e2aSmrgint
415b944e2aSmrgcreate_master(Display* dpy, int argc, char** argv, char* name, char *desc)
425b944e2aSmrg{
4353719b08Smrg    XIAddMasterInfo c;
445b944e2aSmrg
455b944e2aSmrg    if (argc == 0)
465b944e2aSmrg    {
475b944e2aSmrg        fprintf(stderr, "Usage: xinput %s %s\n", name, desc);
485b944e2aSmrg        return EXIT_FAILURE;
495b944e2aSmrg    }
505b944e2aSmrg
5153719b08Smrg    c.type = XIAddMaster;
525b944e2aSmrg    c.name = argv[0];
5353719b08Smrg    c.send_core = (argc >= 2) ? atoi(argv[1]) : 1;
545b944e2aSmrg    c.enable = (argc >= 3) ? atoi(argv[2]) : 1;
555b944e2aSmrg
5653719b08Smrg    return XIChangeHierarchy(dpy, (XIAnyHierarchyChangeInfo*)&c, 1);
575b944e2aSmrg}
585b944e2aSmrg
595b944e2aSmrg/**
605b944e2aSmrg * Remove a master device.
615b944e2aSmrg * By default, all attached devices are set to Floating, unless parameters are
625b944e2aSmrg * given.
635b944e2aSmrg */
645b944e2aSmrgint
655b944e2aSmrgremove_master(Display* dpy, int argc, char** argv, char *name, char *desc)
665b944e2aSmrg{
6753719b08Smrg    XIRemoveMasterInfo r;
6853719b08Smrg    XIDeviceInfo *info;
695b944e2aSmrg    int ret;
705b944e2aSmrg
715b944e2aSmrg    if (argc == 0)
725b944e2aSmrg    {
735b944e2aSmrg        fprintf(stderr, "usage: xinput %s %s\n", name, desc);
745b944e2aSmrg        return EXIT_FAILURE;
755b944e2aSmrg    }
765b944e2aSmrg
7753719b08Smrg    info = xi2_find_device_info(dpy, argv[0]);
785b944e2aSmrg
795b944e2aSmrg    if (!info) {
805b944e2aSmrg	fprintf(stderr, "unable to find device %s\n", argv[0]);
815b944e2aSmrg	return EXIT_FAILURE;
825b944e2aSmrg    }
835b944e2aSmrg
8453719b08Smrg    r.type = XIRemoveMaster;
8553719b08Smrg    r.deviceid = info->deviceid;
865b944e2aSmrg    if (argc >= 2)
875b944e2aSmrg    {
885b944e2aSmrg        if (!strcmp(argv[1], "Floating"))
8953719b08Smrg            r.return_mode = XIFloating;
905b944e2aSmrg        else if (!strcmp(argv[1], "AttachToMaster"))
9153719b08Smrg            r.return_mode = XIAttachToMaster;
925b944e2aSmrg        else
9353719b08Smrg            Error(BadValue, "Invalid return_mode.\n");
945b944e2aSmrg    } else
9553719b08Smrg        r.return_mode = XIFloating;
965b944e2aSmrg
9753719b08Smrg    if (r.return_mode == XIAttachToMaster)
985b944e2aSmrg    {
9953719b08Smrg        r.return_pointer = 0;
10053719b08Smrg        if (argc >= 3) {
10153719b08Smrg            info = xi2_find_device_info(dpy, argv[2]);
10253719b08Smrg            if (!info) {
10353719b08Smrg                fprintf(stderr, "unable to find device %s\n", argv[2]);
10453719b08Smrg                return EXIT_FAILURE;
10553719b08Smrg            }
10653719b08Smrg
10753719b08Smrg            r.return_pointer = info->deviceid;
10853719b08Smrg        }
10953719b08Smrg
11053719b08Smrg        r.return_keyboard = 0;
11153719b08Smrg        if (argc >= 4) {
11253719b08Smrg            info = xi2_find_device_info(dpy, argv[3]);
11353719b08Smrg            if (!info) {
11453719b08Smrg                fprintf(stderr, "unable to find device %s\n", argv[3]);
11553719b08Smrg                return EXIT_FAILURE;
11653719b08Smrg            }
11753719b08Smrg
11853719b08Smrg            r.return_keyboard = info->deviceid;
11953719b08Smrg        }
12053719b08Smrg
12153719b08Smrg        if (!r.return_pointer || !r.return_keyboard) {
12253719b08Smrg            int i, ndevices;
12353719b08Smrg            info = XIQueryDevice(dpy, XIAllMasterDevices, &ndevices);
12453719b08Smrg            for(i = 0; i < ndevices; i++) {
12553719b08Smrg                if (info[i].use == XIMasterPointer && !r.return_pointer)
12653719b08Smrg                    r.return_pointer = info[i].deviceid;
12753719b08Smrg                if (info[i].use == XIMasterKeyboard && !r.return_keyboard)
12853719b08Smrg                    r.return_keyboard = info[i].deviceid;
12953719b08Smrg                if (r.return_pointer && r.return_keyboard)
13053719b08Smrg                    break;
13153719b08Smrg            }
13253719b08Smrg
13353719b08Smrg            XIFreeDeviceInfo(info);
13453719b08Smrg        }
1355b944e2aSmrg    }
1365b944e2aSmrg
13753719b08Smrg    ret = XIChangeHierarchy(dpy, (XIAnyHierarchyChangeInfo*)&r, 1);
1385b944e2aSmrg    return ret;
1395b944e2aSmrg}
1405b944e2aSmrg
1415b944e2aSmrg/**
1425b944e2aSmrg * Swap a device from one master to another.
1435b944e2aSmrg */
1445b944e2aSmrgint
1455b944e2aSmrgchange_attachment(Display* dpy, int argc, char** argv, char *name, char* desc)
1465b944e2aSmrg{
14753719b08Smrg    XIDeviceInfo *sd_info, *md_info;
14853719b08Smrg    XIAttachSlaveInfo c;
1495b944e2aSmrg    int ret;
1505b944e2aSmrg
1515b944e2aSmrg    if (argc < 2)
1525b944e2aSmrg    {
1535b944e2aSmrg        fprintf(stderr, "usage: xinput %s %s\n", name, desc);
1545b944e2aSmrg        return EXIT_FAILURE;
1555b944e2aSmrg    }
1565b944e2aSmrg
15753719b08Smrg    sd_info = xi2_find_device_info(dpy, argv[0]);
15853719b08Smrg    md_info= xi2_find_device_info(dpy, argv[1]);
1595b944e2aSmrg
16053719b08Smrg    if (!sd_info) {
1615b944e2aSmrg	fprintf(stderr, "unable to find device %s\n", argv[0]);
1625b944e2aSmrg	return EXIT_FAILURE;
1635b944e2aSmrg    }
1645b944e2aSmrg
16553719b08Smrg    if (!md_info) {
1665b944e2aSmrg	fprintf(stderr, "unable to find device %s\n", argv[1]);
1675b944e2aSmrg	return EXIT_FAILURE;
1685b944e2aSmrg    }
1695b944e2aSmrg
17053719b08Smrg    c.type = XIAttachSlave;
17153719b08Smrg    c.deviceid = sd_info->deviceid;
17253719b08Smrg    c.new_master = md_info->deviceid;
1735b944e2aSmrg
17453719b08Smrg    ret = XIChangeHierarchy(dpy, (XIAnyHierarchyChangeInfo*)&c, 1);
1755b944e2aSmrg    return ret;
1765b944e2aSmrg}
1775b944e2aSmrg
1785b944e2aSmrg/**
1795b944e2aSmrg * Set a device floating.
1805b944e2aSmrg */
1815b944e2aSmrgint
1825b944e2aSmrgfloat_device(Display* dpy, int argc, char** argv, char* name, char* desc)
1835b944e2aSmrg{
18453719b08Smrg    XIDeviceInfo *info;
18553719b08Smrg    XIDetachSlaveInfo c;
1865b944e2aSmrg    int ret;
1875b944e2aSmrg
1885b944e2aSmrg    if (argc < 1)
1895b944e2aSmrg    {
1905b944e2aSmrg        fprintf(stderr, "usage: xinput %s %s\n", name, desc);
1915b944e2aSmrg        return EXIT_FAILURE;
1925b944e2aSmrg    }
1935b944e2aSmrg
19453719b08Smrg    info = xi2_find_device_info(dpy, argv[0]);
1955b944e2aSmrg
1965b944e2aSmrg    if (!info) {
1975b944e2aSmrg	fprintf(stderr, "unable to find device %s\n", argv[0]);
1985b944e2aSmrg	return EXIT_FAILURE;
1995b944e2aSmrg    }
2005b944e2aSmrg
20153719b08Smrg    c.type = XIDetachSlave;
20253719b08Smrg    c.deviceid = info->deviceid;
2035b944e2aSmrg
20453719b08Smrg    ret = XIChangeHierarchy(dpy, (XIAnyHierarchyChangeInfo*)&c, 1);
2055b944e2aSmrg    return ret;
2065b944e2aSmrg}
2075b944e2aSmrg
2085b944e2aSmrg
209