Releasing debian version 0.5.1-3.
[debian/lxappearance.git] / src / cursor-theme.c
1 /*
2 * cursor-theme.c
3 *
4 * Copyright 2010 PCMan <pcman.tw@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 */
21
22 #include "cursor-theme.h"
23 #include "icon-theme.h"
24 #include "lxappearance.h"
25 #include <gdk/gdkx.h>
26
27 static void update_cursor_demo()
28 {
29 GtkListStore* store = gtk_list_store_new(1, GDK_TYPE_PIXBUF);
30 GdkCursor* cursor;
31 GdkCursorType types[] = {
32 GDK_LEFT_PTR,
33 GDK_HAND2,
34 GDK_WATCH,
35 GDK_FLEUR,
36 GDK_XTERM,
37 GDK_LEFT_SIDE,
38 GDK_TOP_LEFT_CORNER,
39 GDK_SB_H_DOUBLE_ARROW};
40 int i, n;
41 for(i = 0; i < G_N_ELEMENTS(types); ++i)
42 {
43 GtkTreeIter it;
44 cursor = gdk_cursor_new(types[i]);
45 GdkPixbuf* pix = gdk_cursor_get_image(cursor);
46 gdk_cursor_unref(cursor);
47 gtk_list_store_insert_with_values(store, &it, -1, 0, pix, -1);
48 g_object_unref(pix);
49 }
50 gtk_icon_view_set_model(GTK_ICON_VIEW(app.cursor_demo_view), GTK_TREE_MODEL(store));
51 g_object_unref(store);
52
53 /* gtk+ programs should reload named cursors correctly.
54 * However, if the cursor is inherited from the root window,
55 * gtk+ won't change it. So we need to update the cursor of root window.
56 * Unfortunately, this doesn't work for non-gtk+ programs.
57 * KDE programs seem to require special handling with XFixes */
58 cursor = gdk_cursor_new(GDK_LEFT_PTR);
59 i = gdk_display_get_n_screens(gdk_display_get_default());
60 while(--i >= 0)
61 {
62 GdkScreen* screen = gdk_display_get_screen(gdk_display_get_default(), i);
63 gdk_window_set_cursor(gdk_screen_get_root_window(screen), cursor);
64 }
65 gdk_cursor_unref(cursor);
66 }
67
68 static void on_cursor_theme_sel_changed(GtkTreeSelection* tree_sel, gpointer user_data)
69 {
70 GtkTreeModel* model;
71 GtkTreeIter it;
72 if(gtk_tree_selection_get_selected(tree_sel, &model, &it))
73 {
74 IconTheme* theme;
75 gtk_tree_model_get(model, &it, 1, &theme, -1);
76 if(g_strcmp0(theme->name, app.cursor_theme))
77 {
78 g_free(app.cursor_theme);
79 app.cursor_theme = g_strdup(theme->name);
80 g_object_set(gtk_settings_get_default(), "gtk-cursor-theme-name", app.cursor_theme, NULL);
81
82 update_cursor_demo();
83 lxappearance_changed();
84 }
85
86 gtk_widget_set_sensitive(app.cursor_theme_remove_btn, theme->is_removable);
87 }
88 }
89
90 static void on_cursor_theme_size_changed(GtkRange* range, gpointer user_data)
91 {
92 int size = (int)gtk_range_get_value(range);
93 if(size != app.cursor_theme_size)
94 {
95 app.cursor_theme_size = size;
96 g_object_set(gtk_settings_get_default(), "gtk-cursor-theme-size", size, NULL);
97
98 update_cursor_demo();
99 lxappearance_changed();
100 }
101 }
102
103 void cursor_theme_init(GtkBuilder* b)
104 {
105 int max_cursor_w, max_cursor_h, max_size;
106 GtkTreeSelection* sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(app.cursor_theme_view));
107 /* treeview and model are already set up in icon_theme_init() */
108 g_signal_connect(sel, "changed", G_CALLBACK(on_cursor_theme_sel_changed), NULL);
109
110 gdk_display_get_maximal_cursor_size(gdk_display_get_default(), &max_cursor_w, &max_cursor_h);
111 max_size = MAX(max_cursor_w, max_cursor_h);
112
113 /* FIXME: this isn't fully working... */
114 app.cursor_size_range = GTK_WIDGET(gtk_builder_get_object(b, "cursor_size"));
115 if(max_size < 128)
116 gtk_range_set_range(GTK_RANGE(app.cursor_size_range), 1, max_size + 10); /* 10 is page size */
117 gtk_range_set_value(GTK_RANGE(app.cursor_size_range), app.cursor_theme_size);
118 g_signal_connect(app.cursor_size_range, "value-changed", G_CALLBACK(on_cursor_theme_size_changed), NULL);
119
120 /* set up demo for cursors */
121 app.cursor_demo_view = GTK_WIDGET(gtk_builder_get_object(b, "cursor_demo_view"));
122 gtk_icon_view_set_pixbuf_column(GTK_ICON_VIEW(app.cursor_demo_view), 0);
123 update_cursor_demo();
124
125 /* install and remove */
126 /* this part is already done in icon-theme.c */
127 }