Android开发之input子系统二之创建自己的input

版权声明:转载请注明出处,谢谢配合 https://blog.csdn.net/qq_33750826/article/details/79447385

参考:http://blog.csdn.net/myarrow/article/details/12105973

一、概略

根据章节一的内容我们大致了解了android系统的input子系统的一些信息,但是有时候系统自动提供的input事件却并不能满足我们的实际需求,android系统针对这个也为我们提供了uinput

二、API

uinput_user_dev
基于Android N,源代码位于:kernel/include/uapi/linux/uinput.h

/*
 *  User level driver support for input subsystem
 *
 * Heavily based on evdev.c by Vojtech Pavlik
 *
 * This program is free software; you can redistribute it and/or modify
 * 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * Author: Aristeu Sergio Rozanski Filho <[email protected]>
 *
 * Changes/Revisions:
 *  0.4 01/09/2014 (Benjamin Tissoires <[email protected]>)
 *      - add UI_GET_SYSNAME ioctl
 *  0.3 24/05/2006 (Anssi Hannula <anssi.hannulagmail.com>)
 *      - update ff support for the changes in kernel interface
 *      - add UINPUT_VERSION
 *  0.2 16/10/2004 (Micah Dowty <[email protected]>)
 *      - added force feedback support
 *             - added UI_SET_PHYS
 *  0.1 20/06/2002
 *      - first public version
 */
#ifndef _UAPI__UINPUT_H_
#define _UAPI__UINPUT_H_

#include <linux/types.h>
#include <linux/input.h>

#define UINPUT_VERSION      4


struct uinput_ff_upload {
    __u32           request_id;
    __s32           retval;
    struct ff_effect    effect;
    struct ff_effect    old;
};

struct uinput_ff_erase {
    __u32           request_id;
    __s32           retval;
    __u32           effect_id;
};

/* ioctl */
#define UINPUT_IOCTL_BASE   'U'
#define UI_DEV_CREATE       _IO(UINPUT_IOCTL_BASE, 1)
#define UI_DEV_DESTROY      _IO(UINPUT_IOCTL_BASE, 2)

#define UI_SET_EVBIT        _IOW(UINPUT_IOCTL_BASE, 100, int)
#define UI_SET_KEYBIT       _IOW(UINPUT_IOCTL_BASE, 101, int)
#define UI_SET_RELBIT       _IOW(UINPUT_IOCTL_BASE, 102, int)
#define UI_SET_ABSBIT       _IOW(UINPUT_IOCTL_BASE, 103, int)
#define UI_SET_MSCBIT       _IOW(UINPUT_IOCTL_BASE, 104, int)
#define UI_SET_LEDBIT       _IOW(UINPUT_IOCTL_BASE, 105, int)
#define UI_SET_SNDBIT       _IOW(UINPUT_IOCTL_BASE, 106, int)
#define UI_SET_FFBIT        _IOW(UINPUT_IOCTL_BASE, 107, int)
#define UI_SET_PHYS     _IOW(UINPUT_IOCTL_BASE, 108, char*)
#define UI_SET_SWBIT        _IOW(UINPUT_IOCTL_BASE, 109, int)
#define UI_SET_PROPBIT      _IOW(UINPUT_IOCTL_BASE, 110, int)

#define UI_BEGIN_FF_UPLOAD  _IOWR(UINPUT_IOCTL_BASE, 200, struct uinput_ff_upload)
#define UI_END_FF_UPLOAD    _IOW(UINPUT_IOCTL_BASE, 201, struct uinput_ff_upload)
#define UI_BEGIN_FF_ERASE   _IOWR(UINPUT_IOCTL_BASE, 202, struct uinput_ff_erase)
#define UI_END_FF_ERASE     _IOW(UINPUT_IOCTL_BASE, 203, struct uinput_ff_erase)

/**
 * UI_GET_SYSNAME - get the sysfs name of the created uinput device
 *
 * @return the sysfs name of the created virtual input device.
 * The complete sysfs path is then /sys/devices/virtual/input/--NAME--
 * Usually, it is in the form "inputN"
 */
#define UI_GET_SYSNAME(len) _IOC(_IOC_READ, UINPUT_IOCTL_BASE, 44, len)

/**
 * UI_GET_VERSION - Return version of uinput protocol
 *
 * This writes uinput protocol version implemented by the kernel into
 * the integer pointed to by the ioctl argument. The protocol version
 * is hard-coded in the kernel and is independent of the uinput device.
 */
#define UI_GET_VERSION      _IOR(UINPUT_IOCTL_BASE, 45, unsigned int)

/*
 * To write a force-feedback-capable driver, the upload_effect
 * and erase_effect callbacks in input_dev must be implemented.
 * The uinput driver will generate a fake input event when one of
 * these callbacks are invoked. The userspace code then uses
 * ioctls to retrieve additional parameters and send the return code.
 * The callback blocks until this return code is sent.
 *
 * The described callback mechanism is only used if ff_effects_max
 * is set.
 *
 * To implement upload_effect():
 *   1. Wait for an event with type == EV_UINPUT and code == UI_FF_UPLOAD.
 *      A request ID will be given in 'value'.
 *   2. Allocate a uinput_ff_upload struct, fill in request_id with
 *      the 'value' from the EV_UINPUT event.
 *   3. Issue a UI_BEGIN_FF_UPLOAD ioctl, giving it the
 *      uinput_ff_upload struct. It will be filled in with the
 *      ff_effects passed to upload_effect().
 *   4. Perform the effect upload, and place a return code back into
        the uinput_ff_upload struct.
 *   5. Issue a UI_END_FF_UPLOAD ioctl, also giving it the
 *      uinput_ff_upload_effect struct. This will complete execution
 *      of our upload_effect() handler.
 *
 * To implement erase_effect():
 *   1. Wait for an event with type == EV_UINPUT and code == UI_FF_ERASE.
 *      A request ID will be given in 'value'.
 *   2. Allocate a uinput_ff_erase struct, fill in request_id with
 *      the 'value' from the EV_UINPUT event.
 *   3. Issue a UI_BEGIN_FF_ERASE ioctl, giving it the
 *      uinput_ff_erase struct. It will be filled in with the
 *      effect ID passed to erase_effect().
 *   4. Perform the effect erasure, and place a return code back
 *      into the uinput_ff_erase struct.
 *   5. Issue a UI_END_FF_ERASE ioctl, also giving it the
 *      uinput_ff_erase_effect struct. This will complete execution
 *      of our erase_effect() handler.
 */

/*
 * This is the new event type, used only by uinput.
 * 'code' is UI_FF_UPLOAD or UI_FF_ERASE, and 'value'
 * is the unique request ID. This number was picked
 * arbitrarily, above EV_MAX (since the input system
 * never sees it) but in the range of a 16-bit int.
 */
#define EV_UINPUT       0x0101
#define UI_FF_UPLOAD        1
#define UI_FF_ERASE     2

#define UINPUT_MAX_NAME_SIZE    80
struct uinput_user_dev {
    char name[UINPUT_MAX_NAME_SIZE];
    struct input_id id;
    __u32 ff_effects_max;
    __s32 absmax[ABS_CNT];
    __s32 absmin[ABS_CNT];
    __s32 absfuzz[ABS_CNT];
    __s32 absflat[ABS_CNT];
};
#endif /* _UAPI__UINPUT_H_ */

