xf86-input-mtrack-0.3.0/0000755000175000017500000000000012142445764015200 5ustar iwamatsuiwamatsuxf86-input-mtrack-0.3.0/src/0000755000175000017500000000000011772504475015772 5ustar iwamatsuiwamatsuxf86-input-mtrack-0.3.0/src/mtstate.c0000644000175000017500000002277511772504475017634 0ustar iwamatsuiwamatsu/*************************************************************************** * * Multitouch X driver * Copyright (C) 2008 Henrik Rydberg * Copyright (C) 2011 Ryan Bourgeois * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * **************************************************************************/ #include "mtstate.h" #include "trig.h" static int inline percentage(int dividend, int divisor) { return (double)dividend / (double)divisor * 100; } static int inline touch_range_ratio(const struct MConfig* cfg, int value) { return (double)(value - cfg->touch_min) / (double)(cfg->touch_max - cfg->touch_min) * 100; } /* Check if a finger is touching the trackpad. */ static int is_touch(const struct MConfig* cfg, const struct FingerState* hw) { if (cfg->touch_type == MCFG_SCALE) return percentage(hw->touch_major, hw->width_major) > cfg->touch_down; else if (cfg->touch_type == MCFG_SIZE) return touch_range_ratio(cfg, hw->touch_major) > cfg->touch_down; else if (cfg->touch_type == MCFG_PRESSURE) return touch_range_ratio(cfg, hw->pressure) > cfg->touch_down; else return 1; } /* Check if a finger is released from the touchpad. */ static int is_release(const struct MConfig* cfg, const struct FingerState* hw) { if (cfg->touch_type == MCFG_SCALE) return percentage(hw->touch_major, hw->width_major) < cfg->touch_up; else if (cfg->touch_type == MCFG_SIZE) return touch_range_ratio(cfg, hw->touch_major) < cfg->touch_up; else if (cfg->touch_type == MCFG_PRESSURE) return touch_range_ratio(cfg, hw->pressure) < cfg->touch_up; else return 0; } static int is_thumb(const struct MConfig* cfg, const struct FingerState* hw) { if (!cfg->touch_minor) return 0; int min = MINVAL(hw->touch_minor, hw->touch_major); int max = MAXVAL(hw->touch_minor, hw->touch_major); int pct = percentage(min, max); int size = touch_range_ratio(cfg, hw->touch_major); if (pct < cfg->thumb_ratio && size > cfg->thumb_size) { #if DEBUG_MTSTATE xf86Msg(X_INFO, "is_thumb: yes %d > %d && %d > %d\n", pct, cfg->thumb_ratio, size, cfg->thumb_size); #endif return 1; } else { #if DEBUG_MTSTATE xf86Msg(X_INFO, "is_thumb: no %d > %d && %d > %d\n", pct, cfg->thumb_ratio, size, cfg->thumb_size); #endif return 0; } } static int is_palm(const struct MConfig* cfg, const struct FingerState* hw) { if (cfg->touch_type != MCFG_SCALE && cfg->touch_type != MCFG_SIZE) return 0; int size = touch_range_ratio(cfg, hw->touch_major); if (size > cfg->palm_size) { #if DEBUG_MTSTATE xf86Msg(X_INFO, "is_palm: yes %d > %d\n", size, cfg->palm_size); #endif return 1; } else { #if DEBUG_MTSTATE xf86Msg(X_INFO, "is_palm: no %d > %d\n", size, cfg->palm_size); #endif return 0; } } /* Find a touch by its tracking ID. Return -1 if not found. */ static int find_touch(struct MTState* ms, int tracking_id) { int i; foreach_bit(i, ms->touch_used) { if (ms->touch[i].tracking_id == tracking_id) return i; } return -1; } /* Add a touch to the MTState. Return the new index of the touch. */ static int touch_append(struct MTState* ms, const struct MConfig* cfg, const struct Capabilities* caps, const struct HWState* hs, int fn) { int x, y; int n = firstbit(~ms->touch_used); const struct FingerState* fs = &hs->data[fn]; if (n < 0) xf86Msg(X_WARNING, "Too many touches to track. Ignoring touch %d.\n", fs->tracking_id); else { x = cfg->axis_x_invert ? get_cap_xflip(caps, fs->position_x) : fs->position_x; y = cfg->axis_y_invert ? get_cap_yflip(caps, fs->position_y) : fs->position_y; ms->touch[n].state = 0U; ms->touch[n].flags = 0U; timercp(&ms->touch[n].down, &hs->evtime); ms->touch[n].direction = TR_NONE; ms->touch[n].tracking_id = fs->tracking_id; ms->touch[n].x = x; ms->touch[n].y = y; ms->touch[n].dx = 0; ms->touch[n].dy = 0; ms->touch[n].total_dx = 0; ms->touch[n].total_dy = 0; SETBIT(ms->touch[n].state, MT_NEW); SETBIT(ms->touch_used, n); } return n; } /* Update a touch. */ static void touch_update(struct MTState* ms, const struct MConfig* cfg, const struct Capabilities* caps, const struct FingerState* fs, int touch) { int x, y; x = cfg->axis_x_invert ? get_cap_xflip(caps, fs->position_x) : fs->position_x; y = cfg->axis_y_invert ? get_cap_yflip(caps, fs->position_y) : fs->position_y; ms->touch[touch].dx = x - ms->touch[touch].x; ms->touch[touch].dy = y - ms->touch[touch].y; ms->touch[touch].total_dx += ms->touch[touch].dx; ms->touch[touch].total_dy += ms->touch[touch].dy; ms->touch[touch].x = x; ms->touch[touch].y = y; ms->touch[touch].direction = trig_direction(ms->touch[touch].dx, ms->touch[touch].dy); CLEARBIT(ms->touch[touch].state, MT_NEW); } /* Release a touch. */ static void touch_release(struct MTState* ms, int touch) { ms->touch[touch].dx = 0; ms->touch[touch].dy = 0; ms->touch[touch].direction = TR_NONE; CLEARBIT(ms->touch[touch].state, MT_NEW); SETBIT(ms->touch[touch].state, MT_RELEASED); } /* Invalidate all touches. */ static void touches_invalidate(struct MTState* ms) { int i; foreach_bit(i, ms->touch_used) SETBIT(ms->touch[i].state, MT_INVALID); } /* Update all touches. */ static void touches_update(struct MTState* ms, const struct MConfig* cfg, const struct HWState* hs, const struct Capabilities* caps) { int i, n, disable = 0; // Release missing touches. foreach_bit(i, ms->touch_used) { if (find_finger(hs, ms->touch[i].tracking_id) == -1) touch_release(ms, i); } // Add and update touches. foreach_bit(i, hs->used) { n = find_touch(ms, hs->data[i].tracking_id); if (n >= 0) { if (is_release(cfg, &hs->data[i])) touch_release(ms, n); else touch_update(ms, cfg, caps, &hs->data[i], n); } else if (is_touch(cfg, &hs->data[i])) n = touch_append(ms, cfg, caps, hs, i); if (n >= 0) { // Track and invalidate thumb, palm, and bottom edge touches. if (is_thumb(cfg, &hs->data[i])) SETBIT(ms->touch[n].state, MT_THUMB); else CLEARBIT(ms->touch[n].state, MT_THUMB); if (is_palm(cfg, &hs->data[i])) SETBIT(ms->touch[n].state, MT_PALM); else CLEARBIT(ms->touch[n].state, MT_PALM); if (ms->touch[n].y > (100 - cfg->bottom_edge)*cfg->pad_height/100) { if (GETBIT(ms->touch[n].state, MT_NEW)) SETBIT(ms->touch[n].state, MT_BOTTOM_EDGE); } else CLEARBIT(ms->touch[n].state, MT_BOTTOM_EDGE); MODBIT(ms->touch[n].state, MT_INVALID, GETBIT(ms->touch[n].state, MT_THUMB) && cfg->ignore_thumb || GETBIT(ms->touch[n].state, MT_PALM) && cfg->ignore_palm || GETBIT(ms->touch[n].state, MT_BOTTOM_EDGE)); disable |= cfg->disable_on_thumb && GETBIT(ms->touch[n].state, MT_THUMB); disable |= cfg->disable_on_palm && GETBIT(ms->touch[n].state, MT_PALM); } } if (disable) touches_invalidate(ms); } /* Remove released touches. */ static void touches_clean(struct MTState* ms) { int i, used; used = ms->touch_used; foreach_bit(i, used) { if (GETBIT(ms->touch[i].state, MT_RELEASED)) CLEARBIT(ms->touch_used, i); } } #if DEBUG_MTSTATE static void mtstate_output(const struct MTState* ms, const struct HWState* hs) { int i, n; char* type; struct timeval tv; n = bitcount(ms->touch_used); if (bitcount(ms->touch_used) > 0) { microtime(&tv); xf86Msg(X_INFO, "mtstate: %d touches at event time %llu (rt %llu)\n", n, timertoms(&hs->evtime), timertoms(&tv)); } foreach_bit(i, ms->touch_used) { if (GETBIT(ms->touch[i].state, MT_RELEASED)) { timersub(&hs->evtime, &ms->touch[i].down, &tv); xf86Msg(X_INFO, " released p(%d, %d) d(%+d, %+d) dir(%f) down(%llu) time(%lld)\n", ms->touch[i].x, ms->touch[i].y, ms->touch[i].dx, ms->touch[i].dy, ms->touch[i].direction, timertoms(&ms->touch[i].down), timertoms(&tv)); } else if (GETBIT(ms->touch[i].state, MT_NEW)) { xf86Msg(X_INFO, " new p(%d, %d) d(%+d, %+d) dir(%f) down(%llu)\n", ms->touch[i].x, ms->touch[i].y, ms->touch[i].dx, ms->touch[i].dy, ms->touch[i].direction, timertoms(&ms->touch[i].down)); } else if (GETBIT(ms->touch[i].state, MT_INVALID)) { timersub(&hs->evtime, &ms->touch[i].down, &tv); xf86Msg(X_INFO, " invalid p(%d, %d) d(%+d, %+d) dir(%f) down(%llu) time(%lld)\n", ms->touch[i].x, ms->touch[i].y, ms->touch[i].dx, ms->touch[i].dy, ms->touch[i].direction, timertoms(&ms->touch[i].down), timertoms(&tv)); } else { xf86Msg(X_INFO, " touching p(%d, %d) d(%+d, %+d) dir(%f) down(%llu)\n", ms->touch[i].x, ms->touch[i].y, ms->touch[i].dx, ms->touch[i].dy, ms->touch[i].direction, timertoms(&ms->touch[i].down)); } } } #endif void mtstate_init(struct MTState* ms) { memset(ms, 0, sizeof(struct MTState)); } // Process changes in touch state. void mtstate_extract(struct MTState* ms, const struct MConfig* cfg, const struct HWState* hs, const struct Capabilities* caps) { ms->state = 0; touches_clean(ms); touches_update(ms, cfg, hs, caps); #if DEBUG_MTSTATE mtstate_output(ms, hs); #endif } xf86-input-mtrack-0.3.0/src/mtouch.c0000644000175000017500000000420111772504475017432 0ustar iwamatsuiwamatsu/*************************************************************************** * * Multitouch X driver * Copyright (C) 2008 Henrik Rydberg * Copyright (C) 2011 Ryan Bourgeois * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * **************************************************************************/ #include "mtouch.h" static const int use_grab = 0; int mtouch_configure(struct MTouch* mt, int fd) { mt->fd = fd; int rc = read_capabilities(&mt->caps, mt->fd); if (rc < 0) return rc; output_capabilities(&mt->caps); return 0; } int mtouch_open(struct MTouch* mt, int fd) { int ret; mt->fd = fd; ret = mtdev_open(&mt->dev, mt->fd); if (ret) goto error; mconfig_init(&mt->cfg, &mt->caps); hwstate_init(&mt->hs, &mt->caps); mtstate_init(&mt->state); gestures_init(mt); if (use_grab) { SYSCALL(ret = ioctl(fd, EVIOCGRAB, 1)); if (ret) goto close; } return 0; close: mtdev_close(&mt->dev); error: return ret; } int mtouch_close(struct MTouch* mt) { int ret; if (use_grab) { SYSCALL(ret = ioctl(mt->fd, EVIOCGRAB, 0)); if (ret) xf86Msg(X_WARNING, "mtouch: ungrab failed\n"); } mtdev_close(&mt->dev); return 0; } int mtouch_read(struct MTouch* mt) { int ret = hwstate_modify(&mt->hs, &mt->dev, mt->fd, &mt->caps); if (ret <= 0) return ret; mtstate_extract(&mt->state, &mt->cfg, &mt->hs, &mt->caps); gestures_extract(mt); return 1; } int mtouch_delayed(struct MTouch* mt) { return gestures_delayed(mt); } xf86-input-mtrack-0.3.0/src/trig.c0000644000175000017500000000514311772504475017106 0ustar iwamatsuiwamatsu/*************************************************************************** * * Multitouch X driver * Copyright (C) 2011 Ryan Bourgeois * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * **************************************************************************/ #include "trig.h" #include "common.h" #include /* Convert a radians value into an mtrack angle. */ static double trig_encode_radians(double radians) { double angle = (radians / M_PI) * 4; if (angle < 0) angle = angle + 8; return angle; } /* Convert an mtrack angle value into radians. */ static double trig_decode_radians(double angle) { if (angle < 4) return (angle * M_PI) / 4; else return ((8 - angle) * M_PI) / -4; } double trig_direction(double dx, double dy) { double angle = TR_NONE; if (dx != 0 || dy != 0) return trig_encode_radians(atan2(dx, dy*-1)); return angle; } int trig_generalize(double dir) { if (dir == -1) return TR_NONE; else if (dir > 1 && dir <= 3) return TR_DIR_RT; else if (dir > 3 && dir <= 5) return TR_DIR_DN; else if (dir > 5 && dir <= 7) return TR_DIR_LT; else return TR_DIR_UP; } double trig_angles_add(double a1, double a2) { double a = MODVAL(a1 + a2, 8.0); if (a < 0) a = a + 8.0; return a; } double trig_angles_sub(double a1, double a2) { return trig_angles_add(a1, -1.0*a2); } double trig_angles_acute(double a1, double a2) { double angle; if (a1 > a2) angle = trig_angles_sub(a1, a2); else angle = trig_angles_sub(a2, a1); if (angle > 4) angle = 8 - angle; return angle; } double trig_angles_avg(double* angles, int len) { int i; double dx, dy, r; dx = dy = 0; for (i = 0; i < len; i++) { r = trig_decode_radians(angles[i]); dx += cos(r); dy += sin(r); } return trig_encode_radians(atan2(dy, dx)); } int trig_angles_cmp(double a1, double a2) { double m1, m2; m1 = MODVAL(a1, 8); m2 = MODVAL(a2, 8); if (m1 == m2) return 0; else if (m1 > m2) return 1; else return -1; } xf86-input-mtrack-0.3.0/src/gestures.c0000644000175000017500000005616711772504475020016 0ustar iwamatsuiwamatsu/*************************************************************************** * * Multitouch X driver * Copyright (C) 2008 Henrik Rydberg * Copyright (C) 2011 Ryan Bourgeois * * Gestures * Copyright (C) 2008 Henrik Rydberg * Copyright (C) 2010 Arturo Castro * Copyright (C) 2011 Ryan Bourgeois * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * **************************************************************************/ #include "gestures.h" #include "mtouch.h" #include "trig.h" #define IS_VALID_BUTTON(x) (x >= 0 && x <= 31) static void trigger_button_up(struct Gestures* gs, int button) { if (IS_VALID_BUTTON(button)) { if (button == 0 && gs->button_emulate > 0) { button = gs->button_emulate; gs->button_emulate = 0; } CLEARBIT(gs->buttons, button); #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "trigger_button_up: %d up\n", button); #endif } } static void trigger_button_down(struct Gestures* gs, int button) { struct timeval epoch; timerclear(&epoch); if (IS_VALID_BUTTON(button) && (button != gs->button_delayed || timercmp(&gs->button_delayed_time, &epoch, ==))) { SETBIT(gs->buttons, button); #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "trigger_button_down: %d down\n", button); #endif } #ifdef DEBUG_GESTURES else if (IS_VALID_BUTTON(button)) xf86Msg(X_INFO, "trigger_button_down: %d down ignored, in delayed mode\n", button); #endif } static void trigger_button_emulation(struct Gestures* gs, int button) { if (IS_VALID_BUTTON(button) && GETBIT(gs->buttons, 0)) { CLEARBIT(gs->buttons, 0); SETBIT(gs->buttons, button); gs->button_emulate = button; #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "trigger_button_emulation: %d emulated\n", button); #endif } } static void trigger_button_click(struct Gestures* gs, int button, struct timeval* trigger_up_time) { struct timeval epoch; timerclear(&epoch); if (IS_VALID_BUTTON(button) && timercmp(&gs->button_delayed_time, &epoch, ==)) { trigger_button_down(gs, button); gs->button_delayed = button; timercp(&gs->button_delayed_time, trigger_up_time); timerclear(&gs->button_delayed_delta); #ifdef DEBUG_GESTRUES xf86Msg(X_INFO, "trigger_button_click: %d placed in delayed mode\n"); #endif } #ifdef DEBUG_GESTURES else if (IS_VALID_BUTTON(button)) xf86Msg(X_INFO, "trigger_button_click: %d ignored, in delayed mode\n", button); #endif } static void trigger_drag_ready(struct Gestures* gs, const struct MConfig* cfg) { gs->move_drag = GS_DRAG_READY; timeraddms(&gs->time, cfg->drag_timeout, &gs->move_drag_expire); #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "trigger_drag_ready: drag is ready\n"); #endif } static int trigger_drag_start(struct Gestures* gs, const struct MConfig* cfg, int dx, int dy) { if (gs->move_drag == GS_DRAG_READY) { timerclear(&gs->move_drag_expire); if (cfg->drag_wait == 0) { gs->move_drag = GS_DRAG_ACTIVE; trigger_button_down(gs, 0); #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "trigger_drag_start: drag is active\n"); #endif } else { gs->move_drag = GS_DRAG_WAIT; gs->move_drag_dx = dx; gs->move_drag_dy = dy; timeraddms(&gs->time, cfg->drag_wait, &gs->move_drag_wait); #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "trigger_drag_start: drag in wait\n"); #endif } } else if (gs->move_drag == GS_DRAG_WAIT) { gs->move_drag_dx += dx; gs->move_drag_dy += dy; if (!timercmp(&gs->time, &gs->move_drag_wait, <)) { gs->move_drag = GS_DRAG_ACTIVE; trigger_button_down(gs, 0); #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "trigger_drag_start: drag is active\n"); #endif } else if (dist2(gs->move_drag_dx, gs->move_drag_dy) > SQRVAL(cfg->drag_dist)) { gs->move_drag = GS_NONE; #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "trigger_drag_start: drag canceled, moved too far\n"); #endif } } return gs->move_drag != GS_DRAG_WAIT; } static void trigger_drag_stop(struct Gestures* gs, int force) { if (gs->move_drag == GS_DRAG_READY && force) { gs->move_drag = GS_NONE; timerclear(&gs->move_drag_expire); #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "trigger_drag_stop: drag canceled\n"); #endif } else if (gs->move_drag == GS_DRAG_ACTIVE) { gs->move_drag = GS_NONE; timerclear(&gs->move_drag_expire); trigger_button_up(gs, 0); #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "trigger_drag_stop: drag stopped\n"); #endif } } static void buttons_update(struct Gestures* gs, const struct MConfig* cfg, const struct HWState* hs, struct MTState* ms) { if (!cfg->button_enable || cfg->trackpad_disable >= 3) return; static bitmask_t button_prev = 0U; int i, down, emulate, touching; down = 0; emulate = GETBIT(hs->button, 0) && !GETBIT(button_prev, 0); for (i = 0; i < 32; i++) { if (GETBIT(hs->button, i) == GETBIT(button_prev, i)) continue; if (GETBIT(hs->button, i)) { down++; trigger_button_down(gs, i); } else trigger_button_up(gs, i); } button_prev = hs->button; if (down) { int earliest, latest, moving = 0; gs->move_type = GS_NONE; timeraddms(&gs->time, cfg->gesture_wait, &gs->move_wait); earliest = -1; latest = -1; foreach_bit(i, ms->touch_used) { if (GETBIT(ms->touch[i].state, MT_INVALID)) continue; if (cfg->button_integrated && !GETBIT(ms->touch[i].flags, GS_BUTTON)) SETBIT(ms->touch[i].flags, GS_BUTTON); if (earliest == -1 || timercmp(&ms->touch[i].down, &ms->touch[earliest].down, <)) earliest = i; if (latest == -1 || timercmp(&ms->touch[i].down, &ms->touch[latest].down, >)) latest = i; } if (emulate) { if (cfg->button_zones && earliest >= 0) { int zones, left, right, pos; double width; zones = 0; if (cfg->button_1touch > 0) zones++; if (cfg->button_2touch > 0) zones++; if (cfg->button_3touch > 0) zones++; if (zones > 0) { width = ((double)cfg->pad_width)/((double)zones); pos = cfg->pad_width / 2 + ms->touch[earliest].x; #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "buttons_update: pad width %d, zones %d, zone width %f, x %d\n", cfg->pad_width, zones, width, pos); #endif for (i = 0; i < zones; i++) { left = width*i; right = width*(i+1); if (pos >= left && pos <= right) { #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "buttons_update: button %d, left %d, right %d (found)\n", i, left, right); #endif break; } #ifdef DEBUG_GESTURES else xf86Msg(X_INFO, "buttons_update: button %d, left %d, right %d\n", i, left, right); #endif } if (i == 0) trigger_button_emulation(gs, cfg->button_1touch - 1); else if (i == 1) trigger_button_emulation(gs, cfg->button_2touch - 1); else trigger_button_emulation(gs, cfg->button_3touch - 1); } } else if (latest >= 0) { touching = 0; struct timeval expire; foreach_bit(i, ms->touch_used) { timeraddms(&ms->touch[i].down, cfg->button_expire, &expire); if (cfg->button_move || cfg->button_expire == 0 || timercmp(&ms->touch[latest].down, &expire, <)) touching++; } if (cfg->button_integrated) touching--; if (touching == 1 && cfg->button_1touch > 0) trigger_button_emulation(gs, cfg->button_1touch - 1); else if (touching == 2 && cfg->button_2touch > 0) trigger_button_emulation(gs, cfg->button_2touch - 1); else if (touching == 3 && cfg->button_3touch > 0) trigger_button_emulation(gs, cfg->button_3touch - 1); } } } } static void tapping_update(struct Gestures* gs, const struct MConfig* cfg, struct MTState* ms) { int i, n, dist, released_max; struct timeval tv_tmp; struct timeval epoch; if (cfg->trackpad_disable >= 1) return; if (cfg->tap_4touch > 0) released_max = 4; else if (cfg->tap_3touch > 0) released_max = 3; else if (cfg->tap_2touch > 0) released_max = 2; else if (cfg->tap_1touch > 0) released_max = 1; else return; timerclear(&epoch); timeraddms(&gs->tap_time_down, cfg->tap_timeout, &tv_tmp); if (!timercmp(&gs->tap_time_down, &epoch, ==) && !timercmp(&gs->time, &tv_tmp, <)) { gs->tap_touching = 0; gs->tap_released = 0; timerclear(&gs->tap_time_down); foreach_bit(i, ms->touch_used) { if (GETBIT(ms->touch[i].flags, GS_TAP)) CLEARBIT(ms->touch[i].flags, GS_TAP); } } else { foreach_bit(i, ms->touch_used) { if (GETBIT(ms->touch[i].state, MT_INVALID) || GETBIT(ms->touch[i].flags, GS_BUTTON)) { if (GETBIT(ms->touch[i].flags, GS_TAP)) { CLEARBIT(ms->touch[i].flags, GS_TAP); gs->tap_touching--; #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "tapping_update: tap_touching-- (%d): invalid or button\n", gs->tap_touching); #endif } } else { if (GETBIT(ms->touch[i].state, MT_NEW)) { SETBIT(ms->touch[i].flags, GS_TAP); gs->tap_touching++; #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "tapping_update: tap_touching++ (%d): new touch\n", gs->tap_touching); #endif timerclear(&tv_tmp); if (timercmp(&gs->tap_time_down, &epoch, ==)) timercp(&gs->tap_time_down, &gs->time); } if (GETBIT(ms->touch[i].flags, GS_TAP)) { dist = dist2(ms->touch[i].total_dx, ms->touch[i].total_dy); if (dist >= SQRVAL(cfg->tap_dist)) { CLEARBIT(ms->touch[i].flags, GS_TAP); gs->tap_touching--; #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "tapping_update: tap_touching-- (%d): moved too far\n", gs->tap_touching); #endif } else if (GETBIT(ms->touch[i].state, MT_RELEASED)) { gs->tap_touching--; gs->tap_released++; #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "tapping_update: tap_touching-- (%d): released\n", gs->tap_touching); xf86Msg(X_INFO, "tapping_update: tap_released++ (%d) (max %d): released\n", gs->tap_released, released_max); #endif } } } } } if ((gs->tap_touching == 0 && gs->tap_released > 0) || gs->tap_released >= released_max) { foreach_bit(i, ms->touch_used) { if (GETBIT(ms->touch[i].flags, GS_TAP)) CLEARBIT(ms->touch[i].flags, GS_TAP); } if (gs->tap_released == 1) n = cfg->tap_1touch - 1; else if (gs->tap_released == 2) n = cfg->tap_2touch - 1; else if (gs->tap_released == 3) n = cfg->tap_3touch - 1; else n = cfg->tap_4touch - 1; trigger_button_click(gs, n, &tv_tmp); if (cfg->drag_enable && n == 0) trigger_drag_ready(gs, cfg); gs->move_type = GS_NONE; timeraddms(&gs->time, cfg->gesture_wait, &gs->move_wait); gs->tap_touching = 0; gs->tap_released = 0; timerclear(&gs->tap_time_down); } } static void trigger_move(struct Gestures* gs, const struct MConfig* cfg, int dx, int dy) { if ((gs->move_type == GS_MOVE || !timercmp(&gs->time, &gs->move_wait, <)) && (dx != 0 || dy != 0)) { if (trigger_drag_start(gs, cfg, dx, dy)) { gs->move_dx = (int)(dx*cfg->sensitivity); gs->move_dy = (int)(dy*cfg->sensitivity); gs->move_type = GS_MOVE; gs->move_dist = 0; gs->move_dir = TR_NONE; gs->move_speed = hypot(gs->move_dx, gs->move_dy)/timertomicro(&gs->dt); timerclear(&gs->move_wait); #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "trigger_move: %d, %d (speed %f)\n", gs->move_dx, gs->move_dy, gs->move_speed); #endif } } } static void trigger_scroll(struct Gestures* gs, const struct MConfig* cfg, double dist, int dir) { if (gs->move_type == GS_SCROLL || !timercmp(&gs->time, &gs->move_wait, <)) { struct timeval tv_tmp; trigger_drag_stop(gs, 1); if (gs->move_type != GS_SCROLL || gs->move_dir != dir) gs->move_dist = 0; gs->move_dx = 0; gs->move_dy = 0; gs->move_type = GS_SCROLL; gs->move_dist += (int)ABSVAL(dist); gs->move_dir = dir; gs->move_speed = dist/timertomicro(&gs->dt); timeraddms(&gs->time, cfg->gesture_wait, &gs->move_wait); if (gs->move_dist >= cfg->scroll_dist) { gs->move_dist = MODVAL(gs->move_dist, cfg->scroll_dist); timeraddms(&gs->time, cfg->gesture_hold, &tv_tmp); if (dir == TR_DIR_UP) trigger_button_click(gs, cfg->scroll_up_btn - 1, &tv_tmp); else if (dir == TR_DIR_DN) trigger_button_click(gs, cfg->scroll_dn_btn - 1, &tv_tmp); else if (dir == TR_DIR_LT) trigger_button_click(gs, cfg->scroll_lt_btn - 1, &tv_tmp); else if (dir == TR_DIR_RT) trigger_button_click(gs, cfg->scroll_rt_btn - 1, &tv_tmp); } #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "trigger_scroll: scrolling %+f in direction %d (at %d of %d) (speed %f)\n", dist, dir, gs->move_dist, cfg->scroll_dist, gs->move_speed); #endif } } static void trigger_swipe(struct Gestures* gs, const struct MConfig* cfg, double dist, int dir, int isfour) { if (gs->move_type == GS_SWIPE || !timercmp(&gs->time, &gs->move_wait, <)) { struct timeval tv_tmp; trigger_drag_stop(gs, 1); if (gs->move_type != GS_SWIPE || gs->move_dir != dir) gs->move_dist = 0; gs->move_dx = 0; gs->move_dy = 0; gs->move_type = GS_SWIPE; gs->move_dist += (int)ABSVAL(dist); gs->move_dir = dir; gs->move_speed = dist/timertomicro(&gs->dt); timeraddms(&gs->time, cfg->gesture_wait, &gs->move_wait); timeraddms(&gs->time, cfg->gesture_hold, &tv_tmp); if (isfour) { if (cfg->swipe4_dist > 0 && gs->move_dist >= cfg->swipe4_dist) { gs->move_dist = MODVAL(gs->move_dist, cfg->swipe4_dist); if (dir == TR_DIR_UP) trigger_button_click(gs, cfg->swipe4_up_btn - 1, &tv_tmp); else if (dir == TR_DIR_DN) trigger_button_click(gs, cfg->swipe4_dn_btn - 1, &tv_tmp); else if (dir == TR_DIR_LT) trigger_button_click(gs, cfg->swipe4_lt_btn - 1, &tv_tmp); else if (dir == TR_DIR_RT) trigger_button_click(gs, cfg->swipe4_rt_btn - 1, &tv_tmp); } #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "trigger_swipe4: swiping %+f in direction %d (at %d of %d) (speed %f)\n", dist, dir, gs->move_dist, cfg->swipe_dist, gs->move_speed); #endif } else { if (cfg->swipe_dist > 0 && gs->move_dist >= cfg->swipe_dist) { gs->move_dist = MODVAL(gs->move_dist, cfg->swipe_dist); if (dir == TR_DIR_UP) trigger_button_click(gs, cfg->swipe_up_btn - 1, &tv_tmp); else if (dir == TR_DIR_DN) trigger_button_click(gs, cfg->swipe_dn_btn - 1, &tv_tmp); else if (dir == TR_DIR_LT) trigger_button_click(gs, cfg->swipe_lt_btn - 1, &tv_tmp); else if (dir == TR_DIR_RT) trigger_button_click(gs, cfg->swipe_rt_btn - 1, &tv_tmp); } #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "trigger_swipe: swiping %+f in direction %d (at %d of %d)\n", dist, dir, gs->move_dist, cfg->swipe_dist); #endif } } } static void trigger_scale(struct Gestures* gs, const struct MConfig* cfg, double dist, int dir) { if (gs->move_type == GS_SCALE || !timercmp(&gs->time, &gs->move_wait, <)) { struct timeval tv_tmp; trigger_drag_stop(gs, 1); if (gs->move_type != GS_SCALE || gs->move_dir != dir) gs->move_dist = 0; gs->move_dx = 0; gs->move_dy = 0; gs->move_type = GS_SCALE; gs->move_dist += (int)ABSVAL(dist); gs->move_dir = dir; gs->move_speed = dist/timertomicro(&gs->dt); timeraddms(&gs->time, cfg->gesture_wait, &gs->move_wait); if (gs->move_dist >= cfg->scale_dist) { gs->move_dist = MODVAL(gs->move_dist, cfg->scale_dist); timeraddms(&gs->time, cfg->gesture_hold, &tv_tmp); if (dir == TR_DIR_UP) trigger_button_click(gs, cfg->scale_up_btn - 1, &tv_tmp); else if (dir == TR_DIR_DN) trigger_button_click(gs, cfg->scale_dn_btn - 1, &tv_tmp); } #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "trigger_scale: scaling %+f in direction %d (at %d of %d) (speed %f)\n", dist, dir, gs->move_dist, cfg->scale_dist, gs->move_speed); #endif } } static void trigger_rotate(struct Gestures* gs, const struct MConfig* cfg, double dist, int dir) { if (gs->move_type == GS_ROTATE || !timercmp(&gs->time, &gs->move_wait, <)) { struct timeval tv_tmp; trigger_drag_stop(gs, 1); if (gs->move_type != GS_ROTATE || gs->move_dir != dir) gs->move_dist = 0; gs->move_dx = 0; gs->move_dy = 0; gs->move_type = GS_ROTATE; gs->move_dist += (int)ABSVAL(dist); gs->move_dir = dir; gs->move_speed = dist/timertomicro(&gs->dt); timeraddms(&gs->time, cfg->gesture_wait, &gs->move_wait); if (gs->move_dist >= cfg->rotate_dist) { gs->move_dist = MODVAL(gs->move_dist, cfg->rotate_dist); timeraddms(&gs->time, cfg->gesture_hold, &tv_tmp); if (dir == TR_DIR_LT) trigger_button_click(gs, cfg->rotate_lt_btn - 1, &tv_tmp); else if (dir == TR_DIR_RT) trigger_button_click(gs, cfg->rotate_rt_btn - 1, &tv_tmp); } #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "trigger_rotate: rotating %+f in direction %d (at %d of %d) (speed %f)\n", dist, dir, gs->move_dist, cfg->rotate_dist, gs->move_speed); #endif } } static void trigger_reset(struct Gestures* gs) { trigger_drag_stop(gs, 0); gs->move_dx = 0; gs->move_dy = 0; gs->move_type = GS_NONE; gs->move_dist = 0; gs->move_dir = TR_NONE; timerclear(&gs->move_wait); } static int get_scroll_dir(const struct Touch* t1, const struct Touch* t2) { if (trig_angles_acute(t1->direction, t2->direction) < 2.0) { double angles[2]; angles[0] = t1->direction; angles[1] = t2->direction; return trig_generalize(trig_angles_avg(angles, 2)); } return TR_NONE; } static int get_rotate_dir(const struct Touch* t1, const struct Touch* t2) { double v, d1, d2; v = trig_direction(t2->x - t1->x, t2->y - t1->y); d1 = trig_angles_add(v, 2); d2 = trig_angles_sub(v, 2); if (trig_angles_acute(t1->direction, d1) < 2 && trig_angles_acute(t2->direction, d2) < 2) return TR_DIR_RT; else if (trig_angles_acute(t1->direction, d2) < 2 && trig_angles_acute(t2->direction, d1) < 2) return TR_DIR_LT; return TR_NONE; } static int get_scale_dir(const struct Touch* t1, const struct Touch* t2) { double v; if (trig_angles_acute(t1->direction, t2->direction) >= 2) { v = trig_direction(t2->x - t1->x, t2->y - t1->y); if (trig_angles_acute(v, t1->direction) < 2) return TR_DIR_DN; else return TR_DIR_UP; } return TR_NONE; } static int get_swipe_dir(const struct Touch* t1, const struct Touch* t2, const struct Touch* t3) { double angles[3]; angles[0] = t1->direction; angles[1] = t2->direction; angles[2] = t3->direction; return trig_generalize(trig_angles_avg(angles, 3)); } static int get_swipe4_dir(const struct Touch* t1, const struct Touch* t2, const struct Touch* t3, const struct Touch* t4) { double angles[4]; angles[0] = t1->direction; angles[1] = t2->direction; angles[2] = t3->direction; angles[3] = t4->direction; return trig_generalize(trig_angles_avg(angles, 4)); } static void moving_update(struct Gestures* gs, const struct MConfig* cfg, struct MTState* ms) { int i, count, btn_count, dx, dy, dir; double dist; struct Touch* touches[4]; count = btn_count = 0; dx = dy = 0; dir = 0; // Reset movement. gs->move_dx = 0; gs->move_dy = 0; // Count touches and aggregate touch movements. foreach_bit(i, ms->touch_used) { if (GETBIT(ms->touch[i].state, MT_INVALID)) continue; else if (GETBIT(ms->touch[i].flags, GS_BUTTON)) { btn_count++; dx += ms->touch[i].dx; dy += ms->touch[i].dy; } else if (!GETBIT(ms->touch[i].flags, GS_TAP)) { if (count < 4) touches[count++] = &ms->touch[i]; } } // Determine gesture type. if (count == 0) { if (btn_count >= 1 && cfg->trackpad_disable < 2) trigger_move(gs, cfg, dx, dy); else if (btn_count < 1) trigger_reset(gs); } else if (count == 1 && cfg->trackpad_disable < 2) { dx += touches[0]->dx; dy += touches[0]->dy; trigger_move(gs, cfg, dx, dy); } else if (count == 2 && cfg->trackpad_disable < 1) { // scroll, scale, or rotate if ((dir = get_scroll_dir(touches[0], touches[1])) != TR_NONE) { dist = hypot( touches[0]->dx + touches[1]->dx, touches[0]->dy + touches[1]->dy); trigger_scroll(gs, cfg, dist/2, dir); } else if ((dir = get_rotate_dir(touches[0], touches[1])) != TR_NONE) { dist = ABSVAL(hypot(touches[0]->dx, touches[0]->dy)) + ABSVAL(hypot(touches[1]->dx, touches[1]->dy)); trigger_rotate(gs, cfg, dist/2, dir); } else if ((dir = get_scale_dir(touches[0], touches[1])) != TR_NONE) { dist = ABSVAL(hypot(touches[0]->dx, touches[0]->dy)) + ABSVAL(hypot(touches[1]->dx, touches[1]->dy)); trigger_scale(gs, cfg, dist/2, dir); } } else if (count == 3 && cfg->trackpad_disable < 1) { if ((dir = get_swipe_dir(touches[0], touches[1], touches[2])) != TR_NONE) { dist = hypot( touches[0]->dx + touches[1]->dx + touches[2]->dx, touches[0]->dy + touches[1]->dy + touches[2]->dy); trigger_swipe(gs, cfg, dist/3, dir, 0); } } else if (count == 4 && cfg->trackpad_disable < 1) { if ((dir = get_swipe4_dir(touches[0], touches[1], touches[2], touches[3])) != TR_NONE) { dist = hypot( touches[0]->dx + touches[1]->dx + touches[2]->dx + touches[3]->dx, touches[0]->dy + touches[1]->dy + touches[2]->dy + touches[3]->dy); trigger_swipe(gs, cfg, dist/4, dir, 1); } } } static void dragging_update(struct Gestures* gs) { if (gs->move_drag == GS_DRAG_READY && timercmp(&gs->time, &gs->move_drag_expire, >)) { #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "dragging_update: drag expired\n"); #endif trigger_drag_stop(gs, 1); } } static void delayed_update(struct Gestures* gs) { struct timeval epoch; timerclear(&epoch); if (timercmp(&gs->button_delayed_time, &epoch, ==)) return; if (!timercmp(&gs->time, &gs->button_delayed_time, <)) { #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "delayed_update: %d delay expired, triggering up\n", gs->button_delayed); #endif trigger_button_up(gs, gs->button_delayed); gs->button_delayed = 0; timerclear(&gs->button_delayed_time); timerclear(&gs->button_delayed_delta); } else { timersub(&gs->button_delayed_time, &gs->time, &gs->button_delayed_delta); } } void gestures_init(struct MTouch* mt) { memset(&mt->gs, 0, sizeof(struct Gestures)); } void gestures_extract(struct MTouch* mt) { timersub(&mt->hs.evtime, &mt->gs.time, &mt->gs.dt); timercp(&mt->gs.time, &mt->hs.evtime); dragging_update(&mt->gs); buttons_update(&mt->gs, &mt->cfg, &mt->hs, &mt->state); tapping_update(&mt->gs, &mt->cfg, &mt->state); moving_update(&mt->gs, &mt->cfg, &mt->state); delayed_update(&mt->gs); } static int gestures_sleep(struct MTouch* mt, const struct timeval* sleep) { if (mtdev_empty(&mt->dev)) { struct timeval now; mtdev_idle(&mt->dev, mt->fd, timertoms(sleep)); microtime(&now); timersub(&now, &mt->gs.time, &mt->gs.dt); timercp(&mt->gs.time, &now); return 1; } return 0; } int gestures_delayed(struct MTouch* mt) { struct Gestures* gs = &mt->gs; struct timeval epoch; timerclear(&epoch); if (timercmp(&gs->button_delayed_time, &epoch, >)) { if (gestures_sleep(mt, &gs->button_delayed_delta)) { #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "gestures_delayed: %d up, timer expired\n", gs->button_delayed); #endif trigger_button_up(gs, gs->button_delayed); gs->move_dx = 0; gs->move_dy = 0; gs->button_delayed = 0; timerclear(&gs->button_delayed_time); timerclear(&gs->button_delayed_delta); return 1; } } return 0; } xf86-input-mtrack-0.3.0/src/mconfig.c0000644000175000017500000002400111772504475017555 0ustar iwamatsuiwamatsu/*************************************************************************** * * Multitouch X driver * Copyright (C) 2011 Ryan Bourgeois * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * **************************************************************************/ #include "mconfig.h" void mconfig_defaults(struct MConfig* cfg) { // Configure MTState cfg->touch_down = DEFAULT_TOUCH_DOWN; cfg->touch_up = DEFAULT_TOUCH_UP; cfg->ignore_thumb = DEFAULT_IGNORE_THUMB; cfg->ignore_palm = DEFAULT_IGNORE_PALM; cfg->disable_on_palm = DEFAULT_DISABLE_ON_PALM; cfg->disable_on_thumb = DEFAULT_DISABLE_ON_THUMB; cfg->thumb_ratio = DEFAULT_THUMB_RATIO; cfg->thumb_size = DEFAULT_THUMB_SIZE; cfg->palm_size = DEFAULT_PALM_SIZE; cfg->bottom_edge = DEFAULT_BOTTOM_EDGE; // Configure Gestures cfg->trackpad_disable = DEFAULT_TRACKPAD_DISABLE; cfg->button_enable = DEFAULT_BUTTON_ENABLE; cfg->button_integrated = DEFAULT_BUTTON_INTEGRATED; cfg->button_expire = DEFAULT_BUTTON_EXPIRE; cfg->button_zones = DEFAULT_BUTTON_ZONES; cfg->button_1touch = DEFAULT_BUTTON_1TOUCH; cfg->button_2touch = DEFAULT_BUTTON_2TOUCH; cfg->button_3touch = DEFAULT_BUTTON_3TOUCH; cfg->tap_1touch = DEFAULT_TAP_1TOUCH; cfg->tap_2touch = DEFAULT_TAP_2TOUCH; cfg->tap_3touch = DEFAULT_TAP_3TOUCH; cfg->tap_4touch = DEFAULT_TAP_4TOUCH; cfg->tap_timeout = DEFAULT_TAP_TIMEOUT; cfg->tap_hold = DEFAULT_TAP_HOLD; cfg->tap_dist = DEFAULT_TAP_DIST; cfg->gesture_hold = DEFAULT_GESTURE_HOLD; cfg->gesture_wait = DEFAULT_GESTURE_WAIT; cfg->scroll_dist = DEFAULT_SCROLL_DIST; cfg->scroll_up_btn = DEFAULT_SCROLL_UP_BTN; cfg->scroll_dn_btn = DEFAULT_SCROLL_DN_BTN; cfg->scroll_lt_btn = DEFAULT_SCROLL_LT_BTN; cfg->scroll_rt_btn = DEFAULT_SCROLL_RT_BTN; cfg->swipe_dist = DEFAULT_SWIPE_DIST; cfg->swipe_up_btn = DEFAULT_SWIPE_UP_BTN; cfg->swipe_dn_btn = DEFAULT_SWIPE_DN_BTN; cfg->swipe_lt_btn = DEFAULT_SWIPE_LT_BTN; cfg->swipe_rt_btn = DEFAULT_SWIPE_RT_BTN; cfg->swipe4_dist = DEFAULT_SWIPE4_DIST; cfg->swipe4_up_btn = DEFAULT_SWIPE4_UP_BTN; cfg->swipe4_dn_btn = DEFAULT_SWIPE4_DN_BTN; cfg->swipe4_lt_btn = DEFAULT_SWIPE4_LT_BTN; cfg->swipe4_rt_btn = DEFAULT_SWIPE4_RT_BTN; cfg->scale_dist = DEFAULT_SCALE_DIST; cfg->scale_up_btn = DEFAULT_SCALE_UP_BTN; cfg->scale_dn_btn = DEFAULT_SCALE_DN_BTN; cfg->rotate_dist = SQRVAL(DEFAULT_ROTATE_DIST); cfg->rotate_lt_btn = DEFAULT_ROTATE_LT_BTN; cfg->rotate_rt_btn = DEFAULT_ROTATE_RT_BTN; cfg->drag_enable = DEFAULT_DRAG_ENABLE; cfg->drag_timeout = DEFAULT_DRAG_TIMEOUT; cfg->sensitivity = DEFAULT_SENSITIVITY; } void mconfig_init(struct MConfig* cfg, const struct Capabilities* caps) { cfg->touch_minor = caps->has_abs[MTDEV_TOUCH_MINOR]; cfg->pad_width = get_cap_xsize(caps); cfg->pad_height = get_cap_ysize(caps); if (caps->has_abs[MTDEV_TOUCH_MAJOR] && caps->has_abs[MTDEV_WIDTH_MAJOR]) { cfg->touch_type = MCFG_SCALE; cfg->touch_min = caps->abs[MTDEV_TOUCH_MAJOR].minimum; cfg->touch_max = caps->abs[MTDEV_TOUCH_MAJOR].maximum; xf86Msg(X_INFO, "Touchpad supports regular and approaching touches.\n"); xf86Msg(X_INFO, " touch_min = %d, touch_max = %d\n", cfg->touch_min, cfg->touch_max); } else if (caps->has_abs[MTDEV_TOUCH_MAJOR]) { cfg->touch_type = MCFG_SIZE; cfg->touch_min = caps->abs[MTDEV_TOUCH_MAJOR].minimum; cfg->touch_max = caps->abs[MTDEV_TOUCH_MAJOR].maximum; xf86Msg(X_INFO, "Touchpad supports regular touches.\n"); xf86Msg(X_INFO, " touch_min = %d, touch_max = %d\n", cfg->touch_min, cfg->touch_max); } else if (caps->has_abs[MTDEV_PRESSURE]) { cfg->touch_type = MCFG_PRESSURE; cfg->touch_min = caps->abs[MTDEV_PRESSURE].minimum; cfg->touch_max = caps->abs[MTDEV_PRESSURE].maximum; xf86Msg(X_INFO, "Touchpad is pressure based.\n"); xf86Msg(X_INFO, " touch_min = %d, touch_max = %d\n", cfg->touch_min, cfg->touch_max); } else { cfg->touch_type = MCFG_NONE; xf86Msg(X_WARNING, "Touchpad has minimal capabilities. Some features will be unavailable.\n"); } if (cfg->touch_minor) xf86Msg(X_INFO, "Touchpad supports minor touch widths.\n"); } void mconfig_configure(struct MConfig* cfg, pointer opts) { // Configure MTState cfg->touch_down = CLAMPVAL(xf86SetIntOption(opts, "FingerHigh", DEFAULT_TOUCH_DOWN), 0, 100); cfg->touch_up = CLAMPVAL(xf86SetIntOption(opts, "FingerLow", DEFAULT_TOUCH_UP), 0, 100); cfg->ignore_thumb = xf86SetBoolOption(opts, "IgnoreThumb", DEFAULT_IGNORE_THUMB); cfg->ignore_palm = xf86SetBoolOption(opts, "IgnorePalm", DEFAULT_IGNORE_PALM); cfg->disable_on_thumb = xf86SetBoolOption(opts, "DisableOnThumb", DEFAULT_DISABLE_ON_THUMB); cfg->disable_on_palm = xf86SetBoolOption(opts, "DisableOnPalm", DEFAULT_DISABLE_ON_PALM); cfg->thumb_ratio = CLAMPVAL(xf86SetIntOption(opts, "ThumbRatio", DEFAULT_THUMB_RATIO), 0, 100); cfg->thumb_size = CLAMPVAL(xf86SetIntOption(opts, "ThumbSize", DEFAULT_THUMB_SIZE), 0, 100); cfg->palm_size = CLAMPVAL(xf86SetIntOption(opts, "PalmSize", DEFAULT_PALM_SIZE), 0, 100); cfg->bottom_edge = CLAMPVAL(xf86SetIntOption(opts, "BottomEdge", DEFAULT_BOTTOM_EDGE), 0, 100); // Configure Gestures cfg->trackpad_disable = CLAMPVAL(xf86SetIntOption(opts, "TrackpadDisable", DEFAULT_TRACKPAD_DISABLE), 0, 3); cfg->button_enable = xf86SetBoolOption(opts, "ButtonEnable", DEFAULT_BUTTON_ENABLE); cfg->button_integrated = xf86SetBoolOption(opts, "ButtonIntegrated", DEFAULT_BUTTON_INTEGRATED); cfg->button_expire = MAXVAL(xf86SetIntOption(opts, "ButtonTouchExpire", DEFAULT_BUTTON_EXPIRE), 0); cfg->button_zones = xf86SetBoolOption(opts, "ButtonZonesEnable", DEFAULT_BUTTON_ZONES); cfg->button_1touch = CLAMPVAL(xf86SetIntOption(opts, "ClickFinger1", DEFAULT_BUTTON_1TOUCH), 0, 32); cfg->button_2touch = CLAMPVAL(xf86SetIntOption(opts, "ClickFinger2", DEFAULT_BUTTON_2TOUCH), 0, 32); cfg->button_3touch = CLAMPVAL(xf86SetIntOption(opts, "ClickFinger3", DEFAULT_BUTTON_3TOUCH), 0, 32); cfg->button_move = xf86SetBoolOption(opts, "ButtonMoveEmulate", DEFAULT_BUTTON_MOVE); cfg->tap_1touch = CLAMPVAL(xf86SetIntOption(opts, "TapButton1", DEFAULT_TAP_1TOUCH), 0, 32); cfg->tap_2touch = CLAMPVAL(xf86SetIntOption(opts, "TapButton2", DEFAULT_TAP_2TOUCH), 0, 32); cfg->tap_3touch = CLAMPVAL(xf86SetIntOption(opts, "TapButton3", DEFAULT_TAP_3TOUCH), 0, 32); cfg->tap_4touch = CLAMPVAL(xf86SetIntOption(opts, "TapButton4", DEFAULT_TAP_4TOUCH), 0, 32); cfg->tap_hold = MAXVAL(xf86SetIntOption(opts, "ClickTime", DEFAULT_TAP_HOLD), 1); cfg->tap_timeout = MAXVAL(xf86SetIntOption(opts, "MaxTapTime", DEFAULT_TAP_TIMEOUT), 1); cfg->tap_dist = MAXVAL(xf86SetIntOption(opts, "MaxTapMove", DEFAULT_TAP_DIST), 1); cfg->gesture_hold = MAXVAL(xf86SetIntOption(opts, "GestureClickTime", DEFAULT_GESTURE_HOLD), 1); cfg->gesture_wait = MAXVAL(xf86SetIntOption(opts, "GestureWaitTime", DEFAULT_GESTURE_WAIT), 0); cfg->scroll_dist = MAXVAL(xf86SetIntOption(opts, "ScrollDistance", DEFAULT_SCROLL_DIST), 1); cfg->scroll_up_btn = CLAMPVAL(xf86SetIntOption(opts, "ScrollUpButton", DEFAULT_SCROLL_UP_BTN), 0, 32); cfg->scroll_dn_btn = CLAMPVAL(xf86SetIntOption(opts, "ScrollDownButton", DEFAULT_SCROLL_DN_BTN), 0, 32); cfg->scroll_lt_btn = CLAMPVAL(xf86SetIntOption(opts, "ScrollLeftButton", DEFAULT_SCROLL_LT_BTN), 0, 32); cfg->scroll_rt_btn = CLAMPVAL(xf86SetIntOption(opts, "ScrollRightButton", DEFAULT_SCROLL_RT_BTN), 0, 32); cfg->swipe_dist = MAXVAL(xf86SetIntOption(opts, "SwipeDistance", DEFAULT_SWIPE_DIST), 1); cfg->swipe_up_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeUpButton", DEFAULT_SWIPE_UP_BTN), 0, 32); cfg->swipe_dn_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeDownButton", DEFAULT_SWIPE_DN_BTN), 0, 32); cfg->swipe_lt_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeLeftButton", DEFAULT_SWIPE_LT_BTN), 0, 32); cfg->swipe_rt_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeRightButton", DEFAULT_SWIPE_RT_BTN), 0, 32); cfg->swipe4_dist = MAXVAL(xf86SetIntOption(opts, "Swipe4Distance", DEFAULT_SWIPE4_DIST), 1); cfg->swipe4_up_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4UpButton", DEFAULT_SWIPE4_UP_BTN), 0, 32); cfg->swipe4_dn_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4DownButton", DEFAULT_SWIPE4_DN_BTN), 0, 32); cfg->swipe4_lt_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4LeftButton", DEFAULT_SWIPE4_LT_BTN), 0, 32); cfg->swipe4_rt_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4RightButton", DEFAULT_SWIPE4_RT_BTN), 0, 32); cfg->scale_dist = MAXVAL(xf86SetIntOption(opts, "ScaleDistance", DEFAULT_SCALE_DIST), 1); cfg->scale_up_btn = CLAMPVAL(xf86SetIntOption(opts, "ScaleUpButton", DEFAULT_SCALE_UP_BTN), 0, 32); cfg->scale_dn_btn = CLAMPVAL(xf86SetIntOption(opts, "ScaleDownButton", DEFAULT_SCALE_DN_BTN), 0, 32); cfg->rotate_dist = MAXVAL(xf86SetIntOption(opts, "RotateDistance", DEFAULT_ROTATE_DIST), 1); cfg->rotate_lt_btn = CLAMPVAL(xf86SetIntOption(opts, "RotateLeftButton", DEFAULT_ROTATE_LT_BTN), 0, 32); cfg->rotate_rt_btn = CLAMPVAL(xf86SetIntOption(opts, "RotateRightButton", DEFAULT_ROTATE_RT_BTN), 0, 23); cfg->drag_enable = xf86SetBoolOption(opts, "TapDragEnable", DEFAULT_DRAG_ENABLE); cfg->drag_timeout = MAXVAL(xf86SetIntOption(opts, "TapDragTime", DEFAULT_DRAG_TIMEOUT), 1); cfg->drag_wait = MAXVAL(xf86SetIntOption(opts, "TapDragWait", DEFAULT_DRAG_WAIT), 0); cfg->drag_dist = MAXVAL(xf86SetIntOption(opts, "TapDragDist", DEFAULT_DRAG_DIST), 0); cfg->axis_x_invert = xf86SetBoolOption(opts, "AxisXInvert", DEFAULT_AXIS_X_INVERT); cfg->axis_y_invert = xf86SetBoolOption(opts, "AxisYInvert", DEFAULT_AXIS_Y_INVERT); cfg->sensitivity = MAXVAL(xf86SetRealOption(opts, "Sensitivity", DEFAULT_SENSITIVITY), 0); } xf86-input-mtrack-0.3.0/src/capabilities.c0000644000175000017500000001277711772504475020605 0ustar iwamatsuiwamatsu/*************************************************************************** * * Multitouch X driver * Copyright (C) 2008 Henrik Rydberg * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * **************************************************************************/ #include "capabilities.h" #define SETABS(c, x, map, key, fd) \ (c->has_##x = getbit(map, key) && getabs(&c->x, key, fd)) #define ADDCAP(s, c, x) strcat(s, c->has_##x ? " " #x : "") static const int SN_COORD = 250; /* coordinate signal-to-noise ratio */ static const int SN_WIDTH = 100; /* width signal-to-noise ratio */ static const int SN_ORIENT = 10; /* orientation signal-to-noise ratio */ static const int bits_per_long = 8 * sizeof(long); static inline int nlongs(int nbit) { return (nbit + bits_per_long - 1) / bits_per_long; } static inline int getbit(const unsigned long *map, int key) { return (map[key / bits_per_long] >> (key % bits_per_long)) & 0x01; } static int getabs(struct input_absinfo *abs, int key, int fd) { int rc; SYSCALL(rc = ioctl(fd, EVIOCGABS(key), abs)); return rc >= 0; } static int has_mt_data(const struct Capabilities *cap) { return cap->has_abs[MTDEV_POSITION_X] && cap->has_abs[MTDEV_POSITION_Y]; } static int has_integrated_button(const struct Capabilities *cap) { static const int bcm5974_vmask_ibt = 1; /* magic trackpad */ if (cap->devid.vendor == 0x05ac && cap->devid.product == 0x030e) return 1; /* macbooks */ if (strcmp(cap->devname, "bcm5974")) return 0; return cap->devid.version & bcm5974_vmask_ibt; } static void default_fuzz(struct Capabilities *cap, unsigned int code, int sn) { int bit = mtdev_abs2mt(code); if (cap->has_abs[bit] && cap->abs[bit].fuzz == 0) cap->abs[bit].fuzz = (cap->abs[bit].maximum - cap->abs[bit].minimum) / sn; } int read_capabilities(struct Capabilities *cap, int fd) { unsigned long evbits[nlongs(EV_MAX)]; unsigned long absbits[nlongs(ABS_MAX)]; unsigned long keybits[nlongs(KEY_MAX)]; int rc, i; memset(cap, 0, sizeof(struct Capabilities)); SYSCALL(rc = ioctl(fd, EVIOCGID, &cap->devid)); if (rc < 0) return rc; SYSCALL(rc = ioctl(fd, EVIOCGNAME(sizeof(cap->devname)), cap->devname)); if (rc < 0) return rc; SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_SYN, sizeof(evbits)), evbits)); if (rc < 0) return rc; SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits)); if (rc < 0) return rc; SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbits)), absbits)); if (rc < 0) return rc; cap->has_left = getbit(keybits, BTN_LEFT); cap->has_middle = getbit(keybits, BTN_MIDDLE); cap->has_right = getbit(keybits, BTN_RIGHT); SETABS(cap, slot, absbits, ABS_MT_SLOT, fd); for (i = 0; i < MT_ABS_SIZE; i++) SETABS(cap, abs[i], absbits, mtdev_mt2abs(i), fd); cap->has_mtdata = has_mt_data(cap); cap->has_ibt = has_integrated_button(cap); default_fuzz(cap, ABS_MT_POSITION_X, SN_COORD); default_fuzz(cap, ABS_MT_POSITION_Y, SN_COORD); default_fuzz(cap, ABS_MT_TOUCH_MAJOR, SN_WIDTH); default_fuzz(cap, ABS_MT_TOUCH_MINOR, SN_WIDTH); default_fuzz(cap, ABS_MT_WIDTH_MAJOR, SN_WIDTH); default_fuzz(cap, ABS_MT_WIDTH_MINOR, SN_WIDTH); default_fuzz(cap, ABS_MT_ORIENTATION, SN_ORIENT); return 0; } int get_cap_xsize(const struct Capabilities *cap) { const struct input_absinfo *x = &cap->abs[MTDEV_POSITION_X]; return x->maximum - x->minimum; } int get_cap_ysize(const struct Capabilities *cap) { const struct input_absinfo *y = &cap->abs[MTDEV_POSITION_Y]; return y->maximum - y->minimum; } int get_cap_wsize(const struct Capabilities *cap) { const struct input_absinfo *w = &cap->abs[MTDEV_TOUCH_MAJOR]; return w->maximum - w->minimum; } int get_cap_xmid(const struct Capabilities *cap) { const struct input_absinfo *x = &cap->abs[MTDEV_POSITION_X]; return (x->maximum + x->minimum) >> 1; } int get_cap_ymid(const struct Capabilities *cap) { const struct input_absinfo *y = &cap->abs[MTDEV_POSITION_Y]; return (y->maximum + y->minimum) >> 1; } int get_cap_xflip(const struct Capabilities *cap, int x) { const struct input_absinfo *i = &cap->abs[MTDEV_POSITION_X]; return i->maximum - (x - i->minimum); } int get_cap_yflip(const struct Capabilities *cap, int y) { const struct input_absinfo *i = &cap->abs[MTDEV_POSITION_Y]; return i->maximum - (y - i->minimum); } void output_capabilities(const struct Capabilities *cap) { char line[1024]; int i; memset(line, 0, sizeof(line)); ADDCAP(line, cap, left); ADDCAP(line, cap, middle); ADDCAP(line, cap, right); ADDCAP(line, cap, mtdata); ADDCAP(line, cap, ibt); xf86Msg(X_INFO, "mtrack: devname: %s\n", cap->devname); xf86Msg(X_INFO, "mtrack: devid: %x %x %x\n", cap->devid.vendor, cap->devid.product, cap->devid.version); xf86Msg(X_INFO, "mtrack: caps:%s\n", line); for (i = 0; i < MT_ABS_SIZE; i++) { if (cap->has_abs[i]) xf86Msg(X_INFO, "mtrack: %d: min: %d max: %d\n", i, cap->abs[i].minimum, cap->abs[i].maximum); } } xf86-input-mtrack-0.3.0/src/hwstate.c0000644000175000017500000000676411772504475017632 0ustar iwamatsuiwamatsu/*************************************************************************** * * Multitouch X driver * Copyright (C) 2008 Henrik Rydberg * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * **************************************************************************/ #include "hwstate.h" void hwstate_init(struct HWState *s, const struct Capabilities *caps) { int i; memset(s, 0, sizeof(struct HWState)); for (i = 0; i < DIM_FINGER; i++) s->data[i].tracking_id = MT_ID_NULL; s->max_x = get_cap_xsize(caps); s->max_y = get_cap_ysize(caps); } static void finish_packet(struct HWState *s, const struct Capabilities *caps, const struct input_event *syn) { static const mstime_t ms = 1000; int i; foreach_bit(i, s->used) { if (!caps->has_abs[MTDEV_TOUCH_MINOR]) s->data[i].touch_minor = s->data[i].touch_major; if (!caps->has_abs[MTDEV_WIDTH_MINOR]) s->data[i].width_minor = s->data[i].width_major; } timercp(&s->evtime, &syn->time); } static int read_event(struct HWState *s, const struct Capabilities *caps, const struct input_event *ev) { switch (ev->type) { case EV_SYN: switch (ev->code) { case SYN_REPORT: finish_packet(s, caps, ev); return 1; } break; case EV_KEY: switch (ev->code) { case BTN_LEFT: MODBIT(s->button, MT_BUTTON_LEFT, ev->value); break; case BTN_MIDDLE: MODBIT(s->button, MT_BUTTON_MIDDLE, ev->value); break; case BTN_RIGHT: MODBIT(s->button, MT_BUTTON_RIGHT, ev->value); break; } break; case EV_ABS: switch (ev->code) { case ABS_MT_SLOT: if (ev->value >= 0 && ev->value < DIM_FINGER) s->slot = ev->value; break; case ABS_MT_TOUCH_MAJOR: s->data[s->slot].touch_major = ev->value; break; case ABS_MT_TOUCH_MINOR: s->data[s->slot].touch_minor = ev->value; break; case ABS_MT_WIDTH_MAJOR: s->data[s->slot].width_major = ev->value; break; case ABS_MT_WIDTH_MINOR: s->data[s->slot].width_minor = ev->value; break; case ABS_MT_ORIENTATION: s->data[s->slot].orientation = ev->value; break; case ABS_MT_PRESSURE: s->data[s->slot].pressure = ev->value; break; case ABS_MT_POSITION_X: s->data[s->slot].position_x = ev->value; break; case ABS_MT_POSITION_Y: s->data[s->slot].position_y = ev->value; break; case ABS_MT_TRACKING_ID: s->data[s->slot].tracking_id = ev->value; MODBIT(s->used, s->slot, ev->value != MT_ID_NULL); break; } break; } return 0; } int hwstate_modify(struct HWState *s, struct mtdev *dev, int fd, const struct Capabilities *caps) { struct input_event ev; int ret; while ((ret = mtdev_get(dev, fd, &ev, 1)) > 0) { if (read_event(s, caps, &ev)) return 1; } return ret; } int find_finger(const struct HWState *s, int tracking_id) { int i; foreach_bit(i, s->used) { if (s->data[i].tracking_id == tracking_id) return i; } return -1; } xf86-input-mtrack-0.3.0/README.md0000644000175000017500000002677311772504475016501 0ustar iwamatsuiwamatsuxf86-input-mtrack ================= An Xorg driver for multitouch trackpads. Supports any trackpad whose kernel driver uses the slotted multitouch protocol. For more information on the protocol see the [kernel documentation][1]. This driver is compatible with Xorg server versions 1.7 to 1.12. It requires the [mtdev][4] library to operate. License ------- * Copyright (C) 2011 Ryan Bourgeois * Copyright (C) 2008 Henrik Rydberg This software is licensed under the [GPLv2][2] and is a fork of the [xf86-input-multitouch][3] driver by Henrik Rydberg. Binaries -------- * [Gentoo][5] * [Ubuntu][6] * [Arch][7] Arch package contributed and maintained by Mike Zackles. Configuration ------------- The following is a minimal working InputClass section for xorg.conf: Section "InputClass" MatchIsTouchpad "on" Identifier "Touchpads" Driver "mtrack" EndSection Configuration options may be defined inside the InputClass section to configure the driver. Available options and their defaults are as follows. **TrackpadDisable** - Disables trackpad touch input. A value of 0 will enable the trackpad. A value of 1 will disable tapping and gestures but not movement. A value of 2 will disable all input. A value of 3 will also disable physical buttons. Integer. Default is 0. **Sensitivity** - Adjusts the sensitivity (movement speed) of the touchpad. This is a real number greater than or equal to zero. Default is 1. A value of 0 will disable pointer movement. **FingerHigh** - Defines the pressure at which a finger is detected as a touch. This is a percentage represented as an integer. Default is 5. **FingerLow** - Defines the pressure at which a finger is detected as a release. This is a percentage represented as an integer. Default is 5. **IgnoreThumb** - Whether or not to ignore touches that are determined to be thumbs. Boolean value. Defaults to false. **IgnorePalm** - Whether or not to ignore touches that are determined to be palms. Boolean value. Defaults to false. **DisableOnThumb** - Whether or not to disable the entire trackpad when a thumb is touching. Boolean value. Defaults to false. **DisableOnPalm** - Whether or not to disable the entire trackpad when a palm is touching. Boolean value. Defaults to false. **ThumbRatio** - The width/length ratio of what's considered a thumb. It is expected that a thumb is longer than it is wide. This tells the driver how much longer. Percentage represented by an integer. Defaults to 70. **ThumbSize** - The minimum size of what's considered a thumb. It is expected that a thumb will be larger than other fingers. This is represented as a percentage of the maximum touch value and is dependent on the trackpad hardware. Integer value. Defaults to 25. **PalmSize** - The minimum size of what's considered a palm. Palms are expected to be very large on the trackpad. This is represented as a percentage of the maximum touch value and is dependent on the trackpad hardware. Integer value. Defaults to 40. **BottomEdge** - The size of an area at the bottom of the trackpad where new touches are ignored (fingers traveling into this area from above will still be tracked). This is represented as a percentage of the total trackpad height. Defaults to 10. **ButtonEnable** - Whether or not to enable the physical buttons on or near the trackpad. Boolean value. Defaults to true. **ButtonIntegrated** - Whether or not the physical buttons are integrated with the trackpad. If you have a one-piece trackpad like on newer MacBooks, this should be set to true. Button emulation depends on this value being correct. Boolean value. Defaults to true. **ButtonMoveEmulate** Whether or not to count the moving finger when emulating button clicks. Useful to disable if you use two hands on trackpad. Boolean value. Defaults to true. **ButtonZonesEnable** - Whether or not to enable button zones. If button zones are enabled then the trackpad will be split into one, two, or three vertical zones. Clicking the integrated button in one of these zones will send the button event for ClickFinger1, ClickFinger2, or ClickFinger3. The driver will only add zones for those ClickFinger values that are enabled. So setting ClickFinger1 to 0 and enabling the other two will create two zones, one for ClickFinger2 and one for ClickFinger3. Boolean value. Defaults to false. **ButtonTouchExpire** - How long (in ms) to consider a touching finger as part of button emulation. A value of 0 will not expire touches. Integer value. Defaults to 100. **ClickFinger1** - Which button to emulate when one finger is touching the trackpad during a click. Integer value. A value of 0 disables one-touch emulation. Defaults to 3. **ClickFinger2** - Which button to emulate when two fingers are touching the trackpad during a click. Integer value. A value of 0 disabled one-touch emulation. Defaults to 2. **ClickFinger3** - Which button to emulate when three fingers are touching the trackpad during a click. Integer value. A value of 0 disabled one-touch emulation. Defaults to 0. **TapButton1** - Which button to emulate for one-finger tapping. Integer value. A value of 0 disables one-finger tapping. Defaults to 1. **TapButton2** - Which button to emulate for two-finger tapping. Integer value. A value of 0 disables two-finger tapping. Defaults to 3. **TapButton3** - Which button to emulate for three-finger tapping. Integer value. A value of 0 disables three-finger tapping. Defaults to 2. **TapButton4** - Which button to emulate for four-finger tapping. Integer value. A value of 0 disables three-finger tapping. Defaults to 0. **ClickTime** - When tapping, how much time to hold down the emulated button. Integer value representing milliseconds. Defaults to 50. **MaxTapTime** - The amount of time to wait for a tap to release before counting it as a move. Integer value representing milliseconds. Defaults to 120. **MaxTapMove** - How far a touch is allowed to move before counting it is no longer considered a tap. Integer value. Defaults to 400. **GestureClickTime** - When a gesture triggers a click, how much time to hold down the emulated button. Integer value representing milliseconds. Defaults to 10. **GestureWaitTime** - Touches are allowed to transition from one gesture to another. For example, you may go from scrolling to swiping without releasing your fingers from the pad. This value is the amount of time you must be performing the new gesture before it is triggered. This prevents accidental touches from triggering other gestures. Integer value representing milliseconds. Defaults to 100. **ScrollDistance** - For two finger scrolling. How far you must move your fingers before a button click is triggered. Integer value. Defaults to 150. **ScrollUpButton** - For two finger scrolling. The button that is triggered by scrolling up. Integer value. A value of 0 disables scrolling up. Defaults to 4. **ScrollDownButton** - For two finger scrolling. The button that is triggered by scrolling down. Integer value. A value of 0 disables scrolling down. Defaults to 5. **ScrollLeftButton** - For two finger scrolling. The button that is triggered by scrolling left. Integer value. A value of 0 disables scrolling left. Defaults to 6. **ScrollDownButton** - For two finger scrolling. The button that is triggered by scrolling right. Integer value. A value of 0 disables scrolling right. Defaults to 7. **SwipeDistance** - For three finger swiping. How far you must move your fingers before a button click is triggered. Integer value. Defaults to 700. **SwipeUpButton** - For three finger swiping. The button that is triggered by swiping up. Integer value. A value of 0 disables swiping up. Defaults to 8. **SwipeDownButton** - For three finger swiping. The button that is triggered by swiping down. Integer value. A value of 0 disables swiping down. Defaults to 9. **SwipeLeftButton** - For three finger swiping. The button that is triggered by swiping left. Integer value. A value of 0 disables swiping left. Defaults to 10. **SwipeRightButton** - For three finger swiping. The button that is triggered by swiping right. Integer value. A value of 0 disables swiping right. Defaults to 11. **Swipe4Distance** - For four finger swiping. How far you must move your fingers before a button click is triggered. Integer value. Defaults to 700. **Swipe4UpButton** - For four finger swiping. The button that is triggered by swiping up. Integer value. A value of 0 disables swiping up. Defaults to 8. **Swipe4DownButton** - For four finger swiping. The button that is triggered by swiping down. Integer value. A value of 0 disables swiping down. Defaults to 9. **Swipe4LeftButton** - For four finger swiping. The button that is triggered by swiping left. Integer value. A value of 0 disables swiping left. Defaults to 10. **Swipe4RightButton** - For four finger swiping. The button that is triggered by swiping right. Integer value. A value of 0 disables swiping right. Defaults to 11. **ScaleDistance** - For pinch scaling. How far you must move your fingers before a button click is triggered. Integer value. Defaults to 150. **ScaleUpButton** - For pinch scaling. The button that is triggered by scaling up. Integer value. A value of 0 disables scaling up. Defaults to 12. **ScaleDownButton** - For pinch scaling. The button that is triggered by scaling down. Integer value. A value of 0 disables scaling down. Defaults to 13. **RotateDistance** - For two finger rotation. How far you must move your fingers before a button click is triggered. Integer value. Defaults to 150. **RotateLeftButton** - For two finger rotation. The button that is triggered by rotating left. Integer value. A value of 0 disables rotation left. Defaults to 14. **RotateRightButton** - For two finger rotation. The button that is triggered by rotating right. Integer value. A value of 0 disables rotation right. Defaults to 14. **TapDragEnable** - Whether or not to enable tap-to-drag functionality. Boolean value. Defaults to true. **TapDragTime** - The tap-to-drag timeout. This is how long the driver will wait after a single tap for a movement event before sending the click. Integer value representing milliseconds. Defaults to 350. **TapDragWait** How long after detecting movement to trigger a button down event. During this time pointer movement will be disabled. Increase this value if you find you're draggin when you don't wish it. Integer value representing milliseconds. Defaults to 40. **TapDragDist** How far the finger is allowed to move during drag wait time. If the finger moves farther than this distance during the wait time then dragging will be canceled and pointer movement will resume. Integer value. Defaults to 200. **AxisXInvert** Whether or not to invert the X axis. Boolean value. Defaults to false. **AxisYInvert** Whether or not to invert the Y axis. Boolean value. Defaults to false. [1]: http://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt "Kernel Multitouch Protocol" [2]: http://www.gnu.org/licenses/gpl-2.0.html "GNU General Public License, version 2" [3]: http://bitmath.org/code/multitouch/ "xf86-input-multitouch website" [4]: http://bitmath.org/code/mtdev/ "mtdev library website" [5]: http://www.dev.fatalmachine.org/xf86-input-mtrack/gentoo "Gentoo Ebuilds" [6]: http://www.dev.fatalmachine.org/xf86-input-mtrack/ubuntu "Ubuntu Packages" [7]: http://aur.archlinux.org/packages.php?ID=48505 "Arch Package" xf86-input-mtrack-0.3.0/Makefile.am0000644000175000017500000000147711772504475017250 0ustar iwamatsuiwamatsuSOURCES_COMMON = \ $(srcdir)/src/capabilities.c \ $(srcdir)/src/gestures.c \ $(srcdir)/src/hwstate.c \ $(srcdir)/src/mconfig.c \ $(srcdir)/src/mtouch.c \ $(srcdir)/src/mtstate.c \ $(srcdir)/src/trig.c @DRIVER_NAME@_drv_la_LTLIBRARIES = @DRIVER_NAME@_drv.la @DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version @DRIVER_NAME@_drv_la_SOURCES = $(SOURCES_COMMON) \ $(srcdir)/driver/mtrack.c \ $(srcdir)/driver/mprops.c @DRIVER_NAME@_drv_ladir = @inputdir@ noinst_PROGRAMS = mtrack-test mtrack_test_SOURCES = $(SOURCES_COMMON) \ $(srcdir)/tools/mtrack-test.c mtrack_test_CFLAGS = $(AM_CFLAGS) AM_CPPFLAGS = -I$(top_srcdir)/include/ \ -I/usr/include/xorg \ -I/usr/include/pixman-1 AM_CFLAGS = $(XORG_CFLAGS) .PHONY: ChangeLog INSTALL INSTALL: $(INSTALL_CMD) ChangeLog: $(CHANGELOG_CMD) dist-hook: ChangeLog INSTALL xf86-input-mtrack-0.3.0/tools/0000755000175000017500000000000011772504475016343 5ustar iwamatsuiwamatsuxf86-input-mtrack-0.3.0/tools/mtrack-test.c0000644000175000017500000000546611772504475020760 0ustar iwamatsuiwamatsu/*************************************************************************** * * Multitouch X driver * Copyright (C) 2008 Henrik Rydberg * Copyright (C) 2011 Ryan Bourgeois * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * **************************************************************************/ #include "mtouch.h" #include #include void xf86Msg(int type, const char *format, ...) { va_list args; va_start(args, format); vfprintf(stderr, format, args); va_end(args); } #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) <= 13 typedef XF86OptionPtr pointer; #endif int xf86SetIntOption(XF86OptionPtr opts, const char *name, int deflt) { return deflt; } int xf86SetBoolOption(XF86OptionPtr opts, const char *name, int deflt) { return deflt; } double xf86SetRealOption(XF86OptionPtr opts, const char *name, double deflt) { return deflt; } static void print_gestures(const struct Gestures* gs) { int i; static bitmask_t buttons_prev = 0U; for (i = 0; i < 32; i++) { if (GETBIT(gs->buttons, i) == GETBIT(buttons_prev, i)) continue; if (GETBIT(gs->buttons, i)) printf("button %d down\n", i+1); else printf("button %d up\n", i+1); } if (gs->move_dx != 0 || gs->move_dy != 0) printf("moving (%+4d, %+4d)\n", gs->move_dx, gs->move_dy); buttons_prev = gs->buttons; } static void loop_device(int fd) { struct MTouch mt; if (mtouch_configure(&mt, fd)) { fprintf(stderr, "error: could not configure device\n"); return; } if (mtouch_open(&mt, fd)) { fprintf(stderr, "error: could not open device\n"); return; } mconfig_defaults(&mt.cfg); printf("width: %d\n", mt.hs.max_x); printf("height: %d\n", mt.hs.max_y); //while (!mtdev_idle(&mt.dev, fd, 5000)) { while (1) { while (mtouch_read(&mt) > 0) print_gestures(&mt.gs); if (mtouch_delayed(&mt)) print_gestures(&mt.gs); } mtouch_close(&mt); } int main(int argc, char *argv[]) { if (argc < 2) { fprintf(stderr, "Usage: test \n"); return -1; } int fd = open(argv[1], O_RDONLY | O_NONBLOCK); if (fd < 0) { fprintf(stderr, "error: could not open file\n"); return -1; } loop_device(fd); close(fd); return 0; } xf86-input-mtrack-0.3.0/COPYING0000644000175000017500000004310511772504475016241 0ustar iwamatsuiwamatsu GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. xf86-input-mtrack-0.3.0/config.h.in0000644000175000017500000000422511772504475017231 0ustar iwamatsuiwamatsu/* config.h.in. Generated from configure.ac by autoheader. */ /* Enable driver debugging. */ #undef DEBUG_DRIVER /* Enable gesture debugging. */ #undef DEBUG_GESTURES /* Enable multitouch state debugging. */ #undef DEBUG_MTSTATE /* Enable property debugging. */ #undef DEBUG_PROPS /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `m' library (-lm). */ #undef HAVE_LIBM /* Define to 1 if you have the `mtdev' library (-lmtdev). */ #undef HAVE_LIBMTDEV /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Major version of this package */ #undef PACKAGE_VERSION_MAJOR /* Minor version of this package */ #undef PACKAGE_VERSION_MINOR /* Patch version of this package */ #undef PACKAGE_VERSION_PATCHLEVEL /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION xf86-input-mtrack-0.3.0/driver/0000755000175000017500000000000011772504475016476 5ustar iwamatsuiwamatsuxf86-input-mtrack-0.3.0/driver/mprops.c0000644000175000017500000004612711772504475020174 0ustar iwamatsuiwamatsu/*************************************************************************** * * Multitouch X driver * Copyright (C) 2011 Ryan Bourgeois * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * **************************************************************************/ #include "mprops.h" #include "common.h" #include "mtouch.h" #define MAX_INT_VALUES 4 #define MAX_FLOAT_VALUES 4 #define VALID_BUTTON(x) (x >= 0 && x <= 32) #define VALID_BOOL(x) (x == 0 || x == 1) #define VALID_PCNT(x) (x >= 0 && x <= 100) struct MProps mprops; Atom atom_init_integer(DeviceIntPtr dev, char* name, int nvalues, int* values, int size) { Atom atom; int i; uint8_t uvals8[MAX_INT_VALUES]; uint16_t uvals16[MAX_INT_VALUES]; uint32_t uvals32[MAX_INT_VALUES]; pointer uvals; nvalues = MINVAL(MAX_INT_VALUES, nvalues); switch(size) { case 8: for (i = 0; i < nvalues; i++) { uvals8[i] = values[i]; } uvals = uvals8; break; case 16: for (i = 0; i < nvalues; i++) { uvals16[i] = values[i]; } uvals = uvals16; break; default: for (i = 0; i < nvalues; i++) { uvals32[i] = values[i]; } uvals = uvals32; break; } atom = MakeAtom(name, strlen(name), TRUE); XIChangeDeviceProperty(dev, atom, XA_INTEGER, size, PropModeReplace, nvalues, uvals, FALSE); XISetDevicePropertyDeletable(dev, atom, FALSE); return atom; } Atom atom_init_float(DeviceIntPtr dev, char* name, int nvalues, float* values, Atom float_type) { Atom atom = MakeAtom(name, strlen(name), TRUE); XIChangeDeviceProperty(dev, atom, float_type, 32, PropModeReplace, nvalues, values, FALSE); XISetDevicePropertyDeletable(dev, atom, FALSE); return atom; } void mprops_init(struct MConfig* cfg, InputInfoPtr local) { int ivals[MAX_INT_VALUES]; float fvals[MAX_FLOAT_VALUES]; mprops.float_type = XIGetKnownProperty(XATOM_FLOAT); if (!mprops.float_type) { mprops.float_type = MakeAtom(XATOM_FLOAT, strlen(XATOM_FLOAT), TRUE); if (!mprops.float_type) { xf86Msg(X_ERROR, "mtrack: %s: Failed to init float atom. Property support is disabled.\n", local->name); return; } } ivals[0] = cfg->trackpad_disable; mprops.trackpad_disable = atom_init_integer(local->dev, MTRACK_PROP_TRACKPAD_DISABLE, 1, ivals, 8); fvals[0] = (float)cfg->sensitivity; mprops.sensitivity = atom_init_float(local->dev, MTRACK_PROP_SENSITIVITY, 1, fvals, mprops.float_type); ivals[0] = cfg->touch_down; ivals[1] = cfg->touch_up; mprops.pressure = atom_init_integer(local->dev, MTRACK_PROP_PRESSURE, 2, ivals, 8); ivals[0] = cfg->button_enable; ivals[1] = cfg->button_integrated; mprops.button_settings = atom_init_integer(local->dev, MTRACK_PROP_BUTTON_SETTINGS, 2, ivals, 8); ivals[0] = cfg->button_zones; ivals[1] = cfg->button_move; ivals[2] = cfg->button_expire; mprops.button_emulate_settings = atom_init_integer(local->dev, MTRACK_PROP_BUTTON_EMULATE_SETTINGS, 3, ivals, 16); ivals[0] = cfg->button_1touch; ivals[1] = cfg->button_2touch; ivals[2] = cfg->button_3touch; mprops.button_emulate_values = atom_init_integer(local->dev, MTRACK_PROP_BUTTON_EMULATE_VALUES, 3, ivals, 8); ivals[0] = cfg->tap_hold; ivals[1] = cfg->tap_timeout; ivals[2] = cfg->tap_dist; mprops.tap_settings = atom_init_integer(local->dev, MTRACK_PROP_TAP_SETTINGS, 3, ivals, 32); ivals[0] = cfg->tap_1touch; ivals[1] = cfg->tap_2touch; ivals[2] = cfg->tap_3touch; ivals[3] = cfg->tap_4touch; mprops.tap_emulate = atom_init_integer(local->dev, MTRACK_PROP_TAP_EMULATE, 4, ivals, 8); ivals[0] = cfg->ignore_thumb; ivals[1] = cfg->disable_on_thumb; mprops.thumb_detect = atom_init_integer(local->dev, MTRACK_PROP_THUMB_DETECT, 2, ivals, 8); ivals[0] = cfg->thumb_size; ivals[1] = cfg->thumb_ratio; mprops.thumb_size = atom_init_integer(local->dev, MTRACK_PROP_THUMB_SIZE, 2, ivals, 32); ivals[0] = cfg->ignore_palm; ivals[1] = cfg->disable_on_palm; mprops.palm_detect = atom_init_integer(local->dev, MTRACK_PROP_PALM_DETECT, 2, ivals, 8); ivals[0] = cfg->palm_size; mprops.palm_size = atom_init_integer(local->dev, MTRACK_PROP_PALM_SIZE, 1, ivals, 32); ivals[0] = cfg->gesture_hold; ivals[1] = cfg->gesture_wait; mprops.gesture_settings = atom_init_integer(local->dev, MTRACK_PROP_GESTURE_SETTINGS, 2, ivals, 16); ivals[0] = cfg->scroll_dist; mprops.scroll_dist = atom_init_integer(local->dev, MTRACK_PROP_SCROLL_DIST, 1, ivals, 32); ivals[0] = cfg->scroll_up_btn; ivals[1] = cfg->scroll_dn_btn; ivals[2] = cfg->scroll_lt_btn; ivals[3] = cfg->scroll_rt_btn; mprops.scroll_buttons = atom_init_integer(local->dev, MTRACK_PROP_SCROLL_BUTTONS, 4, ivals, 8); ivals[0] = cfg->swipe_dist; mprops.swipe_dist = atom_init_integer(local->dev, MTRACK_PROP_SWIPE_DIST, 1, ivals, 32); ivals[0] = cfg->swipe_up_btn; ivals[1] = cfg->swipe_dn_btn; ivals[2] = cfg->swipe_lt_btn; ivals[3] = cfg->swipe_rt_btn; mprops.swipe_buttons = atom_init_integer(local->dev, MTRACK_PROP_SWIPE_BUTTONS, 4, ivals, 8); ivals[0] = cfg->swipe4_dist; mprops.swipe4_dist = atom_init_integer(local->dev, MTRACK_PROP_SWIPE4_DIST, 1, ivals, 32); ivals[0] = cfg->swipe4_up_btn; ivals[1] = cfg->swipe4_dn_btn; ivals[2] = cfg->swipe4_lt_btn; ivals[3] = cfg->swipe4_rt_btn; mprops.swipe4_buttons = atom_init_integer(local->dev, MTRACK_PROP_SWIPE4_BUTTONS, 4, ivals, 8); ivals[0] = cfg->scale_dist; mprops.scale_dist = atom_init_integer(local->dev, MTRACK_PROP_SCALE_DIST, 1, ivals, 32); ivals[0] = cfg->scale_up_btn; ivals[1] = cfg->scale_dn_btn; mprops.scale_buttons = atom_init_integer(local->dev, MTRACK_PROP_SCALE_BUTTONS, 2, ivals, 8); ivals[0] = cfg->rotate_dist; mprops.rotate_dist = atom_init_integer(local->dev, MTRACK_PROP_ROTATE_DIST, 1, ivals, 32); ivals[0] = cfg->rotate_lt_btn; ivals[1] = cfg->rotate_rt_btn; mprops.rotate_buttons = atom_init_integer(local->dev, MTRACK_PROP_SCALE_BUTTONS, 2, ivals, 8); ivals[0] = cfg->drag_enable; ivals[1] = cfg->drag_timeout; ivals[2] = cfg->drag_wait; ivals[3] = cfg->drag_dist; mprops.drag_settings = atom_init_integer(local->dev, MTRACK_PROP_DRAG_SETTINGS, 4, ivals, 32); ivals[0] = cfg->axis_x_invert; ivals[1] = cfg->axis_y_invert; mprops.axis_invert = atom_init_integer(local->dev, MTRACK_PROP_AXIS_INVERT, 2, ivals, 8); } int mprops_set_property(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, BOOL checkonly) { InputInfoPtr local = dev->public.devicePrivate; struct MConfig* cfg = &((struct MTouch*)local->private)->cfg; uint8_t* ivals8; uint16_t* ivals16; uint32_t* ivals32; float* fvals; if (property == mprops.trackpad_disable) { if (prop->size != 1 || prop->format != 8 || prop->type != XA_INTEGER) return BadMatch; ivals8 = (uint8_t*)prop->data; if (ivals8[0] < 0 || ivals8[0] > 3) return BadMatch; if (!checkonly) { cfg->trackpad_disable = ivals8[0]; #ifdef DEBUG_PROPS if (cfg->trackpad_disable) xf86Msg(X_INFO, "mtrack: trackpad input disabled\n"); else xf86Msg(X_INFO, "mtrack: trackpad input enabled\n"); #endif } } else if (property == mprops.sensitivity) { if (prop->size != 1 || prop->format != 32 || prop->type != mprops.float_type) return BadMatch; fvals = (float*)prop->data; if (fvals[0] < 0) return BadMatch; if (!checkonly) { cfg->sensitivity = fvals[0]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set sensitivity to %f\n", cfg->sensitivity); #endif } } else if (property == mprops.pressure) { if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER) return BadMatch; ivals8 = (uint8_t*)prop->data; if (!VALID_PCNT(ivals8[0]) || !VALID_PCNT(ivals8[1])) return BadMatch; if (!checkonly) { cfg->touch_down = ivals8[0]; cfg->touch_up = ivals8[1]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set touch pressure to %d %d\n", cfg->touch_down, cfg->touch_up); #endif } } else if (property == mprops.button_settings) { if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER) return BadMatch; ivals8 = (uint8_t*)prop->data; if (!VALID_BOOL(ivals16[0]) || !VALID_BOOL(ivals16[1])) return BadMatch; if (!checkonly) { cfg->button_enable = ivals8[0]; cfg->button_integrated = ivals8[1]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set button settings to %d %d\n", cfg->button_enable, cfg->button_integrated); #endif } } else if (property == mprops.button_emulate_settings) { if (prop->size != 3 || prop->format != 16 || prop->type != XA_INTEGER) return BadMatch; ivals16 = (uint16_t*)prop->data; if (!VALID_BOOL(ivals16[0]) || !VALID_BOOL(ivals16[1]) || ivals16[2] < 0) return BadMatch; if (!checkonly) { cfg->button_zones = ivals16[0]; cfg->button_move = ivals16[1]; cfg->button_expire = ivals16[2]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set button emulate settings to %d %d %d\n", cfg->button_zones, cfg->button_move, cfg->button_expire); #endif } } else if (property == mprops.button_emulate_values) { if (prop->size != 3 || prop->format != 8 || prop->type != XA_INTEGER) return BadMatch; ivals8 = (uint8_t*)prop->data; if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2])) return BadMatch; if (!checkonly) { cfg->button_1touch = ivals8[0]; cfg->button_2touch = ivals8[1]; cfg->button_3touch = ivals8[2]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set button emulation to %d %d %s\n", cfg->button_1touch, cfg->button_2touch, cfg->button_3touch); #endif } } else if (property == mprops.tap_settings) { if (prop->size != 3 || prop->format != 32 || prop->type != XA_INTEGER) return BadMatch; ivals32 = (uint32_t*)prop->data; if (ivals32[0] < 1 || ivals32[1] < 1 || ivals32[2] < 1) return BadMatch; if (!checkonly) { cfg->tap_hold = ivals32[0]; cfg->tap_timeout = ivals32[1]; cfg->tap_dist = ivals32[2]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set tap settings to %d %d %d\n", cfg->tap_hold, cfg->tap_timeout, cfg->tap_dist); #endif } } else if (property == mprops.tap_emulate) { if (prop->size != 4 || prop->format != 8 || prop->type != XA_INTEGER) return BadMatch; ivals8 = (uint8_t*)prop->data; if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3])) return BadMatch; if (!checkonly) { cfg->tap_1touch = ivals8[0]; cfg->tap_2touch = ivals8[1]; cfg->tap_3touch = ivals8[2]; cfg->tap_4touch = ivals8[3]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set tap emulation to %d %d %d %d\n", cfg->tap_1touch, cfg->tap_2touch, cfg->tap_3touch, cfg->tap_4touch); #endif } } else if (property == mprops.thumb_detect) { if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER) return BadMatch; ivals8 = (uint8_t*)prop->data; if (!VALID_BOOL(ivals8[0]) || !VALID_BOOL(ivals8[1])) return BadMatch; if (!checkonly) { cfg->ignore_thumb = ivals8[0]; cfg->disable_on_thumb = ivals8[1]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set thumb detect to %d %d\n", cfg->ignore_thumb, cfg->disable_on_thumb); #endif } } else if (property == mprops.thumb_size) { if (prop->size != 2 || prop->format != 32 || prop->type != XA_INTEGER) return BadMatch; ivals32 = (uint32_t*)prop->data; if (ivals32[0] < 0 || !VALID_PCNT(ivals32[1])) return BadMatch; if (!checkonly) { cfg->thumb_size = ivals32[0]; cfg->thumb_ratio = ivals32[0]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set thumb size to %d %d\n", cfg->thumb_size, cfg->thumb_ratio); #endif } } else if (property == mprops.palm_detect) { if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER) return BadMatch; ivals8 = (uint8_t*)prop->data; if (!VALID_BOOL(ivals8[0]) || !VALID_BOOL(ivals8[1])) return BadMatch; if (!checkonly) { cfg->ignore_palm = ivals8[0]; cfg->disable_on_palm = ivals8[1]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set palm detect to %d %d\n", cfg->ignore_palm, cfg->disable_on_palm); #endif } } else if (property == mprops.palm_size) { if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER) return BadMatch; ivals32 = (uint32_t*)prop->data; if (ivals32[0] < 0) return BadMatch; if (!checkonly) { cfg->palm_size = ivals32[0]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set palm size to %d\n", cfg->palm_size); #endif } } else if (property == mprops.gesture_settings) { if (prop->size != 2 || prop->format != 16 || prop->type != XA_INTEGER) return BadMatch; ivals16 = (uint16_t*)prop->data; if (ivals16[0] < 1 || ivals16[1] < 0) return BadMatch; if (!checkonly) { cfg->gesture_hold = ivals16[0]; cfg->gesture_wait = ivals16[1]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set gesture settings to %d %d\n", cfg->gesture_hold, cfg->gesture_wait); #endif } } else if (property == mprops.scroll_dist) { if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER) return BadMatch; ivals32 = (uint32_t*)prop->data; if (ivals32[0] < 1) return BadMatch; if (!checkonly) { cfg->scroll_dist = ivals32[0]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set scroll distance to %d\n", cfg->scroll_dist); #endif } } else if (property == mprops.scroll_buttons) { if (prop->size != 4 || prop->format != 8 || prop->type != XA_INTEGER) return BadMatch; ivals8 = (uint8_t*)prop->data; if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3])) return BadMatch; if (!checkonly) { cfg->scroll_up_btn = ivals8[0]; cfg->scroll_dn_btn = ivals8[1]; cfg->scroll_lt_btn = ivals8[2]; cfg->scroll_rt_btn = ivals8[3]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set scroll buttons to %d %d %d %d\n", cfg->scroll_up_btn, cfg->scroll_dn_btn, cfg->scroll_lt_btn, cfg->scroll_rt_btn); #endif } } else if (property == mprops.swipe_dist) { if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER) return BadMatch; ivals32 = (uint32_t*)prop->data; if (ivals32[0] < 1) return BadMatch; if (!checkonly) { cfg->swipe_dist = ivals32[0]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set swipe distance to %d\n", cfg->swipe_dist); #endif } } else if (property == mprops.swipe_buttons) { if (prop->size != 4 || prop->format != 8 || prop->type != XA_INTEGER) return BadMatch; ivals8 = (uint8_t*)prop->data; if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3])) return BadMatch; if (!checkonly) { cfg->swipe_up_btn = ivals8[0]; cfg->swipe_dn_btn = ivals8[1]; cfg->swipe_lt_btn = ivals8[2]; cfg->swipe_rt_btn = ivals8[3]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set swipe buttons to %d %d %d %d\n", cfg->swipe_up_btn, cfg->swipe_dn_btn, cfg->swipe_lt_btn, cfg->swipe_rt_btn); #endif } } else if (property == mprops.swipe4_dist) { if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER) return BadMatch; ivals32 = (uint32_t*)prop->data; if (ivals32[0] < 1) return BadMatch; if (!checkonly) { cfg->swipe4_dist = ivals32[0]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set swipe4 distance to %d\n", cfg->swipe4_dist); #endif } } else if (property == mprops.swipe4_buttons) { if (prop->size != 4 || prop->format != 8 || prop->type != XA_INTEGER) return BadMatch; ivals8 = (uint8_t*)prop->data; if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3])) return BadMatch; if (!checkonly) { cfg->swipe4_up_btn = ivals8[0]; cfg->swipe4_dn_btn = ivals8[1]; cfg->swipe4_lt_btn = ivals8[2]; cfg->swipe4_rt_btn = ivals8[3]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set swipe4 buttons to %d %d %d %d\n", cfg->swipe4_up_btn, cfg->swipe4_dn_btn, cfg->swipe4_lt_btn, cfg->swipe4_rt_btn); #endif } } else if (property == mprops.scale_dist) { if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER) return BadMatch; ivals32 = (uint32_t*)prop->data; if (ivals32[0] < 1) return BadMatch; if (!checkonly) { cfg->scale_dist = ivals32[0]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set scale distance to %d\n", cfg->scale_dist); #endif } } else if (property == mprops.scale_buttons) { if (prop->size != 4 || prop->format != 8 || prop->type != XA_INTEGER) return BadMatch; ivals8 = (uint8_t*)prop->data; if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3])) return BadMatch; if (!checkonly) { cfg->scale_up_btn = ivals8[0]; cfg->scale_dn_btn = ivals8[1]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set scale buttons to %d %d\n", cfg->scale_up_btn, cfg->scale_dn_btn); #endif } } else if (property == mprops.rotate_dist) { if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER) return BadMatch; ivals32 = (uint32_t*)prop->data; if (ivals32[0] < 1) return BadMatch; if (!checkonly) { cfg->rotate_dist = ivals32[0]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set rotate distance to %d\n", cfg->rotate_dist); #endif } } else if (property == mprops.rotate_buttons) { if (prop->size != 4 || prop->format != 8 || prop->type != XA_INTEGER) return BadMatch; ivals8 = (uint8_t*)prop->data; if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3])) return BadMatch; if (!checkonly) { cfg->rotate_lt_btn = ivals8[0]; cfg->rotate_rt_btn = ivals8[1]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set rotate buttons to %d %d\n", cfg->rotate_lt_btn, cfg->rotate_rt_btn); #endif } } else if (property == mprops.drag_settings) { if (prop->size != 4 || prop->format != 32 || prop->type != XA_INTEGER) return BadMatch; ivals32 = (uint32_t*)prop->data; if (!VALID_BOOL(ivals32[0]) || ivals32[1] < 1 || ivals32[2] < 0 || ivals32[3] < 0) return BadMatch; if (!checkonly) { cfg->drag_enable = ivals32[0]; cfg->drag_timeout = ivals32[1]; cfg->drag_wait = ivals32[2]; cfg->drag_dist = ivals32[3]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set drag settings to %d %d %d %d\n", cfg->drag_enable, cfg->drag_timeout, cfg->drag_wait, cfg->drag_dist); #endif } } else if (property == mprops.axis_invert) { if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER) return BadMatch; ivals8 = (uint8_t*)prop->data; if (!VALID_BOOL(ivals8[0]) || !VALID_BOOL(ivals8[1])) return BadMatch; if (!checkonly) { cfg->axis_x_invert = ivals8[0]; cfg->axis_y_invert = ivals8[1]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set axis inversion to %d %d\n", cfg->axis_x_invert, cfg->axis_y_invert); #endif } } return Success; } xf86-input-mtrack-0.3.0/driver/mtrack.c0000644000175000017500000002203611772504475020126 0ustar iwamatsuiwamatsu/*************************************************************************** * * Multitouch X driver * Copyright (C) 2008 Henrik Rydberg * Copyright (C) 2011 Ryan Bourgeois * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * **************************************************************************/ #include "mtouch.h" #include "mprops.h" #include #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 #include #include #endif #define TAP_HOLD 100 #define TAP_TIMEOUT 200 #define TAP_THRESHOLD 0.05 #define TICK_TIMEOUT 50 #define SCROLL_THRESHOLD 0.05 #define SWIPE_THRESHOLD 0.15 #define SCALE_THRESHOLD 0.15 #define ROTATE_THRESHOLD 0.15 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12 typedef InputInfoPtr LocalDevicePtr; #endif /* button mapping simplified */ #define PROPMAP(m, x, y) m[x] = XIGetKnownProperty(y) static void pointer_control(DeviceIntPtr dev, PtrCtrl *ctrl) { #if DEBUG_DRIVER xf86Msg(X_INFO, "pointer_control\n"); #endif } #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 static void initAxesLabels(Atom map[2]) { memset(map, 0, 2 * sizeof(Atom)); PROPMAP(map, 0, AXIS_LABEL_PROP_REL_X); PROPMAP(map, 1, AXIS_LABEL_PROP_REL_Y); } static void initButtonLabels(Atom map[DIM_BUTTON]) { memset(map, 0, DIM_BUTTON * sizeof(Atom)); PROPMAP(map, MT_BUTTON_LEFT, BTN_LABEL_PROP_BTN_LEFT); PROPMAP(map, MT_BUTTON_MIDDLE, BTN_LABEL_PROP_BTN_MIDDLE); PROPMAP(map, MT_BUTTON_RIGHT, BTN_LABEL_PROP_BTN_RIGHT); PROPMAP(map, MT_BUTTON_WHEEL_UP, BTN_LABEL_PROP_BTN_WHEEL_UP); PROPMAP(map, MT_BUTTON_WHEEL_DOWN, BTN_LABEL_PROP_BTN_WHEEL_DOWN); PROPMAP(map, MT_BUTTON_HWHEEL_LEFT, BTN_LABEL_PROP_BTN_HWHEEL_LEFT); PROPMAP(map, MT_BUTTON_HWHEEL_RIGHT, BTN_LABEL_PROP_BTN_HWHEEL_RIGHT); /* how to map swipe buttons? */ PROPMAP(map, MT_BUTTON_SWIPE_UP, BTN_LABEL_PROP_BTN_0); PROPMAP(map, MT_BUTTON_SWIPE_DOWN, BTN_LABEL_PROP_BTN_1); PROPMAP(map, MT_BUTTON_SWIPE_LEFT, BTN_LABEL_PROP_BTN_2); PROPMAP(map, MT_BUTTON_SWIPE_RIGHT, BTN_LABEL_PROP_BTN_3); /* how to map scale and rotate? */ PROPMAP(map, MT_BUTTON_SCALE_DOWN, BTN_LABEL_PROP_BTN_4); PROPMAP(map, MT_BUTTON_SCALE_UP, BTN_LABEL_PROP_BTN_5); PROPMAP(map, MT_BUTTON_ROTATE_LEFT, BTN_LABEL_PROP_BTN_6); PROPMAP(map, MT_BUTTON_ROTATE_RIGHT, BTN_LABEL_PROP_BTN_7); } #endif static int device_init(DeviceIntPtr dev, LocalDevicePtr local) { struct MTouch *mt = local->private; unsigned char btmap[DIM_BUTTON + 1] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 Atom axes_labels[2], btn_labels[DIM_BUTTON]; initAxesLabels(axes_labels); initButtonLabels(btn_labels); #endif local->fd = xf86OpenSerial(local->options); if (local->fd < 0) { xf86Msg(X_ERROR, "mtrack: cannot open device\n"); return !Success; } if (mtouch_configure(mt, local->fd)) { xf86Msg(X_ERROR, "mtrack: cannot configure device\n"); return !Success; } xf86CloseSerial(local->fd); #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3 InitPointerDeviceStruct((DevicePtr)dev, btmap, DIM_BUTTON, GetMotionHistory, pointer_control, GetMotionHistorySize(), 2); #elif GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 7 InitPointerDeviceStruct((DevicePtr)dev, btmap, DIM_BUTTON, pointer_control, GetMotionHistorySize(), 2); #elif GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 InitPointerDeviceStruct((DevicePtr)dev, btmap, DIM_BUTTON, btn_labels, pointer_control, GetMotionHistorySize(), 2, axes_labels); #else #error "Unsupported ABI_XINPUT_VERSION" #endif xf86InitValuatorAxisStruct(dev, 0, #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 axes_labels[0], #endif mt->caps.abs[MTDEV_POSITION_X].minimum, mt->caps.abs[MTDEV_POSITION_X].maximum, #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12 1, 0, 1, Absolute); #else 1, 0, 1); #endif xf86InitValuatorDefaults(dev, 0); xf86InitValuatorAxisStruct(dev, 1, #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 axes_labels[1], #endif mt->caps.abs[MTDEV_POSITION_Y].minimum, mt->caps.abs[MTDEV_POSITION_Y].maximum, #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12 1, 0, 1, Absolute); #else 1, 0, 1); #endif xf86InitValuatorDefaults(dev, 1); mprops_init(&mt->cfg, local); XIRegisterPropertyHandler(dev, mprops_set_property, NULL, NULL); return Success; } static int device_on(LocalDevicePtr local) { struct MTouch *mt = local->private; local->fd = xf86OpenSerial(local->options); if (local->fd < 0) { xf86Msg(X_ERROR, "mtrack: cannot open device\n"); return !Success; } if (mtouch_open(mt, local->fd)) { xf86Msg(X_ERROR, "mtrack: cannot grab device\n"); return !Success; } xf86AddEnabledDevice(local); return Success; } static int device_off(LocalDevicePtr local) { struct MTouch *mt = local->private; xf86RemoveEnabledDevice(local); if (mtouch_close(mt)) xf86Msg(X_WARNING, "mtrack: cannot ungrab device\n"); xf86CloseSerial(local->fd); return Success; } static int device_close(LocalDevicePtr local) { return Success; } static void handle_gestures(LocalDevicePtr local, const struct Gestures* gs) { static bitmask_t buttons_prev = 0U; int i; for (i = 0; i < 32; i++) { if (GETBIT(gs->buttons, i) == GETBIT(buttons_prev, i)) continue; if (GETBIT(gs->buttons, i)) { xf86PostButtonEvent(local->dev, FALSE, i+1, 1, 0, 0); #if DEBUG_DRIVER xf86Msg(X_INFO, "button %d down\n", i+1); #endif } else { xf86PostButtonEvent(local->dev, FALSE, i+1, 0, 0, 0); #if DEBUG_DRIVER xf86Msg(X_INFO, "button %d up\n", i+1); #endif } } buttons_prev = gs->buttons; if (gs->move_dx != 0 || gs->move_dy != 0) xf86PostMotionEvent(local->dev, 0, 0, 2, gs->move_dx, gs->move_dy); } /* called for each full received packet from the touchpad */ static void read_input(LocalDevicePtr local) { struct MTouch *mt = local->private; while (mtouch_read(mt) > 0) handle_gestures(local, &mt->gs); if (mtouch_delayed(mt)) handle_gestures(local, &mt->gs); } static Bool device_control(DeviceIntPtr dev, int mode) { LocalDevicePtr local = dev->public.devicePrivate; switch (mode) { case DEVICE_INIT: xf86Msg(X_INFO, "device control: init\n"); return device_init(dev, local); case DEVICE_ON: xf86Msg(X_INFO, "device control: on\n"); return device_on(local); case DEVICE_OFF: xf86Msg(X_INFO, "device control: off\n"); return device_off(local); case DEVICE_CLOSE: xf86Msg(X_INFO, "device control: close\n"); return device_close(local); default: xf86Msg(X_INFO, "device control: default\n"); return BadValue; } } #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12 static int preinit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) { struct MTouch *mt; mt = calloc(1, sizeof(*mt)); if (!mt) return BadAlloc; pInfo->private = mt; pInfo->type_name = XI_TOUCHPAD; pInfo->device_control = device_control; pInfo->read_input = read_input; pInfo->switch_mode = 0; xf86CollectInputOptions(pInfo, NULL); xf86OptionListReport(pInfo->options); xf86ProcessCommonOptions(pInfo, pInfo->options); mconfig_configure(&mt->cfg, pInfo->options); return Success; } #else static InputInfoPtr preinit(InputDriverPtr drv, IDevPtr dev, int flags) { struct MTouch *mt; InputInfoPtr local = xf86AllocateInput(drv, 0); if (!local) goto error; mt = calloc(1, sizeof(struct MTouch)); if (!mt) goto error; local->name = dev->identifier; local->type_name = XI_TOUCHPAD; local->device_control = device_control; local->read_input = read_input; local->private = mt; local->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS; local->conf_idev = dev; xf86CollectInputOptions(local, NULL, NULL); xf86OptionListReport(local->options); xf86ProcessCommonOptions(local, local->options); mconfig_configure(&mt->cfg, local->options); local->flags |= XI86_CONFIGURED; error: return local; } #endif static void uninit(InputDriverPtr drv, InputInfoPtr local, int flags) { free(local->private); local->private = 0; xf86DeleteInput(local, 0); } static InputDriverRec MTRACK = { 1, "mtrack", NULL, preinit, uninit, NULL, 0 }; static XF86ModuleVersionInfo moduleVersion = { "mtrack", MODULEVENDORSTRING, MODINFOSTRING1, MODINFOSTRING2, XORG_VERSION_CURRENT, 0, 1, 0, ABI_CLASS_XINPUT, ABI_XINPUT_VERSION, MOD_CLASS_XINPUT, {0, 0, 0, 0} }; static pointer setup(pointer module, pointer options, int *errmaj, int *errmin) { xf86AddInputDriver(&MTRACK, module, 0); return module; } _X_EXPORT XF86ModuleData mtrackModuleData = {&moduleVersion, &setup, NULL }; xf86-input-mtrack-0.3.0/upstream.debian/0000755000175000017500000000000011772504475020264 5ustar iwamatsuiwamatsuxf86-input-mtrack-0.3.0/upstream.debian/README.Debian0000644000175000017500000000014011772504475022320 0ustar iwamatsuiwamatsuXorg Multitouch Trackpad Driver * Install the Debian package * Configure xorg.conf * Restart X xf86-input-mtrack-0.3.0/upstream.debian/control0000644000175000017500000000107111772504475021666 0ustar iwamatsuiwamatsuSource: xserver-xorg-input-mtrack Section: misc Priority: optional Maintainer: Ryan Bourgeois Build-Depends: debhelper (>= 5), xserver-xorg-dev (>= 2:1.7.6), libmtdev-dev (>= 1.0.10) Standards-Version: 3.7.2 Homepage: https://github.com/BlueDragonX/xf86-input-mtrack Package: xserver-xorg-input-mtrack Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, libmtdev1 (>= 1.0) Description: Xorg Multitouch Trackpad Driver This X input driver provides gestures support for multitouch touchpads, with or without an integrated button. xf86-input-mtrack-0.3.0/upstream.debian/copyright0000644000175000017500000000207511772504475022223 0ustar iwamatsuiwamatsuSource URL: https://github.com/BlueDragonX/xf86-input-mtrack Upstream Author: Ryan Bourgeois Copyright: Copyright (C) 2008 Henrik Rydberg (rydberg@euromail.se) Copyright (C) 2011 Ryan Bourgeois (bluedragonx@gmail.com) License: This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Packaging: Copyright (C) 2008 by Henrik Rydberg Copyright (C) 2011 by Ryan Bourgeois released under GPL 2 xf86-input-mtrack-0.3.0/upstream.debian/dirs0000644000175000017500000000000111772504475021137 0ustar iwamatsuiwamatsu xf86-input-mtrack-0.3.0/upstream.debian/rules0000755000175000017500000000126111772504475021344 0ustar iwamatsuiwamatsu#!/usr/bin/make -f # -*- makefile -*- # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 build-arch: dh_testdir $(MAKE) build-indep: build: build-arch build-indep install: dh_testdir dh_testroot dh_clean -k dh_installdirs $(MAKE) DESTDIR=$(CURDIR)/debian/xserver-xorg-input-mtrack install binary-arch: build-arch install dh_testdir dh_testroot dh_link dh_strip dh_compress dh_fixperms dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary-indep: build-indep binary: binary-arch binary-indep clean: dh_testdir dh_testroot $(MAKE) clean dh_clean .PHONY: build-arch build-indep build install binary-arch binary-indep binary clean xf86-input-mtrack-0.3.0/upstream.debian/compat0000644000175000017500000000000211772504475021462 0ustar iwamatsuiwamatsu5 xf86-input-mtrack-0.3.0/upstream.debian/changelog0000644000175000017500000000173011772504475022137 0ustar iwamatsuiwamatsuxserver-xorg-input-mtrack (0.2.0) unstable; urgency=low * Now built via autoconf/automake. * Fully configurable via XInput. * Sensitivify now configurable. * Trackpad can now be disabled on keystroke via an external daemon. * Four finger tapping/swiping added. * Button zones added, a new button emulation method. * Tap-to-drag fixed. * Three finger tapping responsiveness fixed. -- Ryan Bourgeois Thu, 26 May 2011 09:44:43 -0500 xserver-xorg-input-mtrack (0.1.1) unstable; urgency=low * Bugfix release. * Disabling tapping no longer (wrongly) disables pointer movement. * Button emulation set to ignore "old" touches. What consitutes an old touch can be adjusted with the ButtonTouchExpire option. -- Ryan Bourgeois Thu, 28 Apr 2011 01:14:58 -0500 xserver-xorg-input-mtrack (0.1.0) unstable; urgency=low * Initial release. -- Ryan Bourgeois Fri, 15 Apr 2011 14:46:10 -0500 xf86-input-mtrack-0.3.0/configure.ac0000644000175000017500000000720611772504475017476 0ustar iwamatsuiwamatsu# Initialize Autoconf AC_PREREQ([2.60]) AC_INIT([xf86-input-mtrack], [0.2.0], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [xf86-input-mtrack]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_AUX_DIR(.) # Initialize Automake AM_INIT_AUTOMAKE([foreign]) AM_MAINTAINER_MODE # Initialize libtool AC_DISABLE_STATIC AC_PROG_LIBTOOL # Initialize X.Org macros 1.8 or later for MAN_SUBSTS set by XORG_MANPAGE_SECTIONS m4_ifndef([XORG_MACROS_VERSION], [m4_fatal([must install xorg-macros 1.8 or later before running autoconf/autogen])]) XORG_MACROS_VERSION(1.8) XORG_DEFAULT_OPTIONS # Checks for libraries. AC_CHECK_LIB([mtdev], [mtdev_open]) AC_CHECK_LIB([m], [atan2]) # Obtain compiler/linker options for the mtrack driver dependencies PKG_CHECK_MODULES(XORG, [xorg-server >= 1.7] xproto inputproto $REQUIRED_MODULES) # Set driver name DRIVER_NAME=mtrack AC_SUBST([DRIVER_NAME]) # configure option for module install directory AC_ARG_WITH(xorg-module-dir, AC_HELP_STRING([--with-xorg-module-dir=DIR], [Default xorg module directory [[default=$libdir/xorg/modules]]]), [moduledir="$withval"], [moduledir="$libdir/xorg/modules"]) inputdir=${moduledir}/input AC_SUBST(inputdir) # configure option to build extra tools AC_ARG_ENABLE(tools, AC_HELP_STRING([--enable-tools], [Build extra tools (default: disabled)]), [ENABLE_TOOLS=yes], [ENABLE_TOOLS=no]) AM_CONDITIONAL([BUILD_TOOLS], [test "x$ENABLE_TOOLS" = xyes]) # configure option to enable gesture ate debugging AC_ARG_ENABLE(debug-gestures, AS_HELP_STRING([--enable-debug-gestures], [Enable gesture debugging (default: disabled)]), [DEBUG_GESTURES=yes], [DEBUG_GESTURES=no]) if test "x$DEBUG_GESTURES" = xyes; then AC_DEFINE(DEBUG_GESTURES, 1, [Enable gesture debugging.]) fi # configure option to enable multitouch state debugging AC_ARG_ENABLE(debug-mtstate, AS_HELP_STRING([--enable-debug-mtstate], [Enable multitouch state debugging (default: disabled)]), [DEBUG_MTSTATE=yes], [DEBUG_MTSTATE=no]) if test "x$DEBUG_MTSTATE" = xyes; then AC_DEFINE(DEBUG_MTSTATE, 1, [Enable multitouch state debugging.]) fi # configure option to enable property debugging AC_ARG_ENABLE(debug-props, AS_HELP_STRING([--enable-debug-props], [Enable property debugging (default: disabled)]), [DEBUG_PROPS=yes], [DEBUG_PROPS=no]) if test "x$DEBUG_PROPS" = xyes; then AC_DEFINE(DEBUG_PROPS, 1, [Enable property debugging.]) fi # configure option to enable driver debugging AC_ARG_ENABLE(debug-driver, AS_HELP_STRING([--enable-debug-driver], [Enable property debugging (default: disabled)]), [DEBUG_DRIVER=yes], [DEBUG_DRIVER=no]) if test "x$DEBUG_DRIVER" = xyes; then AC_DEFINE(DEBUG_DRIVER, 1, [Enable property debugging.]) fi # configure option to enable all debugging AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug], [Enable all debugging (default: disabled)]), [DEBUG_ALL=$enableval], [DEBUG_ALL=no]) if test "x$DEBUG_ALL" = xyes; then AC_DEFINE(DEBUG_GESTURES, 1, [Enable gesture debugging.]) AC_DEFINE(DEBUG_MTSTATE, 1, [Enable multitouch state debugging.]) AC_DEFINE(DEBUG_PROPS, 1, [Enable property debugging.]) AC_DEFINE(DEBUG_DRIVER, 1, [Enable driver debugging.]) fi # Everything else AC_PROG_CC AC_PROG_INSTALL AC_CONFIG_FILES([Makefile]) AC_OUTPUT xf86-input-mtrack-0.3.0/CREDITS0000644000175000017500000000514311772504475016226 0ustar iwamatsuiwamatsuThis is a copy of the CREDITS file from the xf86-input-multitouch driver. --- Multitouch X driver (GPL license) Copyright (C) 2008 Henrik Rydberg This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --- The Multitouch X driver extracts a lot of X knowledge from the synaptics X driver (MIT license) Copyright (C) 1997 C. Scott Ananian Copyright (C) 1998-2000 Bruce Kalk Copyright (C) 1999 Henry Davies Copyright (C) 2001 Stefan Gmeiner Copyright (C) 2002 Linuxcare Inc. David Kennedy Copyright (C) 2003 Fred Hucht Copyright (C) 2003 Neil Brown Copyright (C) 2003 Jörg Bösner Copyright (C) 2003 Hartwig Felger Copyright (C) 2002-2007 Peter Osterlund Copyright (C) 2004 Arne Schwabe Copyright (C) 2004 Matthias Ihmig Copyright (C) 2004 Alexei Gilchrist Copyright (C) 2006-2007 Christian Thaeter Copyright (C) 2006 Stefan Bethge Copyright (C) 2007 Joseph P. Skudlarek Copyright (C) 2007 Florian Loitsch Copyright (C) 2008 Fedor P. Goncharov Copyright (C) 2008-2009 Red Hat, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --- xf86-input-mtrack-0.3.0/include/0000755000175000017500000000000011772504475016626 5ustar iwamatsuiwamatsuxf86-input-mtrack-0.3.0/include/mconfig.h0000644000175000017500000001721711772504475020431 0ustar iwamatsuiwamatsu/*************************************************************************** * * Multitouch X driver * Copyright (C) 2011 Ryan Bourgeois * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * **************************************************************************/ #ifndef MCONFIG_H #define MCONFIG_H #include "capabilities.h" #define DEFAULT_TRACKPAD_DISABLE 0 #define DEFAULT_TOUCH_DOWN 5 #define DEFAULT_TOUCH_UP 5 #define DEFAULT_IGNORE_THUMB 0 #define DEFAULT_IGNORE_PALM 0 #define DEFAULT_DISABLE_ON_THUMB 0 #define DEFAULT_DISABLE_ON_PALM 0 #define DEFAULT_THUMB_RATIO 70 #define DEFAULT_THUMB_SIZE 25 #define DEFAULT_PALM_SIZE 40 #define DEFAULT_BOTTOM_EDGE 10 #define DEFAULT_BUTTON_ENABLE 1 #define DEFAULT_BUTTON_INTEGRATED 1 #define DEFAULT_BUTTON_ZONES 0 #define DEFAULT_BUTTON_1TOUCH 3 #define DEFAULT_BUTTON_2TOUCH 2 #define DEFAULT_BUTTON_3TOUCH 0 #define DEFAULT_BUTTON_MOVE 1 #define DEFAULT_BUTTON_EXPIRE 100 #define DEFAULT_TAP_1TOUCH 1 #define DEFAULT_TAP_2TOUCH 3 #define DEFAULT_TAP_3TOUCH 2 #define DEFAULT_TAP_4TOUCH 0 #define DEFAULT_TAP_TIMEOUT 120 #define DEFAULT_TAP_HOLD 50 #define DEFAULT_TAP_DIST 400 #define DEFAULT_GESTURE_HOLD 10 #define DEFAULT_GESTURE_WAIT 100 #define DEFAULT_SCROLL_DIST 150 #define DEFAULT_SCROLL_UP_BTN 4 #define DEFAULT_SCROLL_DN_BTN 5 #define DEFAULT_SCROLL_LT_BTN 6 #define DEFAULT_SCROLL_RT_BTN 7 #define DEFAULT_SWIPE_DIST 700 #define DEFAULT_SWIPE_UP_BTN 8 #define DEFAULT_SWIPE_DN_BTN 9 #define DEFAULT_SWIPE_LT_BTN 10 #define DEFAULT_SWIPE_RT_BTN 11 #define DEFAULT_SWIPE4_DIST 700 #define DEFAULT_SWIPE4_UP_BTN 0 #define DEFAULT_SWIPE4_DN_BTN 0 #define DEFAULT_SWIPE4_LT_BTN 0 #define DEFAULT_SWIPE4_RT_BTN 0 #define DEFAULT_SCALE_DIST 150 #define DEFAULT_SCALE_UP_BTN 12 #define DEFAULT_SCALE_DN_BTN 13 #define DEFAULT_ROTATE_DIST 150 #define DEFAULT_ROTATE_LT_BTN 14 #define DEFAULT_ROTATE_RT_BTN 15 #define DEFAULT_DRAG_ENABLE 1 #define DEFAULT_DRAG_TIMEOUT 350 #define DEFAULT_DRAG_WAIT 40 #define DEFAULT_DRAG_DIST 200 #define DEFAULT_AXIS_X_INVERT 0 #define DEFAULT_AXIS_Y_INVERT 0 #define DEFAULT_SENSITIVITY 1.0 #define MCFG_NONE 0 #define MCFG_SCALE 1 #define MCFG_SIZE 2 #define MCFG_PRESSURE 3 struct MConfig { /* Used by MTState */ // Set by caps. int touch_type; // How to determine touch? 0 for none, 1 for scale, 2 for size, 3 for pressure int touch_minor; // Does the touchpad report touches as ellipses? 0 or 1 int touch_min; // Minimum touch value. int touch_max; // Maximum touch value. int pad_width; // Width of the touchpad. int pad_height; // Height of the touchpad. // Set by config. int touch_down; // When is a finger touching? 0 - 100 (percentage) int touch_up; // When is a finger released? 0 - 100 (percentage) int ignore_thumb; // Whether or not to ignore thumbs. 0 or 1 int ignore_palm; // Whether or not to ignore palms. 0 or 1 int disable_on_thumb; // Disable the touchpad if thumb detected. 0 or 1 int disable_on_palm; // Disable the touchpad if palm detected. 0 or 1 int thumb_ratio; // Ratio of width to length that makes a touch a thumb. 0 - 100 int thumb_size; // Minimum touch size for a thumb. 0 - 100 int palm_size; // Minimum touch size for a palm. 0 - 100 int bottom_edge; // Percent of bottom of trackpad to ignore for new touches. 0 - 100 int axis_x_invert; // Whether or not to invert the x axis. 0 or 1. int axis_y_invert; // Whether or not to invert the y axis. 0 or 1. /* Used by Gestures */ // Set by config. int trackpad_disable; // Disable the trackpad? 0 or 1 int button_enable; // Enable physical buttons? 0 or 1 int button_integrated; // Is the button under the touchpad? 0 or 1 int button_expire; // How long to consider a touch for button emulation. >= 0 int button_zones; // Use button zones for emulation? int button_1touch; // What button to emulate when one finger is on the // pad or the first zone is clicked? 0 to 32 int button_2touch; // What button to emulate when two fingers are on the // pad or the second zone is clicked? 0 to 32 int button_3touch; // What button to emulate when three fingers are on the // pad or the third zone is clicked? 0 to 32 int button_move; // Whether or not to count the moving touch towards button // emulation. int tap_1touch; // What button to emulate for one touch taps? 0 to 32 int tap_2touch; // What button to emulate for two touch taps? 0 to 32 int tap_3touch; // What button to emulate for three touch taps? 0 to 32 int tap_4touch; // What button to emulate for four touch taps? 0 to 32 int tap_timeout; // Window for touches when counting for the button. > 0 int tap_hold; // How long to "hold down" the emulated button on tap. > 0 int tap_dist; // How far to allow a touch to move before it's a moving touch. > 0 int gesture_hold; // How long to "hold down" the emulated button for gestures. > 0 int gesture_wait; // How long after a gesture to wait before movement is allowed. >= 0 int scroll_dist; // Distance needed to trigger a button. >= 0, 0 disables int scroll_up_btn; // Button to use for scroll up. >= 0, 0 is none int scroll_dn_btn; // Button to use for scroll down. >= 0, 0 is none int scroll_lt_btn; // Button to use for scroll left. >= 0, 0 is none int scroll_rt_btn; // Button to use for scroll right. >= 0, 0 is none int swipe_dist; // Distance needed to trigger a button. >= 0, 0 disables int swipe_up_btn; // Button to use for swipe up. >= 0, 0 is none int swipe_dn_btn; // Button to use for swipe down. >= 0, 0 is none int swipe_lt_btn; // Button to use for swipe left. >= 0, 0 is none int swipe_rt_btn; // Button to use for swipe right. >= 0, 0 is none int swipe4_dist; // Distance needed to trigger a button. >= 0, 0 disables int swipe4_up_btn; // Button to use for four finger swipe up. >= 0, 0 is none int swipe4_dn_btn; // Button to use for four finger swipe down. >= 0, 0 is none int swipe4_lt_btn; // Button to use for four finger swipe left. >= 0, 0 is none int swipe4_rt_btn; // Button to use for four finger swipe right. >= 0, 0 is none int scale_dist; // Distance needed to trigger a button. >= 0, 0 disables int scale_up_btn; // Button to use for scale up. >= 0, 0 is none int scale_dn_btn; // Button to use for scale down. >= 0, 0 is none int rotate_dist; // Distance needed to trigger a button. >= 0, 0 disables int rotate_lt_btn; // Button to use for rotate left. >= 0, 0 is none int rotate_rt_btn; // Button to use for rotate right. >= 0, 0 is none int drag_enable; // Enable tap-to-drag? 0 or 1 int drag_timeout; // How long to wait for a move after tapping? > 0 int drag_wait; // How long to wait before triggering button down? >= 0 int drag_dist; // How far is the finger allowed to move during wait time? >= 0 double sensitivity; // Mouse movement multiplier. >= 0 }; /* Load the MConfig struct with its defaults. */ void mconfig_defaults(struct MConfig* cfg); /* Initialize the MConfig struct. */ void mconfig_init(struct MConfig* cfg, const struct Capabilities* caps); void mconfig_configure(struct MConfig* cfg, pointer opts); #endif xf86-input-mtrack-0.3.0/include/common.h0000644000175000017500000000770611772504475020301 0ustar iwamatsuiwamatsu/*************************************************************************** * * Multitouch X driver * Copyright (C) 2008 Henrik Rydberg * Copyright (C) 2011 Ryan Bourgeois * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * **************************************************************************/ #ifndef COMMON_H #define COMMON_H #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #define DIM_FINGER 32 #define DIM_TOUCHES 32 /* year-proof millisecond event time */ typedef __u64 mstime_t; /* all bit masks have this type */ typedef unsigned int bitmask_t; #define BITMASK(x) (1U << (x)) #define BITONES(x) (BITMASK(x) - 1U) #define GETBIT(m, x) (((m) >> (x)) & 1U) #define SETBIT(m, x) (m |= BITMASK(x)) #define CLEARBIT(m, x) (m &= ~BITMASK(x)) #define MODBIT(m, x, b) ((b) ? SETBIT(m, x) : CLEARBIT(m, x)) #define ABSVAL(x) ((x) < 0 ? -1*(x) : (x)) #define MINVAL(x, y) ((x) < (y) ? (x) : (y)) #define MAXVAL(x, y) ((x) > (y) ? (x) : (y)) #define MODVAL(x, y) ((x) - ((int)((x) / (y))) * (y)) #define SQRVAL(x) ((x) * (x)) #define CLAMPVAL(x, min, max) MAXVAL(MINVAL(x, max), min) /* Retrieve the current time and place it in tv. */ static inline void microtime(struct timeval* tv) { gettimeofday(tv, NULL); } /* Copy one time value to another. */ static inline void timercp(struct timeval* dest, const struct timeval* src) { memcpy(dest, src, sizeof(struct timeval)); } /* Convert a timeval to milliseconds since the epoch. Truncates additional * timer resolution effectively rounding down. */ static inline mstime_t timertoms(const struct timeval* tv) { return (mstime_t)(tv->tv_sec*1000) + (mstime_t)(tv->tv_usec/1000); } /* Convert a value in milliseconds to a timeval and place the value in tv. */ static inline void timerfromms(struct timeval* tv, const mstime_t ms) { tv->tv_sec = (time_t)(ms/1000); tv->tv_usec = (suseconds_t)((ms%1000)*1000); } /* Convert a timeval to microseconds. */ static inline suseconds_t timertomicro(const struct timeval* tv) { return tv->tv_sec * 1000000 + tv->tv_usec; } /* Add milliseconds to a timeval and place the resulting value in dest. */ static inline void timeraddms(const struct timeval* a, const mstime_t b, struct timeval* dest) { struct timeval tv; timerfromms(&tv, b); timeradd(a, &tv, dest); } /* Clamp value to 15 bits. */ static inline int clamp15(int x) { return x < -32767 ? -32767 : x > 32767 ? 32767 : x; } /* Absolute scale is assumed to fit in 15 bits. */ static inline int dist2(int dx, int dy) { dx = clamp15(dx); dy = clamp15(dy); return dx * dx + dy * dy; } /* Count number of bits (Sean Eron Andersson's Bit Hacks). */ static inline int bitcount(unsigned v) { v -= ((v>>1) & 0x55555555); v = (v&0x33333333) + ((v>>2) & 0x33333333); return (((v + (v>>4)) & 0xF0F0F0F) * 0x1010101) >> 24; } /* Return index of first bit [0-31], -1 on zero\ */ #define firstbit(v) (__builtin_ffs(v) - 1) /* Boost-style foreach bit. */ #define foreach_bit(i, m) \ for (i = firstbit(m); i >= 0; i = firstbit((m) & (~0U << i + 1))) /* Robust system ioctl calls. */ #define SYSCALL(call) while (((call) == -1) && (errno == EINTR)) #endif xf86-input-mtrack-0.3.0/include/gestures.h0000644000175000017500000000453011772504475020642 0ustar iwamatsuiwamatsu/*************************************************************************** * * Multitouch X driver * Copyright (C) 2008 Henrik Rydberg * Copyright (C) 2011 Ryan Bourgeois * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * **************************************************************************/ #ifndef GESTURES_H #define GESTURES_H #include "common.h" #include "mconfig.h" #include "hwstate.h" #include "mtstate.h" struct MTouch; #define GS_TAP 0 #define GS_BUTTON 1 #define GS_NONE 0 #define GS_MOVE 1 #define GS_SCROLL 2 #define GS_SWIPE 3 #define GS_SCALE 4 #define GS_ROTATE 5 #define GS_DRAG_READY 6 #define GS_DRAG_WAIT 7 #define GS_DRAG_ACTIVE 8 struct Gestures { /* Taps, physical buttons, and gestures will trigger * button events. If a bit is set, the button is down. * If a bit is not set, the button is up. * Bit 0 is button 1. */ bitmask_t buttons; /* Pointer movement is tracked here. */ int move_dx, move_dy; /* Current time and time delta. Updated after each event and after sleeping. */ struct timeval time; struct timeval dt; /* Internal state tracking. Not for direct access. */ int button_emulate; int button_delayed; struct timeval button_delayed_time; struct timeval button_delayed_delta; int tap_touching; int tap_released; struct timeval tap_time_down; int move_type; int move_dist; int move_dir; int move_drag; int move_drag_dx; int move_drag_dy; double move_speed; struct timeval move_wait; struct timeval move_drag_wait; struct timeval move_drag_expire; }; void gestures_init(struct MTouch* mt); void gestures_extract(struct MTouch* mt); int gestures_delayed(struct MTouch* mt); #endif xf86-input-mtrack-0.3.0/include/capabilities.h0000644000175000017500000000337111772504475021434 0ustar iwamatsuiwamatsu/*************************************************************************** * * Multitouch X driver * Copyright (C) 2008 Henrik Rydberg * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * **************************************************************************/ #ifndef CAPABILITIES_H #define CAPABILITIES_H #include "common.h" #include "button.h" struct Capabilities { struct input_id devid; char devname[32]; int has_left, has_middle, has_right; int has_mtdata, has_ibt; int has_slot; int has_abs[MT_ABS_SIZE]; struct input_absinfo slot; struct input_absinfo abs[MT_ABS_SIZE]; }; int read_capabilities(struct Capabilities *cap, int fd); int get_cap_xsize(const struct Capabilities *cap); int get_cap_ysize(const struct Capabilities *cap); int get_cap_wsize(const struct Capabilities *cap); int get_cap_xmid(const struct Capabilities *cap); int get_cap_ymid(const struct Capabilities *cap); int get_cap_xflip(const struct Capabilities *cap, int x); int get_cap_yflip(const struct Capabilities *cap, int y); void output_capabilities(const struct Capabilities *cap); #endif xf86-input-mtrack-0.3.0/include/button.h0000644000175000017500000000271111772504475020313 0ustar iwamatsuiwamatsu/*************************************************************************** * * Multitouch X driver * Copyright (C) 2008 Henrik Rydberg * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * **************************************************************************/ #ifndef BUTTON_H #define BUTTON_H #define DIM_BUTTON 15 #define MT_BUTTON_LEFT 0 #define MT_BUTTON_MIDDLE 1 #define MT_BUTTON_RIGHT 2 #define MT_BUTTON_WHEEL_UP 3 #define MT_BUTTON_WHEEL_DOWN 4 #define MT_BUTTON_HWHEEL_LEFT 5 #define MT_BUTTON_HWHEEL_RIGHT 6 #define MT_BUTTON_SWIPE_UP 7 #define MT_BUTTON_SWIPE_DOWN 8 #define MT_BUTTON_SWIPE_LEFT 9 #define MT_BUTTON_SWIPE_RIGHT 10 #define MT_BUTTON_SCALE_DOWN 11 #define MT_BUTTON_SCALE_UP 12 #define MT_BUTTON_ROTATE_LEFT 13 #define MT_BUTTON_ROTATE_RIGHT 14 #endif xf86-input-mtrack-0.3.0/include/mprops.h0000644000175000017500000001146711772504475020330 0ustar iwamatsuiwamatsu/*************************************************************************** * * Multitouch X driver * Copyright (C) 2011 Ryan Bourgeois * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * **************************************************************************/ #ifndef MTRACK_PROPS_H #define MTRACK_PROPS_H #include #include #include #include #include #include #include "mconfig.h" #ifndef XATOM_FLOAT #define XATOM_FLOAT "FLOAT" #endif // int, 1 value #define MTRACK_PROP_TRACKPAD_DISABLE "Trackpad Disable Input" // float, 1 value #define MTRACK_PROP_SENSITIVITY "Trackpad Sensitivity" // int, 2 values - finger low, finger high #define MTRACK_PROP_PRESSURE "Trackpad Touch Pressure" // int, 2 values - enable buttons, has integrated button #define MTRACK_PROP_BUTTON_SETTINGS "Trackpad Button Settings" // int, 3 values - enable button zones, button move emulation, emulation touch expiration #define MTRACK_PROP_BUTTON_EMULATE_SETTINGS "Trackpad Button Emulation Settings" // int, 3 values - button to emulate with 1 touch, 2 touches, 3 touches #define MTRACK_PROP_BUTTON_EMULATE_VALUES "Trackpad Button Emulation Values" // int, 3 values - click time, touch timeout, invalidate distance #define MTRACK_PROP_TAP_SETTINGS "Trackpad Tap Settings" // int, 3 values - 1 touch button, 2 touch button, 3 touch button, 4 touch button #define MTRACK_PROP_TAP_EMULATE "Trackpad Tap Button Emulation" // int, 2 values - ignore thumb touches, disable trackpad on thumb touches #define MTRACK_PROP_THUMB_DETECT "Trackpad Thumb Detection" // int, 2 values - size, width to length ratio #define MTRACK_PROP_THUMB_SIZE "Trackpad Thumb Size" // int, 2 values - ignore palm touches, disable trackpad on palm touches #define MTRACK_PROP_PALM_DETECT "Trackpad Palm Detection" // int, 1 value - size #define MTRACK_PROP_PALM_SIZE "Trackpad Palm Size" // int, 2 value - button hold, wait time #define MTRACK_PROP_GESTURE_SETTINGS "Trackpad Gesture Settings" // int, 1 value - distance before a scroll event is triggered #define MTRACK_PROP_SCROLL_DIST "Trackpad Scroll Distance" // int, 4 values - up button, down button, left button, right button #define MTRACK_PROP_SCROLL_BUTTONS "Trackpad Scroll Buttons" // int, 1 value - distance before a swipe event is triggered #define MTRACK_PROP_SWIPE_DIST "Trackpad Swipe Distance" // int, 4 values - up button, down button, left button, right button #define MTRACK_PROP_SWIPE_BUTTONS "Trackpad Swipe Buttons" // int, 1 value - distance before a swipe event is triggered #define MTRACK_PROP_SWIPE4_DIST "Trackpad Swipe4 Distance" // int, 4 values - up button, down button, left button, right button #define MTRACK_PROP_SWIPE4_BUTTONS "Trackpad Swipe4 Buttons" // int, 1 value - distance before a scale event is triggered #define MTRACK_PROP_SCALE_DIST "Trackpad Scale Distance" // int, 2 values - up button, down button #define MTRACK_PROP_SCALE_BUTTONS "Trackpad Scale Buttons" // int, 1 value - distance before a rotate event is triggered #define MTRACK_PROP_ROTATE_DIST "Trackpad Rotate Distance" // int, 2 values - left button, right button #define MTRACK_PROP_ROTATE_BUTTONS "Trackpad Rotate Buttons" // int, 4 values - enable, timeout, wait, dist #define MTRACK_PROP_DRAG_SETTINGS "Trackpad Drag Settings" // int, 2 values - invert x axis, invert y axis #define MTRACK_PROP_AXIS_INVERT "Trackpad Axis Inversion" struct MProps { // Properties Config Atom float_type; // Adjustable Properties Atom api; Atom trackpad_disable; Atom sensitivity; Atom pressure; Atom button_settings; Atom button_emulate_settings; Atom button_emulate_values; Atom tap_settings; Atom tap_emulate; Atom thumb_detect; Atom thumb_size; Atom palm_detect; Atom palm_size; Atom gesture_settings; Atom scroll_dist; Atom scroll_buttons; Atom swipe_dist; Atom swipe_buttons; Atom swipe4_dist; Atom swipe4_buttons; Atom scale_dist; Atom scale_buttons; Atom rotate_dist; Atom rotate_buttons; Atom drag_settings; Atom axis_invert; }; void mprops_init(struct MConfig* cfg, InputInfoPtr local); int mprops_set_property(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, BOOL checkonly); #endif xf86-input-mtrack-0.3.0/include/mtstate.h0000644000175000017500000000341611772504475020464 0ustar iwamatsuiwamatsu/*************************************************************************** * * Multitouch X driver * Copyright (C) 2008 Henrik Rydberg * Copyright (C) 2011 Ryan Bourgeois * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * **************************************************************************/ #ifndef MTSTATE_H #define MTSTATE_H #include "common.h" #include "mconfig.h" #include "hwstate.h" #include "capabilities.h" #define MT_NEW 0 #define MT_RELEASED 1 #define MT_INVALID 2 #define MT_THUMB 3 #define MT_PALM 4 #define MT_BOTTOM_EDGE 5 struct Touch { bitmask_t state; bitmask_t flags; double direction; int tracking_id; int x, y, dx, dy; int total_dx, total_dy; struct timeval down; }; struct MTState { bitmask_t state; struct Touch touch[DIM_TOUCHES]; bitmask_t touch_used; }; /* Initialize an MTState struct. */ void mtstate_init(struct MTState* ms); /* Extract the MTState from the current hardware state. */ void mtstate_extract(struct MTState* ms, const struct MConfig* cfg, const struct HWState* hs, const struct Capabilities* caps); #endif xf86-input-mtrack-0.3.0/include/mtouch.h0000644000175000017500000000303111772504475020273 0ustar iwamatsuiwamatsu/*************************************************************************** * * Multitouch X driver * Copyright (C) 2008 Henrik Rydberg * Copyright (C) 2011 Ryan Bourgeois * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * **************************************************************************/ #ifndef MTOUCH_H #define MTOUCH_H #include "common.h" #include "capabilities.h" #include "hwstate.h" #include "mtstate.h" #include "mconfig.h" #include "gestures.h" struct MTouch { int fd; struct mtdev dev; struct Capabilities caps; struct HWState hs; struct MTState state; struct MConfig cfg; struct Gestures gs; }; int mtouch_configure(struct MTouch* mt, int fd); int mtouch_open(struct MTouch* mt, int fd); int mtouch_close(struct MTouch* mt); int mtouch_read(struct MTouch* mt); int mtouch_delayed(struct MTouch* mt); #endif xf86-input-mtrack-0.3.0/include/trig.h0000644000175000017500000000454511772504475017754 0ustar iwamatsuiwamatsu/*************************************************************************** * * Multitouch X driver * Copyright (C) 2011 Ryan Bourgeois * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * **************************************************************************/ /* Some bastardized trig functions. These calculations flip the * Y axis since that axis on touchpads is opposite that of the * Cartesian system. */ #ifndef MT_TRIG_H #define MT_TRIG_H #define TR_NONE -1 #define TR_DIR_UP 0 #define TR_DIR_RT 2 #define TR_DIR_DN 4 #define TR_DIR_LT 6 /* Determine the direction of a vector. This uses the slope of the * vector to approximate the angle, as such it is only accurate at * increments of 45 degrees. This is sufficient for our uses. * * The returned value is 0 <= a < 8 such that the circle is split * into 45 degree sections. Each whole number lies 45 degrees apart * and so whole numbers are exact. All fractional parts are * aproximations. * * TR_NONE will be returned if the magnitude of the vector is zero. */ double trig_direction(double dx, double dy); /* Generalize a direction. Returns TR_NONE, TR_DIR_UP, TR_DIR_RT, * TR_DIR_DN, or TR_DIR_LT. */ int trig_generalize(double dir); /* Add two angles. */ double trig_angles_add(double a1, double a2); /* Subtract two angles. */ double trig_angles_sub(double a1, double a2); /* Calculate the acute angle between two angles. */ double trig_angles_acute(double a1, double a2); /* Average a collection of angles. */ double trig_angles_avg(double* angles, int len); /* Compare two angles. Returns 0 if a1 == a2. Returns < 0 if a1 < a2. * Returns > 0 if a1 > a2. */ int trig_angles_cmp(double a1, double a2); #endif xf86-input-mtrack-0.3.0/include/hwstate.h0000644000175000017500000000316511772504475020463 0ustar iwamatsuiwamatsu/*************************************************************************** * * Multitouch X driver * Copyright (C) 2008 Henrik Rydberg * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * **************************************************************************/ #ifndef HWSTATE_H #define HWSTATE_H #include "common.h" #include "capabilities.h" struct FingerState { int touch_major, touch_minor; int width_major, width_minor; int orientation, pressure; int position_x, position_y; int tracking_id; }; struct HWState { struct FingerState data[DIM_FINGER]; bitmask_t used; bitmask_t slot; bitmask_t button; int max_x, max_y; struct timeval evtime; }; void hwstate_init(struct HWState *s, const struct Capabilities *caps); int hwstate_modify(struct HWState *s, struct mtdev *dev, int fd, const struct Capabilities *caps); void hwstate_output(const struct HWState *s); int find_finger(const struct HWState *s, int tracking_id); #endif