]> diplodocus.org Git - xorg-xinput/blobdiff - src/list.c
gitlab CI: stop requiring Signed-off-by in commits
[xorg-xinput] / src / list.c
index 6e660ae4d35061d9825183b080d8f101abb9c0c4..38bc777f5d98e31eda1903cbd37ad8f259b7c6a6 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 "xinput.h"
+#include <string.h>
+
+enum print_format {
+    FORMAT_NONE,
+    FORMAT_SHORT,
+    FORMAT_LONG,
+    FORMAT_NAME,
+    FORMAT_ID,
+};
+
 
 static void
-print_info(XDeviceInfo *info)
+print_info(Display* dpy, XDeviceInfo   *info, enum print_format format)
 {
     int                        i,j;
     XAnyClassPtr       any;
@@ -33,9 +43,48 @@ print_info(XDeviceInfo       *info)
     XValuatorInfoPtr   v;
     XAxisInfoPtr       a;
 
-    printf("\"%s\"\tid=%ld\t[%s]\n", info->name, info->id,
-          (info->use == IsXExtensionDevice) ? "XExtensionDevice" :
-          ((info->use == IsXPointer) ? "XPointer" : "XKeyboard"));
+    if (format == FORMAT_NAME)
+    {
+        printf("%s\n", info->name);
+        return;
+    } else if (format == FORMAT_ID)
+    {
+        printf("%ld\n", info->id);
+        return;
+    }
+
+    printf("\"%s\"\tid=%ld\t[", info->name, info->id);
+
+    switch (info->use) {
+    case IsXPointer:
+       printf("XPointer");
+       break;
+    case IsXKeyboard:
+       printf("XKeyboard");
+       break;
+    case IsXExtensionDevice:
+       printf("XExtensionDevice");
+       break;
+    case IsXExtensionKeyboard:
+       printf("XExtensionKeyboard");
+       break;
+    case IsXExtensionPointer:
+       printf("XExtensionPointer");
+       break;
+    default:
+       printf("Unknown class");
+       break;
+    }
+    printf("]\n");
+
+    if (format == FORMAT_SHORT)
+        return;
+
+    if (info->type != None) {
+       char *type = XGetAtomName(dpy, info->type);
+       printf("\tType is %s\n", type);
+       XFree(type);
+    }
 
     if (info->num_classes > 0) {
        any = (XAnyClassPtr) (info->inputclassinfo);
@@ -55,7 +104,7 @@ print_info(XDeviceInfo       *info)
 
            case ValuatorClass:
                v = (XValuatorInfoPtr) any;
-               a = (XAxisInfoPtr) ((char *) v + 
+               a = (XAxisInfoPtr) ((char *) v +
                                    sizeof (XValuatorInfo));
                printf("\tNum_axes is %d\n", v->num_axes);
                printf("\tMode is %s\n", (v->mode == Absolute) ? "Absolute" : "Relative");
@@ -67,7 +116,6 @@ print_info(XDeviceInfo       *info)
                    printf ("\t\tResolution is %d\n", a->resolution);
                }
                break;
-               
            default:
                printf ("unknown class\n");
            }
@@ -76,6 +124,225 @@ print_info(XDeviceInfo     *info)
     }
 }
 