====================================================
input_id、input_event
基于Android N 源代码位于kernel/include/uapi/linux/input.h

/*
 * Copyright (c) 1999-2002 Vojtech Pavlik
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 */
#ifndef _UAPI_INPUT_H
#define _UAPI_INPUT_H


#ifndef __KERNEL__
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <linux/types.h>
#endif

#include "input-event-codes.h"

/*
 * The event structure itself
 */

struct input_event {
    struct timeval time;
    __u16 type;
    __u16 code;
    __s32 value;
};

/*
 * Protocol version.
 */

#define EV_VERSION      0x010001

/*
 * IOCTLs (0x00 - 0x7f)
 */

struct input_id {
    __u16 bustype;
    __u16 vendor;
    __u16 product;
    __u16 version;
};

/**
 * struct input_absinfo - used by EVIOCGABS/EVIOCSABS ioctls
 * @value: latest reported value for the axis.
 * @minimum: specifies minimum value for the axis.
 * @maximum: specifies maximum value for the axis.
 * @fuzz: specifies fuzz value that is used to filter noise from
 *  the event stream.
 * @flat: values that are within this value will be discarded by
 *  joydev interface and reported as 0 instead.
 * @resolution: specifies resolution for the values reported for
 *  the axis.
 *
 * Note that input core does not clamp reported values to the
 * [minimum, maximum] limits, such task is left to userspace.
 *
 * Resolution for main axes (ABS_X, ABS_Y, ABS_Z) is reported in
 * units per millimeter (units/mm), resolution for rotational axes
 * (ABS_RX, ABS_RY, ABS_RZ) is reported in units per radian.
 */
struct input_absinfo {
    __s32 value;
    __s32 minimum;
    __s32 maximum;
    __s32 fuzz;
    __s32 flat;
    __s32 resolution;
};

/**
 * struct input_keymap_entry - used by EVIOCGKEYCODE/EVIOCSKEYCODE ioctls
 * @scancode: scancode represented in machine-endian form.
 * @len: length of the scancode that resides in @scancode buffer.
 * @index: index in the keymap, may be used instead of scancode
 * @flags: allows to specify how kernel should handle the request. For
 *  example, setting INPUT_KEYMAP_BY_INDEX flag indicates that kernel
 *  should perform lookup in keymap by @index instead of @scancode
 * @keycode: key code assigned to this scancode
 *
 * The structure is used to retrieve and modify keymap data. Users have
 * option of performing lookup either by @scancode itself or by @index
 * in keymap entry. EVIOCGKEYCODE will also return scancode or index
 * (depending on which element was used to perform lookup).
 */
struct input_keymap_entry {
#define INPUT_KEYMAP_BY_INDEX   (1 << 0)
    __u8  flags;
    __u8  len;
    __u16 index;
    __u32 keycode;
    __u8  scancode[32];
};

struct input_mask {
    __u32 type;
    __u32 codes_size;
    __u64 codes_ptr;
};

#define EVIOCGVERSION       _IOR('E', 0x01, int)            /* get driver version */
#define EVIOCGID        _IOR('E', 0x02, struct input_id)    /* get device ID */
#define EVIOCGREP       _IOR('E', 0x03, unsigned int[2])    /* get repeat settings */
#define EVIOCSREP       _IOW('E', 0x03, unsigned int[2])    /* set repeat settings */

#define EVIOCGKEYCODE       _IOR('E', 0x04, unsigned int[2])        /* get keycode */
#define EVIOCGKEYCODE_V2    _IOR('E', 0x04, struct input_keymap_entry)
#define EVIOCSKEYCODE       _IOW('E', 0x04, unsigned int[2])        /* set keycode */
#define EVIOCSKEYCODE_V2    _IOW('E', 0x04, struct input_keymap_entry)

#define EVIOCGNAME(len)     _IOC(_IOC_READ, 'E', 0x06, len)     /* get device name */
#define EVIOCGPHYS(len)     _IOC(_IOC_READ, 'E', 0x07, len)     /* get physical location */
#define EVIOCGUNIQ(len)     _IOC(_IOC_READ, 'E', 0x08, len)     /* get unique identifier */
#define EVIOCGPROP(len)     _IOC(_IOC_READ, 'E', 0x09, len)     /* get device properties */

/**
 * EVIOCGMTSLOTS(len) - get MT slot values
 * @len: size of the data buffer in bytes
 *
 * The ioctl buffer argument should be binary equivalent to
 *
 * struct input_mt_request_layout {
 *  __u32 code;
 *  __s32 values[num_slots];
 * };
 *
 * where num_slots is the (arbitrary) number of MT slots to extract.
 *
 * The ioctl size argument (len) is the size of the buffer, which
 * should satisfy len = (num_slots + 1) * sizeof(__s32).  If len is
 * too small to fit all available slots, the first num_slots are
 * returned.
 *
 * Before the call, code is set to the wanted ABS_MT event type. On
 * return, values[] is filled with the slot values for the specified
 * ABS_MT code.
 *
 * If the request code is not an ABS_MT value, -EINVAL is returned.
 */
#define EVIOCGMTSLOTS(len)  _IOC(_IOC_READ, 'E', 0x0a, len)

#define EVIOCGKEY(len)      _IOC(_IOC_READ, 'E', 0x18, len)     /* get global key state */
#define EVIOCGLED(len)      _IOC(_IOC_READ, 'E', 0x19, len)     /* get all LEDs */
#define EVIOCGSND(len)      _IOC(_IOC_READ, 'E', 0x1a, len)     /* get all sounds status */
#define EVIOCGSW(len)       _IOC(_IOC_READ, 'E', 0x1b, len)     /* get all switch states */

#define EVIOCGBIT(ev,len)   _IOC(_IOC_READ, 'E', 0x20 + (ev), len)  /* get event bits */
#define EVIOCGABS(abs)      _IOR('E', 0x40 + (abs), struct input_absinfo)   /* get abs value/limits */
#define EVIOCSABS(abs)      _IOW('E', 0xc0 + (abs), struct input_absinfo)   /* set abs value/limits */

#define EVIOCSFF        _IOW('E', 0x80, struct ff_effect)   /* send a force effect to a force feedback device */
#define EVIOCRMFF       _IOW('E', 0x81, int)            /* Erase a force effect */
#define EVIOCGEFFECTS       _IOR('E', 0x84, int)            /* Report number of effects playable at the same time */

#define EVIOCGRAB       _IOW('E', 0x90, int)            /* Grab/Release device */
#define EVIOCREVOKE     _IOW('E', 0x91, int)            /* Revoke device access */

