static gboolean
test_maybe_timeout (struct test_data_t *data)
{
	double_click_state = DOUBLE_CLICK_TEST_OFF;

	gtk_image_set_from_stock (GTK_IMAGE (data->image),
				  MOUSE_DBLCLCK_OFF, mouse_capplet_dblclck_icon_get_size());

	*data->timeout_id = 0;

	return FALSE;
}
/* Set up the property editors in the dialog. */
static void
setup_dialog (GtkBuilder *dialog)
{
	GtkRadioButton    *radio;

	/* Orientation radio buttons */
	radio = GTK_RADIO_BUTTON (WID ("left_handed_radio"));
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(radio),
		g_settings_get_boolean(mouse_settings, "left-handed"));
	/* explicitly connect to button-release so that you can change orientation with either button */
	g_signal_connect (WID ("right_handed_radio"), "button_release_event",
		G_CALLBACK (orientation_radio_button_release_event), NULL);
	g_signal_connect (WID ("left_handed_radio"), "button_release_event",
		G_CALLBACK (orientation_radio_button_release_event), NULL);
	g_signal_connect (WID ("left_handed_radio"), "toggled",
		G_CALLBACK (orientation_radio_button_toggled), dialog);

	/* Locate pointer toggle */
	g_settings_bind (mouse_settings, "locate-pointer", WID ("locate_pointer_toggle"),
		"active", G_SETTINGS_BIND_DEFAULT);

	/* Double-click time */
	g_settings_bind (mouse_settings, DOUBLE_CLICK_KEY,
		gtk_range_get_adjustment (GTK_RANGE (WID ("delay_scale"))), "value",
		G_SETTINGS_BIND_DEFAULT);
	
	gtk_image_set_from_stock (GTK_IMAGE (WID ("double_click_image")), MOUSE_DBLCLCK_OFF, mouse_capplet_dblclck_icon_get_size ());
	g_object_set_data (G_OBJECT (WID ("double_click_eventbox")), "image", WID ("double_click_image"));
	g_signal_connect (WID ("double_click_eventbox"), "button_press_event",
			  G_CALLBACK (event_box_button_press_event), NULL);

	/* speed */
	g_settings_bind (mouse_settings, "motion-acceleration",
		gtk_range_get_adjustment (GTK_RANGE (WID ("accel_scale"))), "value",
		G_SETTINGS_BIND_DEFAULT);
	g_settings_bind (mouse_settings, "motion-threshold",
		gtk_range_get_adjustment (GTK_RANGE (WID ("sensitivity_scale"))), "value",
		G_SETTINGS_BIND_DEFAULT);

	/* DnD threshold */
	g_settings_bind (mouse_settings, "drag-threshold",
		gtk_range_get_adjustment (GTK_RANGE (WID ("drag_threshold_scale"))), "value",
		G_SETTINGS_BIND_DEFAULT);

	/* Trackpad page */
	if (find_synaptics () == FALSE)
		gtk_notebook_remove_page (GTK_NOTEBOOK (WID ("prefs_widget")), -1);
	else {
		g_settings_bind (touchpad_settings, "touchpad-enabled",
			WID ("touchpad_enable"), "active",
			G_SETTINGS_BIND_DEFAULT);
		g_settings_bind (touchpad_settings, "touchpad-enabled",
			WID ("vbox_touchpad_general"), "sensitive",
			G_SETTINGS_BIND_DEFAULT);
		g_settings_bind (touchpad_settings, "touchpad-enabled",
			WID ("vbox_touchpad_scrolling"), "sensitive",
			G_SETTINGS_BIND_DEFAULT);
		g_settings_bind (touchpad_settings, "disable-while-typing",
			WID ("disable_w_typing_toggle"), "active",
			G_SETTINGS_BIND_DEFAULT);
		g_settings_bind (touchpad_settings, "tap-to-click",
			WID ("tap_to_click_toggle"), "active",
			G_SETTINGS_BIND_DEFAULT);
		g_settings_bind (touchpad_settings, "horiz-scroll-enabled",
			WID ("horiz_scroll_toggle"), "active",
			G_SETTINGS_BIND_DEFAULT);
		g_settings_bind (touchpad_settings, "natural-scroll",
			WID ("natural_scroll_toggle"), "active",
			G_SETTINGS_BIND_DEFAULT);

		scrollmethod_gsettings_changed_event (touchpad_settings, "scroll-method", dialog);

		char * emulation_values[] = { _("Disabled"), _("Left button"), _("Middle button"), _("Right button") };

		GtkWidget *two_click_comboxbox = gtk_combo_box_text_new ();
		GtkWidget *three_click_comboxbox = gtk_combo_box_text_new ();
		gtk_box_pack_start (GTK_BOX (WID ("hbox_two_finger_click")), two_click_comboxbox, FALSE, FALSE, 6);
		gtk_box_pack_start (GTK_BOX (WID ("hbox_three_finger_click")), three_click_comboxbox, FALSE, FALSE, 6);
		int i;
		for (i=0; i<4; i++) {
			gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (two_click_comboxbox), emulation_values[i]);	
			gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (three_click_comboxbox), emulation_values[i]);	
		}
		
		gtk_combo_box_set_active (GTK_COMBO_BOX (two_click_comboxbox), g_settings_get_int (touchpad_settings, "two-finger-click"));
		gtk_combo_box_set_active (GTK_COMBO_BOX (three_click_comboxbox), g_settings_get_int (touchpad_settings, "three-finger-click"));
		gtk_widget_show (two_click_comboxbox);
		gtk_widget_show (three_click_comboxbox);
		g_signal_connect (two_click_comboxbox, "changed", G_CALLBACK (comboxbox_changed_callback), "two-finger-click");
		g_signal_connect (three_click_comboxbox, "changed", G_CALLBACK (comboxbox_changed_callback), "three-finger-click");

		radio = GTK_RADIO_BUTTON (WID ("scroll_disabled_radio"));
		GSList *radio_group = gtk_radio_button_get_group (radio);
		GSList *item = NULL;

		synaptics_check_capabilities (dialog);
		for (item = radio_group; item != NULL; item = item->next) {
			g_signal_connect (G_OBJECT (item->data), "clicked",
				  G_CALLBACK(scrollmethod_clicked_event),
				  dialog);
		}
		g_signal_connect (touchpad_settings,
			"changed::scroll-method",
			G_CALLBACK(scrollmethod_gsettings_changed_event),
			dialog);
	}

}
static gboolean
event_box_button_press_event (GtkWidget   *widget,
			      GdkEventButton *event,
			      gpointer user_data)
{
	gint                       double_click_time;
	static struct test_data_t  data;
	static gint                test_on_timeout_id     = 0;
	static gint                test_maybe_timeout_id  = 0;
	static guint32             double_click_timestamp = 0;
	GtkWidget                 *image;

	if (event->type != GDK_BUTTON_PRESS)
		return FALSE;

	image = g_object_get_data (G_OBJECT (widget), "image");

	double_click_time = g_settings_get_int (mouse_settings, DOUBLE_CLICK_KEY);

	if (test_maybe_timeout_id != 0) {
		g_source_remove  (test_maybe_timeout_id);
		test_maybe_timeout_id = 0;
	}
	if (test_on_timeout_id != 0) {
		g_source_remove (test_on_timeout_id);
		test_on_timeout_id = 0;
	}

	switch (double_click_state) {
	case DOUBLE_CLICK_TEST_OFF:
		double_click_state = DOUBLE_CLICK_TEST_MAYBE;
		data.image = image;
		data.timeout_id = &test_maybe_timeout_id;
		test_maybe_timeout_id = g_timeout_add (double_click_time, (GSourceFunc) test_maybe_timeout, &data);
		break;
	case DOUBLE_CLICK_TEST_MAYBE:
		if (event->time - double_click_timestamp < double_click_time) {
			double_click_state = DOUBLE_CLICK_TEST_ON;
			data.image = image;
			data.timeout_id = &test_on_timeout_id;
			test_on_timeout_id = g_timeout_add (2500, (GSourceFunc) test_maybe_timeout, &data);
		}
		break;
	case DOUBLE_CLICK_TEST_ON:
		double_click_state = DOUBLE_CLICK_TEST_OFF;
		break;
	}

	double_click_timestamp = event->time;

	switch (double_click_state) {
	case DOUBLE_CLICK_TEST_ON:
		gtk_image_set_from_stock (GTK_IMAGE (image),
					  MOUSE_DBLCLCK_ON, mouse_capplet_dblclck_icon_get_size());
		break;
	case DOUBLE_CLICK_TEST_MAYBE:
		gtk_image_set_from_stock (GTK_IMAGE (image),
					  MOUSE_DBLCLCK_MAYBE, mouse_capplet_dblclck_icon_get_size());
		break;
	case DOUBLE_CLICK_TEST_OFF:
		gtk_image_set_from_stock (GTK_IMAGE (image),
					  MOUSE_DBLCLCK_OFF, mouse_capplet_dblclck_icon_get_size());
		break;
	}

	return TRUE;
}
/* Set up the property editors in the dialog. */
static void
setup_dialog (GladeXML *dialog, GConfChangeSet *changeset)
{
	GtkRadioButton    *radio;
	GObject           *peditor;

	/* Orientation radio buttons */
	radio = GTK_RADIO_BUTTON (WID ("left_handed_radio"));
	peditor = gconf_peditor_new_select_radio
		(changeset, "/desktop/gnome/peripherals/mouse/left_handed", gtk_radio_button_get_group (radio),
		 "conv-to-widget-cb", left_handed_from_gconf,
		 "conv-from-widget-cb", left_handed_to_gconf,
		 NULL);
	g_signal_connect (WID ("right_handed_radio"), "button_release_event",
		G_CALLBACK (orientation_radio_button_release_event), NULL);
	g_signal_connect (WID ("left_handed_radio"), "button_release_event",
		G_CALLBACK (orientation_radio_button_release_event), NULL);

	/* Locate pointer toggle */
	peditor = gconf_peditor_new_boolean
		(changeset, "/desktop/gnome/peripherals/mouse/locate_pointer", WID ("locate_pointer_toggle"), NULL);

	/* Double-click time */
	peditor = gconf_peditor_new_numeric_range
		(changeset, DOUBLE_CLICK_KEY, WID ("delay_scale"),
		 "conv-to-widget-cb", double_click_from_gconf,
		 NULL);
	gtk_image_set_from_stock (GTK_IMAGE (WID ("double_click_image")), MOUSE_DBLCLCK_OFF, mouse_capplet_dblclck_icon_get_size ());
	g_object_set_data (G_OBJECT (WID ("double_click_eventbox")), "image", WID ("double_click_image"));
	g_signal_connect (WID ("double_click_eventbox"), "button_press_event",
			  G_CALLBACK (event_box_button_press_event), changeset);

	/* speed */
      	gconf_peditor_new_numeric_range
		(changeset, "/desktop/gnome/peripherals/mouse/motion_acceleration", WID ("accel_scale"),
		 "conv-to-widget-cb", motion_acceleration_from_gconf,
		 "conv-from-widget-cb", motion_acceleration_to_gconf,
		 NULL);

	gconf_peditor_new_numeric_range
		(changeset, "/desktop/gnome/peripherals/mouse/motion_threshold", WID ("sensitivity_scale"),
		 "conv-to-widget-cb", threshold_from_gconf,
		 NULL);

	/* DnD threshold */
	gconf_peditor_new_numeric_range
		(changeset, "/desktop/gnome/peripherals/mouse/drag_threshold", WID ("drag_threshold_scale"),
		 "conv-to-widget-cb", drag_threshold_from_gconf,
		 NULL);
}
static gboolean
event_box_button_press_event (GtkWidget   *widget,
			      GdkEventButton *event,
			      GConfChangeSet *changeset)
{
	gint                       double_click_time;
	GConfValue                *value;
	static struct test_data_t  data;
	static gint                test_on_timeout_id     = 0;
	static gint                test_maybe_timeout_id  = 0;
	static guint32             double_click_timestamp = 0;
	GtkWidget                  *image;
	GConfClient               *client;

	if (event->type != GDK_BUTTON_PRESS)
		return FALSE;

	image = g_object_get_data (G_OBJECT (widget), "image");

	if (!(changeset && gconf_change_set_check_value (changeset, DOUBLE_CLICK_KEY, &value))) {
		client = gconf_client_get_default();
		double_click_time = gconf_client_get_int (client, DOUBLE_CLICK_KEY, NULL);
		g_object_unref (client);

	} else
		double_click_time = gconf_value_get_int (value);

	if (test_maybe_timeout_id != 0)
		gtk_timeout_remove  (test_maybe_timeout_id);
	if (test_on_timeout_id != 0)
		gtk_timeout_remove (test_on_timeout_id);

	switch (double_click_state) {
	case DOUBLE_CLICK_TEST_OFF:
		double_click_state = DOUBLE_CLICK_TEST_MAYBE;
		data.image = image;
		data.timeout_id = &test_maybe_timeout_id;
		test_maybe_timeout_id = gtk_timeout_add (double_click_time, (GtkFunction) test_maybe_timeout, &data);
		break;
	case DOUBLE_CLICK_TEST_MAYBE:
		if (event->time - double_click_timestamp < double_click_time) {
			double_click_state = DOUBLE_CLICK_TEST_ON;
			data.image = image;
			data.timeout_id = &test_on_timeout_id;
			test_on_timeout_id = gtk_timeout_add (2500, (GtkFunction) test_maybe_timeout, &data);
		}
		break;
	case DOUBLE_CLICK_TEST_ON:
		double_click_state = DOUBLE_CLICK_TEST_OFF;
		break;
	}

	double_click_timestamp = event->time;

	switch (double_click_state) {
	case DOUBLE_CLICK_TEST_ON:
		gtk_image_set_from_stock (GTK_IMAGE (image),
					  MOUSE_DBLCLCK_ON, mouse_capplet_dblclck_icon_get_size());
		break;
	case DOUBLE_CLICK_TEST_MAYBE:
		gtk_image_set_from_stock (GTK_IMAGE (image),
					  MOUSE_DBLCLCK_MAYBE, mouse_capplet_dblclck_icon_get_size());
		break;
	case DOUBLE_CLICK_TEST_OFF:
		gtk_image_set_from_stock (GTK_IMAGE (image),
					  MOUSE_DBLCLCK_OFF, mouse_capplet_dblclck_icon_get_size());
		break;
	}

	return TRUE;
}