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