同樣當我們想應用 python-evdev uinput 程式庫寫作程式,在閱讀 『技術文件 』時,請務須仔細而且確實,千萬不要隨意放過不清楚的『術語』。底下列出相關文檔,方便讀者參考︰
class evdev.uinput.UInput(events=None, name=’py-evdev-uinput’, vendor=1, product=1, version=1, bustype=3, devnode=’/dev/uinput’)
A userland input device and that can inject input events into the linux input subsystem.
__init__
(events=None, name=’py-evdev-uinput’, vendor=1, product=1, version=1, bustype=3, devnode=’/dev/uinput’)-
Parameters: - events (dictionary of event types mapping to lists of event codes.) – the event types and codes that the uinput device will be able to inject – defaults to all key codes.
- name – the name of the input device.
- vendor – vendor identifier.
- product – product identifier.
- version – version identifier.
- bustype – bustype identifier.
Note
If you do not specify any events, the uinput device will be able to inject only KEY_*
and BTN_*
event codes.
name
- Uinput device name.
vendor
- Device vendor identifier.
product
- Device product identifier.
version
- Device version identifier.
bustype
- Device bustype – eg.
BUS_USB
.
devnode
- Uinput device node – eg.
/dev/uinput/
.
fd
- Write-only, non-blocking file descriptor to the uinput device node.
device
- An
InputDevice
instance for the fake input device.None
if the device cannot be opened for reading and writing.
write_event
(event)- Inject an input event into the input subsystem. Events are queued until a synchronization event is received.
Parameters: event – InputEvent instance or an object with an event
attribute (KeyEvent
,RelEvent
etc).Example:
ev = InputEvent(1334414993, 274296, ecodes.EV_KEY, ecodes.KEY_A, 1) ui.write_event(ev)
write
(etype, code, value)- Inject an input event into the input subsystem. Events are queued until a synchronization event is received.
Parameters: - etype – event type (eg.
EV_KEY
). - code – event code (eg.
KEY_A
). - value – event value (eg. 0 1 2 – depends on event type).
Example:
- etype – event type (eg.
ui.write(e.EV_KEY, e.KEY_A, 1) # key A - down ui.write(e.EV_KEY, e.KEY_A, 0) # key A - up
syn
()- Inject a
SYN_REPORT
event into the input subsystem. Events queued bywrite()
will be fired. If possible, events will be merged into an ‘atomic’ event.
capabilities
(verbose=False, absinfo=True)- See
capabilities
.
【Linux uinput 設備資料結構】
【uinput_request】
45 struct uinput_request { 46 unsigned int id; 47 unsigned int code; /* UI_FF_UPLOAD, UI_FF_ERASE */ 48 49 int retval; 50 struct completion done; 51 52 union { 53 unsigned int effect_id; 54 struct { 55 struct ff_effect *effect; 56 struct ff_effect *old; 57 } upload; 58 } u; 59 };
【uinput_device】
61 struct uinput_device { 62 struct input_dev *dev; 63 struct mutex mutex; 64 enum uinput_state state; 65 wait_queue_head_t waitq; 66 unsigned char ready; 67 unsigned char head; 68 unsigned char tail; 69 struct input_event buff[UINPUT_BUFFER_SIZE]; 70 unsigned int ff_effects_max; 71 72 struct uinput_request *requests[UINPUT_NUM_REQUESTS]; 73 wait_queue_head_t requests_waitq; 74 spinlock_t requests_lock; 75 };
【Linux 輸入設備資料結構】
121 struct input_dev { 122 const char *name; 123 const char *phys; 124 const char *uniq; 125 struct input_id id; 126 127 unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)]; 128 129 unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; 130 unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; 131 unsigned long relbit[BITS_TO_LONGS(REL_CNT)]; 132 unsigned long absbit[BITS_TO_LONGS(ABS_CNT)]; 133 unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)]; 134 unsigned long ledbit[BITS_TO_LONGS(LED_CNT)]; 135 unsigned long sndbit[BITS_TO_LONGS(SND_CNT)]; 136 unsigned long ffbit[BITS_TO_LONGS(FF_CNT)]; 137 unsigned long swbit[BITS_TO_LONGS(SW_CNT)]; 138 139 unsigned int hint_events_per_packet; 140 141 unsigned int keycodemax; 142 unsigned int keycodesize; 143 void *keycode; 144 145 int (*setkeycode)(struct input_dev *dev, 146 const struct input_keymap_entry *ke, 147 unsigned int *old_keycode); 148 int (*getkeycode)(struct input_dev *dev, 149 struct input_keymap_entry *ke); 150 151 struct ff_device *ff; 152 153 unsigned int repeat_key; 154 struct timer_list timer; 155 156 int rep[REP_CNT]; 157 158 struct input_mt *mt; 159 160 struct input_absinfo *absinfo; 161 162 unsigned long key[BITS_TO_LONGS(KEY_CNT)]; 163 unsigned long led[BITS_TO_LONGS(LED_CNT)]; 164 unsigned long snd[BITS_TO_LONGS(SND_CNT)]; 165 unsigned long sw[BITS_TO_LONGS(SW_CNT)]; 166 167 int (*open)(struct input_dev *dev); 168 void (*close)(struct input_dev *dev); 169 int (*flush)(struct input_dev *dev, struct file *file); 170 int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); 171 172 struct input_handle __rcu *grab; 173 174 spinlock_t event_lock; 175 struct mutex mutex; 176 177 unsigned int users; 178 bool going_away; 179 180 struct device dev; 181 182 struct list_head h_list; 183 struct list_head node; 184 185 unsigned int num_vals; 186 unsigned int max_vals; 187 struct input_value *vals; 188 189 bool devres_managed; 190 };
【Linux uinput API】
Linux/include/uapi/linux/uinput.h
【input_event】
24 struct input_event { 25 struct timeval time; 26 __u16 type; 27 __u16 code; 28 __s32 value; 29 };
【input_id】
41 struct input_id { 42 __u16 bustype; 43 __u16 vendor; 44 __u16 product; 45 __u16 version; 46 };
【核心說明文件】
再經過範例的練習,
【Injecting input events】
>>> from evdev import UInput, ecodes as e >>> ui = UInput() >>> # accepts only KEY_* events by default >>> ui.write(e.EV_KEY, e.KEY_A, 1) # KEY_A down >>> ui.write(e.EV_KEY, e.KEY_A, 0) # KEY_A up >>> ui.syn() >>> ui.close()
【Injecting events (2)】
>>> ev = InputEvent(1334414993, 274296, ecodes.EV_KEY, ecodes.KEY_A, 1) >>> with UInput() as ui: ... ui.write_event(ev) ... ui.syn()
【Specifying uinput device options】
>>> from evdev import UInput, AbsInfo, ecodes as e >>> cap = { ... e.EV_KEY : [e.KEY_A, e.KEY_B], ... e.EV_ABS : [ ... (e.ABS_X, AbsInfo(value=0, min=0, max=255, ... fuzz=0, flat=0, resolution=0)), ... (e.ABS_Y, AbsInfo(0, 0, 255, 0, 0, 0)), ... (e.ABS_MT_POSITION_X, (0, 255, 128, 0)) ] ... } >>> ui = UInput(cap, name='example-device', version=0x3) >>> print(ui) name "example-device", bus "BUS_USB", vendor "0001", product "0001", version "0003" event types: EV_KEY EV_ABS EV_SYN >>> print(ui.capabilities()) {0: [0, 1, 3], 1: [30, 48], 3: [(0, AbsInfo(value=0, min=0, max=0, fuzz=255, flat=0, resolution=0)), (1, AbsInfo(value=0, min=0, max=0, fuzz=255, flat=0, resolution=0)), (53, AbsInfo(value=0, min=0, max=255, fuzz=128, flat=0, resolution=0))]} >>> # move mouse cursor >>> ui.write(e.EV_ABS, e.ABS_X, 20) >>> ui.write(e.EV_ABS, e.ABS_Y, 20) >>> ui.syn()
,或將能對『核心輸入子系統』以及『python-evdev 程式庫』多些了解的乎!?