~ubuntu-branches/ubuntu/trusty/xfce4-settings/trusty-proposed

« back to all changes in this revision

Viewing changes to dialogs/mouse-settings/main.c

  • Committer: Package Import Robot
  • Author(s): Lionel Le Folgoc
  • Date: 2012-01-23 21:10:18 UTC
  • Revision ID: package-import@ubuntu.com-20120123211018-g3wszngv4plljt2p
Tags: 4.8.3-1ubuntu1
* debian/control: add xfce4-dev-tools, autoconf, automake and libtool
  to build-depends, needed for xdt-autogen, and exo-utils, needed for
  exo-csource.
* debian/rules: run xdt-autogen before configure, and clean up autogenerated
  files after build.
* debian/patches:
  - xubuntu_improved-mouse-touchpad-dialog.patch: added, backport the new
    pointing device dialog from master. lp: #818131
  - xubuntu_refreshed-translations.patch: added, new translations taken
    from master.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id$ */
2
1
/*
3
 
 *  Copyright (c) 2008 Nick Schermer <nick@xfce.org>
4
 
 *                     Jannis Pohlmann <jannis@xfce.org>
 
2
 *  Copyright (c) 2008-2011 Nick Schermer <nick@xfce.org>
 
3
 *  Copyright (c) 2008      Jannis Pohlmann <jannis@xfce.org>
5
4
 *
6
5
 *  This program is free software; you can redistribute it and/or modify
7
6
 *  it under the terms of the GNU General Public License as published by
33
32
#endif
34
33
 
35
34
#include <X11/Xlib.h>
 
35
#include <X11/Xatom.h>
36
36
#include <X11/extensions/XI.h>
37
37
#include <X11/extensions/XInput.h>
38
38
#include <X11/extensions/XIproto.h>
79
79
/* lock counter to avoid signals during updates */
80
80
static gint locked = 0;
81
81
 
82
 
/* the display for this window */
83
 
static GdkDisplay *display;
84
 
 
85
82
/* device update id */
86
83
static guint timeout_id = 0;
87
84
 
129
126
 
130
127
enum
131
128
{
132
 
    COLUMN_DEVICE_ICON,
133
129
    COLUMN_DEVICE_NAME,
134
 
    COLUMN_DEVICE_DISPLAY_NAME,
 
130
    COLUMN_DEVICE_XFCONF_NAME,
135
131
    COLUMN_DEVICE_XID,
136
 
    COLUMN_DEVICE_NBUTTONS,
137
132
    N_DEVICE_COLUMNS
138
133
};
139
134
 
140
135
 
 
136
 
 
137
static gchar *
 
138
mouse_settings_format_value_px (GtkScale *scale,
 
139
                                gdouble   value)
 
140
{
 
141
   /* pixel value for some of the scales in the dialog */
 
142
   return g_strdup_printf (_("%g px"), value);
 
143
}
 
144
 
 
145
 
 
146
 
 
147
static gchar *
 
148
mouse_settings_format_value_ms (GtkScale *scale,
 
149
                                gdouble   value)
 
150
{
 
151
   /* miliseconds value for some of the scales in the dialog */
 
152
   return g_strdup_printf (_("%g ms"), value);
 
153
}
 
154
 
 
155
 
 
156
 
 
157
 
141
158
#ifdef HAVE_XCURSOR
142
159
static GdkPixbuf *
143
160
mouse_settings_themes_pixbuf_from_filename (const gchar *filename,
317
334
                            COLUMN_THEME_NAME, &name, -1);
318
335
 
319
336
        /* update the preview widget */
320
 
        image = gtk_builder_get_object (builder, "mouse-theme-preview");
 
337
        image = gtk_builder_get_object (builder, "theme-preview");
321
338
        mouse_settings_themes_preview_image (path, GTK_IMAGE (image));
322
339
 
323
340
        /* write configuration (not during a lock) */
530
547
    g_free (active_theme);
531
548
 
532
549
    /* set the treeview store */
533
 
    treeview = gtk_builder_get_object (builder, "mouse-theme-treeview");
 
550
    treeview = gtk_builder_get_object (builder, "theme-treeview");
534
551
    gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (store));
535
552
    gtk_tree_view_set_tooltip_column (GTK_TREE_VIEW (treeview), COLUMN_THEME_COMMENT);
536
553
 
565
582
 
566
583
 
567
584
 
568
 
static void
569
 
mouse_settings_device_selection_changed (GtkTreeSelection *selection,
570
 
                                         GtkBuilder       *builder)
571
 
{
572
 
    gint               nbuttons;
573
 
    Display           *xdisplay;
 
585
static gint
 
586
mouse_settings_device_get_int_property (XDevice *device,
 
587
                                        Atom     prop,
 
588
                                        guint    offset,
 
589
                                        gint    *horiz)
 
590
{
 
591
    Atom     type;
 
592
    gint     format;
 
593
    gulong   n_items, bytes_after;
 
594
    guchar  *data;
 
595
    gint     val = -1;
 
596
    gint     res;
 
597
 
 
598
    gdk_error_trap_push ();
 
599
    res = XGetDeviceProperty (GDK_DISPLAY (), device, prop, 0, 1000, False,
 
600
                              AnyPropertyType, &type, &format,
 
601
                              &n_items, &bytes_after, &data);
 
602
    if (gdk_error_trap_pop () == 0 && res == Success)
 
603
    {
 
604
        if (type == XA_INTEGER)
 
605
        {
 
606
            if (n_items > offset)
 
607
                val = data[offset];
 
608
 
 
609
            if (n_items > 1 + offset && horiz != NULL)
 
610
                *horiz = data[offset + 1];
 
611
        }
 
612
 
 
613
        XFree (data);
 
614
    }
 
615
 
 
616
    return val;
 
617
}
 
618
 
 
619
 
 
620
 
 
621
static gboolean
 
622
mouse_settings_device_get_selected (GtkBuilder  *builder,
 
623
                                    XDevice    **device,
 
624
                                    gchar      **xfconf_name)
 
625
{
 
626
    GObject      *combobox;
 
627
    GtkTreeIter   iter;
 
628
    gboolean      found = FALSE;
 
629
    gulong        xid;
 
630
    GtkTreeModel *model;
 
631
 
 
632
    /* get the selected item */
 
633
    combobox = gtk_builder_get_object (builder, "device-combobox");
 
634
    found = gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combobox), &iter);
 
635
    if (found)
 
636
    {
 
637
        /* get the device id  */
 
638
        model = gtk_combo_box_get_model (GTK_COMBO_BOX (combobox));
 
639
        gtk_tree_model_get (model, &iter, COLUMN_DEVICE_XID, &xid, -1);
 
640
 
 
641
        if (xfconf_name != NULL)
 
642
            gtk_tree_model_get (model, &iter, COLUMN_DEVICE_XFCONF_NAME, xfconf_name, -1);
 
643
 
 
644
        if (device != NULL)
 
645
        {
 
646
            /* open the device */
 
647
            gdk_error_trap_push ();
 
648
            *device = XOpenDevice (GDK_DISPLAY (), xid);
 
649
            if (gdk_error_trap_pop () != 0 || *device == NULL)
 
650
            {
 
651
                g_critical ("Unable to open device %ld", xid);
 
652
                *device = NULL;
 
653
                found = FALSE;
 
654
            }
 
655
        }
 
656
    }
 
657
 
 
658
    return found;
 
659
}
 
660
 
 
661
 
 
662
 
 
663
static void
 
664
mouse_settings_wacom_set_rotation (GtkComboBox *combobox,
 
665
                                   GtkBuilder  *builder)
 