/**
 * EVIOCGMASK - Retrieve current event mask
 *
 * This ioctl allows user to retrieve the current event mask for specific
 * event type. The argument must be of type "struct input_mask" and
 * specifies the event type to query, the address of the receive buffer and
 * the size of the receive buffer.
 *
 * The event mask is a per-client mask that specifies which events are
 * forwarded to the client. Each event code is represented by a single bit
 * in the event mask. If the bit is set, the event is passed to the client
 * normally. Otherwise, the event is filtered and will never be queued on
 * the client's receive buffer.
 *
 * Event masks do not affect global state of the input device. They only
 * affect the file descriptor they are applied to.
 *
 * The default event mask for a client has all bits set, i.e. all events
 * are forwarded to the client. If the kernel is queried for an unknown
 * event type or if the receive buffer is larger than the number of
 * event codes known to the kernel, the kernel returns all zeroes for those
 * codes.
 *
 * At maximum, codes_size bytes are copied.
 *
 * This ioctl may fail with ENODEV in case the file is revoked, EFAULT
 * if the receive-buffer points to invalid memory, or EINVAL if the kernel
 * does not implement the ioctl.
 */
#define EVIOCGMASK      _IOR('E', 0x92, struct input_mask)  /* Get event-masks */

/**
 * EVIOCSMASK - Set event mask
 *
 * This ioctl is the counterpart to EVIOCGMASK. Instead of receiving the
 * current event mask, this changes the client's event mask for a specific
 * type.  See EVIOCGMASK for a description of event-masks and the
 * argument-type.
 *
 * This ioctl provides full forward compatibility. If the passed event type
 * is unknown to the kernel, or if the number of event codes specified in
 * the mask is bigger than what is known to the kernel, the ioctl is still
 * accepted and applied. However, any unknown codes are left untouched and
 * stay cleared. That means, the kernel always filters unknown codes
 * regardless of what the client requests.  If the new mask doesn't cover
 * all known event-codes, all remaining codes are automatically cleared and
 * thus filtered.
 *
 * This ioctl may fail with ENODEV in case the file is revoked. EFAULT is
 * returned if the receive-buffer points to invalid memory. EINVAL is returned
 * if the kernel does not implement the ioctl.
 */
#define EVIOCSMASK      _IOW('E', 0x93, struct input_mask)  /* Set event-masks */

#define EVIOCSCLOCKID       _IOW('E', 0xa0, int)            /* Set clockid to be used for timestamps */

/*
 * IDs.
 */

#define ID_BUS          0
#define ID_VENDOR       1
#define ID_PRODUCT      2
#define ID_VERSION      3

#define BUS_PCI         0x01
#define BUS_ISAPNP      0x02
#define BUS_USB         0x03
#define BUS_HIL         0x04
#define BUS_BLUETOOTH       0x05
#define BUS_VIRTUAL     0x06

#define BUS_ISA         0x10
#define BUS_I8042       0x11
#define BUS_XTKBD       0x12
#define BUS_RS232       0x13
#define BUS_GAMEPORT        0x14
#define BUS_PARPORT     0x15
#define BUS_AMIGA       0x16
#define BUS_ADB         0x17
#define BUS_I2C         0x18
#define BUS_HOST        0x19
#define BUS_GSC         0x1A
#define BUS_ATARI       0x1B
#define BUS_SPI         0x1C

/*
 * MT_TOOL types
 */
#define MT_TOOL_FINGER      0
#define MT_TOOL_PEN     1
#define MT_TOOL_PALM        2
#define MT_TOOL_MAX     2

/*
 * Values describing the status of a force-feedback effect
 */
#define FF_STATUS_STOPPED   0x00
#define FF_STATUS_PLAYING   0x01
#define FF_STATUS_MAX       0x01

/*
 * Structures used in ioctls to upload effects to a device
 * They are pieces of a bigger structure (called ff_effect)
 */

/*
 * All duration values are expressed in ms. Values above 32767 ms (0x7fff)
 * should not be used and have unspecified results.
 */

/**
 * struct ff_replay - defines scheduling of the force-feedback effect
 * @length: duration of the effect
 * @delay: delay before effect should start playing
 */
struct ff_replay {
    __u16 length;
    __u16 delay;
};

/**
 * struct ff_trigger - defines what triggers the force-feedback effect
 * @button: number of the button triggering the effect
 * @interval: controls how soon the effect can be re-triggered
 */
struct ff_trigger {
    __u16 button;
    __u16 interval;
};

/**
 * struct ff_envelope - generic force-feedback effect envelope
 * @attack_length: duration of the attack (ms)
 * @attack_level: level at the beginning of the attack
 * @fade_length: duration of fade (ms)
 * @fade_level: level at the end of fade
 *
 * The @attack_level and @fade_level are absolute values; when applying
 * envelope force-feedback core will convert to positive/negative
 * value based on polarity of the default level of the effect.
 * Valid range for the attack and fade levels is 0x0000 - 0x7fff
 */
struct ff_envelope {
    __u16 attack_length;
    __u16 attack_level;
    __u16 fade_length;
    __u16 fade_level;
};

/**
 * struct ff_constant_effect - defines parameters of a constant force-feedback effect
 * @level: strength of the effect; may be negative
 * @envelope: envelope data
 */
struct ff_constant_effect {
    __s16 level;
    struct ff_envelope envelope;
};

/**
 * struct ff_ramp_effect - defines parameters of a ramp force-feedback effect
 * @start_level: beginning strength of the effect; may be negative
 * @end_level: final strength of the effect; may be negative
 * @envelope: envelope data
 */
struct ff_ramp_effect {
    __s16 start_level;
    __s16 end_level;
    struct ff_envelope envelope;
};

/**
 * struct ff_condition_effect - defines a spring or friction force-feedback effect
 * @right_saturation: maximum level when joystick moved all way to the right
 * @left_saturation: same for the left side
 * @right_coeff: controls how fast the force grows when the joystick moves
 *  to the right
 * @left_coeff: same for the left side
 * @deadband: size of the dead zone, where no force is produced
 * @center: position of the dead zone
 */
struct ff_condition_effect {
    __u16 right_saturation;
    __u16 left_saturation;

    __s16 right_coeff;
    __s16 left_coeff;

    __u16 deadband;
    __s16 center;
};

/**
 * struct ff_periodic_effect - defines parameters of a periodic force-feedback effect
 * @waveform: kind of the effect (wave)
 * @period: period of the wave (ms)
 * @magnitude: peak value
 * @offset: mean value of the wave (roughly)
 * @phase: 'horizontal' shift
 * @envelope: envelope data
 * @custom_len: number of samples (FF_CUSTOM only)
 * @custom_data: buffer of samples (FF_CUSTOM only)
 *
 * Known waveforms - FF_SQUARE, FF_TRIANGLE, FF_SINE, FF_SAW_UP,
 * FF_SAW_DOWN, FF_CUSTOM. The exact syntax FF_CUSTOM is undefined
 * for the time being as no driver supports it yet.
 *
 * Note: the data pointed by custom_data is copied by the driver.
 * You can therefore dispose of the memory after the upload/update.
 */
struct ff_periodic_effect {
    __u16 waveform;
    __u16 period;
    __s16 magnitude;
    __s16 offset;
    __u16 phase;

    struct ff_envelope envelope;

    __u32 custom_len;
    __s16 __user *custom_data;
};

/**
 * struct ff_rumble_effect - defines parameters of a periodic force-feedback effect
 * @strong_magnitude: magnitude of the heavy motor
 * @weak_magnitude: magnitude of the light one
 *
 * Some rumble pads have two motors of different weight. Strong_magnitude
 * represents the magnitude of the vibration generated by the heavy one.
 */
