4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2000, Thomas Leonard, <tal197@ecs.soton.ac.uk>.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
22 /* gui_support.c - general (GUI) support routines */
29 #include <sys/param.h>
35 #include <X11/Xatom.h>
39 #include "gui_support.h"
42 GdkFont
*item_font
= NULL
;
43 GdkFont
*fixed_font
= NULL
;
44 GtkStyle
*fixed_style
= NULL
;
46 GdkColor red
= {0, 0xffff, 0, 0};
47 GdkGC
*red_gc
= NULL
; /* Not automatically initialised */
50 static GdkAtom xa_cardinal
;
52 void gui_support_init()
54 fixed_font
= gdk_font_load("fixed");
55 item_font
= gtk_widget_get_default_style()->font
;
57 fixed_style
= gtk_style_copy(gtk_widget_get_default_style());
58 fixed_style
->font
= fixed_font
;
60 fixed_width
= gdk_string_width(fixed_font
, "m");
62 xa_cardinal
= gdk_atom_intern("CARDINAL", FALSE
);
64 gdk_color_alloc(gtk_widget_get_default_colormap(), &red
);
67 static void choice_clicked(GtkWidget
*widget
, gpointer number
)
71 choice_return
= gtk_object_get_data(GTK_OBJECT(widget
),
75 *choice_return
= (int) number
;
78 /* Open a modal dialog box showing a message.
79 * The user can choose from a selection of buttons at the bottom.
80 * Returns -1 if the window is destroyed, or the number of the button
81 * if one is clicked (starting from zero).
83 int get_choice(char *title
,
85 int number_of_buttons
, ...)
88 GtkWidget
*vbox
, *action_area
, *separator
;
89 GtkWidget
*text
, *text_container
;
90 GtkWidget
*button
= NULL
;
95 dialog
= gtk_window_new(GTK_WINDOW_DIALOG
);
96 gtk_window_set_modal(GTK_WINDOW(dialog
), TRUE
);
97 gtk_window_set_title(GTK_WINDOW(dialog
), title
);
98 gtk_window_set_position(GTK_WINDOW(dialog
), GTK_WIN_POS_CENTER
);
100 vbox
= gtk_vbox_new(FALSE
, 0);
101 gtk_container_add(GTK_CONTAINER(dialog
), vbox
);
103 action_area
= gtk_hbox_new(TRUE
, 5);
104 gtk_container_set_border_width(GTK_CONTAINER(action_area
), 10);
105 gtk_box_pack_end(GTK_BOX(vbox
), action_area
, FALSE
, TRUE
, 0);
107 separator
= gtk_hseparator_new ();
108 gtk_box_pack_end(GTK_BOX(vbox
), separator
, FALSE
, TRUE
, 0);
110 text
= gtk_label_new(message
);
111 gtk_label_set_line_wrap(GTK_LABEL(text
), TRUE
);
112 text_container
= gtk_event_box_new();
113 gtk_container_set_border_width(GTK_CONTAINER(text_container
), 32);
114 gtk_container_add(GTK_CONTAINER(text_container
), text
);
116 gtk_box_pack_start(GTK_BOX(vbox
),
120 va_start(ap
, number_of_buttons
);
122 for (i
= 0; i
< number_of_buttons
; i
++)
124 button
= gtk_button_new_with_label(va_arg(ap
, char *));
125 gtk_object_set_data(GTK_OBJECT(button
), "choice_return",
127 gtk_box_pack_start(GTK_BOX(action_area
),
130 gtk_signal_connect(GTK_OBJECT(button
), "clicked",
131 choice_clicked
, (gpointer
) i
);
133 gtk_window_set_focus(GTK_WINDOW(dialog
), button
);
136 gtk_widget_grab_focus(button
);
140 gtk_object_set_data(GTK_OBJECT(dialog
), "choice_return",
142 gtk_signal_connect(GTK_OBJECT(dialog
), "destroy", choice_clicked
,
147 gtk_widget_show_all(dialog
);
149 while (choice_return
== -2)
150 g_main_iteration(TRUE
);
152 retval
= choice_return
;
155 gtk_widget_destroy(dialog
);
160 /* Display a message in a window */
161 void report_error(char *title
, char *message
)
163 g_return_if_fail(message
!= NULL
);
168 get_choice(title
, message
, 1, "OK");
171 void set_cardinal_property(GdkWindow
*window
, GdkAtom prop
, guint32 value
)
173 gdk_property_change(window
, prop
, xa_cardinal
, 32,
174 GDK_PROP_MODE_REPLACE
, (gchar
*) &value
, 1);
177 void make_panel_window(GdkWindow
*window
)
179 static gboolean need_init
= TRUE
;
180 static GdkAtom xa_state
;
184 xa_state
= gdk_atom_intern("_WIN_STATE", FALSE
);
188 gdk_window_set_decorations(window
, 0);
189 gdk_window_set_functions(window
, 0);
191 set_cardinal_property(window
, xa_state
,
192 WIN_STATE_STICKY
| WIN_STATE_HIDDEN
|
193 WIN_STATE_FIXED_POSITION
| WIN_STATE_ARRANGE_IGNORE
);
196 gint
hide_dialog_event(GtkWidget
*widget
, GdkEvent
*event
, gpointer window
)
198 gtk_widget_hide((GtkWidget
*) window
);
203 static gboolean
error_idle_cb(gpointer data
)
205 char **error
= (char **) data
;
207 report_error(error
[0], error
[1]);
210 error
[0] = error
[1] = NULL
;
212 if (--number_of_windows
== 0)
218 /* Display an error next time we are idle */
219 void delayed_error(char *title
, char *error
)
221 static char *delayed_error_data
[2] = {NULL
, NULL
};
222 gboolean already_open
;
224 g_return_if_fail(error
!= NULL
);
226 already_open
= delayed_error_data
[1] != NULL
;
228 g_free(delayed_error_data
[0]);
229 g_free(delayed_error_data
[1]);
231 delayed_error_data
[0] = g_strdup(title
);
232 delayed_error_data
[1] = g_strdup(error
);
237 gtk_idle_add(error_idle_cb
, delayed_error_data
);
242 /* Load the file into memory. Return TRUE on success.
243 * Block is zero terminated (but this is not included in the length).
245 gboolean
load_file(char *pathname
, char **data_out
, long *length_out
)
250 gboolean retval
= FALSE
;
252 file
= fopen(pathname
, "r");
258 message
= g_strdup_printf("open(%s): %s",
259 pathname
, g_strerror(errno
));
260 delayed_error(PROJECT
, message
);
265 fseek(file
, 0, SEEK_END
);
266 length
= ftell(file
);
268 buffer
= malloc(length
+ 1);
271 fseek(file
, 0, SEEK_SET
);
272 fread(buffer
, 1, length
, file
);
276 delayed_error(_("Error reading file"),
283 *length_out
= length
;
284 buffer
[length
] = '\0';
289 delayed_error(PROJECT
,
290 _("Can't allocate memory for buffer to "
298 GtkWidget
*new_help_button(HelpFunc show_help
, gpointer data
)
302 b
= gtk_button_new();
303 gtk_button_set_relief(GTK_BUTTON(b
), GTK_RELIEF_NONE
);
304 icon
= gtk_pixmap_new(im_help
->pixmap
, im_help
->mask
);
305 gtk_container_add(GTK_CONTAINER(b
), icon
);
306 gtk_signal_connect_object(GTK_OBJECT(b
), "clicked", show_help
, data
);
308 GTK_WIDGET_UNSET_FLAGS(b
, GTK_CAN_FOCUS
);