参考: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 <aris@cathedrallabs.org>
*
* Changes/Revisions:
* 0.4 01/09/2014 (Benjamin Tissoires <benjamin.tissoires@redhat.com>)
* - 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 <micah@navi.cx>)
* - 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;
}