struct ff_rumble_effect {
    __u16 strong_magnitude;
    __u16 weak_magnitude;
};

/**
 * struct ff_effect - defines force feedback effect
 * @type: type of the effect (FF_CONSTANT, FF_PERIODIC, FF_RAMP, FF_SPRING,
 *  FF_FRICTION, FF_DAMPER, FF_RUMBLE, FF_INERTIA, or FF_CUSTOM)
 * @id: an unique id assigned to an effect
 * @direction: direction of the effect
 * @trigger: trigger conditions (struct ff_trigger)
 * @replay: scheduling of the effect (struct ff_replay)
 * @u: effect-specific structure (one of ff_constant_effect, ff_ramp_effect,
 *  ff_periodic_effect, ff_condition_effect, ff_rumble_effect) further
 *  defining effect parameters
 *
 * This structure is sent through ioctl from the application to the driver.
 * To create a new effect application should set its @id to -1; the kernel
 * will return assigned @id which can later be used to update or delete
 * this effect.
 *
 * Direction of the effect is encoded as follows:
 *  0 deg -> 0x0000 (down)
 *  90 deg -> 0x4000 (left)
 *  180 deg -> 0x8000 (up)
 *  270 deg -> 0xC000 (right)
 */
struct ff_effect {
    __u16 type;
    __s16 id;
    __u16 direction;
    struct ff_trigger trigger;
    struct ff_replay replay;

    union {
        struct ff_constant_effect constant;
        struct ff_ramp_effect ramp;
        struct ff_periodic_effect periodic;
        struct ff_condition_effect condition[2]; /* One for each axis */
        struct ff_rumble_effect rumble;
    } u;
};

/*
 * Force feedback effect types
 */

#define FF_RUMBLE   0x50
#define FF_PERIODIC 0x51
#define FF_CONSTANT 0x52
#define FF_SPRING   0x53
#define FF_FRICTION 0x54
#define FF_DAMPER   0x55
#define FF_INERTIA  0x56
#define FF_RAMP     0x57

#define FF_EFFECT_MIN   FF_RUMBLE
#define FF_EFFECT_MAX   FF_RAMP

/*
 * Force feedback periodic effect types
 */

#define FF_SQUARE   0x58
#define FF_TRIANGLE 0x59
#define FF_SINE     0x5a
#define FF_SAW_UP   0x5b
#define FF_SAW_DOWN 0x5c
#define FF_CUSTOM   0x5d

#define FF_WAVEFORM_MIN FF_SQUARE
#define FF_WAVEFORM_MAX FF_CUSTOM

/*
 * Set ff device properties
 */

#define FF_GAIN     0x60
#define FF_AUTOCENTER   0x61

/*
 * ff->playback(effect_id = FF_GAIN) is the first effect_id to
 * cause a collision with another ff method, in this case ff->set_gain().
 * Therefore the greatest safe value for effect_id is FF_GAIN - 1,
 * and thus the total number of effects should never exceed FF_GAIN.
 */
#define FF_MAX_EFFECTS  FF_GAIN

#define FF_MAX      0x7f
#define FF_CNT      (FF_MAX+1)

#endif /* _UAPI_INPUT_H */

相关宏定义:

/******************************************************************************
 *
 *  Copyright (C) 2009-2012 Broadcom Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

#ifndef __UINPUT_H
#define __UINPUT_H

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>
#include <sys/time.h>
#include <sys/ioctl.h>

/*******************************************************************************
**  Constants & Macros
********************************************************************************/

/* Events */

#define EV_SYN          0x00
#define EV_KEY          0x01
#define EV_REL          0x02
#define EV_ABS          0x03
#define EV_MSC          0x04
#define EV_LED          0x11
#define EV_SND          0x12
#define EV_REP          0x14
#define EV_FF           0x15
#define EV_PWR          0x16
#define EV_FF_STATUS        0x17
#define EV_MAX          0x1f

/* Synchronization events */

#define SYN_REPORT      0
#define SYN_CONFIG      1

/* Keys and buttons */

#define KEY_RESERVED        0
#define KEY_ESC         1
#define KEY_1           2
#define KEY_2           3
#define KEY_3           4
#define KEY_4           5
#define KEY_5           6
#define KEY_6           7
#define KEY_7           8
#define KEY_8           9
#define KEY_9           10
#define KEY_0           11
#define KEY_MINUS       12
#define KEY_EQUAL       13
#define KEY_BACKSPACE       14
#define KEY_TAB         15
#define KEY_Q           16
#define KEY_W           17
#define KEY_E           18
#define KEY_R           19
#define KEY_T           20
#define KEY_Y           21
#define KEY_U           22
#define KEY_I           23
#define KEY_O           24
#define KEY_P           25
#define KEY_LEFTBRACE       26
#define KEY_RIGHTBRACE      27
#define KEY_ENTER       28
#define KEY_LEFTCTRL        29
#define KEY_A           30
#define KEY_S           31
#define KEY_D           32
#define KEY_F           33
#define KEY_G           34
#define KEY_H           35
#define KEY_J           36
#define KEY_K           37
#define KEY_L           38
#define KEY_SEMICOLON       39
#define KEY_APOSTROPHE      40
#define KEY_GRAVE       41
#define KEY_LEFTSHIFT       42
#define KEY_BACKSLASH       43
#define KEY_Z           44
#define KEY_X           45
#define KEY_C           46
#define KEY_V           47
#define KEY_B           48
#define KEY_N           49
#define KEY_M           50
#define KEY_COMMA       51
#define KEY_DOT         52
#define KEY_SLASH       53
#define KEY_RIGHTSHIFT      54
#define KEY_KPASTERISK      55
#define KEY_LEFTALT     56
#define KEY_SPACE       57
#define KEY_CAPSLOCK        58
#define KEY_F1          59
#define KEY_F2          60
#define KEY_F3          61
#define KEY_F4          62
#define KEY_F5          63
#define KEY_F6          64
#define KEY_F7          65
#define KEY_F8          66
#define KEY_F9          67
#define KEY_F10         68
#define KEY_NUMLOCK     69
#define KEY_SCROLLLOCK      70
#define KEY_KP7         71
#define KEY_KP8         72
#define KEY_KP9         73
#define KEY_KPMINUS     74
#define KEY_KP4         75
#define KEY_KP5         76
#define KEY_KP6         77
#define KEY_KPPLUS      78
#define KEY_KP1         79
#define KEY_KP2         80
#define KEY_KP3         81
#define KEY_KP0         82
#define KEY_KPDOT       83
#define KEY_103RD       84
#define KEY_F13         85
#define KEY_102ND       86
#define KEY_F11         87
#define KEY_F12         88
#define KEY_F14         89
#define KEY_F15         90
#define KEY_F16         91
#define KEY_F17         92
#define KEY_F18         93
#define KEY_F19         94
#define KEY_F20         95
#define KEY_KPENTER     96
#define KEY_RIGHTCTRL       97
#define KEY_KPSLASH     98
#define KEY_SYSRQ       99
#define KEY_RIGHTALT        100
#define KEY_LINEFEED        101
#define KEY_HOME        102
#define KEY_UP          103
#define KEY_PAGEUP      104
#define KEY_LEFT        105
#define KEY_RIGHT       106
#define KEY_END         107
#define KEY_DOWN        108
#define KEY_PAGEDOWN        109
#define KEY_INSERT      110
#define KEY_DELETE      111
#define KEY_MACRO       112
#define KEY_MUTE        113
#define KEY_VOLUMEDOWN      114
#define KEY_VOLUMEUP        115
#define KEY_POWER       116
#define KEY_KPEQUAL     117
#define KEY_KPPLUSMINUS     118
#define KEY_PAUSE       119
#define KEY_F21         120
#define KEY_F22         121
#define KEY_F23         122
#define KEY_F24         123
#define KEY_KPCOMMA     124
#define KEY_LEFTMETA        125
#define KEY_RIGHTMETA       126
#define KEY_COMPOSE     127

