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 struct pointer_accelerator_flat {
38 struct motion_filter base;
39
40 double factor;
41 int dpi;
42 };
43
44 static struct normalized_coords
accelerator_filter_flat(struct motion_filter * filter,const struct device_float_coords * unaccelerated,void * data,uint64_t time)45 accelerator_filter_flat(struct motion_filter *filter,
46 const struct device_float_coords *unaccelerated,
47 void *data, uint64_t time)
48 {
49 struct pointer_accelerator_flat *accel_filter =
50 (struct pointer_accelerator_flat *)filter;
51 double factor; /* unitless factor */
52 struct normalized_coords accelerated;
53
54 /* You want flat acceleration, you get flat acceleration for the
55 * device */
56 factor = accel_filter->factor;
57 accelerated.x = factor * unaccelerated->x;
58 accelerated.y = factor * unaccelerated->y;
59
60 return accelerated;
61 }
62
63 static struct normalized_coords
accelerator_filter_noop_flat(struct motion_filter * filter,const struct device_float_coords * unaccelerated,void * data,uint64_t time)64 accelerator_filter_noop_flat(struct motion_filter *filter,
65 const struct device_float_coords *unaccelerated,
66 void *data, uint64_t time)
67 {
68 struct pointer_accelerator_flat *accel =
69 (struct pointer_accelerator_flat *) filter;
70
71 return normalize_for_dpi(unaccelerated, accel->dpi);
72 }
73
74 static bool
accelerator_set_speed_flat(struct motion_filter * filter,double speed_adjustment)75 accelerator_set_speed_flat(struct motion_filter *filter,
76 double speed_adjustment)
77 {
78 struct pointer_accelerator_flat *accel_filter =
79 (struct pointer_accelerator_flat *)filter;
80
81 assert(speed_adjustment >= -1.0 && speed_adjustment <= 1.0);
82
83 /* Speed range is 0-200% of the nominal speed, with 0 mapping to the
84 * nominal speed. Anything above 200 is pointless, we're already
85 * skipping over ever second pixel at 200% speed.
86 */
87
88 accel_filter->factor = max(0.005, 1 + speed_adjustment);
89 filter->speed_adjustment = speed_adjustment;
90
91 return true;
92 }
93
94 static void
accelerator_destroy_flat(struct motion_filter * filter)95 accelerator_destroy_flat(struct motion_filter *filter)
96 {
97 struct pointer_accelerator_flat *accel =
98 (struct pointer_accelerator_flat *) filter;
99
100 free(accel);
101 }
102
103 struct motion_filter_interface accelerator_interface_flat = {
104 .type = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT,
105 .filter = accelerator_filter_flat,
106 .filter_constant = accelerator_filter_noop_flat,
107 .restart = NULL,
108 .destroy = accelerator_destroy_flat,
109 .set_speed = accelerator_set_speed_flat,
110 };
111
112 struct motion_filter *
create_pointer_accelerator_filter_flat(int dpi)113 create_pointer_accelerator_filter_flat(int dpi)
114 {
115 struct pointer_accelerator_flat *filter;
116
117 filter = zalloc(sizeof *filter);
118 filter->base.interface = &accelerator_interface_flat;
119 filter->dpi = dpi;
120
121 return &filter->base;
122 }
123