Linux Audio

Check our new training course

Loading...
v3.1
  1/*
  2 * Input Multitouch Library
  3 *
  4 * Copyright (c) 2008-2010 Henrik Rydberg
  5 *
  6 * This program is free software; you can redistribute it and/or modify it
  7 * under the terms of the GNU General Public License version 2 as published by
  8 * the Free Software Foundation.
  9 */
 10
 11#include <linux/input/mt.h>
 
 12#include <linux/slab.h>
 13
 14#define TRKID_SGN	((TRKID_MAX + 1) >> 1)
 15
 16/**
 17 * input_mt_init_slots() - initialize MT input slots
 18 * @dev: input device supporting MT events and finger tracking
 19 * @num_slots: number of slots used by the device
 20 *
 21 * This function allocates all necessary memory for MT slot handling
 22 * in the input device, prepares the ABS_MT_SLOT and
 23 * ABS_MT_TRACKING_ID events for use and sets up appropriate buffers.
 24 * May be called repeatedly. Returns -EINVAL if attempting to
 25 * reinitialize with a different number of slots.
 26 */
 27int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots)
 28{
 29	int i;
 30
 31	if (!num_slots)
 32		return 0;
 33	if (dev->mt)
 34		return dev->mtsize != num_slots ? -EINVAL : 0;
 35
 36	dev->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL);
 37	if (!dev->mt)
 38		return -ENOMEM;
 39
 40	dev->mtsize = num_slots;
 41	input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0);
 42	input_set_abs_params(dev, ABS_MT_TRACKING_ID, 0, TRKID_MAX, 0, 0);
 43	input_set_events_per_packet(dev, 6 * num_slots);
 44
 45	/* Mark slots as 'unused' */
 46	for (i = 0; i < num_slots; i++)
 47		input_mt_set_value(&dev->mt[i], ABS_MT_TRACKING_ID, -1);
 48
 49	return 0;
 50}
 51EXPORT_SYMBOL(input_mt_init_slots);
 52
 53/**
 54 * input_mt_destroy_slots() - frees the MT slots of the input device
 55 * @dev: input device with allocated MT slots
 56 *
 57 * This function is only needed in error path as the input core will
 58 * automatically free the MT slots when the device is destroyed.
 59 */
 60void input_mt_destroy_slots(struct input_dev *dev)
 61{
 62	kfree(dev->mt);
 63	dev->mt = NULL;
 64	dev->mtsize = 0;
 65	dev->slot = 0;
 66	dev->trkid = 0;
 67}
 68EXPORT_SYMBOL(input_mt_destroy_slots);
 69
 70/**
 71 * input_mt_report_slot_state() - report contact state
 72 * @dev: input device with allocated MT slots
 73 * @tool_type: the tool type to use in this slot
 74 * @active: true if contact is active, false otherwise
 75 *
 76 * Reports a contact via ABS_MT_TRACKING_ID, and optionally
 77 * ABS_MT_TOOL_TYPE. If active is true and the slot is currently
 78 * inactive, or if the tool type is changed, a new tracking id is
 79 * assigned to the slot. The tool type is only reported if the
 80 * corresponding absbit field is set.
 81 */
 82void input_mt_report_slot_state(struct input_dev *dev,
 83				unsigned int tool_type, bool active)
 84{
 85	struct input_mt_slot *mt;
 86	int id;
 87
 88	if (!dev->mt || !active) {
 89		input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
 90		return;
 91	}
 92
 93	mt = &dev->mt[dev->slot];
 94	id = input_mt_get_value(mt, ABS_MT_TRACKING_ID);
 95	if (id < 0 || input_mt_get_value(mt, ABS_MT_TOOL_TYPE) != tool_type)
 96		id = input_mt_new_trkid(dev);
 97
 98	input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, id);
 99	input_event(dev, EV_ABS, ABS_MT_TOOL_TYPE, tool_type);
100}
101EXPORT_SYMBOL(input_mt_report_slot_state);
102
103/**
104 * input_mt_report_finger_count() - report contact count
105 * @dev: input device with allocated MT slots
106 * @count: the number of contacts
107 *
108 * Reports the contact count via BTN_TOOL_FINGER, BTN_TOOL_DOUBLETAP,
109 * BTN_TOOL_TRIPLETAP and BTN_TOOL_QUADTAP.
110 *
111 * The input core ensures only the KEY events already setup for
112 * this device will produce output.
113 */
114void input_mt_report_finger_count(struct input_dev *dev, int count)
115{
116	input_event(dev, EV_KEY, BTN_TOOL_FINGER, count == 1);
117	input_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, count == 2);
118	input_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, count == 3);
119	input_event(dev, EV_KEY, BTN_TOOL_QUADTAP, count == 4);
 