666
{
 
667
    XDevice      *device;
 
668
    GtkTreeIter   iter;
 
669
    GtkTreeModel *model;
 
670
    gint          rotation = 0;
 
671
    gchar        *name = NULL;
 
672
    gchar        *prop;
 
673
 
 
674
    if (locked > 0)
 
675
        return;
 
676
 
 
677
    if (mouse_settings_device_get_selected (builder, &device, &name))
 
678
    {
 
679
        if (gtk_combo_box_get_active_iter (combobox, &iter))
 
680
        {
 
681
            model = gtk_combo_box_get_model (combobox);
 
682
            gtk_tree_model_get (model, &iter, 0, &rotation, -1);
 
683
 
 
684
            prop = g_strconcat ("/", name, "/Properties/Wacom_Rotation", NULL);
 
685
            xfconf_channel_set_int (pointers_channel, prop, rotation);
 
686
            g_free (prop);
 
687
        }
 
688
 
 
689
        XCloseDevice (GDK_DISPLAY (), device);
 
690
    }
 
691
 
 
692
    g_free (name);
 
693
}
 
694
 
 
695
 
 
696
 
 
697
static void
 
698
mouse_settings_wacom_set_mode (GtkComboBox *combobox,
 
699
                               GtkBuilder  *builder)
 
700
{
 
701
    XDevice      *device;
 
702
    Display      *xdisplay = GDK_DISPLAY ();
 
703
    GtkTreeIter   iter;
 
704
    GtkTreeModel *model;
 
705
    gchar        *mode = NULL;
 
706
    gchar        *name = NULL;
 
707
    gchar        *prop;
 
708
 
 
709
    if (locked > 0)
 
710
        return;
 
711
 
 
712
    if (mouse_settings_device_get_selected (builder, &device, &name))
 
713
    {
 
714
        if (gtk_combo_box_get_active_iter (combobox, &iter))
 
715
        {
 
716
            model = gtk_combo_box_get_model (combobox);
 
717
            gtk_tree_model_get (model, &iter, 0, &mode, -1);
 
718
 
 
719
            prop = g_strconcat ("/", name, "/Mode", NULL);
 
720
            xfconf_channel_set_string (pointers_channel, prop, mode);
 
721
            g_free (prop);
 
722
 
 
723
            g_free (mode);
 
724
        }
 
725
 
 
726
        XCloseDevice (xdisplay, device);
 
727
    }
 
728
 
 
729
    g_free (name);
 
730
}
 
731
 
 
732
 
 
733
 
 
734
static void
 
735
mouse_settings_synaptics_set_tap_to_click (GtkBuilder *builder)
 
736
{
 
737
    Display   *xdisplay = GDK_DISPLAY ();
 
738
    XDevice   *device;
 
739
    gchar     *name = NULL;
 
740
    Atom       tap_ation_prop;
 
741
    Atom       type;
 
742
    gint       format;
 
743
    gulong     n, n_items, bytes_after;
 
744
    guchar    *data;
 
745
    gboolean   tap_to_click;
 
746
    GPtrArray *array;
 
747
    gint       res;
 
748
    GObject   *object;
 
749
    gchar     *prop;
 
750
    GValue    *val;
 
751
 
 
752
    if (mouse_settings_device_get_selected (builder, &device, &name))
 
753
    {
 
754
        gdk_error_trap_push ();
 
755
        tap_ation_prop = XInternAtom (xdisplay, "Synaptics Tap Action", True);
 
756
        res = XGetDeviceProperty (xdisplay, device, tap_ation_prop, 0, 1000, False,
 
757
                                  AnyPropertyType, &type, &format,
 
758
                                  &n_items, &bytes_after, &data);
 
759
        if (gdk_error_trap_pop () == 0
 
760
            && res == Success)
 
761
        {
 
762
            if (type == XA_INTEGER
 
763
                && format == 8
 
764
                && n_items >= 7)
 
765
            {
 
766
                object = gtk_builder_get_object (builder, "synaptics-tap-to-click");
 
767
                tap_to_click = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (object));
 
768
 
 
769
                /* format: RT, RB, LT, LB, F1, F2, F3 */
 
770
                data[4] = tap_to_click ? 1 : 0;
 
771
                data[5] = tap_to_click ? 3 : 0;
 
772
                data[6] = tap_to_click ? 2 : 0;
 
773
 
 
774
                array = g_ptr_array_sized_new (n_items);
 
775
                for (n = 0; n < n_items; n++)
 
776
                {
 
777
                    val = g_new0 (GValue, 1);
 
778
                    g_value_init (val, G_TYPE_INT);
 
779
                    g_value_set_int (val, data[n]);
 
780
                    g_ptr_array_add (array, val);
 
781
                }
 
782
 
 
783
                prop = g_strconcat ("/", name, "/Properties/Synaptics_Tap_Action", NULL);
 
784
                xfconf_channel_set_arrayv (pointers_channel, prop, array);
 
785
                g_free (prop);
 
786
 
 
787
                xfconf_array_free (array);
 
788
            }
 
789
 
 
790
            XFree (data);
 
791
        }
 
792
    }
 
793
 
 
794
    g_free (name);
 
795
}
 
796
 
 
797
 
 
798
 
 
799
static void
 
800
mouse_settings_synaptics_hscroll_sensitive (GtkBuilder *builder)
 
801
{
 
802
    gboolean  sensitive = FALSE;
 
803
    GObject  *object;
 
804
 
 
805
    object = gtk_builder_get_object (builder, "synaptics-scroll-edge");
 
806
    if (gtk_widget_get_sensitive (GTK_WIDGET (object))
 
807
        && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (object)))
 
808
        sensitive = TRUE;
 
809
 
 
810
    object = gtk_builder_get_object (builder, "synaptics-scroll-two");
 
811
    if (gtk_widget_get_sensitive (GTK_WIDGET (object))
 
812
        && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (object)))
 
813
        sensitive = TRUE;
 
814
 
 
815
    object = gtk_builder_get_object (builder, "synaptics-scroll-horiz");
 
816
    gtk_widget_set_sensitive (GTK_WIDGET (object), sensitive);
 
817
}
 
818
 
 
819
 
 
820
 
 
821
static void
 
822
mouse_settings_synaptics_set_scrolling (GtkWidget  *widget,
 
823
                                        GtkBuilder *builder)
 
824
{
 
825
    gint      edge_scroll[3] = { 0, 0, 0 };
 
826
    gint      two_scroll[2] = { 0, 0 };
 
827
    GObject  *object;
 
828
    gboolean  horizontal = FALSE;
 
829
    gchar    *name = NULL, *prop;
 
830
 
 
831
    if (locked > 0)
 
832
        return;
 
833
 
 
834
    /*  skip double event if a radio button is toggled */
 
835
    if (GTK_IS_RADIO_BUTTON (widget)
 
836
        && !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
 
837
        return;
 
838
 
 
839
    mouse_settings_synaptics_hscroll_sensitive (builder);
 
840
 
 
841
    object = gtk_builder_get_object (builder, "synaptics-scroll-horiz");
 
842
    if (gtk_widget_get_sensitive (GTK_WIDGET (object)))
 
843
        horizontal = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (object));
 
844
 
 
845
    object = gtk_builder_get_object (builder, "synaptics-scroll-edge");
 
846
    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (object))
 
847
        && gtk_widget_get_sensitive (GTK_WIDGET (object)))
 
848
    {
 
849
        edge_scroll[0] = TRUE;
 
850
        edge_scroll[1] = horizontal;
 
851
    }
 
852
 
 
853
    object = gtk_builder_get_object (builder, "synaptics-scroll-two");
 
854
    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (object))
 
855
        && gtk_widget_get_sensitive (GTK_WIDGET (object)))
 
856
    {
 
857
        two_scroll[0] = TRUE;
 
858
        two_scroll[1] = horizontal;
 
859
    }
 
860
 
 
861
    if (mouse_settings_device_get_selected (builder, NULL, &name))
 
862
    {
 
863
        /* 3 values: vertical, horizontal, corner. */
 
864
        prop = g_strconcat ("/", name, "/Properties/Synaptics_Edge_Scrolling", NULL);
 
865
        xfconf_channel_set_array (pointers_channel, prop,
 
866
                                  G_TYPE_INT, &edge_scroll[0],
 
867
                                  G_TYPE_INT, &edge_scroll[1],
 
868
                                  G_TYPE_INT, &edge_scroll[2],
 
869
                                  G_TYPE_INVALID);
 
870
        g_free (prop);
 
871
 
 
872
        /* 2 values: vertical, horizontal. */
 
873
        prop = g_strconcat ("/", name, "/Properties/Synaptics_Two-Finger_Scrolling", NULL);
 
874
        xfconf_channel_set_array (pointers_channel, prop,
 
875
                                  G_TYPE_INT, &two_scroll[0],
 
876
                                  G_TYPE_INT, &two_scroll[1],
 
877
                                  G_TYPE_INVALID);
 
878
        g_free (prop);
 
879
    }
 
