1 /*
2 * Copyright © 2006-2009 Simon Thum
3 * Copyright © 2012 Jonas Ådahl
4 * Copyright © 2014-2015 Red Hat, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25
26 #include "config.h"
27
28 #include <assert.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <stdint.h>
32
33 #include "filter.h"
34 #include "libinput-util.h"
35 #include "filter-private.h"
36
37
38 #define TP_MAGIC_SLOWDOWN_FLAT 0.2968
39
40 struct touchpad_accelerator_flat {
41 struct motion_filter base;
42
43 double factor;
44 int dpi;
45 };
46
47 static struct normalized_coords
accelerator_filter_touchpad_flat(struct motion_filter * filter,const struct device_float_coords * unaccelerated,void * data,uint64_t time)48 accelerator_filter_touchpad_flat(struct motion_filter *filter,
49 const struct device_float_coords *unaccelerated,
50 void *data, uint64_t time)
51 {
52 struct touchpad_accelerator_flat *accel_filter =
53 (struct touchpad_accelerator_flat *)filter;
54 double factor; /* unitless factor */
55 struct normalized_coords accelerated;
56
57 /* You want flat acceleration, you get flat acceleration for the
58 * device */
59 factor = accel_filter->factor;
60 accelerated.x = TP_MAGIC_SLOWDOWN_FLAT * factor * unaccelerated->x;
61 accelerated.y = TP_MAGIC_SLOWDOWN_FLAT * factor * unaccelerated->y;
62
63 return accelerated;
64 }
65
66 static struct normalized_coords
accelerator_filter_noop_touchpad_flat(struct motion_filter * filter,const struct device_float_coords * unaccelerated,void * data,uint64_t time)67 accelerator_filter_noop_touchpad_flat(struct motion_filter *filter,
68 const struct device_float_coords *unaccelerated,
69 void *data, uint64_t time)
70 {
71 struct touchpad_accelerator_flat *accel =
72 (struct touchpad_accelerator_flat *) filter;
73 struct normalized_coords normalized;
74
75 normalized = normalize_for_dpi(unaccelerated, accel->dpi);
76 normalized.x = TP_MAGIC_SLOWDOWN_FLAT * normalized.x;
77 normalized.y = TP_MAGIC_SLOWDOWN_FLAT * normalized.y;
78
79 return normalized;
80 }
81
82 static bool
accelerator_set_speed_touchpad_flat(struct motion_filter * filter,double speed_adjustment)83 accelerator_set_speed_touchpad_flat(struct motion_filter *filter,
84 double speed_adjustment)
85 {
86 struct touchpad_accelerator_flat *accel_filter =
87 (struct touchpad_accelerator_flat *)filter;
88
89 assert(speed_adjustment >= -1.0 && speed_adjustment <= 1.0);
90
91 accel_filter->factor = max(0.005, 1 + speed_adjustment);
92 filter->speed_adjustment = speed_adjustment;
93
94 return true;
95 }
96
97 static void
accelerator_destroy_touchpad_flat(struct motion_filter * filter)98 accelerator_destroy_touchpad_flat(struct motion_filter *filter)
99 {
100 struct touchpad_accelerator_flat *accel =
101 (struct touchpad_accelerator_flat *) filter;
102
103 free(accel);
104 }
105
106 struct motion_filter_interface accelerator_interface_touchpad_flat = {
107 .type = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT,
108 .filter = accelerator_filter_touchpad_flat,
109 .filter_constant = accelerator_filter_noop_touchpad_flat,
110 .restart = NULL,
111 .destroy = accelerator_destroy_touchpad_flat,
112 .set_speed = accelerator_set_speed_touchpad_flat,
113 };
114
115 struct motion_filter *
create_pointer_accelerator_filter_touchpad_flat(int dpi)116 create_pointer_accelerator_filter_touchpad_flat(int dpi)
117 {
118 struct touchpad_accelerator_flat *filter;
119
120 filter = zalloc(sizeof *filter);
121 filter->base.interface = &accelerator_interface_touchpad_flat;
122 filter->dpi = dpi;
123
124 return &filter->base;
125 }
126