128515619Smrg/*
228515619Smrg * Copyright � 2012 Canonical, Ltd.
328515619Smrg *
428515619Smrg * Permission is hereby granted, free of charge, to any person obtaining a
528515619Smrg * copy of this software and associated documentation files (the "Software"),
628515619Smrg * to deal in the Software without restriction, including without limitation
728515619Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
828515619Smrg * and/or sell copies of the Software, and to permit persons to whom the
928515619Smrg * Software is furnished to do so, subject to the following conditions:
1028515619Smrg *
1128515619Smrg * The above copyright notice and this permission notice (including the next
1228515619Smrg * paragraph) shall be included in all copies or substantial portions of the
1328515619Smrg * Software.
1428515619Smrg *
1528515619Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1628515619Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1728515619Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1828515619Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1928515619Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2028515619Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2128515619Smrg * DEALINGS IN THE SOFTWARE.
2228515619Smrg */
2328515619Smrg
2428515619Smrg#include "synproto.h"
2528515619Smrg#include "synapticsstr.h"
2628515619Smrg
2728515619Smrgstatic int
2828515619SmrgHwStateAllocTouch(struct SynapticsHwState *hw, SynapticsPrivate * priv)
2928515619Smrg{
3028515619Smrg    int num_vals;
3128515619Smrg    int i = 0;
3228515619Smrg
3328515619Smrg    hw->num_mt_mask = priv->num_slots;
3428515619Smrg    hw->mt_mask = malloc(hw->num_mt_mask * sizeof(ValuatorMask *));
3528515619Smrg    if (!hw->mt_mask)
3628515619Smrg        goto fail;
3728515619Smrg
3828515619Smrg    num_vals = 2;               /* x and y */
3928515619Smrg    num_vals += 2;              /* scroll axes */
4028515619Smrg    num_vals += priv->num_mt_axes;
4128515619Smrg
4228515619Smrg    for (; i < hw->num_mt_mask; i++) {
4328515619Smrg        hw->mt_mask[i] = valuator_mask_new(num_vals);
4428515619Smrg        if (!hw->mt_mask[i])
4528515619Smrg            goto fail;
4628515619Smrg    }
4728515619Smrg
4828515619Smrg    hw->slot_state = calloc(hw->num_mt_mask, sizeof(enum SynapticsSlotState));
4928515619Smrg    if (!hw->slot_state)
5028515619Smrg        goto fail;
5128515619Smrg
5228515619Smrg    return Success;
5328515619Smrg
5428515619Smrg fail:
5528515619Smrg    for (i--; i >= 0; i--)
5628515619Smrg        valuator_mask_free(&hw->mt_mask[i]);
5728515619Smrg    free(hw->mt_mask);
5828515619Smrg    hw->mt_mask = NULL;
5928515619Smrg    return BadAlloc;
6028515619Smrg}
6128515619Smrg
6228515619Smrgstruct SynapticsHwState *
6328515619SmrgSynapticsHwStateAlloc(SynapticsPrivate * priv)
6428515619Smrg{
6528515619Smrg    struct SynapticsHwState *hw;
6628515619Smrg
6728515619Smrg    hw = calloc(1, sizeof(struct SynapticsHwState));
6828515619Smrg    if (!hw)
6928515619Smrg        return NULL;
7028515619Smrg
7128515619Smrg    if (HwStateAllocTouch(hw, priv) != Success) {
7228515619Smrg        free(hw);
7328515619Smrg        return NULL;
7428515619Smrg    }
7528515619Smrg
7628515619Smrg    return hw;
7728515619Smrg}
7828515619Smrg
7928515619Smrgvoid
8028515619SmrgSynapticsHwStateFree(struct SynapticsHwState **hw)
8128515619Smrg{
8228515619Smrg    int i;
8328515619Smrg
8428515619Smrg    if (!*hw)
8528515619Smrg        return;
8628515619Smrg
8728515619Smrg    free((*hw)->slot_state);
8828515619Smrg    for (i = 0; i < (*hw)->num_mt_mask; i++)
8928515619Smrg        valuator_mask_free(&(*hw)->mt_mask[i]);
9028515619Smrg    free((*hw)->mt_mask);
9128515619Smrg
9228515619Smrg    free(*hw);
9328515619Smrg    *hw = NULL;
9428515619Smrg}
9528515619Smrg
9628515619Smrgvoid
9728515619SmrgSynapticsCopyHwState(struct SynapticsHwState *dst,
9828515619Smrg                     const struct SynapticsHwState *src)
9928515619Smrg{
10028515619Smrg    int i;
10128515619Smrg
10228515619Smrg    dst->millis = src->millis;
10328515619Smrg    dst->x = src->x;
10428515619Smrg    dst->y = src->y;
10528515619Smrg    dst->z = src->z;
10628515619Smrg    dst->cumulative_dx = src->cumulative_dx;
10728515619Smrg    dst->cumulative_dy = src->cumulative_dy;
10828515619Smrg    dst->numFingers = src->numFingers;
10928515619Smrg    dst->fingerWidth = src->fingerWidth;
11028515619Smrg    dst->left = src->left & BTN_EMULATED_FLAG ? 0 : src->left;
11128515619Smrg    dst->right = src->right & BTN_EMULATED_FLAG ? 0 : src->right;
11228515619Smrg    dst->up = src->up;
11328515619Smrg    dst->down = src->down;
11428515619Smrg    memcpy(dst->multi, src->multi, sizeof(dst->multi));
11528515619Smrg    dst->middle = src->middle & BTN_EMULATED_FLAG ? 0 : src->middle;
11628515619Smrg    for (i = 0; i < dst->num_mt_mask && i < src->num_mt_mask; i++)
11728515619Smrg        valuator_mask_copy(dst->mt_mask[i], src->mt_mask[i]);
11828515619Smrg    memcpy(dst->slot_state, src->slot_state,
11928515619Smrg           dst->num_mt_mask * sizeof(enum SynapticsSlotState));
12028515619Smrg}
12128515619Smrg
12228515619Smrgvoid
12328515619SmrgSynapticsResetHwState(struct SynapticsHwState *hw)
12428515619Smrg{
12528515619Smrg    hw->millis = 0;
12628515619Smrg    hw->x = INT_MIN;
12728515619Smrg    hw->y = INT_MIN;
12828515619Smrg    hw->z = 0;
12928515619Smrg    hw->cumulative_dx = 0;
13028515619Smrg    hw->cumulative_dy = 0;
13128515619Smrg    hw->numFingers = 0;
13228515619Smrg    hw->fingerWidth = 0;
13328515619Smrg
13428515619Smrg    hw->left = 0;
13528515619Smrg    hw->right = 0;
13628515619Smrg    hw->up = 0;
13728515619Smrg    hw->down = 0;
13828515619Smrg
13928515619Smrg    hw->middle = 0;
14028515619Smrg    memset(hw->multi, 0, sizeof(hw->multi));
14128515619Smrg
14228515619Smrg    SynapticsResetTouchHwState(hw, TRUE);
14328515619Smrg}
14428515619Smrg
14528515619Smrgvoid
14628515619SmrgSynapticsResetTouchHwState(struct SynapticsHwState *hw, Bool set_slot_empty)
14728515619Smrg{
14828515619Smrg    int i;
14928515619Smrg
15028515619Smrg    for (i = 0; i < hw->num_mt_mask; i++) {
15128515619Smrg        int j;
15228515619Smrg
15328515619Smrg        /* Leave x and y valuators in case we need to restart touch */
15428515619Smrg        for (j = 2; j < valuator_mask_num_valuators(hw->mt_mask[i]); j++)
15528515619Smrg            valuator_mask_unset(hw->mt_mask[i], j);
15628515619Smrg
15728515619Smrg        switch (hw->slot_state[i]) {
15828515619Smrg        case SLOTSTATE_OPEN:
15928515619Smrg        case SLOTSTATE_OPEN_EMPTY:
16028515619Smrg        case SLOTSTATE_UPDATE:
16128515619Smrg            hw->slot_state[i] =
16228515619Smrg                set_slot_empty ? SLOTSTATE_EMPTY : SLOTSTATE_OPEN_EMPTY;
16328515619Smrg            break;
16428515619Smrg
16528515619Smrg        default:
16628515619Smrg            hw->slot_state[i] = SLOTSTATE_EMPTY;
16728515619Smrg            break;
16828515619Smrg        }
16928515619Smrg    }
17028515619Smrg}
171