Index: gnome-settings-daemon/gnome-settings-mouse.c
===================================================================
--- gnome-settings-daemon/gnome-settings-mouse.c	(Revision 8097)
+++ gnome-settings-daemon/gnome-settings-mouse.c	(Arbeitskopie)
@@ -458,6 +458,56 @@
 }
 
 static void
+synaptics_set (gchar *key, gint value)
+{
+	gchar *command;
+	
+	command = g_strdup_printf ("synclient %s=%d", key, value);
+	g_spawn_command_line_async (command, NULL);
+	g_free (command);
+}
+
+static void
+set_touchpad_off (gboolean touchpad_off)
+{
+	synaptics_set ("TouchpadOff", touchpad_off ? 1 : 0);
+}
+
+static void
+set_max_tap_time (gint max_tap_time)
+{
+	if (max_tap_time < 0) {
+		max_tap_time = 0;
+	}
+	
+	synaptics_set ("MaxTapTime", max_tap_time);
+}
+
+static void
+set_vert_edge_scroll (gboolean vert_edge_scroll)
+{
+	synaptics_set ("VertEdgeScroll", vert_edge_scroll ? 1 : 0);
+}
+
+static void
+set_vert_scroll_delta (gint vert_scroll_delta)
+{
+	synaptics_set ("VertScrollDelta", vert_scroll_delta);
+}
+
+static void
+set_horiz_edge_scroll (gboolean horiz_edge_scroll)
+{
+	synaptics_set ("HorizEdgeScroll", horiz_edge_scroll ? 1 : 0);
+}
+
+static void
+set_horiz_scroll_delta (gint horiz_scroll_delta)
+{
+	synaptics_set ("HorizScrollDelta", horiz_scroll_delta);
+}
+
+static void
 mouse_callback (GConfEntry *entry)
 {
 	if (! strcmp (entry->key, "/desktop/gnome/peripherals/mouse/left_handed")) {
@@ -475,10 +525,41 @@
 	}
 }
 
+static void
+touchpad_callback (GConfEntry *entry)
+{
+	if (! strcmp (entry->key, "/desktop/gnome/peripherals/touchpad/off")) {
+		if (entry->value->type == GCONF_VALUE_BOOL) {
+			set_touchpad_off (gconf_value_get_bool (entry->value));
+		}
+	} else if (! strcmp (entry->key, "/desktop/gnome/peripherals/touchpad/max_tap_time")) {
+		if (entry->value->type == GCONF_VALUE_INT) {
+			set_max_tap_time (gconf_value_get_int (entry->value));
+		}
+	} else if (! strcmp (entry->key, "/desktop/gnome/peripherals/touchpad/vert_edge_scroll")) {
+		if (entry->value->type == GCONF_VALUE_BOOL) {
+			set_vert_edge_scroll (gconf_value_get_bool (entry->value));
+		}
+	} else if (! strcmp (entry->key, "/desktop/gnome/peripherals/touchpad/vert_scroll_delta")) {
+		if (entry->value->type == GCONF_VALUE_INT) {
+			set_vert_scroll_delta (gconf_value_get_int (entry->value));
+		}
+	} else if (! strcmp (entry->key, "/desktop/gnome/peripherals/touchpad/horiz_edge_scroll")) {
+		if (entry->value->type == GCONF_VALUE_BOOL) {
+			set_horiz_edge_scroll (gconf_value_get_bool (entry->value));
+		}
+	} else if (! strcmp (entry->key, "/desktop/gnome/peripherals/touchpad/horiz_scroll_delta")) {
+		if (entry->value->type == GCONF_VALUE_INT) {
+			set_horiz_scroll_delta (gconf_value_get_int (entry->value));
+		}
+	}
+}
+
 static gboolean
 gnome_settings_module_mouse_initialize (GnomeSettingsModule *module, GConfClient *config_client)
 {
 	gnome_settings_register_config_callback ("/desktop/gnome/peripherals/mouse", mouse_callback);
+	gnome_settings_register_config_callback ("/desktop/gnome/peripherals/touchpad", touchpad_callback);
 
 	return TRUE;
 }