#define KEY_STOP        128
#define KEY_AGAIN       129
#define KEY_PROPS       130
#define KEY_UNDO        131
#define KEY_FRONT       132
#define KEY_COPY        133
#define KEY_OPEN        134
#define KEY_PASTE       135
#define KEY_FIND        136
#define KEY_CUT         137
#define KEY_HELP        138
#define KEY_MENU        139
#define KEY_CALC        140
#define KEY_SETUP       141
#define KEY_SLEEP       142
#define KEY_WAKEUP      143
#define KEY_FILE        144
#define KEY_SENDFILE        145
#define KEY_DELETEFILE      146
#define KEY_XFER        147
#define KEY_PROG1       148
#define KEY_PROG2       149
#define KEY_WWW         150
#define KEY_MSDOS       151
#define KEY_COFFEE      152
#define KEY_DIRECTION       153
#define KEY_CYCLEWINDOWS    154
#define KEY_MAIL        155
#define KEY_BOOKMARKS       156
#define KEY_COMPUTER        157
#define KEY_BACK        158
#define KEY_FORWARD     159
#define KEY_CLOSECD     160
#define KEY_EJECTCD     161
#define KEY_EJECTCLOSECD    162
#define KEY_NEXTSONG        163
#define KEY_PLAYPAUSE       164
#define KEY_PREVIOUSSONG    165
#define KEY_STOPCD      166
#define KEY_RECORD      167
#define KEY_REWIND      168
#define KEY_PHONE       169
#define KEY_ISO         170
#define KEY_CONFIG      171
#define KEY_HOMEPAGE        172
#define KEY_REFRESH     173
#define KEY_EXIT        174
#define KEY_MOVE        175
#define KEY_EDIT        176
#define KEY_SCROLLUP        177
#define KEY_SCROLLDOWN      178
#define KEY_KPLEFTPAREN     179
#define KEY_KPRIGHTPAREN    180

#define KEY_INTL1       181
#define KEY_INTL2       182
#define KEY_INTL3       183
#define KEY_INTL4       184
#define KEY_INTL5       185
#define KEY_INTL6       186
#define KEY_INTL7       187
#define KEY_INTL8       188
#define KEY_INTL9       189
#define KEY_LANG1       190
#define KEY_LANG2       191
#define KEY_LANG3       192
#define KEY_LANG4       193
#define KEY_LANG5       194
#define KEY_LANG6       195
#define KEY_LANG7       196
#define KEY_LANG8       197
#define KEY_LANG9       198

#define KEY_PLAYCD      200
#define KEY_PAUSECD     201
#define KEY_PROG3       202
#define KEY_PROG4       203
#define KEY_SUSPEND     205
#define KEY_CLOSE       206
#define KEY_PLAY        207
#define KEY_FAST_FORWARD  208

#define KEY_UNKNOWN     220

#define KEY_BRIGHTNESSDOWN  224
#define KEY_BRIGHTNESSUP    225

#define BTN_MISC        0x100
#define BTN_0           0x100
#define BTN_1           0x101
#define BTN_2           0x102
#define BTN_3           0x103
#define BTN_4           0x104
#define BTN_5           0x105
#define BTN_6           0x106
#define BTN_7           0x107
#define BTN_8           0x108
#define BTN_9           0x109

#define BTN_MOUSE       0x110
#define BTN_LEFT        0x110
#define BTN_RIGHT       0x111
#define BTN_MIDDLE      0x112
#define BTN_SIDE        0x113
#define BTN_EXTRA       0x114
#define BTN_FORWARD     0x115
#define BTN_BACK        0x116
#define BTN_TASK        0x117

#define BTN_JOYSTICK        0x120
#define BTN_TRIGGER     0x120
#define BTN_THUMB       0x121
#define BTN_THUMB2      0x122
#define BTN_TOP         0x123
#define BTN_TOP2        0x124
#define BTN_PINKIE      0x125
#define BTN_BASE        0x126
#define BTN_BASE2       0x127
#define BTN_BASE3       0x128
#define BTN_BASE4       0x129
#define BTN_BASE5       0x12a
#define BTN_BASE6       0x12b
#define BTN_DEAD        0x12f

#define BTN_GAMEPAD     0x130
#define BTN_A           0x130
#define BTN_B           0x131
#define BTN_C           0x132
#define BTN_X           0x133
#define BTN_Y           0x134
#define BTN_Z           0x135
#define BTN_TL          0x136
#define BTN_TR          0x137
#define BTN_TL2         0x138
#define BTN_TR2         0x139
#define BTN_SELECT      0x13a
#define BTN_START       0x13b
#define BTN_MODE        0x13c
#define BTN_THUMBL      0x13d
#define BTN_THUMBR      0x13e

#define BTN_DIGI        0x140
#define BTN_TOOL_PEN        0x140
#define BTN_TOOL_RUBBER     0x141
#define BTN_TOOL_BRUSH      0x142
#define BTN_TOOL_PENCIL     0x143
#define BTN_TOOL_AIRBRUSH   0x144
#define BTN_TOOL_FINGER     0x145
#define BTN_TOOL_MOUSE      0x146
#define BTN_TOOL_LENS       0x147
#define BTN_TOUCH       0x14a
#define BTN_STYLUS      0x14b
#define BTN_STYLUS2     0x14c
#define BTN_TOOL_DOUBLETAP  0x14d
#define BTN_TOOL_TRIPLETAP  0x14e

#define BTN_WHEEL       0x150
#define BTN_GEAR_DOWN       0x150
#define BTN_GEAR_UP     0x151

