4 * ROX-Filer, filer for the ROX desktop project
5 * By Thomas Leonard, <tal197@ecs.soton.ac.uk>.
8 /* gui_support.c - general (GUI) support routines */
13 #include <sys/param.h>
19 #include <X11/Xatom.h>
23 #include "gui_support.h"
25 static GdkAtom xa_win_state
;
26 static GdkAtom xa_win_layer
;
27 static GdkAtom xa_win_hints
;
28 static GdkAtom xa_cardinal
;
30 void gui_support_init()
32 xa_win_state
= gdk_atom_intern("_WIN_STATE", FALSE
);
33 xa_win_layer
= gdk_atom_intern("_WIN_LAYER", FALSE
);
34 xa_win_hints
= gdk_atom_intern("_WIN_HINTS", FALSE
);
35 xa_cardinal
= gdk_atom_intern("CARDINAL", FALSE
);
38 static void choice_clicked(GtkWidget
*widget
, gpointer number
)
42 choice_return
= gtk_object_get_data(GTK_OBJECT(widget
),
46 *choice_return
= (int) number
;
49 /* Open a modal dialog box showing a message.
50 * The user can choose from a selection of buttons at the bottom.
51 * Returns -1 if the window is destroyed, or the number of the button
52 * if one is clicked (starting from zero).
54 int get_choice(char *title
,
56 int number_of_buttons
, ...)
59 GtkWidget
*vbox
, *action_area
, *separator
;
60 GtkWidget
*text
, *text_container
;
66 dialog
= gtk_window_new(GTK_WINDOW_DIALOG
);
67 gtk_window_set_modal(GTK_WINDOW(dialog
), TRUE
);
68 gtk_window_set_title(GTK_WINDOW(dialog
), title
);
69 gtk_window_set_position(GTK_WINDOW(dialog
), GTK_WIN_POS_CENTER
);
71 vbox
= gtk_vbox_new(FALSE
, 0);
72 gtk_container_add(GTK_CONTAINER(dialog
), vbox
);
74 action_area
= gtk_hbox_new(TRUE
, 5);
75 gtk_container_set_border_width(GTK_CONTAINER(action_area
), 10);
76 gtk_box_pack_end(GTK_BOX(vbox
), action_area
, FALSE
, TRUE
, 0);
78 separator
= gtk_hseparator_new ();
79 gtk_box_pack_end(GTK_BOX(vbox
), separator
, FALSE
, TRUE
, 0);
81 text
= gtk_label_new(message
);
82 gtk_label_set_line_wrap(GTK_LABEL(text
), TRUE
);
83 text_container
= gtk_event_box_new();
84 gtk_container_set_border_width(GTK_CONTAINER(text_container
), 32);
85 gtk_container_add(GTK_CONTAINER(text_container
), text
);
87 gtk_box_pack_start(GTK_BOX(vbox
),
91 va_start(ap
, number_of_buttons
);
93 for (i
= 0; i
< number_of_buttons
; i
++)
95 button
= gtk_button_new_with_label(va_arg(ap
, char *));
96 gtk_object_set_data(GTK_OBJECT(button
), "choice_return",
98 gtk_box_pack_start(GTK_BOX(action_area
),
101 gtk_signal_connect(GTK_OBJECT(button
), "clicked",
102 choice_clicked
, (gpointer
) i
);
105 gtk_widget_grab_focus(button
);
109 gtk_object_set_data(GTK_OBJECT(dialog
), "choice_return",
111 gtk_signal_connect(GTK_OBJECT(dialog
), "destroy", choice_clicked
,
116 gtk_widget_show_all(dialog
);
118 while (choice_return
== -2)
119 g_main_iteration(TRUE
);
121 retval
= choice_return
;
124 gtk_widget_destroy(dialog
);
129 /* Display a message in a window */
130 void report_error(char *title
, char *message
)
132 g_return_if_fail(message
!= NULL
);
137 get_choice(title
, message
, 1, "OK");
140 void set_cardinal_property(GdkWindow
*window
, GdkAtom prop
, guint32 value
)
142 gdk_property_change(window
, prop
, xa_cardinal
, 32,
143 GDK_PROP_MODE_REPLACE
, (gchar
*) &value
, 1);
146 void make_panel_window(GdkWindow
*window
)
148 static gboolean need_init
= TRUE
;
149 static GdkAtom xa_state
;
153 xa_state
= gdk_atom_intern("_WIN_STATE", FALSE
);
157 gdk_window_set_decorations(window
, 0);
158 gdk_window_set_functions(window
, 0);
160 set_cardinal_property(window
, xa_state
,
161 WIN_STATE_STICKY
| WIN_STATE_HIDDEN
|
162 WIN_STATE_FIXED_POSITION
| WIN_STATE_ARRANGE_IGNORE
);
165 gint
hide_dialog_event(GtkWidget
*widget
, GdkEvent
*event
, gpointer window
)
167 gtk_widget_hide((GtkWidget
*) window
);
172 static gboolean
error_idle_cb(gpointer data
)
174 char **error
= (char **) data
;
176 report_error(error
[0], error
[1]);
179 error
[0] = error
[1] = NULL
;
181 if (--number_of_windows
== 0)
187 /* Display an error next time we are idle */
188 void delayed_error(char *title
, char *error
)
190 static char *delayed_error_data
[2] = {NULL
, NULL
};
191 gboolean already_open
;
193 g_return_if_fail(error
!= NULL
);
195 already_open
= delayed_error_data
[1] != NULL
;
197 g_free(delayed_error_data
[0]);
198 g_free(delayed_error_data
[1]);
200 delayed_error_data
[0] = g_strdup(title
);
201 delayed_error_data
[1] = g_strdup(error
);
206 gtk_idle_add(error_idle_cb
, delayed_error_data
);
211 /* Load the file into memory. Return TRUE on success.
212 * Block is zero terminated (but this is not included in the length).
214 gboolean
load_file(char *pathname
, char **data_out
, long *length_out
)
219 gboolean retval
= FALSE
;
221 file
= fopen(pathname
, "r");
225 delayed_error("Opening file for DND", g_strerror(errno
));
229 fseek(file
, 0, SEEK_END
);
230 length
= ftell(file
);
232 buffer
= malloc(length
+ 1);
235 fseek(file
, 0, SEEK_SET
);
236 fread(buffer
, 1, length
, file
);
240 delayed_error("Loading file for DND",
247 *length_out
= length
;
248 buffer
[length
] = '\0';
253 delayed_error("Loading file for DND",
254 "Can't allocate memory for buffer to "
255 "transfer this file");