880
 
 
881
    g_free (name);
 
882
}
 
883
 
 
884
 
 
885
 
 
886
 
 
887
static void
 
888
mouse_settings_device_set_enabled (GtkToggleButton *button,
 
889
                                   GtkBuilder      *builder)
 
890
{
 
891
    gchar    *name = NULL;
 
892
    gchar    *prop;
 
893
    gboolean  enabled;
 
894
    GObject  *object;
 
895
 
 
896
    enabled = gtk_toggle_button_get_active (button);
 
897
    object = gtk_builder_get_object (builder, "device-notebook");
 
898
    gtk_widget_set_sensitive (GTK_WIDGET (object), enabled);
 
899
 
 
900
    if (locked > 0)
 
901
        return;
 
902
 
 
903
    if (mouse_settings_device_get_selected (builder, NULL, &name))
 
904
    {
 
905
        prop = g_strconcat ("/", name, "/Properties/Device_Enabled", NULL);
 
906
        xfconf_channel_set_int (pointers_channel, prop, enabled);
 
907
        g_free (prop);
 
908
    }
 
909
 
 
910
    g_free (name);
 
911
}
 
912
 
 
913
 
 
914
 
 
915
static void
 
916
mouse_settings_device_selection_changed (GtkBuilder *builder)
 
917
{
 
918
    gint               nbuttons = 0;
 
919
    Display           *xdisplay = GDK_DISPLAY ();
574
920
    XDevice           *device;
 
921
    XDeviceInfo       *device_info;
575
922
    XFeedbackState    *states, *pt;
 
923
    XAnyClassPtr       any;
576
924
    gint               nstates;
577
925
    XPtrFeedbackState *state;
578
 
    gint               i;
 
926
    gint               i, n;
579
927
    guchar            *buttonmap;
580
928
    gint               id_1 = 0, id_3 = 0;
581
929
    gint               id_4 = 0, id_5 = 0;
582
930
    gdouble            acceleration = -1.00;
583
931
    gint               threshold = -1;
584
932
    GObject           *object;
585
 
    GtkTreeModel      *model;
586
 
    GtkTreeIter        iter;
587
 
    gboolean           has_selection;
588
 
    XID                xid;
 
933
    gint               ndevices;
 
934
    Atom               synaptics_prop;
 
935
    Atom               wacom_prop;
 
936
    Atom               synaptics_tap_prop;
 
937
    Atom               synaptics_edge_scroll_prop;
 
938
    Atom               synaptics_two_scroll_prop;
 
939
    Atom               device_enabled_prop;
 
940
    Atom               wacom_rotation_prop;
 
941
    gint               is_enabled = -1;
 
942
    gboolean           is_synaptics = FALSE;
 
943
    gboolean           is_wacom = FALSE;
 
944
    gint               synaptics_tap_to_click = -1;
 
945
    gint               synaptics_edge_scroll = -1;
 
946
    gint               synaptics_edge_hscroll = -1;
 
947
    gint               synaptics_two_scroll = -1;
 
948
    gint               synaptics_two_hscroll = -1;
 
949
    gint               wacom_rotation = -1;
 
950
    Atom              *props;
 
951
    gint               nprops;
 
952
    gint               wacom_mode = -1;
589
953
 
590
954
    /* lock the dialog */
591
955
    locked++;
592
956
 
593
 
    /* flush x and trap errors */
594
 
    gdk_flush ();
595
 
    gdk_error_trap_push ();
596
 
 
597
957
    /* get the selected item */
598
 
    has_selection = gtk_tree_selection_get_selected (selection, &model, &iter);
599
 
    if (G_LIKELY (has_selection))
 
958
    if (mouse_settings_device_get_selected (builder, &device, NULL))
600
959
    {
601
 
        /* get device id and number of buttons */
602
 
        gtk_tree_model_get (model, &iter, COLUMN_DEVICE_XID, &xid,
603
 
                            COLUMN_DEVICE_NBUTTONS, &nbuttons, -1);
604
 
 
605
 
        /* get the x display */
606
 
        xdisplay = gdk_x11_display_get_xdisplay (display);
607
 
 
608
 
        /* open the device */
609
 
        device = XOpenDevice (xdisplay, xid);
610
 
 
611
 
        if (G_LIKELY (device))
612
 
        {
613
 
            /* allocate button map */
 
960
        gdk_error_trap_push ();
 
961
        device_info = XListInputDevices (xdisplay, &ndevices);
 
962
        if (gdk_error_trap_pop () == 0 && device_info != NULL)
 
963
        {
 
964
            /* find mode and number of buttons */
 
965
            for (i = 0; i < ndevices; i++)
 
966
            {
 
967
                if (device_info[i].id != device->device_id)
 
968
                    continue;
 
969
 
 
970
                any = device_info[i].inputclassinfo;
 
971
                for (n = 0; n < device_info[i].num_classes; n++)
 
972
                {
 
973
                    if (any->class == ButtonClass)
 
974
                        nbuttons = ((XButtonInfoPtr) any)->num_buttons;
 
975
                    else if (any->class == ValuatorClass)
 
976
                        wacom_mode = ((XValuatorInfoPtr) any)->mode == Absolute ? 0 : 1;
 
977
 
 
978
                    any = (XAnyClassPtr) ((gchar *) any + any->length);
 
979
                }
 
980
 
 
981
                break;
 
982
            }
 
983
 
 
984
            XFreeDeviceList (device_info);
 
985
        }
 
986
 
 
987
        /* get the button mapping */
 
988
        if (nbuttons > 0)
 
989
        {
614
990
            buttonmap = g_new0 (guchar, nbuttons);
615
 
 
616
 
            /* get the button mapping */
 
991
            gdk_error_trap_push ();
617
992
            XGetDeviceButtonMapping (xdisplay, device, buttonmap, nbuttons);
 
993
            if (gdk_error_trap_pop () != 0)
 
994
                g_critical ("Failed to get button map");
618
995
 
619
996
            /* figure out the position of the first and second/third button in the map */
620
997
            for (i = 0; i < nbuttons; i++)
629
1006
                    id_5 = i;
630
1007
            }
631
1008
 
632
 
            /* cleanup */
633
1009
            g_free (buttonmap);
 
1010
        }
 
1011
        else
 
1012
        {
 
1013
            g_critical ("Device has no buttons");
 
1014
        }
634
1015
 
635
 
            /* get the feedback states for this device */
636
 
            states = XGetFeedbackControl (xdisplay, device, &nstates);
637
 
            if (states != NULL)
 
1016
        /* get the feedback states for this device */
 
1017
        gdk_error_trap_push ();
 
1018
        states = XGetFeedbackControl (xdisplay, device, &nstates);
 
1019
        if (gdk_error_trap_pop () != 0 || states == NULL)
 
1020
        {
 
1021
             g_critical ("Failed to get feedback states");
 
1022
        }
 
1023
        else
 
1024
        {
 
1025
            /* get the pointer feedback class */
 
1026
            for (pt = states, i = 0; i < nstates; i++)
638
1027
            {
639
 
                /* get the pointer feedback class */
640
 
                for (pt = states, i = 0; i < nstates; i++)
 
1028
                if (pt->class == PtrFeedbackClass)
641
1029
                {
642
 
                    if (pt->class == PtrFeedbackClass)
643
 
                    {
644
 
                        /* get the state */
645
 
                        state = (XPtrFeedbackState *) pt;
646
 
                        acceleration = (gdouble) state->accelNum / (gdouble) state->accelDenom;
647
 
                        threshold = state->threshold;
648
 
 
649
 
                        /* done */
650
 
                        break;
651
 
                    }
652
 
 
653
 
                    /* advance the offset */
654
 
                    pt = (XFeedbackState *) ((gchar *) pt + pt->length);
 
1030
                    /* get the state */
 
1031
                    state = (XPtrFeedbackState *) pt;
 
1032
                    acceleration = (gdouble) state->accelNum / (gdouble) state->accelDenom;
 
1033
                    threshold = state->threshold;
655
1034
                }
656
1035
 
657
 
                XFreeFeedbackList (states);
658
 
            }
659
 
 
660
 
            /* close the device */
661
 
            XCloseDevice (xdisplay, device);
662
 
        }
 
1036
                /* advance the offset */
 
1037
                pt = (XFeedbackState *) ((gchar *) pt + pt->length);
 
1038
            }
 
1039
 
 
1040
            XFreeFeedbackList (states);
 
1041
        }
 
