/*
* expose input properties via udev
*
* Copyright (C) 2009 Martin Pitt <martin.pitt@ubuntu.com>
* Portions Copyright (C) 2004 David Zeuthen, <david@fubar.dk>
* Copyright (C) 2011 Kay Sievers <kay@vrfy.org>
* Copyright (C) 2014 Carlos Garnacho <carlosg@gnome.org>
* Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
*
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "fd-util.h"
#include "stdio-util.h"
#include "string-util.h"
#include "udev.h"
#include "util.h"
/* we must use this kernel-compatible implementation */
}
if (fd < 0)
return;
return;
return;
}
/*
* Read a capability attribute and return bitmask.
* @param dev udev_device
* @param attr sysfs attribute name (e. g. "capabilities/key")
* @param bitmask: Output array which has a sizeof of bitmask_size
*/
bool test) {
const char *v;
unsigned i;
char* word;
unsigned long val;
if (!v)
v = "";
i = 0;
if (i < bitmask_size/sizeof(unsigned long))
else
*word = '\0';
++i;
}
if (i < bitmask_size / sizeof(unsigned long))
else
if (test) {
/* printf pattern with the right unsigned long number of hex chars */
2 * sizeof(unsigned long));
val = bitmask_size / sizeof (unsigned long);
/* skip over leading zeros */
--val;
for (i = 0; i < val; ++i) {
}
}
}
/* pointer devices */
const unsigned long* bitmask_ev,
const unsigned long* bitmask_abs,
const unsigned long* bitmask_key,
const unsigned long* bitmask_rel,
const unsigned long* bitmask_props,
bool test) {
bool has_abs_coordinates = false;
bool has_rel_coordinates = false;
bool has_mt_coordinates = false;
bool has_joystick_axes_or_buttons = false;
bool is_direct = false;
bool has_touch = false;
bool has_3d_coordinates = false;
bool has_keys = false;
bool stylus_or_pen = false;
bool finger_but_no_pen = false;
bool has_mouse_button = false;
bool is_mouse = false;
bool is_touchpad = false;
bool is_touchscreen = false;
bool is_tablet = false;
bool is_joystick = false;
bool is_accelerometer = false;
bool is_pointing_stick= false;
if (!has_keys && has_3d_coordinates)
is_accelerometer = true;
if (is_accelerometer) {
return true;
}
has_rel_coordinates = test_bit(EV_REL, bitmask_ev) && test_bit(REL_X, bitmask_rel) && test_bit(REL_Y, bitmask_rel);
has_mt_coordinates = test_bit(ABS_MT_POSITION_X, bitmask_abs) && test_bit(ABS_MT_POSITION_Y, bitmask_abs);
/* unset has_mt_coordinates if devices claims to have all abs axis */
if(has_mt_coordinates && test_bit(ABS_MT_SLOT, bitmask_abs) && test_bit(ABS_MT_SLOT - 1, bitmask_abs))
has_mt_coordinates = false;
/* joysticks don't necessarily have buttons; e. g.
* other fancy axes */
if (has_abs_coordinates) {
if (stylus_or_pen)
is_tablet = true;
else if (finger_but_no_pen && !is_direct)
is_touchpad = true;
else if (has_mouse_button)
/* This path is taken by VMware's USB mouse, which has
is_mouse = true;
is_touchscreen = true;
else if (has_joystick_axes_or_buttons)
is_joystick = true;
}
is_touchscreen = true;
if (has_rel_coordinates && has_mouse_button)
is_mouse = true;
if (is_pointing_stick)
if (is_mouse)
if (is_touchpad)
if (is_touchscreen)
if (is_joystick)
if (is_tablet)
}
/* key like devices */
const unsigned long* bitmask_ev,
const unsigned long* bitmask_key,
bool test) {
unsigned i;
unsigned long found;
unsigned long mask;
bool ret = false;
/* do we have any KEY_* capability? */
log_debug("test_key: no EV_KEY capability");
return false;
}
/* only consider KEY_* here, not BTN_* */
found = 0;
for (i = 0; i < BTN_MISC/BITS_PER_LONG; ++i) {
found |= bitmask_key[i];
log_debug("test_key: checking bit block %lu for any keys; found=%i", (unsigned long)i*BITS_PER_LONG, found > 0);
}
/* If there are no keys in the lower block, check the higher block */
if (!found) {
for (i = KEY_OK; i < BTN_TRIGGER_HAPPY; ++i) {
if (test_bit(i, bitmask_key)) {
log_debug("test_key: Found key %x in high block", i);
found = 1;
break;
}
}
}
if (found > 0) {
ret = true;
}
/* the first 32 bits are ESC, numbers, and Q to D; if we have all of
* those, consider it a full keyboard; do not test KEY_RESERVED, though */
mask = 0xFFFFFFFE;
ret = true;
}
return ret;
}
bool is_pointer;
bool is_key;
/* walk up the parental chain until we find the real input device; the
* argument is very likely a subdevice of this, like eventN */
if (pdev) {
/* Use this as a flag that input devices were detected, so that this
* program doesn't need to be called more than once per device */
/* Some evdev nodes have only a scrollwheel */
}
return EXIT_SUCCESS;
}
.name = "input_id",
.cmd = builtin_input_id,
.help = "Input device properties",
};