1 /*
2 * Copyright � 2012 Canonical, Ltd.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "synproto.h"
25 #include "synapticsstr.h"
26
27 static int
HwStateAllocTouch(struct SynapticsHwState * hw,SynapticsPrivate * priv)28 HwStateAllocTouch(struct SynapticsHwState *hw, SynapticsPrivate * priv)
29 {
30 int num_vals;
31 int i = 0;
32
33 hw->num_mt_mask = priv->num_slots;
34 hw->mt_mask = malloc(hw->num_mt_mask * sizeof(ValuatorMask *));
35 if (!hw->mt_mask)
36 goto fail;
37
38 num_vals = 2; /* x and y */
39 num_vals += 2; /* scroll axes */
40 num_vals += priv->num_mt_axes;
41
42 for (; i < hw->num_mt_mask; i++) {
43 hw->mt_mask[i] = valuator_mask_new(num_vals);
44 if (!hw->mt_mask[i])
45 goto fail;
46 }
47
48 hw->slot_state = calloc(hw->num_mt_mask, sizeof(enum SynapticsSlotState));
49 if (!hw->slot_state)
50 goto fail;
51
52 return Success;
53
54 fail:
55 for (i--; i >= 0; i--)
56 valuator_mask_free(&hw->mt_mask[i]);
57 free(hw->mt_mask);
58 hw->mt_mask = NULL;
59 return BadAlloc;
60 }
61
62 struct SynapticsHwState *
SynapticsHwStateAlloc(SynapticsPrivate * priv)63 SynapticsHwStateAlloc(SynapticsPrivate * priv)
64 {
65 struct SynapticsHwState *hw;
66
67 hw = calloc(1, sizeof(struct SynapticsHwState));
68 if (!hw)
69 return NULL;
70
71 if (HwStateAllocTouch(hw, priv) != Success) {
72 free(hw);
73 return NULL;
74 }
75
76 return hw;
77 }
78
79 void
SynapticsHwStateFree(struct SynapticsHwState ** hw)80 SynapticsHwStateFree(struct SynapticsHwState **hw)
81 {
82 int i;
83
84 if (!*hw)
85 return;
86
87 free((*hw)->slot_state);
88 for (i = 0; i < (*hw)->num_mt_mask; i++)
89 valuator_mask_free(&(*hw)->mt_mask[i]);
90 free((*hw)->mt_mask);
91
92 free(*hw);
93 *hw = NULL;
94 }
95
96 void
SynapticsCopyHwState(struct SynapticsHwState * dst,const struct SynapticsHwState * src)97 SynapticsCopyHwState(struct SynapticsHwState *dst,
98 const struct SynapticsHwState *src)
99 {
100 int i;
101
102 dst->millis = src->millis;
103 dst->x = src->x;
104 dst->y = src->y;
105 dst->z = src->z;
106 dst->cumulative_dx = src->cumulative_dx;
107 dst->cumulative_dy = src->cumulative_dy;
108 dst->numFingers = src->numFingers;
109 dst->fingerWidth = src->fingerWidth;
110 dst->left = src->left & BTN_EMULATED_FLAG ? 0 : src->left;
111 dst->right = src->right & BTN_EMULATED_FLAG ? 0 : src->right;
112 dst->up = src->up;
113 dst->down = src->down;
114 memcpy(dst->multi, src->multi, sizeof(dst->multi));
115 dst->middle = src->middle & BTN_EMULATED_FLAG ? 0 : src->middle;
116 for (i = 0; i < dst->num_mt_mask && i < src->num_mt_mask; i++)
117 valuator_mask_copy(dst->mt_mask[i], src->mt_mask[i]);
118 memcpy(dst->slot_state, src->slot_state,
119 dst->num_mt_mask * sizeof(enum SynapticsSlotState));
120 }
121
122 void
SynapticsResetHwState(struct SynapticsHwState * hw)123 SynapticsResetHwState(struct SynapticsHwState *hw)
124 {
125 hw->millis = 0;
126 hw->x = INT_MIN;
127 hw->y = INT_MIN;
128 hw->z = 0;
129 hw->cumulative_dx = 0;
130 hw->cumulative_dy = 0;
131 hw->numFingers = 0;
132 hw->fingerWidth = 0;
133
134 hw->left = 0;
135 hw->right = 0;
136 hw->up = 0;
137 hw->down = 0;
138
139 hw->middle = 0;
140 memset(hw->multi, 0, sizeof(hw->multi));
141
142 SynapticsResetTouchHwState(hw, TRUE);
143 }
144
145 void
SynapticsResetTouchHwState(struct SynapticsHwState * hw,Bool set_slot_empty)146 SynapticsResetTouchHwState(struct SynapticsHwState *hw, Bool set_slot_empty)
147 {
148 int i;
149
150 for (i = 0; i < hw->num_mt_mask; i++) {
151 int j;
152
153 /* Leave x and y valuators in case we need to restart touch */
154 for (j = 2; j < valuator_mask_num_valuators(hw->mt_mask[i]); j++)
155 valuator_mask_unset(hw->mt_mask[i], j);
156
157 switch (hw->slot_state[i]) {
158 case SLOTSTATE_OPEN:
159 case SLOTSTATE_OPEN_EMPTY:
160 case SLOTSTATE_UPDATE:
161 hw->slot_state[i] =
162 set_slot_empty ? SLOTSTATE_EMPTY : SLOTSTATE_OPEN_EMPTY;
163 break;
164
165 default:
166 hw->slot_state[i] = SLOTSTATE_EMPTY;
167 break;
168 }
169 }
170 }
171