1042
 
 
1043
        /* wacom and synaptics specific properties */
 
1044
        device_enabled_prop = XInternAtom (xdisplay, "Device Enabled", True);
 
1045
        synaptics_prop = XInternAtom (xdisplay, "Synaptics Off", True);
 
1046
        wacom_prop = XInternAtom (xdisplay, "Wacom Tool Type", True);
 
1047
        synaptics_tap_prop = XInternAtom (xdisplay, "Synaptics Tap Action", True);
 
1048
        synaptics_edge_scroll_prop = XInternAtom (xdisplay, "Synaptics Edge Scrolling", True);
 
1049
        synaptics_two_scroll_prop = XInternAtom (xdisplay, "Synaptics Two-Finger Scrolling", True);
 
1050
        wacom_rotation_prop = XInternAtom (xdisplay, "Wacom Rotation", True);
 
1051
 
 
1052
        /* check if this is a synaptics or wacom device */
 
1053
        gdk_error_trap_push ();
 
1054
        props = XListDeviceProperties (xdisplay, device, &nprops);
 
1055
        if (gdk_error_trap_pop () == 0 && props != NULL)
 
1056
        {
 
1057
            for (i = 0; i < nprops; i++)
 
1058
            {
 
1059
                if (props[i] == device_enabled_prop)
 
1060
                    is_enabled = mouse_settings_device_get_int_property (device, props[i], 0, NULL);
 
1061
                else if (props[i] == synaptics_prop)
 
1062
                    is_synaptics = TRUE;
 
1063
                else if (props[i] == wacom_prop)
 
1064
                    is_wacom = TRUE;
 
1065
                else if (props[i] == synaptics_tap_prop)
 
1066
                    synaptics_tap_to_click = mouse_settings_device_get_int_property (device, props[i], 4, NULL);
 
1067
                else if (props[i] == synaptics_edge_scroll_prop)
 
1068
                    synaptics_edge_scroll = mouse_settings_device_get_int_property (device, props[i], 0, &synaptics_edge_hscroll);
 
1069
                else if (props[i] == synaptics_two_scroll_prop)
 
1070
                    synaptics_two_scroll = mouse_settings_device_get_int_property (device, props[i], 0, &synaptics_two_hscroll);
 
1071
                else if (props[i] == wacom_rotation_prop)
 
1072
                    wacom_rotation = mouse_settings_device_get_int_property (device, props[i], 0, NULL);
 
1073
            }
 
1074
 
 
1075
            XFree (props);
 
1076
        }
 
1077
 
 
1078
        /* close the device */
 
1079
        XCloseDevice (xdisplay, device);
663
1080
    }
664
1081
 
665
1082
    /* update button order */
666
 
    object = gtk_builder_get_object (builder, id_1 > id_3 ? "mouse-left-handed" : "mouse-right-handed");
 
1083
    object = gtk_builder_get_object (builder, id_1 > id_3 ? "device-left-handed" : "device-right-handed");
667
1084
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (object), TRUE);
668
1085
 
669
 
    object = gtk_builder_get_object (builder, "mouse-reverse-scrolling");
 
1086
    object = gtk_builder_get_object (builder, "device-reverse-scrolling");
670
1087
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (object), !!(id_5 < id_4));
671
1088
    gtk_widget_set_sensitive (GTK_WIDGET (object), nbuttons >= 5);
672
1089
 
673
1090
    /* update acceleration scale */
674
 
    object = gtk_builder_get_object (builder, "mouse-acceleration-scale");
 
1091
    object = gtk_builder_get_object (builder, "device-acceleration-scale");
675
1092
    gtk_range_set_value (GTK_RANGE (object), acceleration);
676
1093
    gtk_widget_set_sensitive (GTK_WIDGET (object), acceleration != -1);
677
1094
 
678
1095
    /* update threshold scale */
679
 
    object = gtk_builder_get_object (builder, "mouse-threshold-scale");
 
1096
    object = gtk_builder_get_object (builder, "device-threshold-scale");
680
1097
    gtk_range_set_value (GTK_RANGE (object), threshold);
681
1098
    gtk_widget_set_sensitive (GTK_WIDGET (object), threshold != -1);
682
1099
 
683
 
    /* flush and remove the x error trap */
684
 
    gdk_flush ();
685
 
    gdk_error_trap_pop ();
 
1100
    object = gtk_builder_get_object (builder, "device-enabled");
 
1101
    gtk_widget_set_sensitive (GTK_WIDGET (object), is_enabled != -1);
 
1102
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (object), is_enabled > 0);
 
1103
 
 
1104
    object = gtk_builder_get_object (builder, "device-notebook");
 
1105
    gtk_widget_set_sensitive (GTK_WIDGET (object), is_enabled == 1);
 
1106
 
 
1107
    /* synaptics options */
 
1108
    object = gtk_builder_get_object (builder, "synaptics-tab");
 
1109
    gtk_widget_set_visible (GTK_WIDGET (object), is_synaptics);
 
1110
 
 
1111
    if (is_synaptics)
 
1112
    {
 
1113
        object = gtk_builder_get_object (builder, "synaptics-tap-to-click");
 
1114
        gtk_widget_set_sensitive (GTK_WIDGET (object), synaptics_tap_to_click != -1);
 
1115
        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (object), synaptics_tap_to_click > 0);
 
1116
 
 
1117
        object = gtk_builder_get_object (builder, "synaptics-scroll-no");
 
1118
        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (object), synaptics_edge_scroll == -1 && synaptics_two_scroll == -1);
 
1119
 
 
1120
        object = gtk_builder_get_object (builder, "synaptics-scroll-edge");
 
1121
        gtk_widget_set_sensitive (GTK_WIDGET (object), synaptics_edge_scroll != -1);
 
1122
        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (object), synaptics_edge_scroll > 0);
 
1123
 
 
1124
        object = gtk_builder_get_object (builder, "synaptics-scroll-two");
 
1125
        gtk_widget_set_sensitive (GTK_WIDGET (object), synaptics_two_scroll != -1);
 
1126
        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (object), synaptics_two_scroll > 0);
 
1127
 
 
1128
        object = gtk_builder_get_object (builder, "synaptics-scroll-horiz");
 
1129
        mouse_settings_synaptics_hscroll_sensitive (builder);
 
1130
        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (object),
 
1131
                                      synaptics_edge_hscroll == 1 || synaptics_two_hscroll == 1);
 
1132
    }
 
1133
 
 
1134
    /* wacom options */
 
1135
    object = gtk_builder_get_object (builder, "wacom-tab");
 
1136
    gtk_widget_set_visible (GTK_WIDGET (object), is_wacom);
 
1137
 
 
1138
    if (is_wacom)
 
1139
    {
 
1140
        object = gtk_builder_get_object (builder, "wacom-mode");
 
1141
        gtk_widget_set_sensitive (GTK_WIDGET (object), wacom_mode != -1);
 
1142
        gtk_combo_box_set_active (GTK_COMBO_BOX (object), wacom_mode == -1 ? 1 : wacom_mode);
 
1143
 
 
1144
        object = gtk_builder_get_object (builder, "wacom-rotation");
 
1145
        gtk_widget_set_sensitive (GTK_WIDGET (object), wacom_rotation != -1);
 
1146
        /* 3 (half) comes afer none */
 
1147
        if (wacom_rotation == 3)
 
1148
            wacom_rotation = 1;
 
1149
        else if (wacom_rotation > 0)
 
1150
            wacom_rotation++;
 
1151
        else if (wacom_rotation == -1)
 
1152
            wacom_rotation = 0;
 
1153
        gtk_combo_box_set_active (GTK_COMBO_BOX (object), wacom_rotation);
 
1154
    }
