summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Jon McCann <jmccann@redhat.com>2010-01-17 15:15:56 -0500
committerWilliam Jon McCann <jmccann@redhat.com>2010-01-18 00:59:48 -0500
commit148e86e9548017feaf85fbf8d41304e4256ed616 (patch)
tree51dbc953b086afd3a822d4c975e8713c461a3d07
parentf1c215ef6dedea5653f420f74178ef6f0b338939 (diff)
downloadgnome-control-center-148e86e9548017feaf85fbf8d41304e4256ed616.tar.gz
[mouse] Port mouse to extension system
-rw-r--r--capplets/mouse/Makefile.am42
-rw-r--r--capplets/mouse/cc-mouse-page.c577
-rw-r--r--capplets/mouse/cc-mouse-page.h55
-rw-r--r--capplets/mouse/cc-mouse-panel.c169
-rw-r--r--capplets/mouse/cc-mouse-panel.h54
-rw-r--r--capplets/mouse/mouse-module.c42
-rw-r--r--po/POTFILES.in2
7 files changed, 936 insertions, 5 deletions
diff --git a/capplets/mouse/Makefile.am b/capplets/mouse/Makefile.am
index 9b1bc9854..8b7d78a7e 100644
--- a/capplets/mouse/Makefile.am
+++ b/capplets/mouse/Makefile.am
@@ -1,8 +1,45 @@
+NULL =
+
# This is used in GNOMECC_CAPPLETS_CFLAGS
cappletname = mouse
+INCLUDES = \
+ $(GNOMECC_CAPPLETS_CFLAGS) \
+ -I$(top_srcdir)/capplets/common/ \
+ -DGNOMELOCALEDIR="\"$(datadir)/locale\"" \
+ -DGNOMECC_DATA_DIR="\"$(pkgdatadir)\"" \
+ -DGNOMECC_UI_DIR="\"$(uidir)\"" \
+ $(NULL)
+
bin_PROGRAMS = gnome-mouse-properties
+ccmodulesdir = $(EXTENSIONSDIR)
+ccmodules_LTLIBRARIES = libmouse.la
+
+libmouse_la_SOURCES = \
+ mouse-module.c \
+ cc-mouse-panel.h \
+ cc-mouse-panel.c \
+ cc-mouse-page.h \
+ cc-mouse-page.c \
+ $(NULL)
+
+libmouse_la_LDFLAGS = \
+ $(EXTENSION_LIBTOOL_FLAGS) \
+ $(NULL)
+
+libmouse_la_LIBADD = \
+ $(EXTENSION_LIBS) \
+ $(EXTENSION_COMMON_LIBS) \
+ $(NULL)
+
+libmouse_la_CFLAGS = \
+ $(EXTENSION_CFLAGS) \
+ $(EXTENSION_COMMON_CFLAGS) \
+ $(NULL)
+
+libmouse_la_LIBTOOLFLAGS = --tag=disable-static
+
gnome_mouse_properties_LDADD = $(GNOMECC_CAPPLETS_LIBS)
gnome_mouse_properties_SOURCES = \
gnome-mouse-properties.c \
@@ -24,11 +61,6 @@ desktopdir = $(datadir)/applications
Desktop_in_files = gnome-settings-mouse.desktop.in
desktop_DATA = $(Desktop_in_files:.desktop.in=.desktop)
-INCLUDES = \
- $(GNOMECC_CAPPLETS_CFLAGS) \
- -DGNOMELOCALEDIR="\"$(datadir)/locale\"" \
- -DGNOMECC_DATA_DIR="\"$(pkgdatadir)\"" \
- -DGNOMECC_UI_DIR="\"$(uidir)\""
CLEANFILES = $(GNOMECC_CAPPLETS_CLEANFILES) $(Desktop_in_files) $(desktop_DATA)
EXTRA_DIST = $(ui_DATA) $(pixmap_DATA)
diff --git a/capplets/mouse/cc-mouse-page.c b/capplets/mouse/cc-mouse-page.c
new file mode 100644
index 000000000..5efdb85b0
--- /dev/null
+++ b/capplets/mouse/cc-mouse-page.c
@@ -0,0 +1,577 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gio/gio.h>
+#include <glib/gi18n-lib.h>
+#include <gconf/gconf-client.h>
+
+#include "gconf-property-editor.h"
+#include "capplet-stock-icons.h"
+
+#include "cc-mouse-page.h"
+
+#define CC_MOUSE_PAGE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_MOUSE_PAGE, CcMousePagePrivate))
+
+#define WID(s) GTK_WIDGET (gtk_builder_get_object (builder, s))
+
+struct CcMousePagePrivate
+{
+ GConfChangeSet *changeset;
+ GtkWidget *double_click_image;
+
+ int double_click_state;
+ guint32 double_click_timestamp;
+ guint test_maybe_timeout_id;
+ guint test_on_timeout_id;
+};
+
+enum {
+ PROP_0,
+};
+
+static void cc_mouse_page_class_init (CcMousePageClass *klass);
+static void cc_mouse_page_init (CcMousePage *mouse_page);
+static void cc_mouse_page_finalize (GObject *object);
+
+G_DEFINE_TYPE (CcMousePage, cc_mouse_page, CC_TYPE_PAGE)
+
+enum {
+ DOUBLE_CLICK_TEST_OFF = 0,
+ DOUBLE_CLICK_TEST_MAYBE,
+ DOUBLE_CLICK_TEST_ON
+};
+
+#define MOUSE_KEY_DIR "/desktop/gnome/peripherals/mouse"
+#define MOUSE_DOUBLE_CLICK_KEY MOUSE_KEY_DIR "/double_click"
+#define MOUSE_LEFT_HANDED_KEY MOUSE_KEY_DIR "/left_handed"
+#define MOUSE_LOCATE_POINTER_KEY MOUSE_KEY_DIR "/locate_pointer"
+#define MOUSE_MOTION_ACCELERATION_KEY MOUSE_KEY_DIR "/motion_acceleration"
+#define MOUSE_MOTION_THRESHOLD_KEY MOUSE_KEY_DIR "/motion_threshold"
+#define MOUSE_DRAG_THRESHOLD_KEY MOUSE_KEY_DIR "/drag_threshold"
+
+static GConfValue *
+double_click_from_gconf (GConfPropertyEditor *peditor,
+ const GConfValue *value)
+{
+ GConfValue *new_value;
+
+ new_value = gconf_value_new (GCONF_VALUE_INT);
+ gconf_value_set_int (new_value,
+ CLAMP ((int) floor ((gconf_value_get_int (value) + 50) / 100.0) * 100, 100, 1000));
+ return new_value;
+}
+
+static void
+get_default_mouse_info (int *default_numerator,
+ int *default_denominator,
+ int *default_threshold)
+{
+ int numerator, denominator;
+ int threshold;
+ int tmp_num, tmp_den, tmp_threshold;
+
+ /* Query X for the default value */
+ XGetPointerControl (GDK_DISPLAY (),
+ &numerator,
+ &denominator,
+ &threshold);
+ XChangePointerControl (GDK_DISPLAY (),
+ True,
+ True,
+ -1,
+ -1,
+ -1);
+ XGetPointerControl (GDK_DISPLAY (),
+ &tmp_num,
+ &tmp_den,
+ &tmp_threshold);
+ XChangePointerControl (GDK_DISPLAY (),
+ True,
+ True,
+ numerator,
+ denominator,
+ threshold);
+
+ if (default_numerator)
+ *default_numerator = tmp_num;
+
+ if (default_denominator)
+ *default_denominator = tmp_den;
+
+ if (default_threshold)
+ *default_threshold = tmp_threshold;
+
+}
+
+static GConfValue *
+motion_acceleration_from_gconf (GConfPropertyEditor *peditor,
+ const GConfValue *value)
+{
+ GConfValue *new_value;
+ gfloat motion_acceleration;
+
+ new_value = gconf_value_new (GCONF_VALUE_FLOAT);
+
+ if (gconf_value_get_float (value) == -1.0) {
+ int numerator, denominator;
+
+ get_default_mouse_info (&numerator,
+ &denominator,
+ NULL);
+
+ motion_acceleration = CLAMP ((gfloat)(numerator / denominator), 0.2, 6.0);
+ }
+ else {
+ motion_acceleration = CLAMP (gconf_value_get_float (value), 0.2, 6.0);
+ }
+
+ if (motion_acceleration >= 1)
+ gconf_value_set_float (new_value, motion_acceleration + 4);
+ else
+ gconf_value_set_float (new_value, motion_acceleration * 5);
+
+ return new_value;
+}
+
+static GConfValue *
+motion_acceleration_to_gconf (GConfPropertyEditor *peditor,
+ const GConfValue *value)
+{
+ GConfValue *new_value;
+ gfloat motion_acceleration;
+
+ new_value = gconf_value_new (GCONF_VALUE_FLOAT);
+ motion_acceleration = CLAMP (gconf_value_get_float (value), 1.0, 10.0);
+
+ if (motion_acceleration < 5)
+ gconf_value_set_float (new_value, motion_acceleration / 5.0);
+ else
+ gconf_value_set_float (new_value, motion_acceleration - 4);
+
+ return new_value;
+}
+
+static GConfValue *
+threshold_from_gconf (GConfPropertyEditor *peditor,
+ const GConfValue *value)
+{
+ GConfValue *new_value;
+
+ new_value = gconf_value_new (GCONF_VALUE_FLOAT);
+
+ if (gconf_value_get_int (value) == -1) {
+ int threshold;
+
+ get_default_mouse_info (NULL, NULL, &threshold);
+ gconf_value_set_float (new_value, CLAMP (threshold, 1, 10));
+ }
+ else {
+ gconf_value_set_float (new_value, CLAMP (gconf_value_get_int (value), 1, 10));
+ }
+
+ 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;
+}
+
+/* Timeout for the double click test */
+static gboolean
+test_maybe_timeout (CcMousePage *page)
+{
+ page->priv->double_click_state = DOUBLE_CLICK_TEST_OFF;
+
+ gtk_image_set_from_stock (GTK_IMAGE (page->priv->double_click_image),
+ MOUSE_DBLCLCK_OFF,
+ mouse_capplet_dblclck_icon_get_size ());
+
+ page->priv->test_maybe_timeout_id = 0;
+
+ return FALSE;
+}
+
+static gboolean
+test_on_timeout (CcMousePage *page)
+{
+ page->priv->double_click_state = DOUBLE_CLICK_TEST_OFF;
+
+ gtk_image_set_from_stock (GTK_IMAGE (page->priv->double_click_image),
+ MOUSE_DBLCLCK_OFF,
+ mouse_capplet_dblclck_icon_get_size ());
+
+ page->priv->test_on_timeout_id = 0;
+
+ return FALSE;
+}
+
+/* Callback issued when the user clicks the double click testing area. */
+
+static gboolean
+on_event_box_button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ CcMousePage *page)
+{
+ gint double_click_time;
+ GConfValue *value;
+ GConfClient *client;
+
+ if (event->type != GDK_BUTTON_PRESS)
+ return FALSE;
+
+ if (!(page->priv->changeset
+ && gconf_change_set_check_value (page->priv->changeset,
+ MOUSE_DOUBLE_CLICK_KEY,
+ &value))) {
+ client = gconf_client_get_default ();
+ double_click_time = gconf_client_get_int (client,
+ MOUSE_DOUBLE_CLICK_KEY,
+ NULL);
+ g_object_unref (client);
+
+ } else {
+ double_click_time = gconf_value_get_int (value);
+ }
+
+ if (page->priv->test_maybe_timeout_id != 0) {
+ g_source_remove (page->priv->test_maybe_timeout_id);
+ page->priv->test_maybe_timeout_id = 0;
+ }
+ if (page->priv->test_on_timeout_id != 0) {
+ g_source_remove (page->priv->test_on_timeout_id);
+ page->priv->test_on_timeout_id = 0;
+ }
+
+ switch (page->priv->double_click_state) {
+ case DOUBLE_CLICK_TEST_OFF:
+ page->priv->double_click_state = DOUBLE_CLICK_TEST_MAYBE;
+ page->priv->test_maybe_timeout_id = g_timeout_add (double_click_time,
+ (GtkFunction) test_maybe_timeout,
+ page);
+ break;
+ case DOUBLE_CLICK_TEST_MAYBE:
+ if (event->time - page->priv->double_click_timestamp < double_click_time) {
+ page->priv->double_click_state = DOUBLE_CLICK_TEST_ON;
+ page->priv->test_on_timeout_id = g_timeout_add (2500,
+ (GtkFunction) test_on_timeout,
+ page);
+ }
+ break;
+ case DOUBLE_CLICK_TEST_ON:
+ page->priv->double_click_state = DOUBLE_CLICK_TEST_OFF;
+ break;
+ }
+
+ page->priv->double_click_timestamp = event->time;
+
+ switch (page->priv->double_click_state) {
+ case DOUBLE_CLICK_TEST_ON:
+ gtk_image_set_from_stock (GTK_IMAGE (page->priv->double_click_image),
+ MOUSE_DBLCLCK_ON,
+ mouse_capplet_dblclck_icon_get_size ());
+ break;
+ case DOUBLE_CLICK_TEST_MAYBE:
+ gtk_image_set_from_stock (GTK_IMAGE (page->priv->double_click_image),
+ MOUSE_DBLCLCK_MAYBE,
+ mouse_capplet_dblclck_icon_get_size ());
+ break;
+ case DOUBLE_CLICK_TEST_OFF:
+ gtk_image_set_from_stock (GTK_IMAGE (page->priv->double_click_image),
+ MOUSE_DBLCLCK_OFF,
+ mouse_capplet_dblclck_icon_get_size ());
+ break;
+ }
+
+ return TRUE;
+}
+
+static void
+orientation_radio_button_release_event (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
+}
+
+static GConfValue *
+left_handed_from_gconf (GConfPropertyEditor *peditor,
+ const GConfValue *value)
+{
+ GConfValue *new_value;
+
+ new_value = gconf_value_new (GCONF_VALUE_INT);
+
+ gconf_value_set_int (new_value, gconf_value_get_bool (value));
+
+ return new_value;
+}
+
+static GConfValue *
+left_handed_to_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) == 1);
+
+ return new_value;
+}
+
+static void
+cc_mouse_page_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+cc_mouse_page_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+setup_page (CcMousePage *page)
+{
+ GtkBuilder *builder;
+ GtkWidget *widget;
+ GError *error;
+ GtkSizeGroup *size_group;
+ GtkRadioButton *radio;
+ GObject *peditor;
+
+ builder = gtk_builder_new ();
+
+ error = NULL;
+ gtk_builder_add_from_file (builder,
+ GNOMECC_UI_DIR
+ "/gnome-mouse-properties.ui",
+ &error);
+ if (error != NULL) {
+ g_error (_("Could not load user interface file: %s"),
+ error->message);
+ g_error_free (error);
+ return;
+ }
+
+ page->priv->double_click_image = WID ("double_click_image");
+
+ size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+ gtk_size_group_add_widget (size_group, WID ("acceleration_label"));
+ gtk_size_group_add_widget (size_group, WID ("sensitivity_label"));
+ gtk_size_group_add_widget (size_group, WID ("threshold_label"));
+ gtk_size_group_add_widget (size_group, WID ("timeout_label"));
+
+ size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+ gtk_size_group_add_widget (size_group, WID ("acceleration_fast_label"));
+ gtk_size_group_add_widget (size_group, WID ("sensitivity_high_label"));
+ gtk_size_group_add_widget (size_group, WID ("threshold_large_label"));
+ gtk_size_group_add_widget (size_group, WID ("timeout_long_label"));
+
+ size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+ gtk_size_group_add_widget (size_group, WID ("acceleration_slow_label"));
+ gtk_size_group_add_widget (size_group, WID ("sensitivity_low_label"));
+ gtk_size_group_add_widget (size_group, WID ("threshold_small_label"));
+ gtk_size_group_add_widget (size_group, WID ("timeout_short_label"));
+
+#if 1
+ /* Orientation radio buttons */
+ radio = GTK_RADIO_BUTTON (WID ("left_handed_radio"));
+ peditor = gconf_peditor_new_select_radio (page->priv->changeset,
+ MOUSE_LEFT_HANDED_KEY,
+ gtk_radio_button_get_group (radio),
+ "conv-to-widget-cb",
+ left_handed_from_gconf,
+ "conv-from-widget-cb",
+ left_handed_to_gconf,
+ NULL);
+
+ /* 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);
+
+ /* Locate pointer toggle */
+ peditor = gconf_peditor_new_boolean (page->priv->changeset,
+ MOUSE_LOCATE_POINTER_KEY,
+ WID ("locate_pointer_toggle"),
+ NULL);
+
+ /* Double-click time */
+ peditor = gconf_peditor_new_numeric_range (page->priv->changeset,
+ MOUSE_DOUBLE_CLICK_KEY,
+ WID ("delay_scale"),
+ "conv-to-widget-cb",
+ double_click_from_gconf,
+ NULL);
+
+#endif
+ gtk_image_set_from_stock (GTK_IMAGE (page->priv->double_click_image),
+ MOUSE_DBLCLCK_OFF,
+ mouse_capplet_dblclck_icon_get_size ());
+
+ g_signal_connect (WID ("double_click_eventbox"),
+ "button_press_event",
+ G_CALLBACK (on_event_box_button_press_event),
+ page);
+
+ /* speed */
+ gconf_peditor_new_numeric_range (page->priv->changeset,
+ MOUSE_MOTION_ACCELERATION_KEY,
+ 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 (page->priv->changeset,
+ MOUSE_MOTION_THRESHOLD_KEY,
+ WID ("sensitivity_scale"),
+ "conv-to-widget-cb",
+ threshold_from_gconf,
+ NULL);
+
+ /* DnD threshold */
+ gconf_peditor_new_numeric_range (page->priv->changeset,
+ MOUSE_DRAG_THRESHOLD_KEY,
+ WID ("drag_threshold_scale"),
+ "conv-to-widget-cb",
+ drag_threshold_from_gconf,
+ NULL);
+
+
+ widget = WID ("general_vbox");
+ gtk_widget_reparent (widget, GTK_WIDGET (page));
+ gtk_widget_show (widget);
+}
+
+static GObject *
+cc_mouse_page_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
+{
+ CcMousePage *mouse_page;
+
+ mouse_page = CC_MOUSE_PAGE (G_OBJECT_CLASS (cc_mouse_page_parent_class)->constructor (type,
+ n_construct_properties,
+ construct_properties));
+
+ g_object_set (mouse_page,
+ "display-name", _("Mouse"),
+ "id", "general",
+ NULL);
+
+ setup_page (mouse_page);
+
+ return G_OBJECT (mouse_page);
+}
+
+static void
+cc_mouse_page_class_init (CcMousePageClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = cc_mouse_page_get_property;
+ object_class->set_property = cc_mouse_page_set_property;
+ object_class->constructor = cc_mouse_page_constructor;
+ object_class->finalize = cc_mouse_page_finalize;
+
+ g_type_class_add_private (klass, sizeof (CcMousePagePrivate));
+}
+
+static void
+cc_mouse_page_init (CcMousePage *page)
+{
+ GConfClient *client;
+
+ page->priv = CC_MOUSE_PAGE_GET_PRIVATE (page);
+
+ client = gconf_client_get_default ();
+ gconf_client_add_dir (client,
+ MOUSE_KEY_DIR,
+ GCONF_CLIENT_PRELOAD_ONELEVEL,
+ NULL);
+ g_object_unref (client);
+
+ capplet_init_stock_icons ();
+}
+
+static void
+cc_mouse_page_finalize (GObject *object)
+{
+ CcMousePage *page;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (CC_IS_MOUSE_PAGE (object));
+
+ page = CC_MOUSE_PAGE (object);
+
+ g_return_if_fail (page->priv != NULL);
+
+
+ G_OBJECT_CLASS (cc_mouse_page_parent_class)->finalize (object);
+}
+
+CcPage *
+cc_mouse_page_new (void)
+{
+ GObject *object;
+
+ object = g_object_new (CC_TYPE_MOUSE_PAGE, NULL);
+
+ return CC_PAGE (object);
+}
diff --git a/capplets/mouse/cc-mouse-page.h b/capplets/mouse/cc-mouse-page.h
new file mode 100644
index 000000000..4caa24e92
--- /dev/null
+++ b/capplets/mouse/cc-mouse-page.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef __CC_MOUSE_PAGE_H
+#define __CC_MOUSE_PAGE_H
+
+#include <gtk/gtk.h>
+#include "cc-page.h"
+
+G_BEGIN_DECLS
+
+#define CC_TYPE_MOUSE_PAGE (cc_mouse_page_get_type ())
+#define CC_MOUSE_PAGE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CC_TYPE_MOUSE_PAGE, CcMousePage))
+#define CC_MOUSE_PAGE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CC_TYPE_MOUSE_PAGE, CcMousePageClass))
+#define CC_IS_MOUSE_PAGE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CC_TYPE_MOUSE_PAGE))
+#define CC_IS_MOUSE_PAGE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CC_TYPE_MOUSE_PAGE))
+#define CC_MOUSE_PAGE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CC_TYPE_MOUSE_PAGE, CcMousePageClass))
+
+typedef struct CcMousePagePrivate CcMousePagePrivate;
+
+typedef struct
+{
+ CcPage parent;
+ CcMousePagePrivate *priv;
+} CcMousePage;
+
+typedef struct
+{
+ CcPageClass parent_class;
+} CcMousePageClass;
+
+GType cc_mouse_page_get_type (void);
+
+CcPage * cc_mouse_page_new (void);
+
+G_END_DECLS
+
+#endif /* __CC_MOUSE_PAGE_H */
diff --git a/capplets/mouse/cc-mouse-panel.c b/capplets/mouse/cc-mouse-panel.c
new file mode 100644
index 000000000..aa78dc200
--- /dev/null
+++ b/capplets/mouse/cc-mouse-panel.c
@@ -0,0 +1,169 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <gtk/gtk.h>
+#include <gio/gio.h>
+#include <glib/gi18n-lib.h>
+
+#include "cc-mouse-panel.h"
+#include "cc-mouse-page.h"
+
+#define CC_MOUSE_PANEL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_MOUSE_PANEL, CcMousePanelPrivate))
+
+struct CcMousePanelPrivate
+{
+ GtkWidget *notebook;
+ CcPage *mouse_page;
+};
+
+enum {
+ PROP_0,
+};
+
+static void cc_mouse_panel_class_init (CcMousePanelClass *klass);
+static void cc_mouse_panel_init (CcMousePanel *mouse_panel);
+static void cc_mouse_panel_finalize (GObject *object);
+
+G_DEFINE_DYNAMIC_TYPE (CcMousePanel, cc_mouse_panel, CC_TYPE_PANEL)
+
+static void
+cc_mouse_panel_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+cc_mouse_panel_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+setup_panel (CcMousePanel *panel)
+{
+ GtkWidget *label;
+ char *display_name;
+
+ panel->priv->notebook = gtk_notebook_new ();
+ gtk_container_add (GTK_CONTAINER (panel), panel->priv->notebook);
+ gtk_widget_show (panel->priv->notebook);
+
+ panel->priv->mouse_page = cc_mouse_page_new ();
+ g_object_get (panel->priv->mouse_page,
+ "display-name", &display_name,
+ NULL);
+ label = gtk_label_new (display_name);
+ g_free (display_name);
+ gtk_notebook_append_page (GTK_NOTEBOOK (panel->priv->notebook),
+ GTK_WIDGET (panel->priv->mouse_page),
+ label);
+ gtk_widget_show (GTK_WIDGET (panel->priv->mouse_page));
+
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (panel->priv->notebook),
+ FALSE);
+}
+
+static GObject *
+cc_mouse_panel_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
+{
+ CcMousePanel *mouse_panel;
+
+ mouse_panel = CC_MOUSE_PANEL (G_OBJECT_CLASS (cc_mouse_panel_parent_class)->constructor (type,
+ n_construct_properties,
+ construct_properties));
+ g_object_set (mouse_panel,
+ "display-name", _("Mouse"),
+ "id", "gnome-settings-mouse.desktop",
+ NULL);
+
+ setup_panel (mouse_panel);
+
+ return G_OBJECT (mouse_panel);
+}
+
+static void
+cc_mouse_panel_class_init (CcMousePanelClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = cc_mouse_panel_get_property;
+ object_class->set_property = cc_mouse_panel_set_property;
+ object_class->constructor = cc_mouse_panel_constructor;
+ object_class->finalize = cc_mouse_panel_finalize;
+
+ g_type_class_add_private (klass, sizeof (CcMousePanelPrivate));
+}
+
+static void
+cc_mouse_panel_class_finalize (CcMousePanelClass *klass)
+{
+}
+
+static void
+cc_mouse_panel_init (CcMousePanel *panel)
+{
+ panel->priv = CC_MOUSE_PANEL_GET_PRIVATE (panel);
+}
+
+static void
+cc_mouse_panel_finalize (GObject *object)
+{
+ CcMousePanel *mouse_panel;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (CC_IS_MOUSE_PANEL (object));
+
+ mouse_panel = CC_MOUSE_PANEL (object);
+
+ g_return_if_fail (mouse_panel->priv != NULL);
+
+ G_OBJECT_CLASS (cc_mouse_panel_parent_class)->finalize (object);
+}
+
+void
+cc_mouse_panel_register (GIOModule *module)
+{
+ cc_mouse_panel_register_type (G_TYPE_MODULE (module));
+ g_io_extension_point_implement (CC_PANEL_EXTENSION_POINT_NAME,
+ CC_TYPE_MOUSE_PANEL,
+ "mouse",
+ 10);
+}
diff --git a/capplets/mouse/cc-mouse-panel.h b/capplets/mouse/cc-mouse-panel.h
new file mode 100644
index 000000000..69057af27
--- /dev/null
+++ b/capplets/mouse/cc-mouse-panel.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef __CC_SIMPLE_PANEL_H
+#define __CC_SIMPLE_PANEL_H
+
+#include <gtk/gtk.h>
+#include "cc-panel.h"
+
+G_BEGIN_DECLS
+
+#define CC_TYPE_MOUSE_PANEL (cc_mouse_panel_get_type ())
+#define CC_MOUSE_PANEL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CC_TYPE_MOUSE_PANEL, CcMousePanel))
+#define CC_MOUSE_PANEL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CC_TYPE_MOUSE_PANEL, CcMousePanelClass))
+#define CC_IS_MOUSE_PANEL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CC_TYPE_MOUSE_PANEL))
+#define CC_IS_MOUSE_PANEL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CC_TYPE_MOUSE_PANEL))
+#define CC_MOUSE_PANEL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CC_TYPE_MOUSE_PANEL, CcMousePanelClass))
+
+typedef struct CcMousePanelPrivate CcMousePanelPrivate;
+
+typedef struct
+{
+ CcPanel parent;
+ CcMousePanelPrivate *priv;
+} CcMousePanel;
+
+typedef struct
+{
+ CcPanelClass parent_class;
+} CcMousePanelClass;
+
+GType cc_mouse_panel_get_type (void);
+void cc_mouse_panel_register (GIOModule *module);
+
+G_END_DECLS
+
+#endif /* __CC_MOUSE_PANEL_H */
diff --git a/capplets/mouse/mouse-module.c b/capplets/mouse/mouse-module.c
new file mode 100644
index 000000000..9628778f5
--- /dev/null
+++ b/capplets/mouse/mouse-module.c
@@ -0,0 +1,42 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+#include <gmodule.h>
+#include <gio/gio.h>
+
+#include "cc-mouse-panel.h"
+
+void
+g_io_module_load (GIOModule *module)
+{
+ bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+
+ cc_mouse_panel_register (module);
+}
+
+void
+g_io_module_unload (GIOModule *module)
+{
+}
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 21048effc..4ee077b5e 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -68,6 +68,8 @@ capplets/keyboard/gnome-keyboard-properties-xkbmc.c
capplets/keyboard/gnome-keyboard-properties-xkbot.c
capplets/keyboard/gnome-keyboard-properties-xkbpv.c
capplets/keyboard/keyboard.desktop.in.in
+capplets/mouse/cc-mouse-page.c
+capplets/mouse/cc-mouse-panel.c
capplets/mouse/gnome-mouse-accessibility.c
capplets/mouse/gnome-mouse-properties.c
[type: gettext/glade]capplets/mouse/gnome-mouse-properties.ui