#define KEY_OK          0x160
#define KEY_SELECT      0x161
#define KEY_GOTO        0x162
#define KEY_CLEAR       0x163
#define KEY_POWER2      0x164
#define KEY_OPTION      0x165
#define KEY_INFO        0x166
#define KEY_TIME        0x167
#define KEY_VENDOR      0x168
#define KEY_ARCHIVE     0x169
#define KEY_PROGRAM     0x16a
#define KEY_CHANNEL     0x16b
#define KEY_FAVORITES       0x16c
#define KEY_EPG         0x16d
#define KEY_PVR         0x16e
#define KEY_MHP         0x16f
#define KEY_LANGUAGE        0x170
#define KEY_TITLE       0x171
#define KEY_SUBTITLE        0x172
#define KEY_ANGLE       0x173
#define KEY_ZOOM        0x174
#define KEY_MODE        0x175
#define KEY_KEYBOARD        0x176
#define KEY_SCREEN      0x177
#define KEY_PC          0x178
#define KEY_TV          0x179
#define KEY_TV2         0x17a
#define KEY_VCR         0x17b
#define KEY_VCR2        0x17c
#define KEY_SAT         0x17d
#define KEY_SAT2        0x17e
#define KEY_CD          0x17f
#define KEY_TAPE        0x180
#define KEY_RADIO       0x181
#define KEY_TUNER       0x182
#define KEY_PLAYER      0x183
#define KEY_TEXT        0x184
#define KEY_DVD         0x185
#define KEY_AUX         0x186
#define KEY_MP3         0x187
#define KEY_AUDIO       0x188
#define KEY_VIDEO       0x189
#define KEY_DIRECTORY       0x18a
#define KEY_LIST        0x18b
#define KEY_MEMO        0x18c
#define KEY_CALENDAR        0x18d
#define KEY_RED         0x18e
#define KEY_GREEN       0x18f
#define KEY_YELLOW      0x190
#define KEY_BLUE        0x191
#define KEY_CHANNELUP       0x192
#define KEY_CHANNELDOWN     0x193
#define KEY_FIRST       0x194
#define KEY_LAST        0x195
#define KEY_AB          0x196
#define KEY_NEXT        0x197
#define KEY_RESTART     0x198
#define KEY_SLOW        0x199
#define KEY_SHUFFLE     0x19a
#define KEY_BREAK       0x19b
#define KEY_PREVIOUS        0x19c
#define KEY_DIGITS      0x19d
#define KEY_TEEN        0x19e
#define KEY_TWEN        0x19f

#define KEY_FRAMEBACK       0x1b2
#define KEY_FRAMEFORWARD    0x1b3
#define KEY_CONTEXT_MENU    0x1fb

#define KEY_MAX         0x1ff

/* Relative axes */

#define REL_X           0x00
#define REL_Y           0x01
#define REL_Z           0x02
#define REL_RX          0x03
#define REL_RY          0x04
#define REL_RZ          0x05
#define REL_HWHEEL      0x06
#define REL_DIAL        0x07
#define REL_WHEEL       0x08
#define REL_MISC        0x09
#define REL_MAX         0x0f

/* Absolute axes */

#define ABS_X           0x00
#define ABS_Y           0x01
#define ABS_Z           0x02
#define ABS_RX          0x03
#define ABS_RY          0x04
#define ABS_RZ          0x05
#define ABS_THROTTLE        0x06
#define ABS_RUDDER      0x07
#define ABS_WHEEL       0x08
#define ABS_GAS         0x09
#define ABS_BRAKE       0x0a
#define ABS_HAT0X       0x10
#define ABS_HAT0Y       0x11
#define ABS_HAT1X       0x12
#define ABS_HAT1Y       0x13
#define ABS_HAT2X       0x14
#define ABS_HAT2Y       0x15
#define ABS_HAT3X       0x16
#define ABS_HAT3Y       0x17
#define ABS_PRESSURE        0x18
#define ABS_DISTANCE        0x19
#define ABS_TILT_X      0x1a
#define ABS_TILT_Y      0x1b
#define ABS_TOOL_WIDTH      0x1c
#define ABS_VOLUME      0x20
#define ABS_MISC        0x28
#define ABS_MAX         0x3f

/* Switch events */

#define SW_0            0x00
#define SW_1            0x01
#define SW_2            0x02
#define SW_3            0x03
#define SW_4            0x04
#define SW_5            0x05
#define SW_6            0x06
#define SW_7            0x07
#define SW_MAX          0x0f

/* Misc events */

#define MSC_SERIAL      0x00
#define MSC_PULSELED        0x01
#define MSC_GESTURE     0x02
#define MSC_RAW         0x03
#define MSC_SCAN        0x04
#define MSC_MAX         0x07

/* LEDs */

#define LED_NUML        0x00
#define LED_CAPSL       0x01
#define LED_SCROLLL     0x02
#define LED_COMPOSE     0x03
#define LED_KANA        0x04
#define LED_SLEEP       0x05
#define LED_SUSPEND     0x06
#define LED_MUTE        0x07
#define LED_MISC        0x08
#define LED_MAIL        0x09
#define LED_CHARGING        0x0a
#define LED_MAX         0x0f

/* Autorepeat values */

#define REP_DELAY       0x00
#define REP_PERIOD      0x01
#define REP_MAX         0x01

/* Sounds */

#define SND_CLICK       0x00
#define SND_BELL        0x01
#define SND_TONE        0x02
#define SND_MAX         0x07

/* Identifiers */

#define ID_BUS          0
#define ID_VENDOR       1
#define ID_PRODUCT      2
#define ID_VERSION      3

#define BUS_PCI         0x01
#define BUS_ISAPNP      0x02
#define BUS_USB         0x03
#define BUS_HIL         0x04
#define BUS_BLUETOOTH       0x05

#define BUS_ISA         0x10
#define BUS_I8042       0x11
#define BUS_XTKBD       0x12
#define BUS_RS232       0x13
#define BUS_GAMEPORT        0x14
#define BUS_PARPORT     0x15
#define BUS_AMIGA       0x16
#define BUS_ADB         0x17
#define BUS_I2C         0x18
#define BUS_HOST        0x19
#define BUS_GSC         0x1A

/* User input interface */

#define UINPUT_IOCTL_BASE   'U'

#define UI_DEV_CREATE       _IO(UINPUT_IOCTL_BASE, 1)
#define UI_DEV_DESTROY      _IO(UINPUT_IOCTL_BASE, 2)

#define UI_SET_EVBIT        _IOW(UINPUT_IOCTL_BASE, 100, int)
#define UI_SET_KEYBIT       _IOW(UINPUT_IOCTL_BASE, 101, int)
#define UI_SET_RELBIT       _IOW(UINPUT_IOCTL_BASE, 102, int)
#define UI_SET_ABSBIT       _IOW(UINPUT_IOCTL_BASE, 103, int)
#define UI_SET_MSCBIT       _IOW(UINPUT_IOCTL_BASE, 104, int)
#define UI_SET_LEDBIT       _IOW(UINPUT_IOCTL_BASE, 105, int)
#define UI_SET_SNDBIT       _IOW(UINPUT_IOCTL_BASE, 106, int)
#define UI_SET_FFBIT        _IOW(UINPUT_IOCTL_BASE, 107, int)
#define UI_SET_PHYS     _IOW(UINPUT_IOCTL_BASE, 108, char*)
#define UI_SET_SWBIT        _IOW(UINPUT_IOCTL_BASE, 109, int)

#ifndef NBITS
#define NBITS(x) ((((x) - 1) / (sizeof(long) * 8)) + 1)
#endif

#define UINPUT_MAX_NAME_SIZE    80


/*******************************************************************************
**  Type definitions and return values
********************************************************************************/

struct uinput_id {
    uint16_t bustype;
    uint16_t vendor;
    uint16_t product;
    uint16_t version;
};

struct uinput_dev {
    char name[UINPUT_MAX_NAME_SIZE];
    struct uinput_id id;
    int ff_effects_max;
    int absmax[ABS_MAX + 1];
    int absmin[ABS_MAX + 1];
    int absfuzz[ABS_MAX + 1];
    int absflat[ABS_MAX + 1];
};