120}
121EXPORT_SYMBOL(input_mt_report_finger_count);
122
123/**
124 * input_mt_report_pointer_emulation() - common pointer emulation
125 * @dev: input device with allocated MT slots
126 * @use_count: report number of active contacts as finger count
127 *
128 * Performs legacy pointer emulation via BTN_TOUCH, ABS_X, ABS_Y and
129 * ABS_PRESSURE. Touchpad finger count is emulated if use_count is true.
130 *
131 * The input core ensures only the KEY and ABS axes already setup for
132 * this device will produce output.
133 */
134void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)
135{
136	struct input_mt_slot *oldest = 0;
137	int oldid = dev->trkid;
138	int count = 0;
139	int i;
140
141	for (i = 0; i < dev->mtsize; ++i) {
142		struct input_mt_slot *ps = &dev->mt[i];
143		int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID);
144
145		if (id < 0)
146			continue;
147		if ((id - oldid) & TRKID_SGN) {
148			oldest = ps;
149			oldid = id;
150		}
151		count++;
152	}
153
154	input_event(dev, EV_KEY, BTN_TOUCH, count > 0);
155	if (use_count)
156		input_mt_report_finger_count(dev, count);
157
158	if (oldest) {
159		int x = input_mt_get_value(oldest, ABS_MT_POSITION_X);
160		int y = input_mt_get_value(oldest, ABS_MT_POSITION_Y);
161		int p = input_mt_get_value(oldest, ABS_MT_PRESSURE);
162
163		input_event(dev, EV_ABS, ABS_X, x);
164		input_event(dev, EV_ABS, ABS_Y, y);
165		input_event(dev, EV_ABS, ABS_PRESSURE, p);
166	} else {
167		input_event(dev, EV_ABS, ABS_PRESSURE, 0);
168	}
169}
170EXPORT_SYMBOL(input_mt_report_pointer_emulation);
v3.5.6
  1/*
  2 * Input Multitouch Library
  3 *
  4 * Copyright (c) 2008-2010 Henrik Rydberg
  5 *
  6 * This program is free software; you can redistribute it and/or modify it
  7 * under the terms of the GNU General Public License version 2 as published by
  8 * the Free Software Foundation.
  9 */
 10
 11#include <linux/input/mt.h>
 12#include <linux/export.h>
 13#include <linux/slab.h>
 14
 15#define TRKID_SGN	((TRKID_MAX + 1) >> 1)
 16
 17/**
 18 * input_mt_init_slots() - initialize MT input slots
 19 * @dev: input device supporting MT events and finger tracking
 20 * @num_slots: number of slots used by the device
 21 *
 22 * This function allocates all necessary memory for MT slot handling
 23 * in the input device, prepares the ABS_MT_SLOT and
 24 * ABS_MT_TRACKING_ID events for use and sets up appropriate buffers.
 25 * May be called repeatedly. Returns -EINVAL if attempting to
 26 * reinitialize with a different number of slots.
 27 */
 28int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots)
 29{
 30	int i;
 31
 32	if (!num_slots)
 33		return 0;
 34	if (dev->mt)
 35		return dev->mtsize != num_slots ? -EINVAL : 0;
 36
 37	dev->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL);
 38	if (!dev->mt)
 39		return -ENOMEM;
 40
 41	dev->mtsize = num_slots;
 42	input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0);
 43	input_set_abs_params(dev, ABS_MT_TRACKING_ID, 0, TRKID_MAX, 0, 0);
 44	input_set_events_per_packet(dev, 6 * num_slots);
 45
 46	/* Mark slots as 'unused' */
 47	for (i = 0; i < num_slots; i++)
 48		input_mt_set_value(&dev->mt[i], ABS_MT_TRACKING_ID, -1);
 49
 50	return 0;
 51}
 52EXPORT_SYMBOL(input_mt_init_slots);
 53
 54/**
 55 * input_mt_destroy_slots() - frees the MT slots of the input device
 56 * @dev: input device with allocated MT slots
 57 *
 58 * This function is only needed in error path as the input core will
 59 * automatically free the MT slots when the device is destroyed.
 60 */
 61void input_mt_destroy_slots(struct input_dev *dev)
 62{
 63	kfree(dev->mt);
 64	dev->mt = NULL;
 65	dev->mtsize = 0;
 66	dev->slot = 0;
 67	dev->trkid = 0;
 68}
 69EXPORT_SYMBOL(input_mt_destroy_slots);
 70
 71/**
 72 * input_mt_report_slot_state() - report contact state
 73 * @dev: input device with allocated MT slots
 74 * @tool_type: the tool type to use in this slot
 75 * @active: true if contact is active, false otherwise
 76 *
 77 * Reports a contact via ABS_MT_TRACKING_ID, and optionally
 78 * ABS_MT_TOOL_TYPE. If active is true and the slot is currently
 79 * inactive, or if the tool type is changed, a new tracking id is
 80 * assigned to the slot. The tool type is only reported if the
 81 * corresponding absbit field is set.
 82 */
 83void input_mt_report_slot_state(struct input_dev *dev,
 84				unsigned int tool_type, bool active)
 85{
 86	struct input_mt_slot *mt;
 87	int id;
 88
 89	if (!dev->mt || !active) {
 90		input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
 91		return;
 92	}
 93
 94	mt = &dev->mt[dev->slot];
 95	id = input_mt_get_value(mt, ABS_MT_TRACKING_ID);
 96	if (id < 0 || input_mt_get_value(mt, ABS_MT_TOOL_TYPE) != tool_type)
 97		id = input_mt_new_trkid(dev);
 98
 99	input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, id);