686
1155
 
687
1156
    /* unlock */
688
1157
    locked--;
693
1162
static void
694
1163
mouse_settings_device_save (GtkBuilder *builder)
695
1164
{
696
 
    GObject          *treeview;
697
 
    GtkTreeSelection *selection;
 
1165
    GObject          *combobox;
698
1166
    GtkTreeModel     *model;
699
1167
    GtkTreeIter       iter;
700
 
    gboolean          has_selection;
701
1168
    gchar            *name;
702
1169
    GObject          *object;
703
1170
    gchar             property_name[512];
710
1177
    if (locked > 0)
711
1178
        return;
712
1179
 
713
 
    /* get the treeview */
714
 
    treeview = gtk_builder_get_object (builder, "mouse-devices-treeview");
715
 
 
716
 
    /* get the selection */
717
 
    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
718
 
 
719
 
    has_selection = gtk_tree_selection_get_selected (selection, &model, &iter);
720
 
    if (G_LIKELY (has_selection))
 
1180
    combobox = gtk_builder_get_object (builder, "device-combobox");
 
1181
    if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combobox), &iter))
721
1182
    {
722
1183
        /* get device id and number of buttons */
723
 
        gtk_tree_model_get (model, &iter, COLUMN_DEVICE_NAME, &name, -1);
 
1184
        model = gtk_combo_box_get_model (GTK_COMBO_BOX (combobox));
 
1185
        gtk_tree_model_get (model, &iter, COLUMN_DEVICE_XFCONF_NAME, &name, -1);
724
1186
 
725
1187
        if (G_LIKELY (name))
726
1188
        {
727
1189
            /* store the button order */
728
 
            object = gtk_builder_get_object (builder, "mouse-right-handed");
 
1190
            object = gtk_builder_get_object (builder, "device-right-handed");
729
1191
            g_snprintf (property_name, sizeof (property_name), "/%s/RightHanded", name);
730
1192
            righthanded = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (object));
731
1193
            if (!xfconf_channel_has_property (pointers_channel, property_name)
733
1195
                xfconf_channel_set_bool (pointers_channel, property_name, righthanded);
734
1196
 
735
1197
            /* store reverse scrolling */
736
 
            object = gtk_builder_get_object (builder, "mouse-reverse-scrolling");
 
1198
            object = gtk_builder_get_object (builder, "device-reverse-scrolling");
737
1199
            g_snprintf (property_name, sizeof (property_name), "/%s/ReverseScrolling", name);
738
1200
            reverse_scrolling = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (object));
739
1201
            if (xfconf_channel_get_bool (pointers_channel, property_name, FALSE) != reverse_scrolling)
740
1202
                xfconf_channel_set_bool (pointers_channel, property_name, reverse_scrolling);
741
1203
 
742
1204
            /* store the threshold */
743
 
            object = gtk_builder_get_object (builder, "mouse-threshold-scale");
 
1205
            object = gtk_builder_get_object (builder, "device-threshold-scale");
744
1206
            g_snprintf (property_name, sizeof (property_name), "/%s/Threshold", name);
745
1207
            threshold = gtk_range_get_value (GTK_RANGE (object));
746
1208
            if (xfconf_channel_get_int (pointers_channel, property_name, -1) != threshold)
747
1209
                xfconf_channel_set_int (pointers_channel, property_name, threshold);
748
1210
 
749
1211
            /* store the acceleration */
750
 
            object = gtk_builder_get_object (builder, "mouse-acceleration-scale");
 
1212
            object = gtk_builder_get_object (builder, "device-acceleration-scale");
751
1213
            g_snprintf (property_name, sizeof (property_name), "/%s/Acceleration", name);
752
1214
            acceleration = gtk_range_get_value (GTK_RANGE (object));
753
1215
            if (xfconf_channel_get_double (pointers_channel, property_name, -1) != acceleration)
761
1223
 
762
1224
 
763
1225
 
764
 
static void
765
 
mouse_settings_device_name_edited (GtkCellRendererText *renderer,
766
 
                                   gchar               *path,
767
 
                                   gchar               *new_name,
768
 
                                   GtkBuilder          *builder)
769
 
{
770
 
    GObject          *treeview;
771
 
    GtkTreeSelection *selection;
772
 
    gboolean          has_selection;
773
 
    GtkTreeModel     *model;
774
 
    GtkTreeIter       iter;
775
 
    gchar            *internal_name;
776
 
    gchar            *property_name;
777
 
    gchar            *new_name_escaped;
778
 
 
779
 
    /* check if the new name is valid */
780
 
    if (new_name == NULL || *new_name == '\0')
781
 
        return;
782
 
 
783
 
    /* get the treeview's selection */
784
 
    treeview = gtk_builder_get_object (builder, "mouse-devices-treeview");
785
 
    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
786
 
 
787
 
    /* get the selected item */
788
 
    has_selection = gtk_tree_selection_get_selected (selection, &model, &iter);
789
 
    if (G_LIKELY (has_selection))
790
 
    {
791
 
        /* get the internal device name */
792
 
        gtk_tree_model_get (model, &iter, COLUMN_DEVICE_NAME, &internal_name, -1);
793
 
 
794
 
        /* store the new name in the channel */
795
 
        property_name = g_strdup_printf ("/%s", internal_name);
796
 
        xfconf_channel_set_string (pointers_channel, property_name, new_name);
797
 
 
798
 
        /* escape before adding in the store */
799
 
        new_name_escaped = g_markup_escape_text (new_name, -1);
800
 
 
801
 
        /* set the new device name in the store */
802
 
        gtk_list_store_set (GTK_LIST_STORE (model), &iter, COLUMN_DEVICE_DISPLAY_NAME, new_name_escaped, -1);
803
 
 
804
 
        /* cleanup */
805
 
        g_free (new_name_escaped);
806
 
        g_free (property_name);
807
 
        g_free (internal_name);
808
 
    }
809
 
}
810
 
 
811
 
 
812
 
 
813
1226
static gchar *
814
1227
mouse_settings_device_xfconf_name (const gchar *name)
815
1228
{
844
1257
mouse_settings_device_populate_store (GtkBuilder *builder,
845
1258
                                      gboolean    create_store)
846
1259
{
847
 
    Display           *xdisplay;
848
 
    XDeviceInfo       *device_list, *device_info;
849
 
    gchar             *display_name, *usb;
850
 
    gshort             num_buttons;
851
 
    gint               ndevices;
852
 
    gint               i, m;
853
 
    XAnyClassPtr       ptr;
854
 
    GtkTreeIter        iter;
855
 
    GtkListStore      *store;
856
 
    GObject           *treeview;
857
 
    GtkTreePath       *path = NULL;
858
 
    GtkTreeViewColumn *column;
859
 
    GtkCellRenderer   *renderer;
860
 
    GtkTreeSelection  *selection;
861
 
    gchar             *device_name;
862
 
    gchar             *property_name;
863
 
    gchar             *property_value;
 
1260
    XDeviceInfo     *device_list, *device_info;
 
1261
    gint             ndevices;
 
1262
    gint             i;
 
1263
    GtkTreeIter      iter;
 
1264
    GtkListStore    *store;
 
1265
    GObject         *combobox;
 
1266
    GtkCellRenderer *renderer;
 
1267
    gchar           *xfconf_name;
 
1268
    gboolean         has_active_item = FALSE;
864
1269
 
865
1270
    /* lock */
866
1271
    locked++;
867
1272
 
868
 
    /* flush x and trap errors */
869
 
    gdk_flush ();
870
 
    gdk_error_trap_push ();
871
 
 
872
 
    /* get the treeview */
873
 
    treeview = gtk_builder_get_object (builder, "mouse-devices-treeview");
 
1273
    combobox = gtk_builder_get_object (builder, "device-combobox");
874
1274
 
875
1275
    /* create or get the store */
876
1276
    if (G_LIKELY (create_store))
877
1277
    {
878
 
        store = gtk_list_store_new (N_DEVICE_COLUMNS, G_TYPE_STRING, G_TYPE_STRING,
879
 
                                    G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT);
 
1278
        store = gtk_list_store_new (N_DEVICE_COLUMNS,
 
1279
                                    G_TYPE_STRING /* COLUMN_DEVICE_NAME */,
 
1280
                                    G_TYPE_STRING /* COLUMN_DEVICE_XFCONF_NAME */,
 
1281
                                    G_TYPE_ULONG /* COLUMN_DEVICE_XID */);
 
1282
        gtk_combo_box_set_model (GTK_COMBO_BOX (combobox), GTK_TREE_MODEL (store));
 
1283
 
 
1284
        /* text renderer */
 
1285
        renderer = gtk_cell_renderer_text_new ();
 
1286
        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox), renderer, TRUE);
 
1287
        gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer,
 
1288
                                        "text", COLUMN_DEVICE_NAME, NULL);
 
1289
 
 
1290
        g_signal_connect_swapped (G_OBJECT (combobox), "changed",
 
1291
            G_CALLBACK (mouse_settings_device_selection_changed), builder);
880
1292
    }
