GnuCash c935c2f+
Loading...
Searching...
No Matches
cursors.c
1/********************************************************************\
2 * cursor.c -- functions for changing cursors *
3 * *
4 * Copyright (C) 1997 Robin D. Clark <rclark@cs.hmc.edu> *
5 * Copyright (C) 1998-2000 Linas Vepstas <linas@linas.org> *
6 * *
7 * This program is free software; you can redistribute it and/or *
8 * modify it under the terms of the GNU General Public License as *
9 * published by the Free Software Foundation; either version 2 of *
10 * the License, or (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License*
18 * along with this program; if not, contact: *
19 * *
20 * Free Software Foundation Voice: +1-617-542-5942 *
21 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
22 * Boston, MA 02110-1301, USA gnu@gnu.org *
23\********************************************************************/
24#include <config.h>
25#include <gtk/gtk.h>
26#include "gnc-ui.h"
27
28
29typedef enum
30{
31 GNC_CURSOR_NORMAL = -1,
32 GNC_CURSOR_BUSY = GDK_WATCH
33} GNCCursorType;
34
35
36/********************************************************************\
37 * gnc_ui_set_cursor *
38 * sets the cursor to the specified type *
39 * *
40 * Args: w - the widget over which to change the cursor *
41 * type - the type of cursor to make *
42 * Return: none *
43\********************************************************************/
44static void
45gnc_ui_set_cursor (GdkWindow *win, GNCCursorType type, gboolean update_now)
46{
47 GdkCursor *cursor = NULL;
48
49 if (win == NULL)
50 return;
51
52 if (type != GNC_CURSOR_NORMAL)
53 cursor = gdk_cursor_new_for_display (gdk_window_get_display (win),
54 (GdkCursorType)type);
55
56 gdk_window_set_cursor (win, cursor);
57
58 if (update_now && type != GNC_CURSOR_NORMAL)
59 {
60 while (gtk_events_pending ())
61 gtk_main_iteration ();
62 }
63
64 if (type != GNC_CURSOR_NORMAL)
65 g_object_unref (cursor);
66}
67
68
69/********************************************************************\
70 * gnc_set_busy_cursor *
71 * sets the cursor to the busy watch for the given window. *
72 * if the window is null, sets the cursor for all toplevel windows*
73 * *
74 * Args: w - the widget over which to make cursor busy *
75 * update_now - if true the cursor will be changed when the *
76 * call returns. *
77 * Return: none *
78\********************************************************************/
79void
80gnc_set_busy_cursor (GtkWidget *w, gboolean update_now)
81{
82 if (w != NULL)
83 gnc_ui_set_cursor (gtk_widget_get_window(w), GNC_CURSOR_BUSY, update_now);
84 else
85 {
86 /* gnc_ui_set_cursor runs the event loop and if there's an
87 * idle waiting that destroys a toplevel further down the list
88 * then we'll get a use after free crash unless we have our
89 * own reference, so take a reference to all of the toplevels
90 * and release them all after the loop finishes.
91 */
92 GList *containerstop = gtk_window_list_toplevels (), *node;
93 g_list_foreach (containerstop, (GFunc)g_object_ref, NULL);
94
95 for (node = containerstop; node; node = node->next)
96 {
97 w = node->data;
98
99 if (!w || !GTK_IS_WIDGET (w) || (!gtk_widget_get_has_window(w)))
100 continue;
101
102 gnc_ui_set_cursor (gtk_widget_get_window(w), GNC_CURSOR_BUSY, update_now);
103 }
104 g_list_free_full (containerstop, (GDestroyNotify)g_object_unref);
105 }
106}
107
108
109/********************************************************************\
110 * gnc_unset_busy_cursor *
111 * sets the cursor to the default cursor for the given window. *
112 * if the window is null, sets the cursor for all toplevel windows*
113 * *
114 * Args: w - the widget over which to make cursor normal *
115 * Return: none *
116\********************************************************************/
117void
118gnc_unset_busy_cursor (GtkWidget *w)
119{
120 if (w != NULL)
121 gnc_ui_set_cursor (gtk_widget_get_window(w), GNC_CURSOR_NORMAL, FALSE);
122 else
123 {
124 GList *containerstop, *node;
125
126 for (containerstop = node = gtk_window_list_toplevels (); node; node = node->next)
127 {
128 w = GTK_WIDGET (node->data);
129
130 if (!w || !GTK_IS_WIDGET (w) || (!gtk_widget_get_has_window(w)))
131 continue;
132
133 gnc_ui_set_cursor (gtk_widget_get_window(w), GNC_CURSOR_NORMAL, FALSE);
134 }
135 g_list_free (containerstop);
136 }
137}
138