xinput.c revision d3263506
1/* 2 * Copyright 1996 by Frederic Lepied, France. <Frederic.Lepied@sugix.frmug.org> 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of the authors not be used in 9 * advertising or publicity pertaining to distribution of the software without 10 * specific, written prior permission. The authors make no 11 * representations about the suitability of this software for any purpose. It 12 * is provided "as is" without express or implied warranty. 13 * 14 * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 * 22 */ 23 24#include "xinput.h" 25#include <ctype.h> 26#include <string.h> 27 28typedef int (*prog)( 29#if NeedFunctionPrototypes 30 Display* display, int argc, char *argv[], 31 char *prog_name, char *prog_desc 32#endif 33); 34 35typedef struct 36{ 37 char *func_name; 38 char *arg_desc; 39 prog func; 40} entry; 41 42static entry drivers[] = 43{ 44 {"get-feedbacks", 45 "<device name>", 46 get_feedbacks 47 }, 48 {"set-ptr-feedback", 49 "<device name> <threshold> <num> <denom>", 50 set_ptr_feedback 51 }, 52 {"set-integer-feedback", 53 "<device name> <feedback id> <value>", 54 set_integer_feedback 55 }, 56 {"get-button-map", 57 "<device name>", 58 get_button_map 59 }, 60 {"set-button-map", 61 "<device name> <map button 1> [<map button 2> [...]]", 62 set_button_map 63 }, 64 {"set-pointer", 65 "<device name> [<x index> <y index>]", 66 set_pointer 67 }, 68 {"set-mode", 69 "<device name> ABSOLUTE|RELATIVE", 70 set_mode 71 }, 72 {"list", 73 "[--loop || --short || <device name>...]", 74 list 75 }, 76 {"query-state", 77 "<device name>", 78 query_state 79 }, 80 {"test", 81 "[-proximity] <device name>", 82 test 83 }, 84 {"version", 85 "", 86 version 87 }, 88#if HAVE_XI2 89 { "create-master", 90 "<id> [sendCore (dflt:1)] [enable (dflt:1)]", 91 create_master 92 }, 93 { "remove-master", 94 "<id> [returnMode (dflt:Floating)] [returnPointer] [returnKeyboard]", 95 remove_master 96 }, 97 { "reattach", 98 "<id> <master>", 99 change_attachment 100 }, 101 { "float", 102 "<id>", 103 float_device 104 }, 105 { "set-cp", 106 "<window> <device>", 107 set_clientpointer 108 }, 109#endif 110 { "list-props", 111 "<device> [<device> ...]", 112 list_props 113 }, 114 { "set-int-prop", 115 "<device> <property> <format (8, 16, 32)> <val> [<val> ...]", 116 set_int_prop 117 }, 118 { "set-float-prop", 119 "<device> <property> <val> [<val> ...]", 120 set_float_prop 121 }, 122 { "set-atom-prop", 123 "<device> <property> <val> [<val> ...]", 124 set_atom_prop 125 }, 126 { "watch-props", 127 "<device>", 128 watch_props 129 }, 130 { "delete-prop", 131 "<device> <property>", 132 delete_prop 133 }, 134 {NULL, NULL, NULL 135 } 136}; 137 138static Bool 139is_xinput_present(Display *display) 140{ 141 XExtensionVersion *version; 142 Bool present; 143 144#if HAVE_XI2 145 version = XQueryInputVersion(display, XI_2_Major, XI_2_Minor); 146#else 147 version = XGetExtensionVersion(display, INAME); 148#endif 149 150 if (version && (version != (XExtensionVersion*) NoSuchExtension)) { 151 present = version->present; 152 XFree(version); 153 return present; 154 } else { 155 return False; 156 } 157} 158 159XDeviceInfo* 160find_device_info(Display *display, 161 char *name, 162 Bool only_extended) 163{ 164 XDeviceInfo *devices; 165 XDeviceInfo *found = NULL; 166 int loop; 167 int num_devices; 168 int len = strlen(name); 169 Bool is_id = True; 170 XID id = (XID)-1; 171 172 for(loop=0; loop<len; loop++) { 173 if (!isdigit(name[loop])) { 174 is_id = False; 175 break; 176 } 177 } 178 179 if (is_id) { 180 id = atoi(name); 181 } 182 183 devices = XListInputDevices(display, &num_devices); 184 185 for(loop=0; loop<num_devices; loop++) { 186 if ((!only_extended || (devices[loop].use >= IsXExtensionDevice)) && 187 ((!is_id && strcmp(devices[loop].name, name) == 0) || 188 (is_id && devices[loop].id == id))) { 189 if (found) { 190 fprintf(stderr, 191 "Warning: There are multiple devices named \"%s\".\n" 192 "To ensure the correct one is selected, please use " 193 "the device ID instead.\n\n", name); 194 return NULL; 195 } else { 196 found = &devices[loop]; 197 } 198 } 199 } 200 return found; 201} 202 203static void 204usage(void) 205{ 206 entry *pdriver = drivers; 207 208 fprintf(stderr, "usage :\n"); 209 210 while(pdriver->func_name) { 211 fprintf(stderr, "\txinput %s %s\n", pdriver->func_name, 212 pdriver->arg_desc); 213 pdriver++; 214 } 215} 216 217int 218main(int argc, char * argv[]) 219{ 220 Display *display; 221 entry *driver = drivers; 222 char *func; 223 224 if (argc < 2) { 225 usage(); 226 return EXIT_FAILURE; 227 } 228 229 display = XOpenDisplay(NULL); 230 231 if (display == NULL) { 232 fprintf(stderr, "Unable to connect to X server\n"); 233 return EXIT_FAILURE; 234 } 235 236 func = argv[1]; 237 while((*func) == '-') func++; 238 239 if (!is_xinput_present(display)) { 240 fprintf(stderr, "%s extension not available\n", INAME); 241 return EXIT_FAILURE; 242 } 243 244 while(driver->func_name) { 245 if (strcmp(driver->func_name, func) == 0) { 246 int r = (*driver->func)(display, argc-2, argv+2, 247 driver->func_name, driver->arg_desc); 248 XSync(display, False); 249 XCloseDisplay(display); 250 return r; 251 } 252 driver++; 253 } 254 255 usage(); 256 257 return EXIT_FAILURE; 258} 259 260/* end of xinput.c */ 261