881
1293
    else
882
1294
    {
883
 
        store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)));
 
1295
        store = GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (combobox)));
884
1296
        gtk_list_store_clear (store);
885
1297
    }
886
1298
 
887
 
    /* get the x display */
888
 
    xdisplay = gdk_x11_display_get_xdisplay (display);
889
 
 
890
1299
    /* get all the registered devices */
891
 
    device_list = XListInputDevices (xdisplay, &ndevices);
 
1300
    gdk_error_trap_push ();
 
1301
    device_list = XListInputDevices (GDK_DISPLAY (), &ndevices);
 
1302
    if (gdk_error_trap_pop () != 0 || device_list == NULL)
 
1303
    {
 
1304
        g_message ("No devices found");
 
1305
        goto bailout;
 
1306
    }
892
1307
 
893
1308
    for (i = 0; i < ndevices; i++)
894
1309
    {
895
1310
        /* get the device */
896
1311
        device_info = &device_list[i];
897
1312
 
898
 
        /* filter out the pointer devices */
899
 
        if (device_info->use == IsXExtensionPointer)
 
1313
        /* filter out the pointer and virtual devices */
 
1314
        if (device_info->use != IsXExtensionPointer
 
1315
            || g_str_has_prefix (device_info->name, "Virtual core XTEST"))
 
1316
            continue;
 
1317
 
 
1318
        /* create a valid xfconf device name */
 
1319
        xfconf_name = mouse_settings_device_xfconf_name (device_info->name);
 
1320
 
 
1321
        /* insert in the store */
 
1322
        gtk_list_store_insert_with_values (store, &iter, i,
 
1323
                                           COLUMN_DEVICE_XFCONF_NAME, xfconf_name,
 
1324
                                           COLUMN_DEVICE_NAME, device_info->name,
 
1325
                                           COLUMN_DEVICE_XID, device_info->id,
 
1326
                                           -1);
 
1327
 
 
1328
        /* check if we should select this device */
 
1329
        if (device_info->name != NULL
 
1330
            && opt_device_name != NULL
 
1331
            && strcmp (opt_device_name, device_info->name) == 0)
900
1332
        {
901
 
            /* get the device classes */
902
 
            ptr = device_info->inputclassinfo;
903
 
 
904
 
            /* walk all the classes */
905
 
            for (m = 0, num_buttons = 0; m < device_info->num_classes; m++)
906
 
            {
907
 
                /* find the button class */
908
 
                if (ptr->class == ButtonClass)
909
 
                {
910
 
                    /* get the number of buttons */
911
 
                    num_buttons = ((XButtonInfoPtr) ptr)->num_buttons;
912
 
 
913
 
                    /* done */
914
 
                    break;
915
 
                }
916
 
 
917
 
                /* advance the offset */
918
 
                ptr = (XAnyClassPtr) ((gchar *) ptr + ptr->length);
919
 
            }
920
 
 
921
 
            /* only append devices with buttons */
922
 
            if (G_UNLIKELY (num_buttons <= 0))
923
 
                continue;
924
 
 
925
 
            /* ignore XTEST device */
926
 
            if (g_str_has_prefix (device_info->name, "Virtual core XTEST"))
927
 
                continue;
928
 
 
929
 
            /* create a valid xfconf device name */
930
 
            device_name = mouse_settings_device_xfconf_name (device_info->name);
931
 
 
932
 
            /* check if there is a custom name set by the user */
933
 
            property_name = g_strdup_printf ("/%s", device_name);
934
 
            if (xfconf_channel_has_property (pointers_channel, property_name))
935
 
            {
936
 
                /* get the name from the config file, escape it */
937
 
                property_value = xfconf_channel_get_string (pointers_channel, property_name, NULL);
938
 
                display_name = g_markup_escape_text (property_value, -1);
939
 
                g_free (property_value);
940
 
            }
941
 
            else
942
 
            {
943
 
                /* get the device name, escaped */
944
 
                display_name = g_markup_escape_text (device_info->name, -1);
945
 
 
946
 
                /* get rid of usb crap in the name */
947
 
                if ((usb = strstr (display_name, "-usb")) != NULL)
948
 
                    *usb = '\0';
949
 
            }
950
 
 
951
 
            /* insert in the store */
952
 
            gtk_list_store_insert_with_values (store, &iter, i,
953
 
                                               COLUMN_DEVICE_ICON, "input-mouse",
954
 
                                               COLUMN_DEVICE_NAME, device_name,
955
 
                                               COLUMN_DEVICE_DISPLAY_NAME, display_name,
956
 
                                               COLUMN_DEVICE_XID, device_info->id,
957
 
                                               COLUMN_DEVICE_NBUTTONS, num_buttons, -1);
958
 
 
959
 
            /* check if we should select this device (for user convience also the display name) */
960
 
            if (opt_device_name && (strcmp (opt_device_name, device_info->name) == 0
961
 
                || (display_name && strcmp (opt_device_name, display_name) == 0)))
962
 
            {
963
 
                path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
964
 
                g_free (opt_device_name);
965
 
                opt_device_name = NULL;
966
 
            }
967
 
 
968
 
            /* cleanup */
969
 
            g_free (property_name);
970
 
            g_free (device_name);
971
 
            g_free (display_name);
 
1333
            gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combobox), &iter);
 
1334
            g_free (opt_device_name);
 
1335
            opt_device_name = NULL;
 
1336
            has_active_item = TRUE;
972
1337
        }
 
1338
 
 
1339
        g_free (xfconf_name);
 
1340
 
973
1341
    }
974
1342
 
975
 
    /* cleanup */
976
1343
    XFreeDeviceList (device_list);
977
1344
 
978
 
    /* flush and remove the x error trap */
979
 
    gdk_flush ();
980
 
    gdk_error_trap_pop ();
981
 
 
982
 
    /* get the selection */
983
 
    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
984
 
 
985
 
    if (G_LIKELY (create_store))
986
 
    {
987
 
        /* set the treeview model */
988
 
        gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (store));
989
 
        gtk_tree_view_set_tooltip_column (GTK_TREE_VIEW (treeview), COLUMN_DEVICE_DISPLAY_NAME);
990
 
 
991
 
        /* icon renderer */
992
 
        renderer = gtk_cell_renderer_pixbuf_new ();
993
 
        column = gtk_tree_view_column_new_with_attributes ("", renderer, "icon-name", COLUMN_DEVICE_ICON, NULL);
994
 
        g_object_set (G_OBJECT (renderer), "stock-size", GTK_ICON_SIZE_DND, NULL);
995
 
        gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
996
 
 
997
 
        /* text renderer */