struct uinput_event {
    struct timeval time;
    uint16_t type;
    uint16_t code;
    int32_t value;
};

#ifdef __cplusplus
}
#endif

#endif /* __UINPUT_H */

三、Example

UinputManager.h

#ifndef UINPUT_MANAGER_H
#define UINPUT_MANAGER_H

#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <math.h>
#include <time.h>
#include <sys/time.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <sys/socket.h>
#include <sys/un.h>
#include <utils/RefBase.h>
#include <cutils/log.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>
#include <linux/uinput.h>
#include <malloc.h>
#include <stdint.h>

#define KEYDOWN 1
#define KEYUP 0
#define TOUCHDOWN 1
#define TOUCHUP 0
#define ROTATING_90 1
#define ROTATING_180 2
#define ROTATING_270 3
class UinputManager{

private:
int fd_keyboard;
int fd_mouse;
int fd_touch;
int width;
int height;
void adapterxy(int &x,int &y,int ori);
public:
    UinputManager();
    virtual ~UinputManager();
    int createKeyboardDevice();
    int handleKey(int keycode,int status);

    int createMouseDevice();
    int handleMouseMove(int RelX,int RelY);
    int handleMouseKey(int status,int keycode);

    int createTouchDevice();
    int handleTouch(int type,int x,int y,int ori,int touchcode);
};

#endif

UinputManager.cpp

#include "UinputManager.h"
UinputManager::UinputManager():fd_mouse(-1),fd_keyboard(-1),fd_touch(-1),width(-1),height(-1){
}
virtual UinputManager::~UinputManager(){
}
int UinputManager::createKeyboardDevice(){
    struct uinput_user_dev uinp; 
    fd_keyboard=open("/dev/uinput", O_WRONLY | O_NDELAY);
    if(fd_keyboard<0){
        return -1;
    }
    memset(&uinp, 0x00, sizeof(uinp));
       strncpy(uinp.name,"myKeyboard", strlen("myKeyboard"));
       uinp.id.version = 1;
       uinp.id.bustype = BUS_USB;
    uinp.id.vendor = ***;
    uinp.id.product = ***;

    uinp.absmin[ABS_HAT0X] = -1;
    uinp.absmax[ABS_HAT0X] = 1;
    uinp.absfuzz[ABS_HAT0X] = 0;
    uinp.absflat[ABS_HAT0X] = 0;

    uinp.absmin[ABS_HAT0Y] = -1;
    uinp.absmax[ABS_HAT0Y] = 1;
    uinp.absfuzz[ABS_HAT0Y] = 0;
    uinp.absflat[ABS_HAT0Y] = 0;
    ioctl(fd_keyboard , UI_SET_EVBIT, EV_KEY);
    ioctl(fd_keyboard , UI_SET_EVBIT, EV_ABS);


    for(int i = 1; i <= 11; i++)
    {
        ioctl(fd_keyboard , UI_SET_KEYBIT, i);
    }
    for(int i = 59; i < 255; i++)
    {
        ioctl(fd_keyboard , UI_SET_KEYBIT, i);
    }

    ioctl(fd_keyboard , UI_SET_KEYBIT, KEY_ENTER);
    ioctl(fd_keyboard , UI_SET_KEYBIT, 0x192);
    ioctl(fd_keyboard, UI_SET_KEYBIT, 0x193);

    ioctl(fd_keyboard, UI_SET_KEYBIT, KEY_SELECT);
    ioctl(fd_keyboard , UI_SET_ABSBIT, ABS_HAT0X);
    ioctl(fd_keyboard , UI_SET_ABSBIT, ABS_HAT0Y);

    if(write(fd_keyboard , &uinp, sizeof(uinp)) != sizeof(uinp))
    {
        close(fd_keyboard);
        fd_keyboard= -1;
            return -1;
    }
    if(ioctl(fd_keyboard , UI_DEV_CREATE))
    {
        close(fd_keyboard);
        fd_keyboard= -1;
        return -1;
    }
        return fd_keyboard;
}

int UinputManager::handleKey(int keycode,int status){
        struct input_event event;
        int ret = -1;
        if(fd_keyboard<0){
            return -1;
        }
        memset(&event, 0, sizeof(event));
        gettimeofday(&event.time, NULL); 
        switch(status)
        {
        case KEYUP:
            event.type = EV_KEY;
            event.code = keycode;
            event.value = 0;
            write(fd_keyboard, &event, sizeof(event));
            event.type = EV_SYN;
            event.code = 0;
            event.value = 0;
         ret = write(fd_keyboard, &event, sizeof(event)) ;
            break;
        case KEYDOWN:
            event.type = EV_KEY;
            event.code = keycode;
            event.value = 1;
            write(fd_keyboard, &event, sizeof(event));
            event.type = EV_SYN;
            event.code = 0;
            event.value = 0;
            ret = write(fd_keyboard, &event, sizeof(event));
            break;
        default:
            break;

        }
        if(ret < 0){
            close(fd_keyboard);
            fd_keyboard= -1;
            return -1; 
        }
        return ret;
}

int UinputManager::createMouseDevice(){
    struct uinput_user_dev uinp;
    fd_mouse = open("/dev/uinput", O_WRONLY | O_NDELAY);
     if(fd_mouse <= 0)
    {
       return -1;
    }
    memset(&uinp, 0x00, sizeof(uinp));
    strncpy(uinp.name, "myMouse", strlen("myMouse"));
    uinp.id.version = 1;
    uinp.id.bustype = BUS_USB;

    ioctl(fd_mouse, UI_SET_EVBIT, EV_KEY);
    ioctl(fd_mouse, UI_SET_EVBIT, EV_REL);
    ioctl(fd_mouse, UI_SET_KEYBIT, BTN_MIDDLE);
    ioctl(fd_mouse, UI_SET_KEYBIT, BTN_LEFT);
    ioctl(fd_mouse, UI_SET_KEYBIT, BTN_RIGHT);
    ioctl(fd_mouse, UI_SET_RELBIT, REL_X);
    ioctl(fd_mouse, UI_SET_RELBIT, REL_Y);

    if(write(fd_mouse, &uinp, sizeof(uinp)) != sizeof(uinp))
    {
        close(fd_mouse);
        fd_mouse = -1;  
        return fd_mouse;
    }

    if(ioctl(fd_mouse, UI_DEV_CREATE))
    {
        close(fd_mouse);
        fd_mouse = -1;  
        return fd_mouse;
    }
    return fd_mouse;

}