+static int list_xi1(Display     *display,
+                    enum print_format format)
+{
+    XDeviceInfo                *info;
+    int                        loop;
+    int                 num_devices;
+
+    info = XListInputDevices(display, &num_devices);
+    for(loop=0; loop<num_devices; loop++) {
+        print_info(display, info+loop, format);
+    }
+    return EXIT_SUCCESS;
+}
+
+#if HAVE_XI2
+/* also used from test_xi2.c */
+void
+print_classes_xi2(Display* display, XIAnyClassInfo **classes,
+                  int num_classes)
+{
+    int i, j;
+
+    printf("\tReporting %d classes:\n", num_classes);
+    for (i = 0; i < num_classes; i++)
+    {
+        printf("\t\tClass originated from: %d. Type: ", classes[i]->sourceid);
+        switch(classes[i]->type)
+        {
+            case XIButtonClass:
+                {
+                    XIButtonClassInfo *b = (XIButtonClassInfo*)classes[i];
+                    char *name;
+                    printf("XIButtonClass\n");
+                    printf("\t\tButtons supported: %d\n", b->num_buttons);
+                    printf("\t\tButton labels:");
+                    for (j = 0; j < b->num_buttons; j++)
+                    {
+                        name = (b->labels[j]) ? XGetAtomName(display, b->labels[j]) : NULL;
+                        if (name)
+                            printf(" \"%s\"", name);
+                        else
+                            printf(" None");
+                        XFree(name);
+                    }
+                    printf("\n");
+                    printf("\t\tButton state:");
+                    for (j = 0; j < b->state.mask_len * 8; j++)
+                        if (XIMaskIsSet(b->state.mask, j))
+                            printf(" %d", j);
+                    printf("\n");
+
+                }
+                break;
+            case XIKeyClass:
+                {
+                    XIKeyClassInfo *k = (XIKeyClassInfo*)classes[i];
+                    printf("XIKeyClass\n");
+                    printf("\t\tKeycodes supported: %d\n", k->num_keycodes);
+                }
+                break;
+            case XIValuatorClass:
+                {
+                    XIValuatorClassInfo *v = (XIValuatorClassInfo*)classes[i];
+                    char *name = v->label ?  XGetAtomName(display, v->label) : NULL;
+
+                    /* Bug in X servers 1.7..1.8.1, mode was | OutOfProximity */
+                    v->mode &= DeviceMode;
+
+                    printf("XIValuatorClass\n");
+                    printf("\t\tDetail for Valuator %d:\n", v->number);
+                    printf("\t\t  Label: %s\n",  (name) ? name : "None");
+                    printf("\t\t  Range: %f - %f\n", v->min, v->max);
+                    printf("\t\t  Resolution: %d units/m\n", v->resolution);
+                    printf("\t\t  Mode: %s\n", v->mode == Absolute ? "absolute" :
+                            "relative");
+                    if (v->mode == Absolute)
+                        printf("\t\t  Current value: %f\n", v->value);
+                    XFree(name);
+                }
+                break;
+#if HAVE_XI21
+            case XIScrollClass:
+                {
+                    XIScrollClassInfo *s = (XIScrollClassInfo*)classes[i];
+
+                    printf("XIScrollClass\n");
+                    printf("\t\tScroll info for Valuator %d\n", s->number);
+                    printf("\t\t  type: %d (%s)\n", s->scroll_type,
+                           (s->scroll_type == XIScrollTypeHorizontal) ? "horizontal" :
+                              (s->scroll_type == XIScrollTypeVertical) ? "vertical" : "unknown");
+                    printf("\t\t  increment: %f\n", s->increment);
+                    printf("\t\t  flags: 0x%x", s->flags);
+                    if (s->flags) {
+                        printf(" (");
+                        if (s->flags & XIScrollFlagNoEmulation)
+                            printf(" no-emulation ");
+                        if (s->flags & XIScrollFlagPreferred)
+                            printf(" preferred ");
+                        printf(")");
+                    }
+                    printf("\n");
+                }
+                break;
+#endif
+#if HAVE_XI22
+            case XITouchClass:
+                {
+                    XITouchClassInfo *t = (XITouchClassInfo*)classes[i];
+
+                    printf("XITouchClass\n");
+                    printf("\t\tTouch mode: %s\n",
+                           (t->mode == XIDirectTouch) ? "direct" : "dependent");
+                    printf("\t\tMax number of touches: %d\n", t->num_touches);
+                }
+#endif
+        }
+    }
+
+    printf("\n");
+}
+
+static void
+print_info_xi2(Display* display, XIDeviceInfo *dev, enum print_format format)
+{
+    if (format == FORMAT_NAME)
+    {
+        printf("%s\n", dev->name);
+        return;
+    } else if (format == FORMAT_ID)
+    {
+        printf("%d\n", dev->deviceid);
+        return;
+    }
+
+    printf("%-40s\tid=%d\t[", dev->name, dev->deviceid);
+    switch(dev->use)
+    {
+        case XIMasterPointer:
+            printf("master pointer  (%d)]\n", dev->attachment);
+            break;
+        case XIMasterKeyboard:
+            printf("master keyboard (%d)]\n", dev->attachment);
+            break;
+        case XISlavePointer:
+            printf("slave  pointer  (%d)]\n", dev->attachment);
+            break;
+        case XISlaveKeyboard:
+            printf("slave  keyboard (%d)]\n", dev->attachment);
+            break;
+        case XIFloatingSlave:
+            printf("floating slave]\n");
+            break;
+    }
+
+    if (format == FORMAT_SHORT)
+        return;
+
+    if (!dev->enabled)
+        printf("\tThis device is disabled\n");
+
+    print_classes_xi2(display, dev->classes, dev->num_classes);
+}
+
+
+static int
+list_xi2(Display *display,
+         enum print_format format)
+{
+    int ndevices;
+    int i, j;
+    XIDeviceInfo *info, *dev;
+
+    info = XIQueryDevice(display, XIAllDevices, &ndevices);
+
+    for(i = 0; i < ndevices; i++)
+    {
+        dev = &info[i];
+        if (dev->use == XIMasterPointer || dev->use == XIMasterKeyboard)
+        {
+            if (format == FORMAT_SHORT || format == FORMAT_LONG)
+            {
+                if (dev->use == XIMasterPointer)
+                    printf("⎡ ");
+                else
+                    printf("⎣ ");
+            }
+
+            print_info_xi2(display, dev, format);
+            for (j = 0; j < ndevices; j++)
+            {
+                XIDeviceInfo* sd = &info[j];
+
+                if ((sd->use == XISlavePointer || sd->use == XISlaveKeyboard) &&
+                     (sd->attachment == dev->deviceid))
+                {
+                    if (format == FORMAT_SHORT || format == FORMAT_LONG)
+                        printf("%s   ↳ ", dev->use == XIMasterPointer ? "⎜" : " ");
+                    print_info_xi2(display, sd, format);
+                }
+            }
+        }
+    }
+
+    for (i = 0; i < ndevices; i++)
+    {
+        dev = &info[i];
+        if (dev->use == XIFloatingSlave)
+        {
+            printf("∼ ");
+            print_info_xi2(display, dev, format);
+        }
+    }
+
+
+    XIFreeDeviceInfo(info);
+    return EXIT_SUCCESS;
+}
+#endif
+
 int
 list(Display   *display,
      int       argc,
@@ -83,33 +350,61 @@ list(Display       *display,
      char      *name,
      char      *desc)
 {
-    XDeviceInfo                *info;
-    int                        loop;
+    enum print_format format = FORMAT_NONE;
+    int arg_dev = 1;
 
-    if (argc == 0) {
-       int             num_devices;
-    
-       info = XListInputDevices(display, &num_devices);
-       
-       for(loop=0; loop<num_devices; loop++) {
-           print_info(info+loop);
-       }
+    if (argc >= 1)
+    {
+        if (strcmp(argv[0], "--short") == 0)
+            format = FORMAT_SHORT;
+        else if (strcmp(argv[0], "--long") == 0)
+            format = FORMAT_LONG;
+        else if (strcmp(argv[0], "--name-only") == 0)
+            format = FORMAT_NAME;
+        else if (strcmp(argv[0], "--id-only") == 0)
+            format = FORMAT_ID;
+        else
+            arg_dev--;
+    }
+
+    if (argc > arg_dev)
+    {
+        if (format == FORMAT_NONE)
+            format = FORMAT_LONG;
+#if HAVE_XI2
+        if (xinput_version(display) == XI_2_Major)
+        {
+            XIDeviceInfo *info = xi2_find_device_info(display, argv[arg_dev]);
+
+            if (!info) {
+                fprintf(stderr, "unable to find device %s\n", argv[arg_dev]);
+                return EXIT_FAILURE;
+            } else {
+                print_info_xi2(display, info, format);
+                return EXIT_SUCCESS;
+            }
+        } else
+#endif
+        {
+            XDeviceInfo *info = find_device_info(display, argv[arg_dev], False);
+
+            if (!info) {
+                fprintf(stderr, "unable to find device %s\n", argv[arg_dev]);
+                return EXIT_FAILURE;
+            } else {
+                print_info(display, info, format);
+                return EXIT_SUCCESS;
+            }
+        }
     } else {
-       int     ret = EXIT_SUCCESS;
-
-       for(loop=0; loop<argc; loop++) {
-           info = find_device_info(display, argv[0], False);
-           
-           if (!info) {
-               fprintf(stderr, "unable to find device %s\n", argv[0]);
-               ret = EXIT_FAILURE;
-           } else {
-               print_info(info);
-           }
-       }
-       return ret;
+        if (format == FORMAT_NONE)
+            format = FORMAT_SHORT;
+#if HAVE_XI2
+        if (xinput_version(display) == XI_2_Major)
+            return list_xi2(display, format);
+#endif
+        return list_xi1(display, format);
     }
-    return EXIT_SUCCESS;
 }
 
 /* end of list.c */