15b944e2aSmrg/*
20309d3b3Smrg * Copyright © 2007 Peter Hutterer
30309d3b3Smrg * Copyright © 2009 Red Hat, Inc.
45b944e2aSmrg *
50309d3b3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
60309d3b3Smrg * copy of this software and associated documentation files (the "Software"),
70309d3b3Smrg * to deal in the Software without restriction, including without limitation
80309d3b3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
90309d3b3Smrg * and/or sell copies of the Software, and to permit persons to whom the
100309d3b3Smrg * Software is furnished to do so, subject to the following conditions:
115b944e2aSmrg *
120309d3b3Smrg * The above copyright notice and this permission notice (including the next
130309d3b3Smrg * paragraph) shall be included in all copies or substantial portions of the
140309d3b3Smrg * Software.
155b944e2aSmrg *
160309d3b3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
170309d3b3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
180309d3b3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
190309d3b3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
200309d3b3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
210309d3b3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
220309d3b3Smrg * DEALINGS IN THE SOFTWARE.
235b944e2aSmrg */
245b944e2aSmrg
255b944e2aSmrg#include "xinput.h"
265b944e2aSmrg#include <string.h>
275b944e2aSmrg
285b944e2aSmrg#define Error(error, ...) \
295b944e2aSmrg{ \
305b944e2aSmrg    fprintf(stderr, __VA_ARGS__); \
315b944e2aSmrg    return error;\
325b944e2aSmrg}
335b944e2aSmrg/**
345b944e2aSmrg * Create a new master device. Name must be supplied, other values are
355b944e2aSmrg * optional.
365b944e2aSmrg */
375b944e2aSmrgint
385b944e2aSmrgcreate_master(Display* dpy, int argc, char** argv, char* name, char *desc)
395b944e2aSmrg{
4053719b08Smrg    XIAddMasterInfo c;
415b944e2aSmrg
425b944e2aSmrg    if (argc == 0)
435b944e2aSmrg    {
445b944e2aSmrg        fprintf(stderr, "Usage: xinput %s %s\n", name, desc);
455b944e2aSmrg        return EXIT_FAILURE;
465b944e2aSmrg    }
475b944e2aSmrg
4853719b08Smrg    c.type = XIAddMaster;
495b944e2aSmrg    c.name = argv[0];
5053719b08Smrg    c.send_core = (argc >= 2) ? atoi(argv[1]) : 1;
515b944e2aSmrg    c.enable = (argc >= 3) ? atoi(argv[2]) : 1;
525b944e2aSmrg
5353719b08Smrg    return XIChangeHierarchy(dpy, (XIAnyHierarchyChangeInfo*)&c, 1);
545b944e2aSmrg}
555b944e2aSmrg
565b944e2aSmrg/**
575b944e2aSmrg * Remove a master device.
585b944e2aSmrg * By default, all attached devices are set to Floating, unless parameters are
595b944e2aSmrg * given.
605b944e2aSmrg */
615b944e2aSmrgint
625b944e2aSmrgremove_master(Display* dpy, int argc, char** argv, char *name, char *desc)
635b944e2aSmrg{
6453719b08Smrg    XIRemoveMasterInfo r;
6553719b08Smrg    XIDeviceInfo *info;
665b944e2aSmrg    int ret;
675b944e2aSmrg
685b944e2aSmrg    if (argc == 0)
695b944e2aSmrg    {
705b944e2aSmrg        fprintf(stderr, "usage: xinput %s %s\n", name, desc);
715b944e2aSmrg        return EXIT_FAILURE;
725b944e2aSmrg    }
735b944e2aSmrg
7453719b08Smrg    info = xi2_find_device_info(dpy, argv[0]);
755b944e2aSmrg
765b944e2aSmrg    if (!info) {
770309d3b3Smrg	fprintf(stderr, "unable to find device '%s'\n", argv[0]);
785b944e2aSmrg	return EXIT_FAILURE;
795b944e2aSmrg    }
805b944e2aSmrg
8153719b08Smrg    r.type = XIRemoveMaster;
8253719b08Smrg    r.deviceid = info->deviceid;
835b944e2aSmrg    if (argc >= 2)
845b944e2aSmrg    {
855b944e2aSmrg        if (!strcmp(argv[1], "Floating"))
8653719b08Smrg            r.return_mode = XIFloating;
875b944e2aSmrg        else if (!strcmp(argv[1], "AttachToMaster"))
8853719b08Smrg            r.return_mode = XIAttachToMaster;
895b944e2aSmrg        else
9053719b08Smrg            Error(BadValue, "Invalid return_mode.\n");
915b944e2aSmrg    } else
9253719b08Smrg        r.return_mode = XIFloating;
935b944e2aSmrg
9453719b08Smrg    if (r.return_mode == XIAttachToMaster)
955b944e2aSmrg    {
9653719b08Smrg        r.return_pointer = 0;
9753719b08Smrg        if (argc >= 3) {
9853719b08Smrg            info = xi2_find_device_info(dpy, argv[2]);
9953719b08Smrg            if (!info) {
1000309d3b3Smrg                fprintf(stderr, "unable to find device '%s'\n", argv[2]);
10153719b08Smrg                return EXIT_FAILURE;
10253719b08Smrg            }
10353719b08Smrg
10453719b08Smrg            r.return_pointer = info->deviceid;
10553719b08Smrg        }
10653719b08Smrg
10753719b08Smrg        r.return_keyboard = 0;
10853719b08Smrg        if (argc >= 4) {
10953719b08Smrg            info = xi2_find_device_info(dpy, argv[3]);
11053719b08Smrg            if (!info) {
1110309d3b3Smrg                fprintf(stderr, "unable to find device '%s'\n", argv[3]);
11253719b08Smrg                return EXIT_FAILURE;
11353719b08Smrg            }
11453719b08Smrg
11553719b08Smrg            r.return_keyboard = info->deviceid;
11653719b08Smrg        }
11753719b08Smrg
11853719b08Smrg        if (!r.return_pointer || !r.return_keyboard) {
11953719b08Smrg            int i, ndevices;
12053719b08Smrg            info = XIQueryDevice(dpy, XIAllMasterDevices, &ndevices);
12153719b08Smrg            for(i = 0; i < ndevices; i++) {
12253719b08Smrg                if (info[i].use == XIMasterPointer && !r.return_pointer)
12353719b08Smrg                    r.return_pointer = info[i].deviceid;
12453719b08Smrg                if (info[i].use == XIMasterKeyboard && !r.return_keyboard)
12553719b08Smrg                    r.return_keyboard = info[i].deviceid;
12653719b08Smrg                if (r.return_pointer && r.return_keyboard)
12753719b08Smrg                    break;
12853719b08Smrg            }
12953719b08Smrg
13053719b08Smrg            XIFreeDeviceInfo(info);
13153719b08Smrg        }
1325b944e2aSmrg    }
1335b944e2aSmrg
13453719b08Smrg    ret = XIChangeHierarchy(dpy, (XIAnyHierarchyChangeInfo*)&r, 1);
1355b944e2aSmrg    return ret;
1365b944e2aSmrg}
1375b944e2aSmrg
1385b944e2aSmrg/**
1395b944e2aSmrg * Swap a device from one master to another.
1405b944e2aSmrg */
1415b944e2aSmrgint
1425b944e2aSmrgchange_attachment(Display* dpy, int argc, char** argv, char *name, char* desc)
1435b944e2aSmrg{
14453719b08Smrg    XIDeviceInfo *sd_info, *md_info;
14553719b08Smrg    XIAttachSlaveInfo c;
1465b944e2aSmrg    int ret;
1475b944e2aSmrg
1485b944e2aSmrg    if (argc < 2)
1495b944e2aSmrg    {
1505b944e2aSmrg        fprintf(stderr, "usage: xinput %s %s\n", name, desc);
1515b944e2aSmrg        return EXIT_FAILURE;
1525b944e2aSmrg    }
1535b944e2aSmrg
15453719b08Smrg    sd_info = xi2_find_device_info(dpy, argv[0]);
15553719b08Smrg    md_info= xi2_find_device_info(dpy, argv[1]);
1565b944e2aSmrg
15753719b08Smrg    if (!sd_info) {
1580309d3b3Smrg	fprintf(stderr, "unable to find device '%s'\n", argv[0]);
1595b944e2aSmrg	return EXIT_FAILURE;
1605b944e2aSmrg    }
1615b944e2aSmrg
16253719b08Smrg    if (!md_info) {
1630309d3b3Smrg	fprintf(stderr, "unable to find device '%s'\n", argv[1]);
1645b944e2aSmrg	return EXIT_FAILURE;
1655b944e2aSmrg    }
1665b944e2aSmrg
16753719b08Smrg    c.type = XIAttachSlave;
16853719b08Smrg    c.deviceid = sd_info->deviceid;
16953719b08Smrg    c.new_master = md_info->deviceid;
1705b944e2aSmrg
17153719b08Smrg    ret = XIChangeHierarchy(dpy, (XIAnyHierarchyChangeInfo*)&c, 1);
1725b944e2aSmrg    return ret;
1735b944e2aSmrg}
1745b944e2aSmrg
1755b944e2aSmrg/**
1765b944e2aSmrg * Set a device floating.
1775b944e2aSmrg */
1785b944e2aSmrgint
1795b944e2aSmrgfloat_device(Display* dpy, int argc, char** argv, char* name, char* desc)
1805b944e2aSmrg{
18153719b08Smrg    XIDeviceInfo *info;
18253719b08Smrg    XIDetachSlaveInfo c;
1835b944e2aSmrg    int ret;
1845b944e2aSmrg
1855b944e2aSmrg    if (argc < 1)
1865b944e2aSmrg    {
1875b944e2aSmrg        fprintf(stderr, "usage: xinput %s %s\n", name, desc);
1885b944e2aSmrg        return EXIT_FAILURE;
1895b944e2aSmrg    }
1905b944e2aSmrg
19153719b08Smrg    info = xi2_find_device_info(dpy, argv[0]);
1925b944e2aSmrg
1935b944e2aSmrg    if (!info) {
1940309d3b3Smrg	fprintf(stderr, "unable to find device '%s'\n", argv[0]);
1955b944e2aSmrg	return EXIT_FAILURE;
1965b944e2aSmrg    }
1975b944e2aSmrg
19853719b08Smrg    c.type = XIDetachSlave;
19953719b08Smrg    c.deviceid = info->deviceid;
2005b944e2aSmrg
20153719b08Smrg    ret = XIChangeHierarchy(dpy, (XIAnyHierarchyChangeInfo*)&c, 1);
2025b944e2aSmrg    return ret;
2035b944e2aSmrg}
2045b944e2aSmrg
2055b944e2aSmrg
206