100	input_event(dev, EV_ABS, ABS_MT_TOOL_TYPE, tool_type);
101}
102EXPORT_SYMBOL(input_mt_report_slot_state);
103
104/**
105 * input_mt_report_finger_count() - report contact count
106 * @dev: input device with allocated MT slots
107 * @count: the number of contacts
108 *
109 * Reports the contact count via BTN_TOOL_FINGER, BTN_TOOL_DOUBLETAP,
110 * BTN_TOOL_TRIPLETAP and BTN_TOOL_QUADTAP.
111 *
112 * The input core ensures only the KEY events already setup for
113 * this device will produce output.
114 */
115void input_mt_report_finger_count(struct input_dev *dev, int count)
116{
117	input_event(dev, EV_KEY, BTN_TOOL_FINGER, count == 1);
118	input_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, count == 2);
119	input_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, count == 3);
120	input_event(dev, EV_KEY, BTN_TOOL_QUADTAP, count == 4);
121	input_event(dev, EV_KEY, BTN_TOOL_QUINTTAP, count == 5);
122}
123EXPORT_SYMBOL(input_mt_report_finger_count);
124
125/**
126 * input_mt_report_pointer_emulation() - common pointer emulation
127 * @dev: input device with allocated MT slots
128 * @use_count: report number of active contacts as finger count
129 *
130 * Performs legacy pointer emulation via BTN_TOUCH, ABS_X, ABS_Y and
131 * ABS_PRESSURE. Touchpad finger count is emulated if use_count is true.
132 *
133 * The input core ensures only the KEY and ABS axes already setup for
134 * this device will produce output.
135 */
136void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)
137{
138	struct input_mt_slot *oldest = 0;
139	int oldid = dev->trkid;
140	int count = 0;
141	int i;
142
143	for (i = 0; i < dev->mtsize; ++i) {
144		struct input_mt_slot *ps = &dev->mt[i];
145		int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID);
146
147		if (id < 0)
148			continue;
149		if ((id - oldid) & TRKID_SGN) {
150			oldest = ps;
151			oldid = id;
152		}
153		count++;
154	}
155
156	input_event(dev, EV_KEY, BTN_TOUCH, count > 0);
157	if (use_count)
158		input_mt_report_finger_count(dev, count);
159
160	if (oldest) {
161		int x = input_mt_get_value(oldest, ABS_MT_POSITION_X);
162		int y = input_mt_get_value(oldest, ABS_MT_POSITION_Y);
163		int p = input_mt_get_value(oldest, ABS_MT_PRESSURE);
164
165		input_event(dev, EV_ABS, ABS_X, x);
166		input_event(dev, EV_ABS, ABS_Y, y);
167		input_event(dev, EV_ABS, ABS_PRESSURE, p);
168	} else {
169		input_event(dev, EV_ABS, ABS_PRESSURE, 0);
170	}
171}
172EXPORT_SYMBOL(input_mt_report_pointer_emulation);