1/* 2 * Copyright © 2007 Peter Hutterer 3 * Copyright © 2009 Red Hat, Inc. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 */ 24 25#include "xinput.h" 26#include <string.h> 27 28#define Error(error, ...) \ 29{ \ 30 fprintf(stderr, __VA_ARGS__); \ 31 return error;\ 32} 33/** 34 * Create a new master device. Name must be supplied, other values are 35 * optional. 36 */ 37int 38create_master(Display* dpy, int argc, char** argv, char* name, char *desc) 39{ 40 XIAddMasterInfo c; 41 42 if (argc == 0) 43 { 44 fprintf(stderr, "Usage: xinput %s %s\n", name, desc); 45 return EXIT_FAILURE; 46 } 47 48 c.type = XIAddMaster; 49 c.name = argv[0]; 50 c.send_core = (argc >= 2) ? atoi(argv[1]) : 1; 51 c.enable = (argc >= 3) ? atoi(argv[2]) : 1; 52 53 return XIChangeHierarchy(dpy, (XIAnyHierarchyChangeInfo*)&c, 1); 54} 55 56/** 57 * Remove a master device. 58 * By default, all attached devices are set to Floating, unless parameters are 59 * given. 60 */ 61int 62remove_master(Display* dpy, int argc, char** argv, char *name, char *desc) 63{ 64 XIRemoveMasterInfo r; 65 XIDeviceInfo *info; 66 int ret; 67 68 if (argc == 0) 69 { 70 fprintf(stderr, "usage: xinput %s %s\n", name, desc); 71 return EXIT_FAILURE; 72 } 73 74 info = xi2_find_device_info(dpy, argv[0]); 75 76 if (!info) { 77 fprintf(stderr, "unable to find device '%s'\n", argv[0]); 78 return EXIT_FAILURE; 79 } 80 81 r.type = XIRemoveMaster; 82 r.deviceid = info->deviceid; 83 if (argc >= 2) 84 { 85 if (!strcmp(argv[1], "Floating")) 86 r.return_mode = XIFloating; 87 else if (!strcmp(argv[1], "AttachToMaster")) 88 r.return_mode = XIAttachToMaster; 89 else 90 Error(BadValue, "Invalid return_mode.\n"); 91 } else 92 r.return_mode = XIFloating; 93 94 if (r.return_mode == XIAttachToMaster) 95 { 96 r.return_pointer = 0; 97 if (argc >= 3) { 98 info = xi2_find_device_info(dpy, argv[2]); 99 if (!info) { 100 fprintf(stderr, "unable to find device '%s'\n", argv[2]); 101 return EXIT_FAILURE; 102 } 103 104 r.return_pointer = info->deviceid; 105 } 106 107 r.return_keyboard = 0; 108 if (argc >= 4) { 109 info = xi2_find_device_info(dpy, argv[3]); 110 if (!info) { 111 fprintf(stderr, "unable to find device '%s'\n", argv[3]); 112 return EXIT_FAILURE; 113 } 114 115 r.return_keyboard = info->deviceid; 116 } 117 118 if (!r.return_pointer || !r.return_keyboard) { 119 int i, ndevices; 120 info = XIQueryDevice(dpy, XIAllMasterDevices, &ndevices); 121 for(i = 0; i < ndevices; i++) { 122 if (info[i].use == XIMasterPointer && !r.return_pointer) 123 r.return_pointer = info[i].deviceid; 124 if (info[i].use == XIMasterKeyboard && !r.return_keyboard) 125 r.return_keyboard = info[i].deviceid; 126 if (r.return_pointer && r.return_keyboard) 127 break; 128 } 129 130 XIFreeDeviceInfo(info); 131 } 132 } 133 134 ret = XIChangeHierarchy(dpy, (XIAnyHierarchyChangeInfo*)&r, 1); 135 return ret; 136} 137 138/** 139 * Swap a device from one master to another. 140 */ 141int 142change_attachment(Display* dpy, int argc, char** argv, char *name, char* desc) 143{ 144 XIDeviceInfo *sd_info, *md_info; 145 XIAttachSlaveInfo c; 146 int ret; 147 148 if (argc < 2) 149 { 150 fprintf(stderr, "usage: xinput %s %s\n", name, desc); 151 return EXIT_FAILURE; 152 } 153 154 sd_info = xi2_find_device_info(dpy, argv[0]); 155 md_info= xi2_find_device_info(dpy, argv[1]); 156 157 if (!sd_info) { 158 fprintf(stderr, "unable to find device '%s'\n", argv[0]); 159 return EXIT_FAILURE; 160 } 161 162 if (!md_info) { 163 fprintf(stderr, "unable to find device '%s'\n", argv[1]); 164 return EXIT_FAILURE; 165 } 166 167 c.type = XIAttachSlave; 168 c.deviceid = sd_info->deviceid; 169 c.new_master = md_info->deviceid; 170 171 ret = XIChangeHierarchy(dpy, (XIAnyHierarchyChangeInfo*)&c, 1); 172 return ret; 173} 174 175/** 176 * Set a device floating. 177 */ 178int 179float_device(Display* dpy, int argc, char** argv, char* name, char* desc) 180{ 181 XIDeviceInfo *info; 182 XIDetachSlaveInfo c; 183 int ret; 184 185 if (argc < 1) 186 { 187 fprintf(stderr, "usage: xinput %s %s\n", name, desc); 188 return EXIT_FAILURE; 189 } 190 191 info = xi2_find_device_info(dpy, argv[0]); 192 193 if (!info) { 194 fprintf(stderr, "unable to find device '%s'\n", argv[0]); 195 return EXIT_FAILURE; 196 } 197 198 c.type = XIDetachSlave; 199 c.deviceid = info->deviceid; 200 201 ret = XIChangeHierarchy(dpy, (XIAnyHierarchyChangeInfo*)&c, 1); 202 return ret; 203} 204 205 206