]> diplodocus.org Git - xorg-xinput/blobdiff - src/xinput.c
xinput 1.5.0
[xorg-xinput] / src / xinput.c
index 8275d1896cfb8b1c5ed22819e7c153458863a6a0..149662d2068c4fb8878e91fa565aa65962afc0a0 100644 (file)
@@ -1,19 +1,19 @@
 /*
  * Copyright 1996 by Frederic Lepied, France. <Frederic.Lepied@sugix.frmug.org>
- *                                                                            
+ *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is  hereby granted without fee, provided that
  * the  above copyright   notice appear  in   all  copies and  that both  that
  * copyright  notice   and   this  permission   notice  appear  in  supporting
- * documentation, and that   the  name of  Frederic   Lepied not  be  used  in
+ * documentation, and that   the  name of  the authors  not  be  used  in
  * advertising or publicity pertaining to distribution of the software without
- * specific,  written      prior  permission.     Frederic  Lepied   makes  no
+ * specific,  written      prior  permission.     The authors  make  no
  * representations about the suitability of this software for any purpose.  It
- * is provided "as is" without express or implied warranty.                   
- *                                                                            
- * FREDERIC  LEPIED DISCLAIMS ALL   WARRANTIES WITH REGARD  TO  THIS SOFTWARE,
+ * is provided "as is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL   WARRANTIES WITH REGARD  TO  THIS SOFTWARE,
  * INCLUDING ALL IMPLIED   WARRANTIES OF MERCHANTABILITY  AND   FITNESS, IN NO
- * EVENT  SHALL FREDERIC  LEPIED BE   LIABLE   FOR ANY  SPECIAL, INDIRECT   OR
+ * EVENT  SHALL THE AUTHORS  BE   LIABLE   FOR ANY  SPECIAL, INDIRECT   OR
  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  * DATA  OR PROFITS, WHETHER  IN  AN ACTION OF  CONTRACT,  NEGLIGENCE OR OTHER
  * TORTIOUS  ACTION, ARISING    OUT OF OR   IN  CONNECTION  WITH THE USE    OR
 #include <ctype.h>
 #include <string.h>
 
-typedef int (*prog)(
-#if NeedFunctionPrototypes
-                   Display* display, int argc, char *argv[],
-                   char *prog_name, char *prog_desc
-#endif
-);
+int xi_opcode;
 
-typedef struct 
+typedef int (*prog)(Display* display, int argc, char *argv[],
+                   char *prog_name, char *prog_desc);
+
+typedef struct
 {
     char       *func_name;
     char       *arg_desc;
@@ -53,6 +51,10 @@ static entry drivers[] =
      "<device name> <feedback id> <value>",
      set_integer_feedback
     },
+    {"get-button-map",
+     "<device name>",
+     get_button_map
+    },
     {"set-button-map",
      "<device name> <map button 1> [<map button 2> [...]]",
      set_button_map
@@ -66,7 +68,7 @@ static entry drivers[] =
      set_mode
     },
     {"list",
-     "[<device name>...]",
+     "[--short || --long] [<device name>...]",
      list
     },
     {"query-state",
@@ -77,29 +79,112 @@ static entry drivers[] =
      "[-proximity] <device name>",
      test
     },
-    {"version",
-     "",
-     version
+#if HAVE_XI2
+    { "create-master",
+      "<id> [<sendCore (dflt:1)>] [<enable (dflt:1)>]",
+      create_master
+    },
+    { "remove-master",
+      "<id> [Floating|AttachToMaster (dflt:Floating)] [<returnPointer>] [<returnKeyboard>]",
+      remove_master
+    },
+    { "reattach",
+      "<id> <master>",
+      change_attachment
+    },
+    { "float",
+      "<id>",
+      float_device
+    },
+    { "set-cp",
+      "<window> <device>",
+      set_clientpointer
+    },
+    { "test-xi2",
+      "<device>",
+      test_xi2,
+    },
+#endif
+    { "list-props",
+      "<device> [<device> ...]",
+      list_props
+    },
+    { "set-int-prop",
+      "<device> <property> <format (8, 16, 32)> <val> [<val> ...]",
+      set_int_prop
+    },
+    { "set-float-prop",
+      "<device> <property> <val> [<val> ...]",
+      set_float_prop
+    },
+    { "set-atom-prop",
+      "<device> <property> <val> [<val> ...]",
+      set_atom_prop
+    },
+    { "watch-props",
+      "<device>",
+      watch_props
+    },
+    { "delete-prop",
+      "<device> <property>",
+      delete_prop
     },
-    {0, 0, 0
+    { "set-prop",
+      "<device> [--type=atom|float|int] [--format=8|16|32] <property> <val> [<val> ...]",
+      set_prop
+    },
+    {NULL, NULL, NULL
     }
 };
 
-static Bool
-is_xinput_present(Display      *display)
+static const char version_id[] = VERSION;
+
+int
+print_version()
 {
     XExtensionVersion  *version;
-    Bool               present;
-    
+    Display *display;
+
+    printf("xinput version %s\n", version_id);
+
+    display = XOpenDisplay(NULL);
+
+    printf("XI version on server: ");
+
+    if (display == NULL)
+        printf("Failed to open display.\n");
+    else {
+        version = XGetExtensionVersion(display, INAME);
+        if (!version || (version == (XExtensionVersion*) NoSuchExtension))
+            printf(" Extension not supported.\n");
+        else {
+            printf("%d.%d\n", version->major_version,
+                    version->minor_version);
+            XFree(version);
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+int
+xinput_version(Display *display)
+{
+    XExtensionVersion  *version;
+    static int vers = -1;
+
+    if (vers != -1)
+        return vers;
+
     version = XGetExtensionVersion(display, INAME);
 
     if (version && (version != (XExtensionVersion*) NoSuchExtension)) {
-       present = version->present;
+       vers = version->major_version;
        XFree(version);
-       return present;
-    } else {
-       return False;
     }
+
+    return vers;
 }
 
 XDeviceInfo*
@@ -108,12 +193,13 @@ find_device_info(Display  *display,
                 Bool           only_extended)
 {
     XDeviceInfo        *devices;
+    XDeviceInfo *found = NULL;
     int                loop;
     int                num_devices;
     int                len = strlen(name);
     Bool       is_id = True;
-    XID                id;
-    
+    XID                id = (XID)-1;
+
     for(loop=0; loop<len; loop++) {
        if (!isdigit(name[loop])) {
            is_id = False;
@@ -124,26 +210,69 @@ find_device_info(Display  *display,
     if (is_id) {
        id = atoi(name);
     }
-    
+
     devices = XListInputDevices(display, &num_devices);
 
     for(loop=0; loop<num_devices; loop++) {
        if ((!only_extended || (devices[loop].use >= IsXExtensionDevice)) &&
            ((!is_id && strcmp(devices[loop].name, name) == 0) ||
             (is_id && devices[loop].id == id))) {
-           return &devices[loop];
+           if (found) {
+               fprintf(stderr,
+                       "Warning: There are multiple devices named \"%s\".\n"
+                       "To ensure the correct one is selected, please use "
+                       "the device ID instead.\n\n", name);
+               return NULL;
+           } else {
+               found = &devices[loop];
+           }
+       }
+    }
+    return found;
+}
+
+#ifdef HAVE_XI2
+XIDeviceInfo*
+xi2_find_device_info(Display *display, char *name)
+{
+    XIDeviceInfo *info;
+    int ndevices;
+    Bool is_id = True;
+    int i, id = -1;
+
+    for(i = 0; i < strlen(name); i++) {
+       if (!isdigit(name[i])) {
+           is_id = False;
+           break;
        }
     }
+
+    if (is_id) {
+       id = atoi(name);
+    }
+
+    info = XIQueryDevice(display, XIAllDevices, &ndevices);
+    for(i = 0; i < ndevices; i++)
+    {
+        if ((is_id && info[i].deviceid == id) ||
+                (!is_id && strcmp(info[i].name, name) == 0))
+        {
+            return &info[i];
+        }
+    }
+
+    XIFreeDeviceInfo(info);
     return NULL;
 }
+#endif
 
 static void
-usage(
+usage(void)
 {
     entry      *pdriver = drivers;
-    
+
     fprintf(stderr, "usage :\n");
-    
+
     while(pdriver->func_name) {
        fprintf(stderr, "\txinput %s %s\n", pdriver->func_name,
                pdriver->arg_desc);
@@ -157,39 +286,50 @@ main(int argc, char * argv[])
     Display    *display;
     entry      *driver = drivers;
     char        *func;
-    
+    int event, error;
+
     if (argc < 2) {
        usage();
        return EXIT_FAILURE;
     }
-    
+
+    func = argv[1];
+    while((*func) == '-') func++;
+
+    if (strcmp("version", func) == 0) {
+        return print_version(argv[0]);
+    }
+
     display = XOpenDisplay(NULL);
-    
+
     if (display == NULL) {
        fprintf(stderr, "Unable to connect to X server\n");
        return EXIT_FAILURE;
     }
 
-    func = argv[1];
-    while((*func) == '-') func++;
+    if (!XQueryExtension(display, "XInputExtension", &xi_opcode, &event, &error)) {
+        printf("X Input extension not available.\n");
+        return EXIT_FAILURE;
+    }
 
-    if (!is_xinput_present(display)) {
+    if (!xinput_version(display)) {
        fprintf(stderr, "%s extension not available\n", INAME);
        return EXIT_FAILURE;
     }
-    
+
     while(driver->func_name) {
        if (strcmp(driver->func_name, func) == 0) {
            int r = (*driver->func)(display, argc-2, argv+2,
                                    driver->func_name, driver->arg_desc);
-           XFlush(display);
+           XSync(display, False);
+           XCloseDisplay(display);
            return r;
        }
        driver++;
     }
-    
+
     usage();
-    
+
     return EXIT_FAILURE;
 }