#ifndef _INPUT_MT_LOCAL_H #define _INPUT_MT_LOCAL_H /* * Input Multitouch Library * * Copyright (c) 2010 Henrik Rydberg * * 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. */ #include #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) #include #else #include #define MT_TOOL_MAX 1 #define TRKID_MAX 0xffff #define TRKID_SGN ((TRKID_MAX + 1) >> 1) static int trkid; static inline void input_abs_set_res(struct input_dev *dev, unsigned int axis, int val) { dev->absres[axis] = val; } static inline void input_mt_set_value(struct input_mt_slot *slot, unsigned code, int value) { slot->abs[code - ABS_MT_FIRST] = value; } static inline int input_mt_get_value(const struct input_mt_slot *slot, unsigned code) { return slot->abs[code - ABS_MT_FIRST]; } static inline int input_mt_new_trkid(struct input_dev *dev) { return trkid++ & TRKID_MAX; } /** * input_mt_init_slots() - initialize MT input slots * @dev: input device supporting MT events and finger tracking * @num_slots: number of slots used by the device * * This function allocates all necessary memory for MT slot handling * in the input device, prepares the ABS_MT_SLOT and * ABS_MT_TRACKING_ID events for use and sets up appropriate buffers. * May be called repeatedly. Returns -EINVAL if attempting to * reinitialize with a different number of slots. */ static int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots) { int ret; if (dev->mt) return dev->mtsize != num_slots ? -EINVAL : 0; ret = input_mt_create_slots(dev, num_slots); if (ret) return ret; input_set_abs_params(dev, ABS_MT_TRACKING_ID, 0, TRKID_MAX, 0, 0); input_set_events_per_packet(dev, 6 * num_slots); return 0; } /** * input_mt_report_state() - report contact state * @dev: input device with allocated MT slots * @active: true if contact is active, false otherwise * * Reports an active touch via ABS_MT_TRACKING_ID. If active is * true and the slot is currently inactive, a new tracking id is * assigned to the slot. */ static void input_mt_report_slot_state(struct input_dev *dev, unsigned type, bool active) { struct input_mt_slot *mt = dev->mt; int id; if (!mt || !active) { input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); return; } id = input_mt_get_value(&mt[dev->slot], ABS_MT_TRACKING_ID); if (id < 0) id = input_mt_new_trkid(dev); input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, id); } /** * input_mt_report_pointer_emulation() - common pointer emulation * @dev: input device with allocated MT slots * * Performs legacy pointer emulation via BTN_TOUCH. */ static void input_mt_report_pointer_emulation(struct input_dev *dev, bool more) { struct input_mt_slot *oldest = 0; int oldid = trkid; int count = 0; int i; for (i = 0; i < dev->mtsize; ++i) { struct input_mt_slot *ps = &dev->mt[i]; int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID); if (id < 0) continue; if ((id - oldid) & TRKID_SGN) { oldest = ps; oldid = id; } count++; } input_event(dev, EV_KEY, BTN_TOUCH, count > 0); input_event(dev, EV_KEY, BTN_TOOL_FINGER, count == 1); input_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, count == 2); input_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, count == 3); input_event(dev, EV_KEY, BTN_TOOL_QUADTAP, count > 3); if (oldest) { int x = input_mt_get_value(oldest, ABS_MT_POSITION_X); int y = input_mt_get_value(oldest, ABS_MT_POSITION_Y); int p = input_mt_get_value(oldest, ABS_MT_PRESSURE); input_event(dev, EV_ABS, ABS_X, x); input_event(dev, EV_ABS, ABS_Y, y); input_event(dev, EV_ABS, ABS_PRESSURE, p); } else { input_event(dev, EV_ABS, ABS_PRESSURE, 0); } } #endif #endif