Report forwarded to debian-bugs-dist@lists.debian.org, warp@debian.org (Zephaniah E. Hull):
Bug#96536; Package gpm.   debian-bugs-dist@lists.debian.orgwarp@debian.org (Zephaniah E. Hull)  Subject: Bug#96536: Should support "wheel" buttons on synaptics touchpad Reply-To: Tom Lear , 96536@bugs.debian.org Resent-From: Tom Lear Resent-To: debian-bugs-dist@lists.debian.org Resent-CC: warp@debian.org (Zephaniah E. Hull) Resent-Date: Sun, 06 May 2001 16:48:01 GMT Resent-Message-ID: Resent-Sender: owner@bugs.debian.org X-Debian-PR-Message: report 96536 X-Debian-PR-Package: gpm X-Debian-PR-Keywords: X-Loop: owner@bugs.debian.org Received: via spool by bugs@bugs.debian.org id=B.98916728419546 (code B ref -1); Sun, 06 May 2001 16:48:01 GMT Date: Sun, 6 May 2001 09:41:19 -0700 From: Tom Lear To: submit@bugs.debian.org Message-ID: <20010506094116.B8721@trap.mtview.ca.us> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.3.15i Delivered-To: submit@bugs.debian.org Package: gpm Version: 1.19.3-6 Severity: wishlist Here's a patch to add support for "wheel" button on the synaptics touchpad. It also adds the ability to remap buttons. - Tom diff -c gpm-1.19.3.orig/ChangeLog gpm-1.19.3/ChangeLog *** gpm-1.19.3.orig/ChangeLog Tue Jul 18 05:22:18 2000 --- gpm-1.19.3/ChangeLog Sun May 6 09:26:27 2001 *************** *** 1,3 **** --- 1,9 ---- + 2001-05-06 Tom Lear + + * Added support for "wheel" buttons (and the gesture + interpretation that support requires - grrrr) + * Added support for remapping buttons to gpm-syn.conf + 2000-07-18 Alessandro Rubini * doc/doc.gpm (Command Line): removed "-q" documentation. diff -c gpm-1.19.3.orig/gpm-syn.conf gpm-1.19.3/gpm-syn.conf *** gpm-1.19.3.orig/gpm-syn.conf Mon Sep 13 15:00:00 1999 --- gpm-1.19.3/gpm-syn.conf Sun May 6 09:26:51 2001 *************** *** 25,27 **** --- 25,33 ---- [upper_right_action] 2 (middle) [lower_left_action] 0 (none) [lower_right_action] 3 (right) + /* button mapping */ + [tap_button_mapping] 1 (left) + [left_button_mapping] 1 (left) + [right_button_mapping] 3 (right) + /* wmode is required to support "wheel" buttons */ + [wmode] 0 diff -c gpm-1.19.3.orig/synaptics.c gpm-1.19.3/synaptics.c *** gpm-1.19.3.orig/synaptics.c Mon Jan 17 13:34:00 2000 --- gpm-1.19.3/synaptics.c Sun May 6 08:56:48 2001 *************** *** 180,185 **** --- 180,199 ---- /* + ** Default button mappings + */ + static int button_mapping[] = { + 1, /* tap defaults to left click */ + 1, /* left defaults to left click */ + 3, /* right defaults to right click */ + }; + + /* wmode parameters */ + static int wmode = 0; + static int wheel_delay = 10; + static int recent_gesture = 0; + + /* ** These types are used to read the configuration data from the config file. */ typedef enum { *************** *** 229,234 **** --- 243,254 ---- { "lower_left_action", Corner_Param, &corner_actions [1] }, { "upper_right_action", Corner_Param, &corner_actions [2] }, { "lower_right_action", Corner_Param, &corner_actions [3] }, + /* button mapping */ + { "tap_button_mapping", Integer_Param, &button_mapping[0] }, + { "left_button_mapping", Integer_Param, &button_mapping[1] }, + { "right_button_mapping", Integer_Param, &button_mapping[2] }, + /* should we use wmode? */ + { "wmode", Integer_Param, &wmode }, /* end of list */ { NULL, Flag_Param, NULL }, }; *************** *** 271,276 **** --- 291,298 ---- int x; int y; int pressure; + int up; + int down; } report_type; *************** *** 380,385 **** --- 402,412 ---- static location_type toss_speed; static location_type touch_loc; + /* remember the state of wheel buttons to control repeating */ + static int last_up = 0; + static int last_down = 0; + static int cur_up_delay = 0; + static int cur_down_delay = 0; /**************************************************************************** ** *************** *** 508,513 **** --- 535,560 ---- /* + ** map_buttons + ** + ** Remap buttons according to config file + */ + static void map_buttons (Gpm_Event *state, + int button) { + switch(button_mapping[button]) { + case 1: + state->buttons |= GPM_B_LEFT; + break; + case 2: + state->buttons |= GPM_B_MIDDLE; + break; + case 3: + state->buttons |= GPM_B_RIGHT; + break; + } + } + + /* ** syn_process_data ** ** Process the touchpad report. *************** *** 531,541 **** --- 578,625 ---- state->buttons = 0; state->dx = 0; state->dy = 0; + state->wdx = 0; + state->wdy = 0; #if DEBUG_REPORTS dump_report_data (report, edges); #endif + /* in wmode we need to do our own gestures */ + if(wmode) { + if(last_gesture) report.gesture=last_gesture-1; + if(last_gesture && report.finger) report.gesture=1; + if(recent_gesture && recent_gesture<12) report.gesture=1; + if(recent_gesture) recent_gesture--; + if(!report.finger && last_finger) { + if(last_gesture) { + if(packet_num < 16) recent_gesture=13; + report.gesture=0; + } else { + if(packet_num > 2 && packet_num < 16) report.gesture=8; + } + } + } + + /* wheel proccessing - repeat faster the longer the button is down */ + if(last_up) last_up--; + if(!report.up) { + cur_up_delay=wheel_delay; + last_up=0; + } + if(last_up==1) cur_up_delay--; + if(report.up && !last_up) last_up=report.up; + if(report.up != last_up) report.up=0; + + if(last_down) last_down--; + if(!report.down) { + cur_down_delay=wheel_delay; + last_down=0; + } + if(last_down==1) cur_down_delay--; + if(report.down && !last_down) last_down=report.down; + if(report.down != last_down) report.down=0; + /* We only need concern ourselves when a finger is on the pad */ if (report.finger) { if (tossing_enabled) { *************** *** 654,659 **** --- 738,763 ---- /* check for buttons if we didn't just complete a toss */ if (!tossing && !was_tossing) { /* + ** set buttons according to mapping (though they may be overwritten + ** in the next segment of code) + */ + if (taps_enabled && + (report.gesture && !is_corner (last_edges))) + map_buttons(state, 0); + + if (report.left) + map_buttons(state, 1); + + if (report.right) + map_buttons(state, 2); + + if (report.up) + state->wdy = 1; + + if (report.down) + state->wdy = -1; + + /* ** If there is no gesture then there are no buttons. ** If there is a continuing gesture then report the same buttons. ** Otherwise compute new buttons. *************** *** 663,675 **** } else if (last_gesture) { state->buttons = last_buttons; } else { - if (report.left || (taps_enabled && - (report.gesture && !is_corner (last_edges)))) - state->buttons |= GPM_B_LEFT; - - if (report.right) - state->buttons |= GPM_B_RIGHT; - process_corner_taps (state, report); } } --- 767,772 ---- *************** *** 1118,1128 **** --- 1215,1267 ---- } /* Translate the reported data into a record for processing */ + static void syn_translate_ps2w_report (unsigned char *data, + report_type *report) + { + int i; + + //printf("mouse event: %02X %02X %02X %02X %02X %02X\n",data[0],data[1],data[2],data[3],data[4],data[5]); + if (((data [0] & 0xc8) == 0x80) && + ((data [3] & 0xc8) == 0xc0)) { + report->gesture = 0; + report->finger = data [2] > 23; + report->left = check_bits (data [0], 0x01); + report->middle = 0; + report->right = check_bits (data [0], 0x02); + report->up = cur_up_delay * check_bits(data[0] ^ data[3], 0x01); + report->down = cur_down_delay * check_bits(data[0] ^ data[3], 0x02); + report->x = (((data [1] & 0x0f) << 8) | + ((data [3] & 0x10) << 8) | + data [4]); + report->y = (((data [1] & 0xf0) << 4) | + ((data [3] & 0x20) << 7) | + data [5]); + report->pressure = data [2]; + } else { + gpm_debug_log (LOG_NOTICE,"tossing PS/2 data: "); + for (i = 0; i < 6; i++) + gpm_debug_log (LOG_NOTICE,"%02X ", data [i]); + report->gesture = 0; + report->finger = 0; + report->left = 0; + report->middle = 0; + report->right = 0; + report->x = 0; + report->y = 0; + report->pressure = 0; + report->up = 0; + report->down = 0; + } + } + + /* Translate the reported data into a record for processing */ static void syn_translate_ps2_report (unsigned char *data, report_type *report) { int i; + report->up = 0; + report->down = 0; if (((data [0] & 0xc8) == 0x80) && ((data [3] & 0xc8) == 0xc0) && ((data [0] & 0x0f) == (data [3] & 0x0f))) { *************** *** 1200,1206 **** { report_type report; ! syn_translate_ps2_report (data, &report); syn_process_data (state, report); } --- 1339,1348 ---- { report_type report; ! if(wmode) ! syn_translate_ps2w_report (data, &report); ! else ! syn_translate_ps2_report (data, &report); syn_process_data (state, report); } *************** *** 1254,1258 **** ps2_set_mode2 (fd, (ABSOLUTE_MODE | HIGH_REPORT_RATE | PS2_NO_SLEEP | ! REPORT_W_OFF)); } --- 1396,1401 ---- ps2_set_mode2 (fd, (ABSOLUTE_MODE | HIGH_REPORT_RATE | PS2_NO_SLEEP | ! (wmode?REPORT_W_ON:REPORT_W_OFF))); ! if(wmode) cur_up_delay=cur_down_delay=wheel_delay; }   Acknowledgement sent to Tom Lear <tom@trap.mtview.ca.us>:
New Bug report received and forwarded. Copy sent to warp@debian.org (Zephaniah E. Hull).   -t  From: owner@bugs.debian.org (Debian Bug Tracking System) To: Tom Lear Subject: Bug#96536: Acknowledgement (Should support "wheel" buttons on synaptics touchpad) Message-ID: In-Reply-To: <20010506094116.B8721@trap.mtview.ca.us> References: <20010506094116.B8721@trap.mtview.ca.us> X-Debian-PR-Message: ack 96536 Thank you for the problem report you have sent regarding Debian. This is an automatically generated reply, to let you know your message has been received. It is being forwarded to the developers mailing list for their attention; they will reply in due course. Your message has been sent to the package maintainer(s): warp@debian.org (Zephaniah E. Hull) If you wish to submit further information on your problem, please send it to 96536@bugs.debian.org (and *not* to bugs@bugs.debian.org). Please do not reply to the address at the top of this message, unless you wish to report a problem with the Bug-tracking system. Darren Benham (administrator, Debian Bugs database)   Received: (at submit) by bugs.debian.org; 6 May 2001 16:41:24 +0000 From tom@trap.mtview.ca.us Sun May 06 11:41:24 2001 Return-path: Received: from dslpw125.hypersurf.com (localhost) [206.40.43.125] by master.debian.org with esmtp (Exim 3.12 1 (Debian)) id 14wRb1-00055A-00; Sun, 06 May 2001 11:41:23 -0500 Received: by trap.mtview.ca.us via sendmail from stdin id (Debian Smail3.2.0.111) for submit@bugs.debian.org; Sun, 6 May 2001 09:41:19 -0700 (PDT) Date: Sun, 6 May 2001 09:41:19 -0700 From: Tom Lear To: submit@bugs.debian.org Subject: Should support "wheel" buttons on synaptics touchpad Message-ID: <20010506094116.B8721@trap.mtview.ca.us> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.3.15i Delivered-To: submit@bugs.debian.org Package: gpm Version: 1.19.3-6 Severity: wishlist Here's a patch to add support for "wheel" button on the synaptics touchpad. It also adds the ability to remap buttons. - Tom diff -c gpm-1.19.3.orig/ChangeLog gpm-1.19.3/ChangeLog *** gpm-1.19.3.orig/ChangeLog Tue Jul 18 05:22:18 2000 --- gpm-1.19.3/ChangeLog Sun May 6 09:26:27 2001 *************** *** 1,3 **** --- 1,9 ---- + 2001-05-06 Tom Lear + + * Added support for "wheel" buttons (and the gesture + interpretation that support requires - grrrr) + * Added support for remapping buttons to gpm-syn.conf + 2000-07-18 Alessandro Rubini * doc/doc.gpm (Command Line): removed "-q" documentation. diff -c gpm-1.19.3.orig/gpm-syn.conf gpm-1.19.3/gpm-syn.conf *** gpm-1.19.3.orig/gpm-syn.conf Mon Sep 13 15:00:00 1999 --- gpm-1.19.3/gpm-syn.conf Sun May 6 09:26:51 2001 *************** *** 25,27 **** --- 25,33 ---- [upper_right_action] 2 (middle) [lower_left_action] 0 (none) [lower_right_action] 3 (right) + /* button mapping */ + [tap_button_mapping] 1 (left) + [left_button_mapping] 1 (left) + [right_button_mapping] 3 (right) + /* wmode is required to support "wheel" buttons */ + [wmode] 0 diff -c gpm-1.19.3.orig/synaptics.c gpm-1.19.3/synaptics.c *** gpm-1.19.3.orig/synaptics.c Mon Jan 17 13:34:00 2000 --- gpm-1.19.3/synaptics.c Sun May 6 08:56:48 2001 *************** *** 180,185 **** --- 180,199 ---- /* + ** Default button mappings + */ + static int button_mapping[] = { + 1, /* tap defaults to left click */ + 1, /* left defaults to left click */ + 3, /* right defaults to right click */ + }; + + /* wmode parameters */ + static int wmode = 0; + static int wheel_delay = 10; + static int recent_gesture = 0; + + /* ** These types are used to read the configuration data from the config file. */ typedef enum { *************** *** 229,234 **** --- 243,254 ---- { "lower_left_action", Corner_Param, &corner_actions [1] }, { "upper_right_action", Corner_Param, &corner_actions [2] }, { "lower_right_action", Corner_Param, &corner_actions [3] }, + /* button mapping */ + { "tap_button_mapping", Integer_Param, &button_mapping[0] }, + { "left_button_mapping", Integer_Param, &button_mapping[1] }, + { "right_button_mapping", Integer_Param, &button_mapping[2] }, + /* should we use wmode? */ + { "wmode", Integer_Param, &wmode }, /* end of list */ { NULL, Flag_Param, NULL }, }; *************** *** 271,276 **** --- 291,298 ---- int x; int y; int pressure; + int up; + int down; } report_type; *************** *** 380,385 **** --- 402,412 ---- static location_type toss_speed; static location_type touch_loc; + /* remember the state of wheel buttons to control repeating */ + static int last_up = 0; + static int last_down = 0; + static int cur_up_delay = 0; + static int cur_down_delay = 0; /**************************************************************************** ** *************** *** 508,513 **** --- 535,560 ---- /* + ** map_buttons + ** + ** Remap buttons according to config file + */ + static void map_buttons (Gpm_Event *state, + int button) { + switch(button_mapping[button]) { + case 1: + state->buttons |= GPM_B_LEFT; + break; + case 2: + state->buttons |= GPM_B_MIDDLE; + break; + case 3: + state->buttons |= GPM_B_RIGHT; + break; + } + } + + /* ** syn_process_data ** ** Process the touchpad report. *************** *** 531,541 **** --- 578,625 ---- state->buttons = 0; state->dx = 0; state->dy = 0; + state->wdx = 0; + state->wdy = 0; #if DEBUG_REPORTS dump_report_data (report, edges); #endif + /* in wmode we need to do our own gestures */ + if(wmode) { + if(last_gesture) report.gesture=last_gesture-1; + if(last_gesture && report.finger) report.gesture=1; + if(recent_gesture && recent_gesture<12) report.gesture=1; + if(recent_gesture) recent_gesture--; + if(!report.finger && last_finger) { + if(last_gesture) { + if(packet_num < 16) recent_gesture=13; + report.gesture=0; + } else { + if(packet_num > 2 && packet_num < 16) report.gesture=8; + } + } + } + + /* wheel proccessing - repeat faster the longer the button is down */ + if(last_up) last_up--; + if(!report.up) { + cur_up_delay=wheel_delay; + last_up=0; + } + if(last_up==1) cur_up_delay--; + if(report.up && !last_up) last_up=report.up; + if(report.up != last_up) report.up=0; + + if(last_down) last_down--; + if(!report.down) { + cur_down_delay=wheel_delay; + last_down=0; + } + if(last_down==1) cur_down_delay--; + if(report.down && !last_down) last_down=report.down; + if(report.down != last_down) report.down=0; + /* We only need concern ourselves when a finger is on the pad */ if (report.finger) { if (tossing_enabled) { *************** *** 654,659 **** --- 738,763 ---- /* check for buttons if we didn't just complete a toss */ if (!tossing && !was_tossing) { /* + ** set buttons according to mapping (though they may be overwritten + ** in the next segment of code) + */ + if (taps_enabled && + (report.gesture && !is_corner (last_edges))) + map_buttons(state, 0); + + if (report.left) + map_buttons(state, 1); + + if (report.right) + map_buttons(state, 2); + + if (report.up) + state->wdy = 1; + + if (report.down) + state->wdy = -1; + + /* ** If there is no gesture then there are no buttons. ** If there is a continuing gesture then report the same buttons. ** Otherwise compute new buttons. *************** *** 663,675 **** } else if (last_gesture) { state->buttons = last_buttons; } else { - if (report.left || (taps_enabled && - (report.gesture && !is_corner (last_edges)))) - state->buttons |= GPM_B_LEFT; - - if (report.right) - state->buttons |= GPM_B_RIGHT; - process_corner_taps (state, report); } } --- 767,772 ---- *************** *** 1118,1128 **** --- 1215,1267 ---- } /* Translate the reported data into a record for processing */ + static void syn_translate_ps2w_report (unsigned char *data, + report_type *report) + { + int i; + + //printf("mouse event: %02X %02X %02X %02X %02X %02X\n",data[0],data[1],data[2],data[3],data[4],data[5]); + if (((data [0] & 0xc8) == 0x80) && + ((data [3] & 0xc8) == 0xc0)) { + report->gesture = 0; + report->finger = data [2] > 23; + report->left = check_bits (data [0], 0x01); + report->middle = 0; + report->right = check_bits (data [0], 0x02); + report->up = cur_up_delay * check_bits(data[0] ^ data[3], 0x01); + report->down = cur_down_delay * check_bits(data[0] ^ data[3], 0x02); + report->x = (((data [1] & 0x0f) << 8) | + ((data [3] & 0x10) << 8) | + data [4]); + report->y = (((data [1] & 0xf0) << 4) | + ((data [3] & 0x20) << 7) | + data [5]); + report->pressure = data [2]; + } else { + gpm_debug_log (LOG_NOTICE,"tossing PS/2 data: "); + for (i = 0; i < 6; i++) + gpm_debug_log (LOG_NOTICE,"%02X ", data [i]); + report->gesture = 0; + report->finger = 0; + report->left = 0; + report->middle = 0; + report->right = 0; + report->x = 0; + report->y = 0; + report->pressure = 0; + report->up = 0; + report->down = 0; + } + } + + /* Translate the reported data into a record for processing */ static void syn_translate_ps2_report (unsigned char *data, report_type *report) { int i; + report->up = 0; + report->down = 0; if (((data [0] & 0xc8) == 0x80) && ((data [3] & 0xc8) == 0xc0) && ((data [0] & 0x0f) == (data [3] & 0x0f))) { *************** *** 1200,1206 **** { report_type report; ! syn_translate_ps2_report (data, &report); syn_process_data (state, report); } --- 1339,1348 ---- { report_type report; ! if(wmode) ! syn_translate_ps2w_report (data, &report); ! else ! syn_translate_ps2_report (data, &report); syn_process_data (state, report); } *************** *** 1254,1258 **** ps2_set_mode2 (fd, (ABSOLUTE_MODE | HIGH_REPORT_RATE | PS2_NO_SLEEP | ! REPORT_W_OFF)); } --- 1396,1401 ---- ps2_set_mode2 (fd, (ABSOLUTE_MODE | HIGH_REPORT_RATE | PS2_NO_SLEEP | ! (wmode?REPORT_W_ON:REPORT_W_OFF))); ! if(wmode) cur_up_delay=cur_down_delay=wheel_delay; }