int UinputManager::handleMouseMove(int RelX,int RelY){
    if(fd_mouse<0){
        return -1;
    }
    int ret=-1;
    static struct input_event ievent[3];
    static struct timespec now;
    float tv_nsec = 0;
    clock_gettime(CLOCK_MONOTONIC, &now);
    tv_nsec = now.tv_nsec / 1000;

    ievent[0].time.tv_sec = now.tv_sec;
    ievent[0].time.tv_usec = tv_nsec;
    ievent[0].type = EV_REL;
    ievent[0].code = REL_X;
    ievent[0].value = RelX;

    ievent[1].time.tv_sec = now.tv_sec;
    ievent[1].time.tv_usec = tv_nsec;
    ievent[1].type = EV_REL;
    ievent[1].code = REL_Y;
    ievent[1].value = RelY;

    ievent[2].time.tv_sec = now.tv_sec;
    ievent[2].time.tv_usec = tv_nsec;
    ievent[2].type = EV_SYN;
    ievent[2].code = 0;
    ievent[2].value = 0;

    ret=write(fd_mouse, &ievent[0], sizeof(ievent[0]));
    ret=write(fd_mouse, &ievent[1], sizeof(ievent[1]));
    ret=write(fd_mouse, &ievent[2], sizeof(ievent[2]));

    return ret;
}
int UinputManager::handleMouseKey(int status,int keycode){

    if(fd_mouse<0){
        return -1;
    }
    int ret=-1;
    struct input_event event;
    memset(&event, 0, sizeof(event));
    gettimeofday(&event.time, NULL); 

    event.type = EV_KEY;
    event.code = keycode;
    event.value = status;
    write(fd_mouse, &event, sizeof(event));

    event.type = EV_SYN;
    event.code = 0;
    event.value = 0;
    ret=write(fd_mouse, &event, sizeof(event));

    return ret;
}

int UinputManager::createTouchDevice(int sw,int sh){
    struct uinput_user_dev uinp; 
    width= sw;
    height= sh;

    fd_touch= open("/dev/uinput", O_WRONLY | O_NDELAY);
    if(fd_touch <= 0)
    {
        return false;
    }
    memset(&uinp, 0x00, sizeof(uinp));
    strncpy(uinp.name, "myTouch", strlen("myTouch"));
    uinp.id.version = 1;
    uinp.id.bustype = BUS_USB;

    uinp.absmin[ABS_MT_POSITION_X] = 0;
    uinp.absmax[ABS_MT_POSITION_X] = sw;
    uinp.absfuzz[ABS_MT_POSITION_X] = 0;
    uinp.absflat[ABS_MT_POSITION_X] = 0;

    uinp.absmin[ABS_MT_POSITION_Y] = 0;
    uinp.absmax[ABS_MT_POSITION_Y] = sh;
    uinp.absfuzz[ABS_MT_POSITION_Y] = 0;
    uinp.absflat[ABS_MT_POSITION_Y] = 0;

    uinp.absmin[ABS_MT_PRESSURE] = 0;
    uinp.absmax[ABS_MT_PRESSURE] = 1;
    uinp.absfuzz[ABS_MT_PRESSURE] = 0;
    uinp.absflat[ABS_MT_PRESSURE] = 0;
    uinp.absmin[ABS_MT_TOUCH_MAJOR] = 0;
    uinp.absmax[ABS_MT_TOUCH_MAJOR] = 31;
    uinp.absfuzz[ABS_MT_TOUCH_MAJOR] = 0;
    uinp.absflat[ABS_MT_TOUCH_MAJOR] = 0;
    uinp.absmin[ABS_MT_SLOT] = 0;
    uinp.absmax[ABS_MT_SLOT] = MT_SLOT_T;
    uinp.absfuzz[ABS_MT_SLOT] = 0;
    uinp.absflat[ABS_MT_SLOT] = 0;
    uinp.absmin[ABS_MT_TRACKING_ID] = 0;
    uinp.absmax[ABS_MT_TRACKING_ID] = MT_SLOT_T;
    uinp.absfuzz[ABS_MT_TRACKING_ID] = 0;
    uinp.absflat[ABS_MT_TRACKING_ID] = 0;

    ioctl(uinput_tfd, UI_SET_EVBIT, EV_ABS);
    ioctl(uinput_tfd, UI_SET_ABSBIT, ABS_MT_SLOT);
    ioctl(uinput_tfd, UI_SET_ABSBIT, ABS_MT_TRACKING_ID);
    ioctl(uinput_tfd, UI_SET_ABSBIT, ABS_MT_PRESSURE);
    ioctl(uinput_tfd, UI_SET_ABSBIT, ABS_MT_TOUCH_MAJOR);
    ioctl(uinput_tfd, UI_SET_ABSBIT, ABS_MT_POSITION_X);
    ioctl(uinput_tfd, UI_SET_ABSBIT, ABS_MT_POSITION_Y);
    ioctl(uinput_tfd, UI_SET_PROPBIT, INPUT_PROP_DIRECT);

    if(write(fd_touch, &uinp, sizeof(uinp)) != sizeof(uinp))
    {
        close(fd_touch);
        fd_touch = -1;
        return fd_touch;
    }

    if(ioctl(fd_touch, UI_DEV_CREATE))
    {
        close(fd_touch);
        fd_touch = -1;
        return fd_touch;
    }    
    return 1;
}
void UinputManager::adapterxy(int &x,int &y,int ori)
{
    int tx = x,ty = y;
    switch(ori)
    {
        case ROTATING_90:   
            x  =  width- ty;
            y  =  tx;
            break;
        case ROTATING_180:
            x = width - tx;
            y = height- ty;
            break;
        case ROTATING_270:
            x = ty;
            y = height -x;
            break;
    }
}

int UinputManager::handleTouch(int type,int x,int y,int ori,int touchcode){
    struct input_event event;

    if(fd_touch<0){
        if(!createTouchDevice(width,height))
        {
            return -1;
        }
    }

    memset(&event, 0, sizeof(event));
    gettimeofday(&event.time, NULL); 

    switch (type){
    case TOUCHDOWN:               //Touch
    {
        adapterxy(x,y,ori);//test
        event.type = EV_ABS;
        event.code = ABS_MT_SLOT;
        event.value = touchcode;
        write(fd_touch, &event, sizeof(event));

        event.type = EV_ABS;
        event.code = ABS_MT_TRACKING_ID;
        event.value = touchcode;
        write(fd_touch, &event, sizeof(event));


        event.type = EV_ABS;
        event.code = ABS_MT_TOUCH_MAJOR;
        event.value = MT_MAJOR;
        write(fd_touch, &event, sizeof(event));


        event.type = EV_ABS;
        event.code = ABS_MT_PRESSURE;
        event.value = 1;
        write(fd_touch, &event, sizeof(event));

        event.type = EV_ABS;
        event.code = ABS_MT_POSITION_X;
        event.value = x;
        write(fd_touch, &event, sizeof(event));

        event.type = EV_ABS;
        event.code = ABS_MT_POSITION_Y;
        event.value = y;
        write(fd_touch, &event, sizeof(event));

        event.type = EV_SYN;
        event.code = SYN_REPORT;
        event.value = 0;
        write(fd_touch, &event, sizeof(event));
    }
    break;

    case TOUCHUP:                //Left    
    {
        event.type = EV_ABS;
        event.code = ABS_MT_SLOT;
        event.value = touchcode;
        write(fd_touch, &event, sizeof(event));

        event.type = EV_ABS;
        event.code = ABS_MT_TRACKING_ID;
        event.value = -1;
        write(fd_touch, &event, sizeof(event));

        event.type = EV_SYN;
        event.code = SYN_REPORT;
        event.value = 0;
        write(fd_touch, &event, sizeof(event));
    }
    break;

    default:
        break;
    }
    return 1;
}

源码gitHub下载

猜你喜欢

转载自blog.csdn.net/qq_33750826/article/details/79447385