synproto.c revision 28515619
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
27static int
28HwStateAllocTouch(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
62struct SynapticsHwState *
63SynapticsHwStateAlloc(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
79void
80SynapticsHwStateFree(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
96void
97SynapticsCopyHwState(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
122void
123SynapticsResetHwState(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
145void
146SynapticsResetTouchHwState(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