@@ -487,6 +568,7 @@
 static gboolean
 gnome_settings_module_mouse_start (GnomeSettingsModule *module)
 {
+	gchar *output;
 	GConfClient *client = gnome_settings_module_get_config_client (module);
 
 	set_left_handed (gconf_client_get_bool (client, "/desktop/gnome/peripherals/mouse/left_handed", NULL));
@@ -497,6 +579,24 @@
 	set_locate_pointer (gconf_client_get_bool (client,
 						   "/desktop/gnome/peripherals/mouse/locate_pointer", NULL));
 
+	/* touchpad */
+	if (g_spawn_command_line_sync ("synclient -l", NULL, &output, NULL, NULL)
+		&& !strstr (output, "SHMConfig")) {
+			set_touchpad_off (gconf_client_get_bool (client,
+							"/desktop/gnome/peripherals/touchpad/off", NULL));
+			set_max_tap_time (gconf_client_get_int (client,
+							"/desktop/gnome/peripherals/touchpad/max_tap_time", NULL));
+			set_vert_edge_scroll (gconf_client_get_bool (client,
+							"/desktop/gnome/peripherals/touchpad/vert_edge_scroll", NULL));
+			set_vert_scroll_delta (gconf_client_get_int (client,
+							"/desktop/gnome/peripherals/touchpad/vert_scroll_delta", NULL));
+			set_horiz_edge_scroll (gconf_client_get_bool (client,
+							"/desktop/gnome/peripherals/touchpad/horiz_edge_scroll", NULL));
+			set_horiz_scroll_delta (gconf_client_get_int (client,
+							"/desktop/gnome/peripherals/touchpad/horiz_scroll_delta", NULL));
+	}
+	g_free (output);
+	
 	return TRUE;
 }

Index: capplets/mouse/gnome-mouse-properties.c
===================================================================
--- capplets/mouse/gnome-mouse-properties.c	(Revision 8097)
+++ capplets/mouse/gnome-mouse-properties.c	(Arbeitskopie)
@@ -223,13 +223,74 @@
 }
 
 static GConfValue *
+touchpad_off_gconf_cb (GConfPropertyEditor *peditor, const GConfValue *value)
+{
+	GConfValue *new_value;
+
+	new_value = gconf_value_new (GCONF_VALUE_BOOL);
+	gconf_value_set_bool (new_value, !(gconf_value_get_bool (value)));
+
+	return new_value;
+}
+
+static GConfValue *
+touchpad_clicking_from_gconf (GConfPropertyEditor *peditor, const GConfValue *value)
+{
+	GConfValue *new_value;
+
+	new_value = gconf_value_new (GCONF_VALUE_BOOL);
+	gconf_value_set_bool (new_value, gconf_value_get_int (value) > 0 ? TRUE : FALSE);
+
+	return new_value;
+}
+
+static GConfValue *
+touchpad_clicking_to_gconf (GConfPropertyEditor *peditor, const GConfValue *value)
+{
+	GConfClient *client;
+	GConfValue *new_value;
+	gint max_tap_time;
+
+	client = gconf_client_get_default();
+	max_tap_time = gconf_client_get_int (client,
+		"/desktop/gnome/peripherals/touchpad/max_tap_time", NULL);
+	g_object_unref (client);
+		
+	if (gconf_value_get_bool (value)) {
+		if (max_tap_time == 0)
+			max_tap_time = 180;
+		else
+			max_tap_time = abs (max_tap_time);
+	} else
+		max_tap_time *= -1;
+		
+	new_value = gconf_value_new (GCONF_VALUE_INT);
+	gconf_value_set_int (new_value, max_tap_time);
+
+	return new_value;
+}
+
+static GConfValue *
+touchpad_scrolling_gconf_cb (GConfPropertyEditor *peditor, const GConfValue *value)
+{
+	GConfValue *new_value;
+	gint vert_scroll_delta;
+
+	vert_scroll_delta = CLAMP (255 - gconf_value_get_int (value), 5, 255);
+
+	new_value = gconf_value_new (GCONF_VALUE_INT);
+	gconf_value_set_int (new_value, vert_scroll_delta);
+
+	return new_value;
+}
+
+static GConfValue *
 drag_threshold_from_gconf (GConfPropertyEditor *peditor, 
 			   const GConfValue *value)
 {
 	GConfValue *new_value;
 
 	new_value = gconf_value_new (GCONF_VALUE_FLOAT);
-
 	gconf_value_set_float (new_value, CLAMP (gconf_value_get_int (value), 1, 10));
 
 	return new_value;
@@ -347,6 +408,92 @@
 	}
 }
 
