hierarchy.c revision 5b944e2a
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{
435b944e2aSmrg    XCreateMasterInfo c;
445b944e2aSmrg
455b944e2aSmrg    if (argc == 0)
465b944e2aSmrg    {
475b944e2aSmrg        fprintf(stderr, "Usage: xinput %s %s\n", name, desc);
485b944e2aSmrg        return EXIT_FAILURE;
495b944e2aSmrg    }
505b944e2aSmrg
515b944e2aSmrg    c.type = CH_CreateMasterDevice;
525b944e2aSmrg    c.name = argv[0];
535b944e2aSmrg    c.sendCore = (argc >= 2) ? atoi(argv[1]) : 1;
545b944e2aSmrg    c.enable = (argc >= 3) ? atoi(argv[2]) : 1;
555b944e2aSmrg
565b944e2aSmrg    return XChangeDeviceHierarchy(dpy, (XAnyHierarchyChangeInfo*)&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{
675b944e2aSmrg    XDeviceInfo *info;
685b944e2aSmrg    XRemoveMasterInfo r;
695b944e2aSmrg    XDevice* master = NULL, *ptr = NULL, *keybd = NULL;
705b944e2aSmrg    int ret;
715b944e2aSmrg
725b944e2aSmrg    if (argc == 0)
735b944e2aSmrg    {
745b944e2aSmrg        fprintf(stderr, "usage: xinput %s %s\n", name, desc);
755b944e2aSmrg        return EXIT_FAILURE;
765b944e2aSmrg    }
775b944e2aSmrg
785b944e2aSmrg    info = find_device_info(dpy, argv[0], False);
795b944e2aSmrg
805b944e2aSmrg    if (!info) {
815b944e2aSmrg	fprintf(stderr, "unable to find device %s\n", argv[0]);
825b944e2aSmrg	return EXIT_FAILURE;
835b944e2aSmrg    }
845b944e2aSmrg
855b944e2aSmrg    master = XOpenDevice(dpy, info->id);
865b944e2aSmrg    if (!master)
875b944e2aSmrg        Error(BadValue, "Unable to open device %s.\n", argv[0]);
885b944e2aSmrg
895b944e2aSmrg    r.type = CH_RemoveMasterDevice;
905b944e2aSmrg    r.device = master;
915b944e2aSmrg    if (argc >= 2)
925b944e2aSmrg    {
935b944e2aSmrg        if (!strcmp(argv[1], "Floating"))
945b944e2aSmrg            r.returnMode = Floating;
955b944e2aSmrg        else if (!strcmp(argv[1], "AttachToMaster"))
965b944e2aSmrg            r.returnMode = AttachToMaster;
975b944e2aSmrg        else
985b944e2aSmrg            Error(BadValue, "Invalid returnMode.\n");
995b944e2aSmrg    } else
1005b944e2aSmrg        r.returnMode = Floating;
1015b944e2aSmrg
1025b944e2aSmrg    if (r.returnMode == AttachToMaster)
1035b944e2aSmrg    {
1045b944e2aSmrg        ptr = XOpenDevice(dpy, atoi(argv[2]));
1055b944e2aSmrg        keybd = XOpenDevice(dpy, atoi(argv[3]));
1065b944e2aSmrg        if (!ptr || !keybd)
1075b944e2aSmrg            Error(BadValue, "Invalid fallback master.\n");
1085b944e2aSmrg        r.returnPointer = ptr;
1095b944e2aSmrg        r.returnKeyboard = keybd;
1105b944e2aSmrg    }
1115b944e2aSmrg
1125b944e2aSmrg    ret = XChangeDeviceHierarchy(dpy, (XAnyHierarchyChangeInfo*)&r, 1);
1135b944e2aSmrg    if (ptr)
1145b944e2aSmrg        XCloseDevice(dpy, ptr);
1155b944e2aSmrg    if (keybd)
1165b944e2aSmrg        XCloseDevice(dpy, keybd);
1175b944e2aSmrg    return ret;
1185b944e2aSmrg}
1195b944e2aSmrg
1205b944e2aSmrg/**
1215b944e2aSmrg * Swap a device from one master to another.
1225b944e2aSmrg */
1235b944e2aSmrgint
1245b944e2aSmrgchange_attachment(Display* dpy, int argc, char** argv, char *name, char* desc)
1255b944e2aSmrg{
1265b944e2aSmrg    XDeviceInfo *info_sd, *info_md;
1275b944e2aSmrg    XChangeAttachmentInfo c;
1285b944e2aSmrg    XDevice *slave, *master;
1295b944e2aSmrg    int ret;
1305b944e2aSmrg
1315b944e2aSmrg    if (argc < 2)
1325b944e2aSmrg    {
1335b944e2aSmrg        fprintf(stderr, "usage: xinput %s %s\n", name, desc);
1345b944e2aSmrg        return EXIT_FAILURE;
1355b944e2aSmrg    }
1365b944e2aSmrg
1375b944e2aSmrg    info_sd = find_device_info(dpy, argv[0], True);
1385b944e2aSmrg    info_md = find_device_info(dpy, argv[1], False);
1395b944e2aSmrg
1405b944e2aSmrg    if (!info_sd) {
1415b944e2aSmrg	fprintf(stderr, "unable to find device %s\n", argv[0]);
1425b944e2aSmrg	return EXIT_FAILURE;
1435b944e2aSmrg    }
1445b944e2aSmrg
1455b944e2aSmrg    if (!info_md) {
1465b944e2aSmrg	fprintf(stderr, "unable to find device %s\n", argv[1]);
1475b944e2aSmrg	return EXIT_FAILURE;
1485b944e2aSmrg    }
1495b944e2aSmrg
1505b944e2aSmrg    slave = XOpenDevice(dpy, info_sd->id);
1515b944e2aSmrg    master = XOpenDevice(dpy, info_md->id);
1525b944e2aSmrg
1535b944e2aSmrg    if (!slave)
1545b944e2aSmrg        Error(BadValue, "Invalid slave device given %d\n", atoi(argv[0]));
1555b944e2aSmrg
1565b944e2aSmrg    if (!master)
1575b944e2aSmrg        Error(BadValue, "Invalid master device given %d\n", atoi(argv[1]));
1585b944e2aSmrg
1595b944e2aSmrg    c.type = CH_ChangeAttachment;
1605b944e2aSmrg    c.changeMode = AttachToMaster;
1615b944e2aSmrg    c.device = slave;
1625b944e2aSmrg    c.newMaster = master;
1635b944e2aSmrg
1645b944e2aSmrg    ret = XChangeDeviceHierarchy(dpy, (XAnyHierarchyChangeInfo*)&c, 1);
1655b944e2aSmrg    XCloseDevice(dpy, slave);
1665b944e2aSmrg    XCloseDevice(dpy, master);
1675b944e2aSmrg    return ret;
1685b944e2aSmrg}
1695b944e2aSmrg
1705b944e2aSmrg/**
1715b944e2aSmrg * Set a device floating.
1725b944e2aSmrg */
1735b944e2aSmrgint
1745b944e2aSmrgfloat_device(Display* dpy, int argc, char** argv, char* name, char* desc)
1755b944e2aSmrg{
1765b944e2aSmrg    XDeviceInfo *info;
1775b944e2aSmrg    XChangeAttachmentInfo c;
1785b944e2aSmrg    XDevice *slave;
1795b944e2aSmrg    int ret;
1805b944e2aSmrg
1815b944e2aSmrg    if (argc < 1)
1825b944e2aSmrg    {
1835b944e2aSmrg        fprintf(stderr, "usage: xinput %s %s\n", name, desc);
1845b944e2aSmrg        return EXIT_FAILURE;
1855b944e2aSmrg    }
1865b944e2aSmrg
1875b944e2aSmrg    info = find_device_info(dpy, argv[0], True);
1885b944e2aSmrg
1895b944e2aSmrg    if (!info) {
1905b944e2aSmrg	fprintf(stderr, "unable to find device %s\n", argv[0]);
1915b944e2aSmrg	return EXIT_FAILURE;
1925b944e2aSmrg    }
1935b944e2aSmrg
1945b944e2aSmrg    slave = XOpenDevice(dpy, info->id);
1955b944e2aSmrg
1965b944e2aSmrg    if (!slave)
1975b944e2aSmrg        return BadValue;
1985b944e2aSmrg
1995b944e2aSmrg    c.type = CH_ChangeAttachment;
2005b944e2aSmrg    c.changeMode = Floating;
2015b944e2aSmrg    c.device = slave;
2025b944e2aSmrg
2035b944e2aSmrg    ret = XChangeDeviceHierarchy(dpy, (XAnyHierarchyChangeInfo*)&c, 1);
2045b944e2aSmrg    XCloseDevice(dpy, slave);
2055b944e2aSmrg    return ret;
2065b944e2aSmrg}
2075b944e2aSmrg
2085b944e2aSmrg
209