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