[Xfce4-commits] r26559 - xfce-mcs-plugins/branches/multi_device

Nick Schermer nick at xfce.org
Fri Jan 11 18:50:36 CET 2008


Author: nick
Date: 2008-01-11 17:50:36 +0000 (Fri, 11 Jan 2008)
New Revision: 26559

Added:
   xfce-mcs-plugins/branches/multi_device/Makefile
   xfce-mcs-plugins/branches/multi_device/xfce-display-dialog.c
   xfce-mcs-plugins/branches/multi_device/xfce-display-dialog.h
   xfce-mcs-plugins/branches/multi_device/xfce-display-main.c
   xfce-mcs-plugins/branches/multi_device/xfce-mouse-dialog.c
   xfce-mcs-plugins/branches/multi_device/xfce-mouse-dialog.h
   xfce-mcs-plugins/branches/multi_device/xfce-mouse-main.c
Log:
* xfce-mouse*: Configure the orientation (left/right handed), acceleration and threshold for each pointer separately.
* xfce-display*: Change resolution for each connected screen, not fully working tho.


Added: xfce-mcs-plugins/branches/multi_device/Makefile
===================================================================
--- xfce-mcs-plugins/branches/multi_device/Makefile	                        (rev 0)
+++ xfce-mcs-plugins/branches/multi_device/Makefile	2008-01-11 17:50:36 UTC (rev 26559)
@@ -0,0 +1,24 @@
+
+CC = gcc
+CFLAGS = -pipe -O -Wall -Werror
+
+all:
+	$(CC) $(CFLAGS) \
+	`pkg-config --cflags --libs gtk+-2.0` \
+	`pkg-config --cflags --libs libxfce4ui-1` \
+	`pkg-config --cflags --libs libxfce4util-1.0` \
+	`pkg-config --cflags --libs xi` \
+	xfce-mouse-dialog.c xfce-mouse-dialog.h \
+	xfce-mouse-main.c -o xfce-mouse-settings
+
+	$(CC) $(CFLAGS) \
+	`pkg-config --cflags --libs gtk+-2.0` \
+	`pkg-config --cflags --libs libxfce4ui-1` \
+	`pkg-config --cflags --libs libxfce4util-1.0` \
+	`pkg-config --cflags --libs xrandr` \
+	`pkg-config --cflags --libs xxf86vm` \
+	xfce-display-dialog.c xfce-display-dialog.h \
+	xfce-display-main.c -o xfce-display-settings
+
+clean:
+	rm -f xfce-mouse-settings xfce-display-settings