+/*
+static gdouble
+synaptics_get_value (const gchar *key)
+{
+	gchar *output;
+	GRegex *regex;
+	GMatchInfo *match_info;
+	gchar *pattern, *word;
+	gdouble value = -1;
+		
+	g_spawn_command_line_sync ("synclient -l", &output,
+		NULL, NULL, NULL);
+		
+	if (output) {
+		pattern = g_strdup_printf ("%s.*= (.*)\n", key);
+		regex = g_regex_new (pattern, 0, 0, NULL);
+		
+		g_regex_match (regex, output, 0, &match_info);
+		g_match_info_matches (match_info);
+		word = g_match_info_fetch (match_info, 1);
+		
+		if (word) {
+			value = g_ascii_strtod (word, NULL);
+		}
+		
+		g_free (word);	
+		g_free (pattern);
+		g_match_info_free (match_info);
+		g_regex_unref (regex);
+		g_free (output);
+	}
+	
+	return value;
+}
+*/
+		
+static void
+touchpad_enabled_toggle_cb (GtkToggleButton *button, GladeXML *dialog)
+{
+	gboolean check;
+
+	check = gtk_toggle_button_get_active (button);
+	
+	gtk_widget_set_sensitive (WID ("touchpad_clicking_toggle"), check);
+	gtk_widget_set_sensitive (WID ("touchpad_vertical_scrolling_toggle"), check);
+	gtk_widget_set_sensitive (WID ("touchpad_vertical_scrolling_scale"), check);
+	gtk_widget_set_sensitive (WID ("touchpad_horizontal_scrolling_toggle"), check);
+	gtk_widget_set_sensitive (WID ("touchpad_horizontal_scrolling_scale"), check);
+}
+
+static void
+touchpad_clicking_toggle_cb (GtkToggleButton *button, GladeXML *dialog)
+{
+	GConfClient *client;
+	gboolean check;
+	
+	check = gtk_toggle_button_get_active (button);
+	
+	client = gconf_client_get_default ();
+	gconf_client_set_int (client, "/desktop/gnome/peripherals/touchpad/max_tap_time",
+		check ? 180 : 0,
+		NULL
+	);
+	g_object_unref (client);
+}
+
+static void
+touchpad_vertical_scrolling_toggle_cb (GtkToggleButton *button, GladeXML *dialog)
+{
+	gboolean check;
+
+	check = gtk_toggle_button_get_active (button);
+
+	gtk_widget_set_sensitive (WID ("touchpad_vertical_scrolling_scale"), check);
+}
+
+static void
+touchpad_horizontal_scrolling_toggle_cb (GtkToggleButton *button, GladeXML *dialog)
+{
+	gboolean check;
+
+	check = gtk_toggle_button_get_active (button);
+
+	gtk_widget_set_sensitive (WID ("touchpad_horizontal_scrolling_scale"), check);
+}
+
 /* Set up the property editors in the dialog. */
 static void
 setup_dialog (GladeXML *dialog, GConfChangeSet *changeset)
@@ -403,6 +550,48 @@
 		(changeset, "/desktop/gnome/peripherals/mouse/drag_threshold", WID ("drag_threshold_scale"),
 		 "conv-to-widget-cb", drag_threshold_from_gconf,
 		 NULL);