998
 
        renderer = gtk_cell_renderer_text_new ();
999
 
        column = gtk_tree_view_column_new_with_attributes ("", renderer, "markup", COLUMN_DEVICE_DISPLAY_NAME, NULL);
1000
 
        g_object_set (G_OBJECT (renderer), "ellipsize", PANGO_ELLIPSIZE_END, "editable", TRUE, NULL);
1001
 
        g_signal_connect (G_OBJECT (renderer), "edited", G_CALLBACK (mouse_settings_device_name_edited), builder);
1002
 
        gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
1003
 
 
1004
 
        /* setup tree selection */
1005
 
        gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
1006
 
        g_signal_connect (G_OBJECT (selection), "changed", G_CALLBACK (mouse_settings_device_selection_changed), builder);
1007
 
    }
1008
 
 
1009
 
    /* select the mouse in the tree */
1010
 
    if (G_LIKELY (path == NULL))
1011
 
        path = gtk_tree_path_new_first ();
1012
 
    gtk_tree_selection_select_path (selection, path);
1013
 
    gtk_tree_path_free (path);
1014
 
 
1015
 
    /* sort after selecting the path */
1016
 
    if (G_LIKELY (create_store))
1017
 
    {
1018
 
        gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), COLUMN_DEVICE_XID, GTK_SORT_ASCENDING);
1019
 
        g_object_unref (G_OBJECT (store));
1020
 
    }
 
1345
    if (!has_active_item)
 
1346
        gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), 0);
 
1347
 
 
1348
    bailout:
1021
1349
 
1022
1350
    /* unlock */
1023
1351
    locked--;
1029
1357
mouse_settings_device_update_sliders (gpointer user_data)
1030
1358
{
1031
1359
    GtkBuilder *builder = GTK_BUILDER (user_data);
1032
 
    GObject    *treeview, *button;
 
1360
    GObject    *button;
1033
1361
 
1034
1362
    GDK_THREADS_ENTER ();
1035
1363
 
1036
 
    /* get the treeview */
1037
 
    treeview = gtk_builder_get_object (builder, "mouse-devices-treeview");
1038
 
 
1039
1364
    /* update */
1040
 
    mouse_settings_device_selection_changed (gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)), builder);
 
1365
    mouse_settings_device_selection_changed (builder);
1041
1366
 
1042
1367
    /* make the button sensitive again */
1043
 
    button = gtk_builder_get_object (builder, "mouse-reset");
 
1368
    button = gtk_builder_get_object (builder, "device-reset-feedback");
1044
1369
    gtk_widget_set_sensitive (GTK_WIDGET (button), TRUE);
1045
1370
 
1046
1371
    GDK_THREADS_LEAVE ();
1063
1388
mouse_settings_device_reset (GtkWidget  *button,
1064
1389
                             GtkBuilder *builder)
1065
1390
{
1066
 
    GObject          *treeview;
1067
 
    GtkTreeSelection *selection;
1068
 
    gchar            *name, *property_name;
1069
 
    gboolean          has_selection;
1070
 
    GtkTreeModel     *model;
1071
 
    GtkTreeIter       iter;
 
1391
    gchar        *name, *property_name;
 
1392
    GtkTreeModel *model;
 
1393
    GtkTreeIter   iter;
 
1394
    GObject      *combobox;
1072
1395
 
1073
1396
    /* leave when locked */
1074
1397
    if (locked > 0)
1075
1398
        return;
1076
1399
 
1077
 
    /* get the treeview */
1078
 
    treeview = gtk_builder_get_object (builder, "mouse-devices-treeview");
1079
 
 
1080
 
    /* get the selection */
1081
 
    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
1082
 
 
1083
 
    has_selection = gtk_tree_selection_get_selected (selection, &model, &iter);
1084
 
    if (G_LIKELY (has_selection))
 
1400
    /* get the selected item */
 
1401
    combobox = gtk_builder_get_object (builder, "device-combobox");
 
1402
    if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combobox), &iter))
