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 <tom@trap.mtview.ca.us>
+
+ * 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 <rubini@morgana.systemy.it>
* 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;
}