+		 
+		 
+	/* Touchpad page */
+	
+	// enable touchpad
+	g_signal_connect (G_OBJECT (WID ("touchpad_enabled_toggle")), "toggled", (GCallback) touchpad_enabled_toggle_cb, dialog);
+	gconf_peditor_new_boolean
+		(changeset, "/desktop/gnome/peripherals/touchpad/off", WID ("touchpad_enabled_toggle"),
+		 "conv-to-widget-cb", touchpad_off_gconf_cb,
+ 		 "conv-from-widget-cb", touchpad_off_gconf_cb,
+		 NULL);	
+		 	
+	// touchpad clicking
+	gconf_peditor_new_boolean
+		(changeset, "/desktop/gnome/peripherals/touchpad/max_tap_time", WID ("touchpad_clicking_toggle"),
+		 "conv-to-widget-cb", touchpad_clicking_from_gconf,
+ 		 "conv-from-widget-cb", touchpad_clicking_to_gconf,
+		 NULL);	
+	
+	// vertical scrolling
+	gconf_peditor_new_boolean
+		(changeset, "/desktop/gnome/peripherals/touchpad/vert_edge_scroll", WID ("touchpad_vertical_scrolling_toggle"),
+		 NULL);	
+	g_signal_connect (G_OBJECT (WID ("touchpad_vertical_scrolling_toggle")), "toggled", (GCallback) touchpad_vertical_scrolling_toggle_cb, dialog);
+
+	gconf_peditor_new_numeric_range
+		(changeset, "/desktop/gnome/peripherals/touchpad/vert_scroll_delta", WID ("touchpad_vertical_scrolling_scale"),
+		 "conv-to-widget-cb", touchpad_scrolling_gconf_cb,
+ 		 "conv-from-widget-cb", touchpad_scrolling_gconf_cb,
+		 NULL);	
+
+	// horizontal scrolling
+	gconf_peditor_new_boolean
+		(changeset, "/desktop/gnome/peripherals/touchpad/horiz_edge_scroll", WID ("touchpad_horizontal_scrolling_toggle"),
+		 NULL);	
+	g_signal_connect (G_OBJECT (WID ("touchpad_horizontal_scrolling_toggle")), "toggled", (GCallback) touchpad_horizontal_scrolling_toggle_cb, dialog);
+
+	gconf_peditor_new_numeric_range
+		(changeset, "/desktop/gnome/peripherals/touchpad/horiz_scroll_delta", WID ("touchpad_horizontal_scrolling_scale"),
+		 "conv-to-widget-cb", touchpad_scrolling_gconf_cb,
+ 		 "conv-from-widget-cb", touchpad_scrolling_gconf_cb,
+		 NULL);	
 }
 
 /* Construct the dialog */
@@ -458,6 +647,8 @@
 	GConfClient    *client;
 	GladeXML       *dialog;
 	GtkWidget      *dialog_win;
+	gchar          *output;
+	gchar          *error_message = NULL;
 
 	bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
 	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
@@ -474,6 +665,7 @@
 
 	client = gconf_client_get_default ();
 	gconf_client_add_dir (client, "/desktop/gnome/peripherals/mouse", GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
+	gconf_client_add_dir (client, "/desktop/gnome/peripherals/touchpad", GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
 	g_object_unref (client);
 
 	dialog = create_dialog ();
@@ -488,6 +680,27 @@
 		capplet_set_icon (dialog_win, "gnome-dev-mouse-optical");
 		gtk_widget_show (dialog_win);
 
+		/* check for synclient and SHMConfig for touchpad configuration */
+		if (g_spawn_command_line_sync ("synclient -l", NULL, &output, NULL, NULL)) {
+			if (strstr (output, "SHMConfig") != NULL)
+				error_message = gettext("You need to set SHMConfig to \"true\" in xorg.conf and restart the X server.");
+		} else {
+			error_message = gettext("Could not find \"synclient\" in $PATH. Please make sure it is installed and restart this capplet.");
+		}
+		
+		if (error_message) {
+			gtk_label_set_label (GTK_LABEL (WID ("touchpad_error_label")), error_message);
+		
+			gtk_widget_show_all (WID ("touchpad_error_aspectframe"));
+			gtk_widget_set_sensitive (WID ("touchpad_enabled_toggle"), FALSE);
+			gtk_widget_set_sensitive (WID ("touchpad_clicking_toggle"), FALSE);
+			gtk_widget_set_sensitive (WID ("touchpad_vertical_scrolling_toggle"), FALSE);
+			gtk_widget_set_sensitive (WID ("touchpad_vertical_scrolling_scale"), FALSE);
+			gtk_widget_set_sensitive (WID ("touchpad_horizontal_scrolling_toggle"), FALSE);
+			gtk_widget_set_sensitive (WID ("touchpad_horizontal_scrolling_scale"), FALSE);			
+		}		
+		g_free (output);
+		
 		gtk_main ();
 
 		g_object_unref (dialog);