Added: xfce-mcs-plugins/branches/multi_device/xfce-display-dialog.c
===================================================================
--- xfce-mcs-plugins/branches/multi_device/xfce-display-dialog.c	                        (rev 0)
+++ xfce-mcs-plugins/branches/multi_device/xfce-display-dialog.c	2008-01-11 17:50:36 UTC (rev 26559)
@@ -0,0 +1,612 @@
+/* $Id$ */
+/*
+ * Copyright 2008 Nick Schermer <nick at xfce.org>
+ *
+ * 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <X11/Xlib.h>
+#include <X11/extensions/randr.h>
+#include <X11/extensions/Xrandr.h>
+#include <X11/extensions/xf86vmode.h>
+
+#include <gdk/gdkx.h>
+
+#include "xfce-display-dialog.h"
+
+#define BORDER (6)
+#define IS_STRING(string) (string != NULL && *string != '\0')
+
+
+
+static void xfce_display_dialog_class_init (XfceDisplayDialogClass *klass);
+static void xfce_display_dialog_init (XfceDisplayDialog *dialog);
+static void xfce_display_dialog_finalize (GObject *object);
+static void xfce_display_dialog_response (GtkDialog *gtkdialog, gint response_id);
+static void xfce_display_dialog_monitor_configs (XfceDisplayDialog *dialog);
+static void xfce_display_dialog_populate_tree (XfceDisplayDialog *dialog, GtkListStore *store);
+static void xfce_display_dialog_selection_changed (GtkTreeSelection *selection, XfceDisplayDialog *dialog);
+static void xfce_display_dialog_populate_resolutions (XfceDisplayDialog *dialog);
+static void xfce_display_dialog_resolution_changed (GtkComboBox *combobox, XfceDisplayDialog *dialog);
+static void xfce_display_dialog_populate_refresh_rates (XfceDisplayDialog *dialog, gint current_size);
+static void xfce_display_dialog_populate_rotation (XfceDisplayDialog *dialog);
+
+
+
+struct _XfceDisplayDialogClass
+{
+  XfceTitledDialogClass __parent__;
+};
+
+struct _XfceDisplayDialog
+{
+  XfceTitledDialog __parent__;
+
+  /* this display */
+  GdkDisplay *display;
+
+  /* connected monitors */
+  GSList     *monitor_configs;
+  guint       selected_monitor;
+
+  GtkWidget  *resolution;
+  GtkWidget  *refresh_rate;
+  GtkWidget  *rotation;
+};
+
+enum
+{
+  COLUMN_MONITOR_ID,
+  COLUMN_MONITOR_ICON,
+  COLUMN_MONITOR_MODEL,
+  N_MONITOR_COLUMNS
+};
+
+typedef struct {
+  Rotation     rotation;
+  const gchar *name;
+} RotationTypes;
+
+static const RotationTypes rotation_names[] = {
+  { RR_Rotate_0,   N_("Normal")   },
+  { RR_Rotate_90,  N_("Left")     },
+  { RR_Rotate_180, N_("Inverted") },
+  { RR_Rotate_270, N_("Right")    }
+};
+
+
+
+G_DEFINE_TYPE (XfceDisplayDialog, xfce_display_dialog, XFCE_TYPE_TITLED_DIALOG);
+
+
+
+static void
+xfce_display_dialog_class_init (XfceDisplayDialogClass *klass)
+{
+  GObjectClass   *gobject_class;
+  GtkDialogClass *gtkdialog_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = xfce_display_dialog_finalize;
+
+  gtkdialog_class = GTK_DIALOG_CLASS (klass);
+  gtkdialog_class->response = xfce_display_dialog_response;
+}
+
+
+
+static void
+xfce_display_dialog_init (XfceDisplayDialog *dialog)
+{
+  GtkWidget         *notebook;
+  GtkWidget         *table;
+  GtkWidget         *scroll;
+  GtkWidget         *treeview;
+  GtkWidget         *label;
+  GtkWidget         *combobox;
+  GtkWidget         *hscale;
+  GtkTreeViewColumn *column;
+  GtkCellRenderer   *renderer;
+  GtkTreeSelection  *selection;
+  GtkListStore      *store;
+  GtkTreePath       *path;
+  GtkWidget         *vbox;
+
+  /* initialize */
+  dialog->display = gdk_display_get_default ();
+  dialog->monitor_configs = NULL;
+  dialog->selected_monitor = 0;
+
+  /* get all the monitor configs */
+  xfce_display_dialog_monitor_configs (dialog);
+
+  /* setup window */
+  gtk_window_set_icon_name (GTK_WINDOW (dialog), "xfce4-display");
+  gtk_window_set_title (GTK_WINDOW (dialog), _("Display Preferences"));
+  gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+  gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 350);
+
+  /* setup buttons */
+  gtk_dialog_add_buttons (GTK_DIALOG (dialog), GTK_STOCK_HELP, GTK_RESPONSE_HELP,
+                          GTK_STOCK_APPLY, GTK_RESPONSE_APPLY,
+                          GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                          GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
+  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_APPLY);
+
+  notebook = gtk_notebook_new ();
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), notebook, TRUE, TRUE, 0);
+  gtk_container_set_border_width (GTK_CONTAINER (notebook), BORDER);
+  gtk_widget_show (notebook);
+
+  /* main table for display settings */
+  table = gtk_table_new (5, 3, FALSE);
+  gtk_container_add (GTK_CONTAINER (notebook), table);
+  gtk_container_set_border_width (GTK_CONTAINER (table), BORDER);
+  gtk_table_set_row_spacings (GTK_TABLE (table), BORDER);
+  gtk_table_set_col_spacings (GTK_TABLE (table), BORDER * 2);
+  gtk_widget_show (table);
+
+  /* notebook label */
+  gtk_notebook_set_tab_label_text (GTK_NOTEBOOK (notebook), table, _("Display Mode"));
+
+  /* monitors treeview */
+  scroll = gtk_scrolled_window_new (NULL, NULL);
+  gtk_table_attach (GTK_TABLE (table), scroll, 0, 1, 0, 5, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
+  gtk_widget_show (scroll);
+
+  /* create store */
+  store = gtk_list_store_new (N_MONITOR_COLUMNS, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING);
+  xfce_display_dialog_populate_tree (dialog, store);
+
+  treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
+  gtk_container_add (GTK_CONTAINER (scroll), treeview);
+  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
+  gtk_widget_show (treeview);
+
+  /* release store */
+  g_object_unref (G_OBJECT (store));
+
+  /* icon renderer */
+  renderer = gtk_cell_renderer_pixbuf_new ();
+  column = gtk_tree_view_column_new_with_attributes ("", renderer, "icon-name", COLUMN_MONITOR_ICON, NULL);
+  g_object_set (G_OBJECT (renderer), "stock-size", GTK_ICON_SIZE_DND, NULL);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+
+  /* text renderer */
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("", renderer, "text", COLUMN_MONITOR_MODEL, NULL);
+  g_object_set (G_OBJECT (renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+
+  /* tree selection */
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+  gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
+  g_signal_connect (G_OBJECT (selection), "changed", G_CALLBACK (xfce_display_dialog_selection_changed), dialog);
+
+  /* resolution */
+  label = gtk_label_new_with_mnemonic (_("R_esolution:"));
+  gtk_table_attach (GTK_TABLE (table), label, 1, 2, 0, 1, GTK_FILL, 0, 0, 0);
+  gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+  gtk_widget_show (label);
+
+  combobox = dialog->resolution = gtk_combo_box_new_text ();
+  gtk_table_attach (GTK_TABLE (table), combobox, 2, 3, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+  g_signal_connect (G_OBJECT (combobox), "changed", G_CALLBACK (xfce_display_dialog_resolution_changed), dialog);
+  gtk_label_set_mnemonic_widget (GTK_LABEL (label), combobox);
+  gtk_widget_show (combobox);
+
+  /* refresh rate */
+  label = gtk_label_new_with_mnemonic (_("Re_fresh rate:"));
+  gtk_table_attach (GTK_TABLE (table), label, 1, 2, 1, 2, GTK_FILL, 0, 0, 0);
+  gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+  gtk_widget_show (label);
+
+  combobox = dialog->refresh_rate = gtk_combo_box_new_text ();
+  gtk_table_attach (GTK_TABLE (table), combobox, 2, 3, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+  gtk_label_set_mnemonic_widget (GTK_LABEL (label), combobox);
+  gtk_widget_show (combobox);
+
+  /* rotation */
+  label = gtk_label_new_with_mnemonic (_("Ro_tation:"));
+  gtk_table_attach (GTK_TABLE (table), label, 1, 2, 2, 3, GTK_FILL, 0, 0, 0);
+  gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+  gtk_widget_show (label);
+
+  combobox = dialog->rotation = gtk_combo_box_new_text ();
+  gtk_table_attach (GTK_TABLE (table), combobox, 2, 3, 2, 3, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+  gtk_label_set_mnemonic_widget (GTK_LABEL (label), combobox);
+  gtk_widget_show (combobox);
+
+  /* brightness */
+  label = gtk_label_new_with_mnemonic (_("Gam_ma:"));
+  gtk_table_attach (GTK_TABLE (table), label, 1, 2, 3, 4, GTK_FILL, 0, 0, 0);
+  gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+  gtk_widget_show (label);
+
+  hscale = gtk_hscale_new_with_range (0.10, 10.00, 0.01);
+  gtk_table_attach (GTK_TABLE (table), hscale, 2, 3, 3, 4, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+  gtk_label_set_mnemonic_widget (GTK_LABEL (label), hscale);
+  gtk_scale_set_value_pos (GTK_SCALE (hscale), GTK_POS_RIGHT);
+  gtk_scale_set_digits (GTK_SCALE (hscale), 2);
+  gtk_range_set_value (GTK_RANGE (hscale), 1.00);
+  gtk_widget_show (hscale);
+
+  /* spacer */
+  label = gtk_label_new (NULL);
+  gtk_table_attach (GTK_TABLE (table), label, 1, 3, 4, 5, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+  gtk_widget_show (label);
+
+  /* dual screen main box */
+  vbox = gtk_vbox_new (FALSE, BORDER);
+  gtk_container_add (GTK_CONTAINER (notebook), vbox);
+  gtk_widget_show (vbox);
+
+  /* notebook label */
+  gtk_notebook_set_tab_label_text (GTK_NOTEBOOK (notebook), vbox, _("Dual Screen Mode"));
+
+
+
+  /* select the first screen in the dialog */
+  path = gtk_tree_path_new_first ();
+  gtk_tree_selection_select_path (selection, path);
+  gtk_tree_path_free (path);
+
+  /* treeview has initial focus */
+  gtk_widget_grab_focus (treeview);
+}
+
+
+
+static void
+xfce_display_dialog_finalize (GObject *object)
+{
+  XfceDisplayDialog *dialog = XFCE_DISPLAY_DIALOG (object);
+  GSList            *li;
+
+  /* cleanup display configs */
+  for (li = dialog->monitor_configs; li != NULL; li = li->next)
+    XRRFreeScreenConfigInfo (li->data);
+
+  (*G_OBJECT_CLASS (xfce_display_dialog_parent_class)->finalize) (object);
+}
+
+
+
+static void
+xfce_display_dialog_response (GtkDialog *gtkdialog,
+                              gint       response_id)
+{
+  //XfceDisplayDialog *dialog = XFCE_DISPLAY_DIALOG (gtkdialog);
+
+  if (response_id == GTK_RESPONSE_HELP)
+    {
+      /* show help */
+    }
+  else if (response_id == GTK_RESPONSE_APPLY)
+    {
+      /* apply */
+    }
+  else
+    {
+      if (response_id == GTK_RESPONSE_OK)
+        {
+          /* apply and save */
+        }
+
+      /* destroy dialog */
+      gtk_widget_destroy (GTK_WIDGET (gtkdialog));
+
+      /* leave */
+      gtk_main_quit ();
+    }
+}
+
+
+
+static void
+xfce_display_dialog_monitor_configs (XfceDisplayDialog *dialog)
+{
+  gint                    i;
+  gint                    nscreens;
+  GdkScreen              *screen;
+  GdkWindow              *root_window;
+  XRRScreenConfiguration *screen_config;
+  Display                *xdisplay;
+
+  g_return_if_fail (XFCE_IS_DISPLAY_DIALOG (dialog));
+  g_return_if_fail (GDK_IS_DISPLAY (dialog->display));
+
+  /* get the number of screens */
+  nscreens = gdk_display_get_n_screens (dialog->display);
+
+  /* get the x display */
+  xdisplay = gdk_x11_display_get_xdisplay (dialog->display);
+
+  /* walk the screens on this display */
+  for (i = 0; i < nscreens; i++)
+    {
+      /* get the screen */
+      screen = gdk_display_get_screen (dialog->display, i);
+
+      /* get the root window */
+      root_window = gdk_screen_get_root_window (screen);
+
+      /* get the randr screen information */
+      screen_config = XRRGetScreenInfo (xdisplay, gdk_x11_drawable_get_xid (GDK_DRAWABLE (root_window)));
+
+      /* append to the list */
+      dialog->monitor_configs = g_slist_append (dialog->monitor_configs, screen_config);
+    }
+}
+
+
+
+static void
+xfce_display_dialog_populate_tree (XfceDisplayDialog *dialog,
+                                   GtkListStore      *store)
+{
+  GSList             *li;
+  guint               i;
+  gchar              *name;
+  XF86VidModeMonitor  monitor;
+  Display            *xdisplay;
+  GtkTreeIter         iter;
+
+  g_return_if_fail (XFCE_IS_DISPLAY_DIALOG (dialog));
+  g_return_if_fail (GDK_IS_DISPLAY (dialog->display));
+
+  /* get the x display */
+  xdisplay = gdk_x11_display_get_xdisplay (dialog->display);
+
+  /* populate the store */
+  for (li = dialog->monitor_configs, i = 0; li != NULL; li = li->next, i++)
+    {
+      /* get the monitor information from X */
+      if (XF86VidModeGetMonitor (xdisplay, i, &monitor) == True)
+        {
+          /* construct name */
+          if (IS_STRING (monitor.model) && IS_STRING (monitor.vendor))
+            name = g_strdup_printf ("%s %s", monitor.vendor, monitor.model);
+          else if (IS_STRING (monitor.model))
+            name = g_strdup (monitor.model);
+          else
+            name = g_strdup_printf ("%s %d", _("Screen"), i + 1);
+
+          /* insert in store */
+          gtk_list_store_insert_with_values (store, &iter, i,
+                                             COLUMN_MONITOR_ID, i,
+                                             COLUMN_MONITOR_ICON, "video-display",
+                                             COLUMN_MONITOR_MODEL, name, -1);
+
+          /* cleanup */
+          g_free (name);
+        }
+    }
+}
+
+
+
+static void
+xfce_display_dialog_selection_changed (GtkTreeSelection  *selection,
+                                       XfceDisplayDialog *dialog)
+{
+  GtkTreeModel *model;
+  GtkTreeIter   iter;
+  gboolean      has_selection;
+  guint         monitor_id;
+
+  /* get the selection */
+  has_selection = gtk_tree_selection_get_selected (selection, &model, &iter);
+  if (G_LIKELY (has_selection))
+    {
+      /* get the monitor id */
+      gtk_tree_model_get (model, &iter, COLUMN_MONITOR_ID, &monitor_id, -1);
+
+      /* set the new active monitor id */
+      dialog->selected_monitor = monitor_id;
+
+      /* update the settings */
+      xfce_display_dialog_populate_resolutions (dialog);
+      xfce_display_dialog_populate_rotation (dialog);
+    }
+}
+
+
+
+static void
+xfce_display_dialog_populate_resolutions (XfceDisplayDialog *dialog)
+{
+  XRRScreenConfiguration *screen_config;
+  GtkListStore           *store;
+  GtkTreeIter             iter;
+  SizeID                  current_size;
+  XRRScreenSize          *sizes;
+  gint                    nsizes;
+  Rotation                rotation;
+  gchar                  *string;
+  gint                    i;
+
+  /* get the selected screen config */
+  screen_config = g_slist_nth_data (dialog->monitor_configs, dialog->selected_monitor);
+
+  /* create store */
+  store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
+  gtk_combo_box_set_model (GTK_COMBO_BOX (dialog->resolution), GTK_TREE_MODEL (store));
+
+  /* get current reolution and list or possible resolutions */
+  sizes = XRRConfigSizes (screen_config, &nsizes);
+  current_size = XRRConfigCurrentConfiguration (screen_config, &rotation);
+
+  /* insert in store */
+  for (i = 0; i < nsizes; i++)
+    {
+      /* create string */
+      string = g_strdup_printf ("%d x %d", sizes[i].width, sizes[i].height);
+
+      /* insert in store */
+      gtk_list_store_insert_with_values (store, &iter, i, 0, string, 1, i, -1);
+
+      /* cleanup */
+      g_free (string);
+
+      /* store active size */
+      if (i == current_size)
+        gtk_combo_box_set_active_iter (GTK_COMBO_BOX (dialog->resolution), &iter);
+    }
+
+  /* release store */
+  g_object_unref (G_OBJECT (store));
+}
+
+
+
+static void
+xfce_display_dialog_resolution_changed (GtkComboBox       *combobox,
+                                        XfceDisplayDialog *dialog)
+{
+  GtkTreeModel *model;
+  GtkTreeIter   iter;
+  gint          selected_size;
+
+  model = gtk_combo_box_get_model (combobox);
+  gtk_combo_box_get_active_iter (combobox, &iter);
+
+  gtk_tree_model_get (model, &iter, 1, &selected_size, -1);
+
+  xfce_display_dialog_populate_refresh_rates (dialog, selected_size);
+}
+
+
+
+static void
+xfce_display_dialog_populate_refresh_rates (XfceDisplayDialog *dialog,
+                                            gint               current_size)
+{
+  XRRScreenConfiguration *screen_config;
+  GtkListStore           *store;
+  GtkTreeIter             iter, active_iter;
+  gshort                 *rates, current_rate;
+  gshort                  current_diff;
+  gshort                  diff = G_MAXSHORT;
+  gint                    nrates;
+  gchar                  *string;
+  gint                    i;
+
+  /* get the selected screen config */
+  screen_config = g_slist_nth_data (dialog->monitor_configs, dialog->selected_monitor);
+
+  /* create store */
+  store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
+
+  /* get refresh rates for this resolution */
+  rates = XRRConfigRates (screen_config, current_size, &nrates);
+  current_rate = XRRConfigCurrentRate (screen_config);
+
+  /* insert in store */
+  for (i = 0; i < nrates; i++)
+    {
+      /* create string */
+      string = g_strdup_printf ("%d %s", rates[i], _("Hz"));
+
+      /* insert in store */
+      gtk_list_store_insert_with_values (store, &iter, i, 0, string, 1, rates[i], -1);
+
+      /* cleanup */
+      g_free (string);
+
+      /* get the active item slosest to the current diff */
+      current_diff = ABS (rates[i] - current_rate);
+
+      /* store active size */
+      if (diff > current_diff)
+        {
+          active_iter = iter;
+          diff = current_diff;
+        }
+    }
+
+  /* update combobox */
+  gtk_combo_box_set_model (GTK_COMBO_BOX (dialog->refresh_rate), GTK_TREE_MODEL (store));
+  gtk_combo_box_set_active_iter (GTK_COMBO_BOX (dialog->refresh_rate), &active_iter);
+  g_object_unref (G_OBJECT (store));
+}
+
+
+
+static void
+xfce_display_dialog_populate_rotation (XfceDisplayDialog *dialog)
+{
+  XRRScreenConfiguration *screen_config;
+  Rotation                rotations;
+  Rotation                current_rotation;
+  gint                    i;
+  GtkTreeIter             iter, active_iter;
+  GtkListStore           *store;
+
+  /* get the selected screen config */
+  screen_config = g_slist_nth_data (dialog->monitor_configs, dialog->selected_monitor);
+
+  /* create store */
+  store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
+
+  /* get the active and possible rotations */
+  rotations = XRRConfigRotations (screen_config, &current_rotation);
+
+  /* test and append rotations */
+  for (i = 0; i < G_N_ELEMENTS (rotation_names); i++)
+    {
+      if ((rotations & rotation_names[i].rotation) != 0)
+        {
+          /* insert in store */
+          gtk_list_store_insert_with_values (store, &iter, i, 0, _(rotation_names[i].name), 1, rotation_names[i].rotation, -1);
+
+          /* get active rotation */
+          if (rotation_names[i].rotation == current_rotation)
+            active_iter = iter;
+        }
+    }
+
+  /* set combobox */
+  gtk_combo_box_set_model (GTK_COMBO_BOX (dialog->rotation), GTK_TREE_MODEL (store));
+  gtk_combo_box_set_active_iter (GTK_COMBO_BOX (dialog->rotation), &active_iter);
+  g_object_unref (G_OBJECT (store));
+}
+
+
+
+#if 0
+  gint permission;
+  XF86VidModeGetPermissions (xdisplay, i, &permission);
+  if ((permission & XF86VM_WRITE_PERMISSION) != 0)
+    g_message ("Permission to write to the XF86VM extension");
+  else if ((permission & XF86VM_READ_PERMISSION) != 0)
+    g_message ("Only permission to read from XF86VM");
+  else
+    g_message ("No persmissions");
+#endif
+
+
+
+GtkWidget *
+xfce_display_dialog_new (void)
+{
+  return g_object_new (XFCE_TYPE_DISPLAY_DIALOG, NULL);
+}

Added: xfce-mcs-plugins/branches/multi_device/xfce-display-dialog.h
===================================================================
--- xfce-mcs-plugins/branches/multi_device/xfce-display-dialog.h	                        (rev 0)
+++ xfce-mcs-plugins/branches/multi_device/xfce-display-dialog.h	2008-01-11 17:50:36 UTC (rev 26559)
@@ -0,0 +1,44 @@
+/* $Id$ */
+/*
+ * Copyright 2008 Nick Schermer <nick at xfce.org>
+ *
+ * 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 __XFCE_DISPLAY_DIALOG_H__
+#define __XFCE_DISPLAY_DIALOG_H__
+
+#include <libxfce4ui/libxfce4ui.h>
+#include <libxfce4util/libxfce4util.h>
+
+G_BEGIN_DECLS
+
+#define XFCE_TYPE_DISPLAY_DIALOG            (xfce_display_dialog_get_type ())
+#define XFCE_DISPLAY_DIALOG(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_TYPE_DISPLAY_DIALOG, XfceDisplayDialog))
+#define XFCE_DISPLAY_DIALOG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_TYPE_DISPLAY_DIALOG, XfceDisplayDialogClass))
+#define XFCE_IS_DISPLAY_DIALOG(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFCE_TYPE_DISPLAY_DIALOG))
+#define XFCE_IS_DISPLAY_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_TYPE_DISPLAY_DIALOG))
+#define XFCE_DISPLAY_DIALOG_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_TYPE_DISPLAY_DIALOG, XfceDisplayDialogClass))
+
+typedef struct _XfceDisplayDialogClass XfceDisplayDialogClass;
+typedef struct _XfceDisplayDialog      XfceDisplayDialog;
+
+GType      xfce_display_dialog_get_type (void) G_GNUC_CONST;
+
+GtkWidget *xfce_display_dialog_new      (void);
+
+G_END_DECLS
+
+#endif /* !__XFCE_DISPLAY_DIALOG_H__ */

Added: xfce-mcs-plugins/branches/multi_device/xfce-display-main.c
===================================================================
--- xfce-mcs-plugins/branches/multi_device/xfce-display-main.c	                        (rev 0)
+++ xfce-mcs-plugins/branches/multi_device/xfce-display-main.c	2008-01-11 17:50:36 UTC (rev 26559)
@@ -0,0 +1,42 @@
+/* $Id$ */
+/*
+ * Copyright 2008 Nick Schermer <nick at xfce.org>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <gtk/gtk.h>
+
+#include "xfce-display-dialog.h"
+
+gint
+main (gint argc, gchar **argv)
+{
+  GtkWidget *dialog;
+
+  /* initialize Gtk+ */
+  gtk_init (&argc, &argv);
+
+  /* show display dialog */
+  dialog = xfce_display_dialog_new ();
+  gtk_widget_show (dialog);
+
+  /* enter main loop */
+  gtk_main ();
+
+  return EXIT_SUCCESS;
+}

Added: xfce-mcs-plugins/branches/multi_device/xfce-mouse-dialog.c
===================================================================
--- xfce-mcs-plugins/branches/multi_device/xfce-mouse-dialog.c	                        (rev 0)
+++ xfce-mcs-plugins/branches/multi_device/xfce-mouse-dialog.c	2008-01-11 17:50:36 UTC (rev 26559)
@@ -0,0 +1,647 @@
+/* $Id$ */
+/*
+ * Copyright 2008 Nick Schermer <nick at xfce.org>
+ *
+ * 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include <X11/Xlib.h>
+#include <X11/extensions/XInput.h>
+#include <gdk/gdkx.h>
+
+#include "xfce-mouse-dialog.h"
+
+#define BORDER (6)
+
+
+
+static void xfce_mouse_dialog_class_init (XfceMouseDialogClass *klass);
+static void xfce_mouse_dialog_init (XfceMouseDialog *dialog);
+static void xfce_mouse_dialog_finalize (GObject *object);
+static void xfce_mouse_dialog_response (GtkDialog *gtkdialog, gint response_id);
+static void xfce_mouse_dialog_device_populate_store (GtkListStore *store, XfceMouseDialog *dialog);
+static XDevice *xfce_mouse_dialog_get_device (XfceMouseDialog *dialog, gint *return_nbuttons);
+static void xfce_mouse_dialog_device_selection_changed (GtkTreeSelection *selection, XfceMouseDialog *dialog);
+static void xfce_mouse_dialog_orientation_toggled (GtkWidget *button, XfceMouseDialog *dialog);
+static void xfce_mouse_dialog_motion_changed (GtkWidget *widget, XfceMouseDialog *dialog);
+
+
+struct _XfceMouseDialogClass
+{
+  XfceTitledDialogClass __parent__;
+};
+
+struct _XfceMouseDialog
+{
+  XfceTitledDialog __parent__;
+
+  /* the display */
+  GdkDisplay *display;
+
+  /* whether the dialog is updating */
+  guint       locked : 1;
+
+  /* dialog widgets */
+  GtkWidget  *treeview;
+  GtkWidget  *right_handed;
+  GtkWidget  *left_handed;
+  GtkWidget  *acceleration;
+  GtkWidget  *threshold;
+};
+
+enum
+{
+  COLUMN_DEVICE_ICON,
+  COLUMN_DEVICE_NAME,
+  COLUMN_DEVICE_XID,
+  COLUMN_DEVICE_NBUTTONS,
+  N_DEVICE_COLUMNS
+};
+
+
+
+G_DEFINE_TYPE (XfceMouseDialog, xfce_mouse_dialog, XFCE_TYPE_TITLED_DIALOG);
+
+
+
+static void
+xfce_mouse_dialog_class_init (XfceMouseDialogClass *klass)
+{
+  GObjectClass   *gobject_class;
+  GtkDialogClass *gtkdialog_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = xfce_mouse_dialog_finalize;
+
+  gtkdialog_class = GTK_DIALOG_CLASS (klass);
+  gtkdialog_class->response = xfce_mouse_dialog_response;
+}
+
+
+
+static void
+xfce_mouse_dialog_init (XfceMouseDialog *dialog)
+{
+  GtkWidget         *notebook;
+  GtkWidget         *main_hbox;
+  GtkWidget         *scroll;
+  GtkWidget         *treeview;
+  GtkWidget         *main_vbox;
+  GtkWidget         *button;
+  GtkWidget         *vbox;
+  GtkWidget         *frame;
+  GtkWidget         *hbox;
+  GtkWidget         *label;
+  GtkWidget         *hscale;
+  GtkSizeGroup      *sg;
+  GtkTreeViewColumn *column;
+  GtkCellRenderer   *renderer;
+  GtkTreeSelection  *selection;
+  GtkListStore      *store;
+  GtkTreePath       *path;
+
+  /* initialize */
+  dialog->display = gdk_display_get_default ();
+  dialog->locked = TRUE;
+
+  /* setup window */
+  gtk_window_set_icon_name (GTK_WINDOW (dialog), "xfce4-mouse");
+  gtk_window_set_title (GTK_WINDOW (dialog), _("Mouse Preferences"));
+  gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+  gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 350);
+
+  /* setup buttons */
+  gtk_dialog_add_buttons (GTK_DIALOG (dialog), GTK_STOCK_HELP, GTK_RESPONSE_HELP,
+                          GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);
+  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE);
+
+  notebook = gtk_notebook_new ();
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), notebook, TRUE, TRUE, 0);
+  gtk_container_set_border_width (GTK_CONTAINER (notebook), BORDER);
+  gtk_widget_show (notebook);
+
+  main_hbox = gtk_hbox_new (FALSE, BORDER * 2);
+  gtk_container_add (GTK_CONTAINER (notebook), main_hbox);
+  gtk_container_set_border_width (GTK_CONTAINER (main_hbox), BORDER);
+  gtk_widget_show (main_hbox);
+
+  /* notebook label */
+  gtk_notebook_set_tab_label_text (GTK_NOTEBOOK (notebook), main_hbox, _("General"));
+
+  /* mouse devices treeview */
+  scroll = gtk_scrolled_window_new (NULL, NULL);
+  gtk_box_pack_start (GTK_BOX (main_hbox), scroll, TRUE, TRUE, 0);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
+  gtk_widget_show (scroll);
+
+  /* store */
+  store = gtk_list_store_new (N_DEVICE_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT);
+  xfce_mouse_dialog_device_populate_store (store, dialog);
+
+  treeview = dialog->treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
+  gtk_container_add (GTK_CONTAINER (scroll), treeview);
+  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
+  gtk_widget_show (treeview);
+
+  /* release store */
+  g_object_unref (G_OBJECT (store));
+
+  /* icon renderer */
+  renderer = gtk_cell_renderer_pixbuf_new ();
+  column = gtk_tree_view_column_new_with_attributes ("", renderer, "icon-name", COLUMN_DEVICE_ICON, NULL);
+  g_object_set (G_OBJECT (renderer), "stock-size", GTK_ICON_SIZE_DND, NULL);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+
+  /* text renderer */
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("", renderer, "text", COLUMN_DEVICE_NAME, NULL);
+  g_object_set (G_OBJECT (renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+
+  /* tree selection */
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+  gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
+  g_signal_connect (G_OBJECT (selection), "changed", G_CALLBACK (xfce_mouse_dialog_device_selection_changed), dialog);
+
+  main_vbox = gtk_vbox_new (FALSE, BORDER);
+  gtk_box_pack_start (GTK_BOX (main_hbox), main_vbox, TRUE, TRUE, 0);
+  gtk_widget_show (main_vbox);
+
+  vbox = gtk_vbox_new (FALSE, 2);
+  gtk_widget_show (vbox);
+
+  frame = xfce_gtk_frame_box_new_with_content (_("Orientation"), vbox);
+  gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
+  gtk_widget_show (frame);
+
+  button = dialog->right_handed = gtk_radio_button_new_with_mnemonic (NULL, _("_Right handed"));
+  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+  g_signal_connect (G_OBJECT (button), "toggled", G_CALLBACK (xfce_mouse_dialog_orientation_toggled), dialog);
+  gtk_widget_show (button);
+
+  button = dialog->left_handed = gtk_radio_button_new_with_mnemonic_from_widget (GTK_RADIO_BUTTON (dialog->right_handed), ("_Left handed"));
+  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+  g_signal_connect (G_OBJECT (button), "toggled", G_CALLBACK (xfce_mouse_dialog_orientation_toggled), dialog);
+  gtk_widget_show (button);
+
+  vbox = gtk_vbox_new (FALSE, 2);
+  gtk_widget_show (vbox);
+
+  frame = xfce_gtk_frame_box_new_with_content (_("Motion"), vbox);
+  gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
+  gtk_widget_show (frame);
+
+  /* create size group */
+  sg = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+
+  /* acceleration */
+  hbox = gtk_hbox_new (FALSE, BORDER * 2);
+  gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
+  gtk_widget_show (hbox);
+
+  label = gtk_label_new_with_mnemonic (_("_Acceleration:"));
+  gtk_misc_set_alignment (GTK_MISC (label), 0.00, 0.50);
+  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+  gtk_size_group_add_widget (sg, label);
+  gtk_widget_show (label);
+
+  hscale = dialog->acceleration = gtk_hscale_new_with_range (1, 30, 1);
+  gtk_box_pack_start (GTK_BOX (hbox), hscale, TRUE, TRUE, 0);
+  gtk_scale_set_value_pos (GTK_SCALE (hscale), GTK_POS_RIGHT);
+  gtk_range_set_update_policy (GTK_RANGE (hscale), GTK_UPDATE_DELAYED);
+  gtk_label_set_mnemonic_widget (GTK_LABEL (label), hscale);
+  g_signal_connect (G_OBJECT (hscale), "value-changed", G_CALLBACK (xfce_mouse_dialog_motion_changed), dialog);
+  gtk_widget_show (hscale);
+
+  /* threshold */
+  hbox = gtk_hbox_new (FALSE, BORDER * 2);
+  gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
+  gtk_widget_show (hbox);
+
+  label = gtk_label_new_with_mnemonic (_("_Threshold:"));
+  gtk_misc_set_alignment (GTK_MISC (label), 0.00, 0.50);
+  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+  gtk_size_group_add_widget (sg, label);
+  gtk_widget_show (label);
+
+  hscale = dialog->threshold = gtk_hscale_new_with_range (1, 50, 1);
+  gtk_box_pack_start (GTK_BOX (hbox), hscale, TRUE, TRUE, 0);
+  gtk_scale_set_value_pos (GTK_SCALE (hscale), GTK_POS_RIGHT);
+  gtk_range_set_update_policy (GTK_RANGE (hscale), GTK_UPDATE_DELAYED);
+  gtk_label_set_mnemonic_widget (GTK_LABEL (label), hscale);
+  g_signal_connect (G_OBJECT (hscale), "value-changed", G_CALLBACK (xfce_mouse_dialog_motion_changed), dialog);
+  gtk_widget_show (hscale);
+
+  /* release size group */
+  g_object_unref (G_OBJECT (sg));
+
+  /* select the first mouse in the tree */
+  path = gtk_tree_path_new_first ();
+  gtk_tree_selection_select_path (selection, path);
+  gtk_tree_path_free (path);
+
+  /* treeview has initial focus */
+  gtk_widget_grab_focus (treeview);
+
+  /* we're done */
+  dialog->locked = FALSE;
+}
+
+
+
+static void
+xfce_mouse_dialog_finalize (GObject *object)
+{
+  //XfceMouseDialog *dialog = XFCE_MOUSE_DIALOG (object);
+
+  (*G_OBJECT_CLASS (xfce_mouse_dialog_parent_class)->finalize) (object);
+}
+
+
+
+static void
+xfce_mouse_dialog_response (GtkDialog *gtkdialog,
+                            gint       response_id)
+{
+  //XfceMouseDialog *dialog = XFCE_MOUSE_DIALOG (gtkdialog);
+
+  if (response_id == GTK_RESPONSE_HELP)
+    {
+      /* show help */
+    }
+  else /* GTK_RESPONSE_CLOSE */
+    {
+      /* destroy dialog */
+      gtk_widget_destroy (GTK_WIDGET (gtkdialog));
+
+      /* leave */
+      gtk_main_quit ();
+    }
+}
+
+
+
+static void
+xfce_mouse_dialog_device_populate_store (GtkListStore    *store,
+                                         XfceMouseDialog *dialog)
+{
+  Display      *xdisplay;
+  XDeviceInfo  *device_list, *device;
+  gchar        *device_name, *usb;
+  gint          num_buttons;
+  gint          ndevices;
+  gint          i, m;
+  XAnyClassPtr  ptr;
+  GtkTreeIter   iter;
+
+  /* get the x display */
+  xdisplay = gdk_x11_display_get_xdisplay (dialog->display);
+
+  /* get all the registered devices */
+  device_list = XListInputDevices (xdisplay, &ndevices);
+
+  for (i = 0; i < ndevices; i++)
+    {
+      /* get the device */
+      device = &device_list[i];
+
+      /* filter out the pointer devices */
+      if (device->use == IsXExtensionPointer)
+        {
+          /* get the device name */
+          device_name = g_strdup (device->name);
+
+          /* get rid of usb crap in the name */
+          if ((usb = strstr (device_name, "-usb")) != NULL)
+            *usb = '\0';
+
+          /* get the number of device buttons */
+          ptr = device->inputclassinfo;
+
+          /* walk all the classes */
+          for (m = 0, num_buttons = 0; m < device->num_classes; m++)
+            {
+              /* find the button class */
+              if (ptr->class == ButtonClass)
+                {
+                  /* get the number of buttons */
+                  num_buttons = ((XButtonInfoPtr) ptr)->num_buttons;
+
+                  /* done */
+                  break;
+                }
+
+              /* advance the offset */
+              ptr = (XAnyClassPtr) ((gchar *) ptr + ptr->length);
+            }
+
+          /* insert the device if it has buttons */
+          if (G_LIKELY (num_buttons > 0))
+            {
+              /* insert in the store */
+              gtk_list_store_insert_with_values (store, &iter, i,
+                                                 COLUMN_DEVICE_ICON, "input-mouse",
+                                                 COLUMN_DEVICE_NAME, device_name,
+                                                 COLUMN_DEVICE_XID, device->id,
+                                                 COLUMN_DEVICE_NBUTTONS, num_buttons, -1);
+            }
+
+          /* cleanup */
+          g_free (device_name);
+        }
+    }
+
+  /* cleanup */
+  XFreeDeviceList (device_list);
+}
+
+
+
+static XDevice *
+xfce_mouse_dialog_get_device (XfceMouseDialog *dialog,
+                              gint            *return_nbuttons)
+{
+  GtkTreeSelection *selection;
+  GtkTreeModel     *model;
+  GtkTreeIter       iter;
+  gboolean          has_selection;
+  XID               xid;
+  Display          *xdisplay;
+  gint              nbuttons = 0;
+  XDevice          *device = NULL;
+
+  /* get the selection */
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->treeview));
+
+  has_selection = gtk_tree_selection_get_selected (selection, &model, &iter);
+  if (G_LIKELY (has_selection))
+    {
+      /* get device id and number of buttons */
+      gtk_tree_model_get (model, &iter, COLUMN_DEVICE_XID, &xid, COLUMN_DEVICE_NBUTTONS, &nbuttons, -1);
+
+      /* get the x display */
+      xdisplay = gdk_x11_display_get_xdisplay (dialog->display);
+
+      /* open the device */
+      device = XOpenDevice (xdisplay, xid);
+    }
+
+  /* set return value */
+  if (return_nbuttons)
+    *return_nbuttons = nbuttons;
+
+  return device;
+}
+
+
+
+static void
+xfce_mouse_dialog_device_selection_changed (GtkTreeSelection *selection,
+                                            XfceMouseDialog  *dialog)
+{
+  gint               nbuttons;
+  Display           *xdisplay;
+  XDevice           *device;
+  XFeedbackState    *states;
+  gint               nstates;
+  XPtrFeedbackState *state;
+  gint               i;
+  guchar            *buttonmap;
+  gint               id_1 = 0, id_3 = 0;
+  gint               acceleration = -1;
+  gint               threshold = -1;
+
+  /* lock */
+  dialog->locked = TRUE;
+
+  /* get device */
+  device = xfce_mouse_dialog_get_device (dialog, &nbuttons);
+  if (G_LIKELY (device))
+    {
+      /* get the x display */
+      xdisplay = gdk_x11_display_get_xdisplay (dialog->display);
+
+      /* allocate button map */
+      buttonmap = g_new0 (guchar, nbuttons);
+
+      /* get the button mapping */
+      XGetDeviceButtonMapping (xdisplay, device, buttonmap, nbuttons);
+
+      /* figure out the position of the first and second/third button in the map */
+      for (i = 0; i < nbuttons; i++)
+        {
+          if (buttonmap[i] == 1)
+            id_1 = i;
+          else if (buttonmap[i] == (nbuttons < 3 ? 2 : 3))
+            id_3 = i;
+        }
+
+      /* cleanup */
+      g_free (buttonmap);
+
+      /* get the feedback states for this device */
+      states = XGetFeedbackControl (xdisplay, device, &nstates);
+
+      /* intial values */
+      acceleration = threshold = -1;
+
+      /* get the pointer feedback class */
+      for (i = 0; i < nstates; i++)
+        {
+          if (states->class == PtrFeedbackClass)
+            {
+              /* get the state */
+              state = (XPtrFeedbackState *) states;
+
+              /* set values */
+              acceleration = state->accelNum;
+              threshold = state->threshold;
+
+              /* done */
+              break;
+            }
+
+          /* advance the offset */
+          states = (XFeedbackState *) ((gchar *) states + states->length);
+        }
+
+      /* close the device */
+      XCloseDevice (xdisplay, device);
+    }
+
+  /* update orientation */
+  if (id_1 > id_3)
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->left_handed), TRUE);
+  else
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->right_handed), TRUE);
+
+  /* update acceleration scale */
+  gtk_range_set_value (GTK_RANGE (dialog->acceleration), acceleration);
+  gtk_widget_set_sensitive (dialog->acceleration, acceleration != -1);
+
+  /* update threshold scale */
+  gtk_range_set_value (GTK_RANGE (dialog->threshold), threshold);
+  gtk_widget_set_sensitive (dialog->threshold, threshold != -1);
+
+  /* unlock */
+  dialog->locked = FALSE;
+}
+
+
+
+static void
+xfce_mouse_dialog_orientation_toggled (GtkWidget       *button,
+                                       XfceMouseDialog *dialog)
+{
+  gboolean  right_handed;
+  XDevice  *device;
+  gint      nbuttons;
+  Display  *xdisplay;
+  guchar   *buttonmap;
+  gint      id_1, id_3;
+  gint      i;
+
+  /* leave when locked or not the active button */
+  if (dialog->locked || !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
+    return;
+
+  /* lock */
+  dialog->locked = TRUE;
+
+  /* get the mode */
+  right_handed = (button == dialog->right_handed ? TRUE : FALSE);
+
+  /* get the active device */
+  device = xfce_mouse_dialog_get_device (dialog, &nbuttons);
+  if (G_LIKELY (device))
+    {
+      /* get the x display */
+      xdisplay = gdk_x11_display_get_xdisplay (dialog->display);
+
+      /* allocate button map */
+      buttonmap = g_new0 (guchar, nbuttons);
+
+      /* get the button mapping */
+      XGetDeviceButtonMapping (xdisplay, device, buttonmap, nbuttons);
+
+      /* figure out the position of the first and second/third button in the map */
+      for (i = 0, id_1 = id_3 = -1; i < nbuttons; i++)
+        {
+          if (buttonmap[i] == 1)
+            id_1 = i;
+          else if (buttonmap[i] == (nbuttons < 3 ? 2 : 3))
+            id_3 = i;
+        }
+
+      /* only change the map when id_1 and id_3 where found */
+      if (G_LIKELY (id_1 != -1 || id_3 != -1))
+        {
+          /* update the button map */
+          if ((!right_handed && (id_1 < id_3)) || (right_handed && (id_1 > id_3)))
+            {
+              buttonmap[id_1] = (nbuttons < 3 ? 2 : 3);
+              buttonmap[id_3] = 1;
+            }
+
+          /* set the new button mapping */
+          XSetDeviceButtonMapping (xdisplay, device, buttonmap, nbuttons);
+        }
+
+      /* cleanup */
+      g_free (buttonmap);
+
+      /* close the device */
+      XCloseDevice (xdisplay, device);
+    }
+
+  /* unlock */
+  dialog->locked = FALSE;
+}
+
+
+
+static void
+xfce_mouse_dialog_motion_changed (GtkWidget       *widget,
+                                  XfceMouseDialog *dialog)
+{
+  XDevice             *device;
+  Display             *xdisplay;
+  XFeedbackState      *states;
+  gint                 nstates;
+  XPtrFeedbackControl  feedback;
+  gint                 i;
+
+  /* leave when locked */
+  if (dialog->locked)
+    return;
+
+  /* lock */
+  dialog->locked = TRUE;
+
+  /* get the active device */
+  device = xfce_mouse_dialog_get_device (dialog, NULL);
+  if (G_LIKELY (device))
+    {
+      /* get the x display */
+      xdisplay = gdk_x11_display_get_xdisplay (dialog->display);
+
+      /* get the feedback states for this device */
+      states = XGetFeedbackControl (xdisplay, device, &nstates);
+
+      /* get the pointer feedback class */
+      for (i = 0; i < nstates; i++)
+        {
+          if (states->class == PtrFeedbackClass)
+            {
+              /* create a new feedback */
+              feedback.class     = PtrFeedbackClass;
+              feedback.length    = sizeof (XPtrFeedbackControl);
+              feedback.id        = states->id;
+              feedback.threshold = (gint) gtk_range_get_value (GTK_RANGE (dialog->threshold));
+              feedback.accelNum  = (gint) gtk_range_get_value (GTK_RANGE (dialog->acceleration));
+
+              /* change feedback for this device */
+              XChangeFeedbackControl (xdisplay, device, DvAccelNum | DvThreshold, (XFeedbackControl *) &feedback);
+
+              /* done */
+              break;
+            }
+
+          /* advance the offset */
+          states = (XFeedbackState *) ((gchar *) states + states->length);
+        }
+
+      /* close the device */
+      XCloseDevice (xdisplay, device);
+    }
+
+  /* unlock */
+  dialog->locked = FALSE;
+}
+
+
+
+GtkWidget *
+xfce_mouse_dialog_new (void)
+{
+  return g_object_new (XFCE_TYPE_MOUSE_DIALOG, NULL);
+}

Added: xfce-mcs-plugins/branches/multi_device/xfce-mouse-dialog.h
===================================================================
--- xfce-mcs-plugins/branches/multi_device/xfce-mouse-dialog.h	                        (rev 0)
+++ xfce-mcs-plugins/branches/multi_device/xfce-mouse-dialog.h	2008-01-11 17:50:36 UTC (rev 26559)
@@ -0,0 +1,44 @@
+/* $Id$ */
+/*
+ * Copyright 2008 Nick Schermer <nick at xfce.org>
+ *
+ * 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 __XFCE_MOUSE_DIALOG_H__
+#define __XFCE_MOUSE_DIALOG_H__
+
+#include <libxfce4ui/libxfce4ui.h>
+#include <libxfce4util/libxfce4util.h>
+
+G_BEGIN_DECLS
+
+#define XFCE_TYPE_MOUSE_DIALOG            (xfce_mouse_dialog_get_type ())
+#define XFCE_MOUSE_DIALOG(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_TYPE_MOUSE_DIALOG, XfceMouseDialog))
+#define XFCE_MOUSE_DIALOG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_TYPE_MOUSE_DIALOG, XfceMouseDialogClass))
+#define XFCE_IS_MOUSE_DIALOG(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFCE_TYPE_MOUSE_DIALOG))
+#define XFCE_IS_MOUSE_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_TYPE_MOUSE_DIALOG))
+#define XFCE_MOUSE_DIALOG_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_TYPE_MOUSE_DIALOG, XfceMouseDialogClass))
+
+typedef struct _XfceMouseDialogClass XfceMouseDialogClass;
+typedef struct _XfceMouseDialog      XfceMouseDialog;
+
+GType      xfce_mouse_dialog_get_type (void) G_GNUC_CONST;
+
+GtkWidget *xfce_mouse_dialog_new      (void);
+
+G_END_DECLS
+
+#endif /* !__XFCE_MOUSE_DIALOG_H__ */

Added: xfce-mcs-plugins/branches/multi_device/xfce-mouse-main.c
===================================================================
--- xfce-mcs-plugins/branches/multi_device/xfce-mouse-main.c	                        (rev 0)
+++ xfce-mcs-plugins/branches/multi_device/xfce-mouse-main.c	2008-01-11 17:50:36 UTC (rev 26559)
@@ -0,0 +1,42 @@
+/* $Id$ */
+/*
+ * Copyright 2008 Nick Schermer <nick at xfce.org>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <gtk/gtk.h>
+
+#include "xfce-mouse-dialog.h"
+
+gint
+main (gint argc, gchar **argv)
+{
+  GtkWidget *dialog;
+
+  /* initialize Gtk+ */
+  gtk_init (&argc, &argv);
+
+  /* show display dialog */
+  dialog = xfce_mouse_dialog_new ();
+  gtk_widget_show (dialog);
+
+  /* enter main loop */
+  gtk_main ();
+
+  return EXIT_SUCCESS;
+}



More information about the Xfce4-commits mailing list