• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define TP_MAGIC_SLOWDOWN_FLAT 0.2968
38 
39 struct touchpad_accelerator_flat {
40 	struct motion_filter base;
41 
42 	double factor;
43 	int dpi;
44 };
45 
46 static struct normalized_coords
accelerator_filter_touchpad_flat(struct motion_filter * filter,const struct device_float_coords * unaccelerated,void * data,uint64_t time)47 accelerator_filter_touchpad_flat(struct motion_filter *filter,
48 				 const struct device_float_coords *unaccelerated,
49 				 void *data, uint64_t time)
50 {
51 	struct touchpad_accelerator_flat *accel =
52 		(struct touchpad_accelerator_flat *)filter;
53 	double factor; /* unitless factor */
54 	struct normalized_coords normalized;
55 
56 	/* You want flat acceleration, you get flat acceleration for the
57 	 * device */
58 	factor = accel->factor;
59 	normalized = normalize_for_dpi(unaccelerated, accel->dpi);
60 	normalized.x = TP_MAGIC_SLOWDOWN_FLAT * factor * normalized.x;
61 	normalized.y = TP_MAGIC_SLOWDOWN_FLAT * factor * normalized.y;
62 
63 	return normalized;
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 	/* We map the unaccelerated flat filter to have the same behavior as
72 	 * the "accelerated" flat filter.
73 	 * The filter by definition is flat, i.e. it does not actually
74 	 * apply any acceleration (merely a constant factor) and we can assume
75 	 * that a user wants all mouse movement to have the same speed, mapped
76 	 * 1:1 to the input speed.
77 	 *
78 	 * Thus we apply the same factor to our non-accelerated motion - this way
79 	 * things like gestures end up having the same movement as
80 	 * pointer motion.
81 	 */
82 	return accelerator_filter_touchpad_flat(filter, unaccelerated, data, time);
83 }
84 
85 static bool
accelerator_set_speed_touchpad_flat(struct motion_filter * filter,double speed_adjustment)86 accelerator_set_speed_touchpad_flat(struct motion_filter *filter,
87 				    double speed_adjustment)
88 {
89 	struct touchpad_accelerator_flat *accel_filter =
90 		(struct touchpad_accelerator_flat *)filter;
91 
92 	assert(speed_adjustment >= -1.0 && speed_adjustment <= 1.0);
93 
94 	accel_filter->factor = max(0.005, 1 + speed_adjustment);
95 	filter->speed_adjustment = speed_adjustment;
96 
97 	return true;
98 }
99 
100 static void
accelerator_destroy_touchpad_flat(struct motion_filter * filter)101 accelerator_destroy_touchpad_flat(struct motion_filter *filter)
102 {
103 	struct touchpad_accelerator_flat *accel =
104 		(struct touchpad_accelerator_flat *) filter;
105 
106 	free(accel);
107 }
108 
109 static const struct motion_filter_interface accelerator_interface_touchpad_flat = {
110 	.type = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT,
111 	.filter = accelerator_filter_touchpad_flat,
112 	.filter_constant = accelerator_filter_noop_touchpad_flat,
113 	.filter_scroll = accelerator_filter_noop_touchpad_flat,
114 	.restart = NULL,
115 	.destroy = accelerator_destroy_touchpad_flat,
116 	.set_speed = accelerator_set_speed_touchpad_flat,
117 };
118 
119 struct motion_filter *
create_pointer_accelerator_filter_touchpad_flat(int dpi)120 create_pointer_accelerator_filter_touchpad_flat(int dpi)
121 {
122 	struct touchpad_accelerator_flat *filter;
123 
124 	filter = zalloc(sizeof *filter);
125 	filter->base.interface = &accelerator_interface_touchpad_flat;
126 	filter->dpi = dpi;
127 
128 	return &filter->base;
129 }
130