Edit

IABSD.fr/xenocara/app/xinput/src/list.c

Branch :

  • Show log

    Commit

  • Author : matthieu
    Date : 2014-05-03 19:37:22
    Hash : 2e8b4cb8
    Message : Update to xinput 1.6.1

  • app/xinput/src/list.c
  • /*
     * 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  the authors  not  be  used  in
     * advertising or publicity pertaining to distribution of the software without
     * 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.
     *
     * THE AUTHORS DISCLAIM ALL   WARRANTIES WITH REGARD  TO  THIS SOFTWARE,
     * INCLUDING ALL IMPLIED   WARRANTIES OF MERCHANTABILITY  AND   FITNESS, IN NO
     * 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
     * PERFORMANCE OF THIS SOFTWARE.
     *
     */
    
    #include "xinput.h"
    #include <string.h>
    
    enum print_format {
        FORMAT_NONE,
        FORMAT_SHORT,
        FORMAT_LONG,
        FORMAT_NAME,
        FORMAT_ID,
    };
    
    
    static void
    print_info(Display* dpy, XDeviceInfo	*info, enum print_format format)
    {
        int			i,j;
        XAnyClassPtr	any;
        XKeyInfoPtr		k;
        XButtonInfoPtr	b;
        XValuatorInfoPtr	v;
        XAxisInfoPtr	a;
    
        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);
    	for (i=0; i<info->num_classes; i++) {
    	    switch (any->class) {
    	    case KeyClass:
    		k = (XKeyInfoPtr) any;
    		printf("\tNum_keys is %d\n", k->num_keys);
    		printf("\tMin_keycode is %d\n", k->min_keycode);
    		printf("\tMax_keycode is %d\n", k->max_keycode);
    		break;
    
    	    case ButtonClass:
    		b = (XButtonInfoPtr) any;
    		printf("\tNum_buttons is %d\n", b->num_buttons);
    		break;
    
    	    case ValuatorClass:
    		v = (XValuatorInfoPtr) any;
    		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");
    		printf("\tMotion_buffer is %ld\n", v->motion_buffer);
    		for (j=0; j<v->num_axes; j++, a++) {
    		    printf("\tAxis %d :\n", j);
    		    printf("\t\tMin_value is %d\n", a->min_value);
    		    printf("\t\tMax_value is %d\n", a->max_value);
    		    printf ("\t\tResolution is %d\n", a->resolution);
    		}
    		break;
    	    default:
    		printf ("unknown class\n");
    	    }
    	    any = (XAnyClassPtr) ((char *) any + any->length);
    	}
        }
    }
    
    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;
    }
    
    #ifdef 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 (have_utf8())
                        if (dev->use == XIMasterPointer)
                            printf("⎡ ");
                        else
                            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)
                            if (have_utf8())
                                printf("%s   ↳ ", dev->use == XIMasterPointer ? "⎜" : " ");
                            else
                                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,
         char	*argv[],
         char	*name,
         char	*desc)
    {
        enum print_format format = FORMAT_NONE;
        int arg_dev = 1;
    
        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;
    #ifdef 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 {
            if (format == FORMAT_NONE)
                format = FORMAT_SHORT;
    #ifdef HAVE_XI2
            if (xinput_version(display) == XI_2_Major)
                return list_xi2(display, format);
    #endif
            return list_xi1(display, format);
        }
    }
    
    Bool
    have_utf8(void){
        char *t;
    
        /*
         * There is no standard way to detect UTF-8 capabilities of a
         * given terminal, but this gets pretty close as a good heuristic.
         */
        if ((t = getenv("LC_ALL")) == NULL) {
    	if ((t = getenv("LC_CTYPE")) == NULL) {
    	    t = getenv("LANG");
    	}
        }
    
        if (t != NULL && (strcasestr(t, "UTF-8") != NULL ||
          strcasestr(t, "UTF8") != NULL))
    	return True;
    
        return False;
    }
    
    /* end of list.c */