1085
1403
    {
1086
1404
        /* get device id and number of buttons */
1087
 
        gtk_tree_model_get (model, &iter, COLUMN_DEVICE_NAME, &name, -1);
 
1405
        model = gtk_combo_box_get_model (GTK_COMBO_BOX (combobox));
 
1406
        gtk_tree_model_get (model, &iter, COLUMN_DEVICE_XFCONF_NAME, &name, -1);
1088
1407
 
1089
 
        if (G_LIKELY (name && timeout_id == 0))
 
1408
        if (G_LIKELY (name != NULL && timeout_id == 0))
1090
1409
        {
1091
1410
            /* make the button insensitive */
1092
1411
            gtk_widget_set_sensitive (button, FALSE);
1136
1455
static void
1137
1456
mouse_settings_create_event_filter (GtkBuilder *builder)
1138
1457
{
1139
 
    Display     *xdisplay;
 
1458
    Display     *xdisplay = GDK_DISPLAY ();
1140
1459
    XEventClass  event_class;
1141
1460
 
1142
 
    /* flush x and trap errors */
1143
 
    gdk_flush ();
1144
 
    gdk_error_trap_push ();
1145
 
 
1146
 
    /* get the default display and root window */
1147
 
    xdisplay = gdk_x11_display_get_xdisplay (display);
1148
 
    if (G_UNLIKELY (!xdisplay))
1149
 
        return;
1150
 
 
1151
1461
    /* monitor device change events */
 
1462
    gdk_error_trap_push ();
1152
1463
    DevicePresence (xdisplay, device_presence_event_type, event_class);
1153
1464
    XSelectExtensionEvent (xdisplay, RootWindow (xdisplay, DefaultScreen (xdisplay)), &event_class, 1);
1154
 
 
1155
 
    /* flush and remove the x error trap */
1156
 
    gdk_flush ();
1157
 
    gdk_error_trap_pop ();
 
1465
    if (gdk_error_trap_pop () != 0)
 
1466
    {
 
1467
        g_critical ("Failed to setup the device event filter");
 
1468
        return;
 
1469
    }
1158
1470
 
1159
1471
    /* add an event filter */
1160
1472
    gdk_window_add_filter (NULL, mouse_settings_event_filter, builder);
1173
1485
    GError            *error = NULL;
1174
1486
    GObject           *object;
1175
1487
    XExtensionVersion *version = NULL;
 
1488
    gchar             *syndaemon;
 
1489
    guint              i;
 
1490
    const gchar       *synaptics_scroll[] = { "synaptics-scroll-no", "synaptics-scroll-edge",
 
1491
                                              "synaptics-scroll-two", "synaptics-scroll-horiz" };
1176
1492
 
1177
1493
    /* setup translation domain */
1178
1494
    xfce_textdomain (GETTEXT_PACKAGE, LOCALEDIR, "UTF-8");
1255
1571
            /* lock */
1256
1572
            locked++;
1257
1573
 
1258
 
            /* set the working display for this instance */
1259
 
            display = gdk_display_get_default ();
1260
 
 
1261
 
            /* populate the devices treeview */
 
1574
            /* populate the devices combobox */
1262
1575
            mouse_settings_device_populate_store (builder, TRUE);
1263
1576
 
1264
1577
            /* connect signals */
1265
 
            object = gtk_builder_get_object (builder, "mouse-acceleration-scale");
1266
 
            g_signal_connect_swapped (G_OBJECT (object), "value-changed", G_CALLBACK (mouse_settings_device_save), builder);
1267
 
 
1268
 
            object = gtk_builder_get_object (builder, "mouse-threshold-scale");
1269
 
            g_signal_connect_swapped (G_OBJECT (object), "value-changed", G_CALLBACK (mouse_settings_device_save), builder);
1270
 
 
1271
 
            object = gtk_builder_get_object (builder, "mouse-left-handed");
1272
 
            g_signal_connect_swapped (G_OBJECT (object), "toggled", G_CALLBACK (mouse_settings_device_save), builder);
1273
 
 
1274
 
            object = gtk_builder_get_object (builder, "mouse-right-handed");
1275
 
            g_signal_connect_swapped (G_OBJECT (object), "toggled", G_CALLBACK (mouse_settings_device_save), builder);
1276
 
 
1277
 
            object = gtk_builder_get_object (builder, "mouse-reverse-scrolling");
1278
 
            g_signal_connect_swapped (G_OBJECT (object), "toggled", G_CALLBACK (mouse_settings_device_save), builder);
1279
 
 
1280
 
            object = gtk_builder_get_object (builder, "mouse-reset");
1281
 
            g_signal_connect (G_OBJECT (object), "clicked", G_CALLBACK (mouse_settings_device_reset), builder);
 
1578
            object = gtk_builder_get_object (builder, "device-enabled");
 
1579
            g_signal_connect (G_OBJECT (object), "toggled",
 
1580
                              G_CALLBACK (mouse_settings_device_set_enabled), builder);
 
1581
 
 
1582
            object = gtk_builder_get_object (builder, "device-acceleration-scale");
 
1583
            g_signal_connect_swapped (G_OBJECT (object), "value-changed",
 
1584
                                      G_CALLBACK (mouse_settings_device_save), builder);
 
1585
 
 
1586
            object = gtk_builder_get_object (builder, "device-threshold-scale");
 
1587
            g_signal_connect (G_OBJECT (object), "format-value",
 
1588
                              G_CALLBACK (mouse_settings_format_value_px), NULL);
 
1589
            g_signal_connect_swapped (G_OBJECT (object), "value-changed",
 
1590
                                      G_CALLBACK (mouse_settings_device_save), builder);
 
1591
 
 
1592
            object = gtk_builder_get_object (builder, "device-left-handed");
 
1593
            g_signal_connect_swapped (G_OBJECT (object), "toggled",
 
1594
                                      G_CALLBACK (mouse_settings_device_save), builder);
 
1595
 
 
1596
            object = gtk_builder_get_object (builder, "device-right-handed");
 
1597
            g_signal_connect_swapped (G_OBJECT (object), "toggled",
 
1598
                                      G_CALLBACK (mouse_settings_device_save), builder);
 
1599
 
 
1600
            object = gtk_builder_get_object (builder, "device-reverse-scrolling");
 
1601
            g_signal_connect_swapped (G_OBJECT (object), "toggled",
 
1602
                                      G_CALLBACK (mouse_settings_device_save), builder);
 
1603
 
 
1604
            object = gtk_builder_get_object (builder, "device-reset-feedback");
 
1605
            g_signal_connect (G_OBJECT (object), "clicked",
 
1606
                              G_CALLBACK (mouse_settings_device_reset), builder);
 
1607
 
 
1608
            object = gtk_builder_get_object (builder, "synaptics-disable-while-type");
 
1609
            syndaemon = g_find_program_in_path ("syndaemon");
 
1610
            gtk_widget_set_sensitive (GTK_WIDGET (object), syndaemon != NULL);
 
1611
            g_free (syndaemon);
 
1612
            xfconf_g_property_bind (pointers_channel, "/DisableTouchpadWhileTyping",
 
1613
                                    G_TYPE_BOOLEAN, G_OBJECT (object), "active");
 
1614
 
 
1615
            object = gtk_builder_get_object (builder, "synaptics-tap-to-click");
 
1616
            g_signal_connect_swapped (G_OBJECT (object), "toggled",
 
1617
                                      G_CALLBACK (mouse_settings_synaptics_set_tap_to_click), builder);
 
1618
 
 
1619
            for (i = 0; i < G_N_ELEMENTS (synaptics_scroll); i++)
 
1620
            {
 
1621
                object = gtk_builder_get_object (builder, synaptics_scroll[i]);
 
1622
                g_signal_connect (G_OBJECT (object), "toggled",
 
1623
                                  G_CALLBACK (mouse_settings_synaptics_set_scrolling), builder);
 
1624
            }
 
1625
 
 
1626
            object = gtk_builder_get_object (builder, "wacom-mode");
 
1627
            g_signal_connect (G_OBJECT (object), "changed",
 
1628
                              G_CALLBACK (mouse_settings_wacom_set_mode), builder);
 
1629
 
 
1630
            object = gtk_builder_get_object (builder, "wacom-rotation");
 
1631
            g_signal_connect (G_OBJECT (object), "changed",
 
1632
                              G_CALLBACK (mouse_settings_wacom_set_rotation), builder);
 
1633
 
 
1634
 
1282
1635
 
1283
1636
#ifdef HAVE_XCURSOR
1284
1637
            /* populate the themes treeview */
1285
1638
            mouse_settings_themes_populate_store (builder);
1286
1639
 
1287
1640
            /* connect the cursor size in the cursor tab */
1288
 
            object = gtk_builder_get_object (builder, "mouse-cursor-size");
1289
 
            xfconf_g_property_bind (xsettings_channel, "/Gtk/CursorThemeSize", G_TYPE_INT, G_OBJECT (object), "value");
 
1641
            object = gtk_builder_get_object (builder, "theme-cursor-size");
 
1642
            xfconf_g_property_bind (xsettings_channel, "/Gtk/CursorThemeSize",
 
1643
                                    G_TYPE_INT, G_OBJECT (object), "value");
1290
1644
#else
1291
1645
            /* hide the themes tab */
1292
 
            object = gtk_builder_get_object (builder, "mouse-themes-hbox");
 
1646
            object = gtk_builder_get_object (builder, "themes-hbox");
1293
1647
            gtk_widget_hide (GTK_WIDGET (object));
1294
1648
#endif /* !HAVE_XCURSOR */
1295
1649
 
1296
1650
            /* connect sliders in the gtk tab */
1297
 
            object = gtk_builder_get_object (builder, "mouse-dnd-threshold");
1298
 
            xfconf_g_property_bind (xsettings_channel, "/Net/DndDragThreshold", G_TYPE_INT, G_OBJECT (object), "value");
1299
 
 
1300
 
            object = gtk_builder_get_object (builder, "mouse-double-click-time");
1301
 
            xfconf_g_property_bind (xsettings_channel, "/Net/DoubleClickTime", G_TYPE_INT, G_OBJECT (object), "value");
1302
 
 
1303
 
            object = gtk_builder_get_object (builder, "mouse-double-click-distance");
1304
 
            xfconf_g_property_bind (xsettings_channel, "/Net/DoubleClickDistance", G_TYPE_INT, G_OBJECT (object), "value");
 
1651
            object = gtk_builder_get_object (builder, "dnd-threshold");
 
1652
            xfconf_g_property_bind (xsettings_channel, "/Net/DndDragThreshold",
 
1653
                                    G_TYPE_INT, G_OBJECT (object), "value");\
 
1654
 
 
1655
            object = gtk_builder_get_object (builder, "dnd-threshold-scale");
 
1656
            g_signal_connect (G_OBJECT (object), "format-value",
 
1657
                              G_CALLBACK (mouse_settings_format_value_px), NULL);
 
1658
 
 
1659
            object = gtk_builder_get_object (builder, "dclick-time");
 
1660
            xfconf_g_property_bind (xsettings_channel, "/Net/DoubleClickTime",
 
1661
                                    G_TYPE_INT, G_OBJECT (object), "value");
 
1662
 
 
1663
            object = gtk_builder_get_object (builder, "dclick-time-scale");
 
1664
            g_signal_connect (G_OBJECT (object), "format-value",
 
1665
                              G_CALLBACK (mouse_settings_format_value_ms), NULL);
 
1666
 
 
1667
            object = gtk_builder_get_object (builder, "dclick-distance");
 
1668
            xfconf_g_property_bind (xsettings_channel, "/Net/DoubleClickDistance",
 
1669
                                    G_TYPE_INT, G_OBJECT (object), "value");
 
1670
 
 
1671
            object = gtk_builder_get_object (builder, "dclick-distance-scale");
 
1672
            g_signal_connect (G_OBJECT (object), "format-value",
 
1673
                              G_CALLBACK (mouse_settings_format_value_px), NULL);
1305
1674
 
1306
1675
#ifdef HAS_DEVICE_HOTPLUGGING
1307
1676
            /* create the event filter for device monitoring */