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