1 /* utils.c - Personal utilities for Gtk+ development
2  *
3  * Copyright (C) 2000 - 2010 Patrice St-Gelais
4  * patrstg@users.sourceforge.net
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  */
20 
21 #include "utils.h"
22 #include "x_alloc.h"
23 #include <string.h>
24 #include <ctype.h>
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <errno.h>
28 #include <sys/types.h>
29 #include <sys/wait.h>
30 #include <sys/stat.h>
31 #include "../icons/attention.xpm"
32 #include "../icons/bombe.xpm"
33 #include "../icons/fleur.xpm"
34 #include "../icons/peur.xpm"
35 #include "../icons/info.xpm"
36 #include "../icons/downarrow.xpm"
37 #include "../icons/uparrow.xpm"
38 
39 
swap_buffers(gpointer * a,gpointer * b)40 void swap_buffers (gpointer *a, gpointer *b) {
41 	gpointer c;
42 	c = *a;
43 	*a = *b;
44 	*b = c;
45 }
order_int(gint * i1,gint * i2)46 void order_int (gint *i1, gint *i2) {
47 //	Order 2 integers so that i2 > i1
48 	gint i;
49 	if ((*i2)>=(*i1))
50 		return;
51 	i = *i2;
52 	*i2 = *i1;
53 	*i1 = i;
54 	return;
55 }
56 
gint_adj_callb(GtkWidget * wdg,gpointer data)57 gint gint_adj_callb (GtkWidget *wdg, gpointer data) {
58 	*((gint *) data) = (gint) GTK_ADJUSTMENT(wdg)->value;
59 	return FALSE;
60 }
61 
gdouble_adj_callb(GtkWidget * wdg,gpointer data)62 gint gdouble_adj_callb (GtkWidget *wdg, gpointer data) {
63 	*((gdouble *) data) = (gdouble) GTK_ADJUSTMENT(wdg)->value;
64 	return FALSE;
65 }
66 
gfloat_adj_callb(GtkWidget * wdg,gpointer data)67 gint gfloat_adj_callb (GtkWidget *wdg, gpointer data) {
68 	*((gfloat *) data) = (gfloat) GTK_ADJUSTMENT(wdg)->value;
69 	return FALSE;
70 }
71 
gboolean_set_true(GtkWidget * wdg,gpointer data)72 gint gboolean_set_true (GtkWidget *wdg, gpointer data) {
73 	*((gboolean *) data) = TRUE;
74 	return FALSE;
75 }
76 
gboolean_set_false(GtkWidget * wdg,gpointer data)77 gint gboolean_set_false (GtkWidget *wdg, gpointer data) {
78 	*((gboolean *) data) = FALSE;
79 	return FALSE;
80 }
81 
gboolean_set_false_event(GtkWidget * wdg,GdkEventButton * event,gpointer data)82 gint gboolean_set_false_event (GtkWidget *wdg, GdkEventButton *event, gpointer data) {
83 	*((gboolean *) data) = FALSE;
84 	return FALSE;
85 }
86 
gboolean_set_true_event(GtkWidget * wdg,GdkEventButton * event,gpointer data)87 gint gboolean_set_true_event (GtkWidget *wdg, GdkEventButton *event, gpointer data) {
88 	*((gboolean *) data) = TRUE;
89 	return FALSE;
90 }
91 
92 
zero_callb(GtkWidget * wdg,gpointer adj)93 void zero_callb (GtkWidget *wdg, gpointer adj) {
94 	// Resets any scale adjustment to 0
95 	if (!GTK_IS_ADJUSTMENT(adj))
96 		return;
97 	gtk_adjustment_set_value(GTK_ADJUSTMENT(adj), 0.0);
98 }
99 
toggle_check_button_callb(GtkWidget * checkbutton,gpointer data)100 gint toggle_check_button_callb (GtkWidget *checkbutton, gpointer data) {
101 //	printf("DATA in toggle_check_button_callb: %p\n",data);
102 	if (GTK_TOGGLE_BUTTON(checkbutton)->active) {
103 		*((gboolean *) data) = TRUE;
104 	}
105 	else
106 		*((gboolean *) data) = FALSE;
107 	return FALSE;
108 }
109 
hide_callb(GtkWidget * wdg,gpointer data)110 void hide_callb(GtkWidget *wdg, gpointer data) {
111 	if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg)))
112 			return;
113 	gtk_widget_hide(GTK_WIDGET(data));
114 }
show_callb(GtkWidget * wdg,gpointer data)115 void show_callb(GtkWidget *wdg, gpointer data) {
116 	if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg)))
117 			return;
118 	gtk_widget_show(GTK_WIDGET(data));
119 }
set_flag_hide(GtkWidget * wdg,gpointer show_flag)120 void set_flag_hide(GtkWidget *wdg, gpointer show_flag) {
121 	if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg)))
122 			return;
123 	*((gboolean *) show_flag) = FALSE;
124 }
set_flag_show(GtkWidget * wdg,gpointer show_flag)125 void set_flag_show(GtkWidget *wdg, gpointer show_flag) {
126 	if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg)))
127 			return;
128 	*((gboolean *) show_flag) = TRUE;
129 }
130 
hideshow_dialog_new(GtkWidget * window,GtkOrientation orient,GtkWidget * wdg,gboolean * flag)131 GtkWidget *hideshow_dialog_new(GtkWidget *window,
132 				GtkOrientation orient,
133 				GtkWidget *wdg,
134 				gboolean *flag) {
135 //	Generates a toolbar allowing to hide / show a widget
136 //	"wdg" is the widget to show/hide
137 	GtkWidget *toolbar, *button1, *button2;
138 	toolbar = gtk_toolbar_new();
139 	gtk_toolbar_set_orientation(GTK_TOOLBAR(toolbar),orient);
140 	gtk_toolbar_set_style(GTK_TOOLBAR(toolbar),GTK_TOOLBAR_ICONS);
141 	gtk_widget_show(GTK_WIDGET(toolbar));
142 
143 	button1 = gtk_toolbar_append_element(GTK_TOOLBAR(toolbar),
144 		GTK_TOOLBAR_CHILD_RADIOBUTTON,NULL,_("Show"),
145 		_("Show the dialog"), NULL,
146 		create_widget_from_xpm(window,downarrow_xpm),
147 		GTK_SIGNAL_FUNC(show_callb),wdg);
148 
149 	button2 = gtk_toolbar_append_element(GTK_TOOLBAR(toolbar),
150 		GTK_TOOLBAR_CHILD_RADIOBUTTON,button1,_("Hide"),
151 		_("Hide the dialog"), NULL,
152 		create_widget_from_xpm(window,uparrow_xpm),
153 		GTK_SIGNAL_FUNC(hide_callb),wdg);
154 	if (flag)	{
155 		gtk_signal_connect (	GTK_OBJECT (button1),
156 					"toggled",
157 					GTK_SIGNAL_FUNC(set_flag_show),
158 					(gpointer) flag);
159 		gtk_signal_connect (	GTK_OBJECT (button2),
160 					"toggled",
161 					GTK_SIGNAL_FUNC(set_flag_hide),
162 					(gpointer) flag);
163 		if (*flag) {
164 			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button1),TRUE);
165 			show_callb(button1, (gpointer) wdg);
166 		}
167 		else {
168 			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button2),TRUE);
169 			hide_callb(button2, (gpointer) wdg);
170 		}
171 	}
172 	return toolbar;
173 }
174 
print_list(GList * list)175 void print_list (GList *list) {
176 	GList *node;
177 	gint i = 0;
178 	for (node = g_list_first(list); node; node = node->next)
179 		printf("(%d)  prev: %p;  CURRENT: %p;  next: %p\n",
180 			++i, (node->prev)?node->prev->data:NULL,
181 			node->data, (node->next)?node->next->data:NULL);
182 }
183 
emit_expose_event(GtkWidget * window)184 void emit_expose_event (GtkWidget *window) {
185 //	Emit an expose event on a widget (typically a window)
186 //	Kind of dummy event, allowing testing of document updates
187 	static GdkEventExpose event;
188 	static gint w, h;
189 	if ( ! window)
190 		return;
191 	if ( ! GDK_IS_WINDOW(window->window) )
192 		return;
193 	gdk_window_get_geometry (window->window, NULL, NULL, &w, &h, NULL);
194 	event.type = GDK_EXPOSE;
195 	event.window = window->window;
196 	event.send_event = FALSE;
197 	event.area.x = 0;
198 	event.area.y = 0;
199 	event.area.width = w;
200 	event.area.height = h;
201 	event.count = 0;
202 	// Change for GTK2
203 //	gtk_widget_event(window, (GdkEvent *) &event);
204 	gdk_window_invalidate_rect (event.window, &event.area , TRUE);
205 }
206 
directory_exists(char * directory_name)207 int directory_exists (char *directory_name) {
208 
209 //	Check if directory_name exists using the stat command
210 
211 	struct stat *statres;
212 	statres = (struct stat *) x_calloc(sizeof(struct stat),1, "struct stat (statres in directory_exists in utils.c)");
213 	stat(directory_name, statres);
214 	if (statres && S_ISDIR(statres->st_mode)) {
215 		x_free(statres);
216 		return TRUE;
217 	}
218 	else {
219 		x_free(statres);
220 		return FALSE;
221 	}
222 }
223 
filexists(char * file_name)224 int filexists(char *file_name) {
225 	FILE *test;
226 	if (!file_name) return FALSE;
227 	test = fopen(file_name,"r");
228 	if (test) {
229 		fclose(test);
230 		return TRUE;
231 	}
232 	else
233 		return FALSE;
234 }
235 
add_filesep(gchar * dname)236 gchar *add_filesep (gchar *dname) {
237 //	Add a separator at the end of a dir name, if it's absent
238 //	Returns a new pointer if a separator is added, otherwise returns the same pointer
239 //	The calling function must free the old pointer, if required
240 
241 	gint i;
242 	gchar *buf;
243 	i = strlen(dname)-1;
244 	while ((dname[i]==' ') && (i>0)) i--; 	// Remove spaces
245 	if (!dname)
246 		return dname;
247 	if (dname[i] == FILESEP)
248 		return dname;
249 	buf = (gchar *) x_malloc(strlen(dname)+2, "gchar (buf in add_filesep in utils.c)");
250 	strcpy(buf,dname);
251 	buf[i+1]= FILESEP ;
252 	buf[i+2]='\0';
253 	return buf;
254 }
255 
concat_dname_fname(gchar * dname,gchar * fname)256 gchar *concat_dname_fname (gchar *dname, gchar *fname) {
257 //	Written for catenating a dir name and a file name, but can be used in other contexts
258 //	Add a separator at the end of dname if it doesn't exist
259 	gchar *buf;
260 	gint sep=0,i;
261 	i = strlen(dname)-1;
262 	while ((dname[i]==' ') && (i>0)) i--;	// Remove spaces
263 	if (dname) {
264 		if (dname[i]!= FILESEP) sep=1;
265 		buf = (gchar *) x_malloc(strlen(dname)+strlen(fname)+1+sep, "gchar (buf in concat_dname_fname)");
266 		strcpy(buf,dname);
267 		if (sep) {
268 			buf[i+1]= FILESEP ;
269 			buf[i+2]='\0';
270 		}
271 		strcat(buf, fname);
272 	}
273 	else	{
274 		buf = (gchar *) x_malloc(strlen(fname)+1, "gchar (buf in concat_dname_fname)");
275 		strcpy(buf, fname);
276 	}
277 	return buf;
278 }
279 
split_dir_file(gchar * path_n_file,gchar ** dname,gchar ** fname,gchar sep)280 void split_dir_file (gchar *path_n_file, gchar **dname, gchar **fname, gchar sep) {
281 //	Splits a path into a file name and a directory name, given the separator
282 //	Creates new strings if a path is found,
283 //	otherwise returns the original string in the file address
284 	gchar *separator;
285 	separator = (gchar *) strrchr(path_n_file, sep);
286 	if (separator) {
287 		(*fname) = (gchar *) x_malloc(strlen(separator)+1, "gchar (fname in split_dir_file)");
288 		strcpy((*fname), separator+1);
289 		(*dname) = (gchar *) x_malloc(separator+2-path_n_file, "gchar (dname in split_dir_file)");
290 		strncpy((*dname), path_n_file, separator+1-path_n_file);
291 		(*dname)[separator+1-path_n_file] = '\0';
292 	}
293 	else {
294 		(*fname) = path_n_file;
295 		(*dname) = NULL;
296 	}
297 }
298 
get_dir_name(gchar * path_n_file,gchar sep)299 gchar *get_dir_name(gchar *path_n_file, gchar sep) {
300 //	Copy the dir name from path_n_file
301 //	If no separator found, returns NULL
302 	gchar *separator, *dname;
303 	separator = (gchar *) strrchr(path_n_file, sep);
304 	if (separator) {
305 		dname = (gchar *) x_malloc(separator+2-path_n_file, "gchar (dname in get_dir_name)");
306 		strncpy(dname, path_n_file, separator+1-path_n_file);
307 		dname[separator+1-path_n_file] = '\0';
308 	}
309 	else
310 		dname = NULL;
311 	return dname;
312 }
313 
get_file_name(gchar * path_n_file,gchar sep)314 gchar *get_file_name(gchar *path_n_file, gchar sep) {
315 //	Copy the file name from path_n_file
316 //	If no separator found, returns a new string with the path_n_file content
317 	gchar *separator, *fname;
318 	gint i;
319 	separator = (gchar *) strrchr(path_n_file, sep);
320 	if (separator) {
321 		fname = (gchar *) x_malloc(strlen(separator)+1, "gchar (fname in get_file_name)");
322 		strcpy(fname, separator+1);
323 	}
324 	else
325 	{
326 		fname = (gchar *) x_malloc(strlen(path_n_file)+1,"gchar (fname in get_file_name)" );
327 		memcpy(fname, path_n_file, strlen(path_n_file)+1);
328 	}
329 	// Remove spaces at the end
330 	i = strlen(fname)-1;
331 	while ((fname[i]==' ') && (i>0)) i--;
332 	fname[i+1]='\0';
333 	fname = (gchar *) x_realloc(fname,1+strlen(fname), "gchar (fname - realloc in get_file_name)");
334 	return fname;
335 }
336 
init_default_dir()337 char* init_default_dir() {
338 //	Default dir is $HOME or "" otherwise
339 //	This function can be used to initialize the global variable
340 //	"default_dir" declared in utils.h, or to initialize a local variable
341 //	with the returned string
342 	char *buf;
343 	if (default_dir)
344 		return default_dir;
345 	buf = getenv("HOME");
346 	if (!buf) {
347 		default_dir = (char *) x_malloc(1, "gchar (default_dir in init_default_dir)");
348 		strcpy(default_dir,"");
349 	}
350 	else {
351 		default_dir = (char *) x_malloc(strlen(buf)+2, "gchar (default_dir in init_default_dir)");
352 		strcpy(default_dir,buf);
353 		strcat(default_dir,"/");
354 	}
355 	return default_dir;
356 }
357 
create_widget_from_xpm(GtkWidget * reference_window,gchar ** data)358 GtkWidget *create_widget_from_xpm (GtkWidget *reference_window, gchar **data) {
359 //	Less or more from Harlow's example
360 	GdkBitmap *mask;
361 	GdkPixmap *pm_data;
362 	GtkWidget *pm_widget;
363 	if (!data)
364 		return (NULL);
365 	if (GTK_IS_WIDGET(reference_window))
366 		pm_data = gdk_pixmap_create_from_xpm_d (reference_window->window, &mask, NULL, (gchar **) data);
367 	else
368 		pm_data = gdk_pixmap_create_from_xpm_d (NULL, &mask, NULL, (gchar **) data);
369 	pm_widget = gtk_pixmap_new(pm_data, mask);
370 	gtk_widget_show(pm_widget);
371 	return(pm_widget);
372 }
373 
msg_callb1(GtkWidget * widget,int flag_exit)374 void msg_callb1(GtkWidget *widget,int flag_exit) {
375 	if (flag_exit == ABORT) {
376 		exit(0);
377 	}
378 }
379 
380 
my_msg_subcall(gchar * message,int flag_exit,GtkWidget * dialog,GtkWidget * label1,GtkWidget * pixmap_widget,int if_vertical)381 void my_msg_subcall(gchar * message, int flag_exit, GtkWidget *dialog, GtkWidget *label1, GtkWidget *pixmap_widget, int if_vertical) {
382 
383 	GtkWidget *label2, *ok, *hbox, *vbox;
384 	GMainLoop *loop;
385 	loop = g_main_new(FALSE);
386 //	To be sure the user sees the dialog, we display it in the center...
387 	gtk_window_set_position(GTK_WINDOW(dialog),GTK_WIN_POS_CENTER);
388 	// The message should be translated before calling my_msg
389 	// Here we don't use gettext
390 	// It could be a composed message created with sprintf, in that
391 	// case it won't translate correctly here
392 	label2 = gtk_label_new(message);
393 	gtk_misc_set_padding(GTK_MISC(label1), 10, 10);
394 	gtk_misc_set_padding(GTK_MISC(label2), 10, 10);
395 	vbox = gtk_vbox_new(FALSE,10);
396 	hbox = gtk_hbox_new(FALSE,10);
397 	gtk_box_pack_start(GTK_BOX(vbox),label1, FALSE, FALSE, 0);
398 	if (if_vertical)
399 		gtk_box_pack_start(GTK_BOX(vbox), pixmap_widget, FALSE, FALSE, 0);
400 	else
401 		gtk_box_pack_start(GTK_BOX(hbox), pixmap_widget, FALSE, FALSE, 0);
402 	gtk_box_pack_start(GTK_BOX(vbox),label2, FALSE, FALSE, 0);
403 	gtk_box_pack_start(GTK_BOX(hbox),vbox, FALSE, FALSE, 0);
404 	ok = gtk_button_new_with_label(_("OK"));
405 	gtk_signal_connect_object(GTK_OBJECT(ok), "clicked",
406 		GTK_SIGNAL_FUNC(gtk_grab_remove), GTK_OBJECT(dialog));
407 	gtk_signal_connect_object(GTK_OBJECT(ok), "clicked",
408 		GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(dialog));
409 	gtk_signal_connect(GTK_OBJECT(dialog), "destroy",
410 		GTK_SIGNAL_FUNC(msg_callb1), (void *)flag_exit);
411 	gtk_signal_connect_object(GTK_OBJECT(dialog), "destroy",
412 		GTK_SIGNAL_FUNC(g_main_loop_quit), (void *) loop);
413 	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),ok);
414 	gtk_button_box_set_layout (GTK_BUTTON_BOX(GTK_DIALOG(dialog)->action_area),  GTK_BUTTONBOX_SPREAD);
415 	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
416 	gtk_widget_show_all(dialog);
417 	gtk_grab_add(dialog);
418 	g_main_run (loop);
419 	g_main_destroy(loop);
420 }
421 
my_msg(gchar * message,gint flag_exit)422 void my_msg(gchar * message, gint flag_exit) {
423 	GtkWidget *pixmap_widget, *label, *dialog;
424 	dialog = gtk_dialog_new();
425 	gtk_widget_realize(GTK_WIDGET(dialog));
426 	switch (flag_exit) {
427 		case WARNING:
428 			label = gtk_label_new(_("WARNING!"));
429 			pixmap_widget = create_widget_from_xpm(GTK_WIDGET(dialog),attention_xpm);
430 			break;
431 		case FAIL:
432 			label = gtk_label_new(_("ERROR!"));
433 			pixmap_widget = create_widget_from_xpm(GTK_WIDGET(dialog),peur_xpm);
434 			break;
435 		case ABORT:
436 			label = gtk_label_new(_("FATAL ERROR! The program will abort"));
437 			pixmap_widget = create_widget_from_xpm(GTK_WIDGET(dialog),bombe_xpm);
438 			break;
439 		case SORRY:
440 			label = gtk_label_new(_("SORRY!"));
441 			pixmap_widget = create_widget_from_xpm(GTK_WIDGET(dialog),fleur_xpm);
442 			break;
443 		case INFO:
444 			label = gtk_label_new(_("INFORMATION"));
445 			pixmap_widget = create_widget_from_xpm(GTK_WIDGET(dialog),info_xpm);
446 	}
447 	my_msg_subcall (message, flag_exit, dialog, label, pixmap_widget, FALSE);
448 }
449 
my_msg_with_image(gchar * title,gchar * message,GtkWidget * pixmap_widget)450 void my_msg_with_image(gchar *title, gchar * message, GtkWidget *pixmap_widget) {
451 
452 	GtkWidget *label, *dialog;
453 	dialog = gtk_dialog_new();
454 	gtk_widget_realize(GTK_WIDGET(dialog));
455 	label = gtk_label_new(_(title));
456 	my_msg_subcall (message, INFO, dialog, label, pixmap_widget, TRUE);
457 }
458 
modal_delete_callb(GtkWidget * dummy,GdkEvent * dummy_event,gpointer * args)459 gint modal_delete_callb (GtkWidget *dummy, GdkEvent *dummy_event, gpointer *args) {
460 //	Kind of "wrapper" for callback OK/CANCEL after a delete window event
461 	cb_args_struct *cb_args;
462 	cb_args = (cb_args_struct *) args;
463 	if (cb_args->callb_fn) {
464 		(*cb_args->callb_fn) (dummy, cb_args->callb_data);
465 	}
466 	return TRUE;
467 }
468 
469 
modal_dialog_with_titles_window_provided(GtkWidget * window,GtkWidget * wdg,gchar * title,gint (* ok_callb)(GtkWidget *,gpointer),gchar * ok_title,gint (* cancel_callb)(GtkWidget *,gpointer),gchar * cancel_title,gpointer callb_data,GtkWindowPosition pos,gboolean if_ok_default)470 void modal_dialog_with_titles_window_provided (GtkWidget *window,
471 			GtkWidget *wdg, gchar *title,
472 			gint (*ok_callb) (GtkWidget*, gpointer),
473 			gchar *ok_title,
474 			gint (*cancel_callb) (GtkWidget *, gpointer),
475 			gchar *cancel_title,
476 			gpointer callb_data,
477 			GtkWindowPosition pos,
478 			gboolean if_ok_default) {
479 
480 	// See modal_dialog_with_titles for explanation
481 	// Providing the window allows to connect to it events from the outer context.
482 	// For instance, a click in a widget contained in "wdg" could destroy the window
483 	GtkWidget *button, *okbox, *vbox;
484 	GMainLoop *loop;
485 	cb_args_struct *args;
486 	args = (cb_args_struct *) x_malloc(sizeof(cb_args_struct), "cbs_args_struct (args in modal_dialog_with_titles_windows_provided)");
487 	loop = g_main_new(FALSE);
488 	// "title" is not translated here, see the explanations in "my_msg"
489 	gtk_window_set_title (GTK_WINDOW (window), title);
490 	if (pos)
491 		gtk_window_set_position(GTK_WINDOW(window), pos);
492 	gtk_widget_realize(GTK_WIDGET(window));
493 
494 //	Defines a vbox for containing from top to bottom: 1. "wdg"; 2. OK - Cancel
495 	vbox = gtk_vbox_new(FALSE,0);
496 	gtk_widget_show(GTK_WIDGET(vbox));
497 
498 //	OK / cancel buttons appear in a hbox at the bottom
499 	okbox = gtk_hbox_new(FALSE,0);
500 	gtk_widget_show(GTK_WIDGET(okbox));
501 	button = gtk_button_new_with_label(_(ok_title));
502 	gtk_widget_show(GTK_WIDGET(button));
503 	gtk_container_set_border_width(GTK_CONTAINER(button),DEF_PAD);
504 	if (ok_callb)
505 		gtk_signal_connect(GTK_OBJECT(button), "clicked",
506 			GTK_SIGNAL_FUNC(ok_callb), (gpointer) callb_data);
507 
508 	gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
509 		GTK_SIGNAL_FUNC(gtk_widget_destroy), (gpointer) window);
510 
511 	gtk_box_pack_start(GTK_BOX(okbox), button, FALSE, FALSE, DEF_PAD);
512 
513 	if (cancel_callb) {
514 		button = gtk_button_new_with_label(_(cancel_title));
515 
516 		gtk_widget_show(GTK_WIDGET(button));
517 
518 		gtk_container_set_border_width(GTK_CONTAINER(button),DEF_PAD);
519 
520 		gtk_signal_connect(GTK_OBJECT(button), "clicked",
521 			GTK_SIGNAL_FUNC(cancel_callb), (gpointer) callb_data);
522 
523 		gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
524 			GTK_SIGNAL_FUNC(gtk_widget_destroy), (gpointer) window);
525 
526 		gtk_box_pack_start(GTK_BOX(okbox), button, FALSE, FALSE, DEF_PAD);
527 	}
528 
529 	if (if_ok_default)
530 	//	Closing the window means "OK";
531 		args->callb_fn = ok_callb;
532 	else
533 	//	Closing the window means "Cancel";
534 		args->callb_fn = cancel_callb;
535 
536 	args->callb_data = callb_data;
537 
538 	gtk_signal_connect(GTK_OBJECT(window), "delete_event",
539 		GTK_SIGNAL_FUNC(modal_delete_callb), (gpointer) args);
540 
541 	gtk_signal_connect_object(GTK_OBJECT(window), "destroy",
542 		GTK_SIGNAL_FUNC(gtk_grab_remove), (gpointer) window);
543 
544 	gtk_signal_connect_object(GTK_OBJECT(window), "destroy",
545 		GTK_SIGNAL_FUNC(g_main_loop_quit), (gpointer) loop);
546 
547 	gtk_box_pack_start(GTK_BOX(vbox), wdg, FALSE, FALSE, 0);
548 	gtk_box_pack_start(GTK_BOX(vbox), align_widget(okbox,0.5,0.5), FALSE, FALSE, 0);
549 	gtk_container_add(GTK_CONTAINER(window), vbox);
550 
551 	gtk_widget_show(GTK_WIDGET(window));
552 	gtk_grab_add(window);
553 
554 	g_main_run (loop);
555 
556 	g_main_destroy(loop);
557 }
558 
modal_dialog_with_titles(GtkWidget * wdg,gchar * title,gint (* ok_callb)(GtkWidget *,gpointer),gchar * ok_title,gint (* cancel_callb)(GtkWidget *,gpointer),gchar * cancel_title,gpointer callb_data,GtkWindowPosition pos,gboolean if_ok_default)559 void modal_dialog_with_titles (GtkWidget *wdg, gchar *title,
560 			gint (*ok_callb) (GtkWidget*, gpointer),
561 			gchar *ok_title,
562 			gint (*cancel_callb) (GtkWidget *, gpointer),
563 			gchar *cancel_title,
564 			gpointer callb_data,
565 			GtkWindowPosition pos,
566 			gboolean if_ok_default) {
567 
568 //	Packs "wdg" in a modal window, with an OK and an optional cancel button
569 //	Returns TRUE if OK, FALSE if CANCEL
570 //	If cancel_callb is NULL, omit the cancel button
571 //	If ok_callb is NULL, display an OK button with basic exit behavior
572 //	"wdg" is usually a container packing peculiar controls / widgets
573 //	"wdg" is destroyed with the window, so maybe the calling app should nullify it
574 //	Note:  closing the window means "OK" (calls the ok callback)
575 //	All terminating events stop the main loop
576 	GtkWidget *window;
577 	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
578 	modal_dialog_with_titles_window_provided (window, wdg, title, ok_callb,
579 		ok_title, cancel_callb, cancel_title, callb_data, pos, if_ok_default);
580 }
581 
modal_dialog(GtkWidget * wdg,gchar * title,gint (* ok_callb)(GtkWidget *,gpointer),gint (* cancel_callb)(GtkWidget *,gpointer),gpointer callb_data,GtkWindowPosition pos,gboolean if_ok_default)582 void modal_dialog(GtkWidget *wdg, gchar *title,
583 			gint (*ok_callb) (GtkWidget*, gpointer),
584 			gint (*cancel_callb) (GtkWidget *, gpointer),
585 			gpointer callb_data,
586 			GtkWindowPosition pos,
587 			gboolean if_ok_default) {
588 	modal_dialog_with_titles (wdg, title, ok_callb, "OK", cancel_callb, "Cancel", callb_data, pos, if_ok_default);
589 }
590 
modal_delete_showhide(GtkWidget * window,GdkEvent * dummy_event,gpointer args)591 gint modal_delete_showhide (GtkWidget *window, GdkEvent *dummy_event, gpointer args) {
592 //	Kind of "wrapper" for callback OK/CANCEL after a delete window event
593 	cb_args_struct *cb_args;
594 	cb_args = (cb_args_struct *) args;
595 	if (cb_args->callb_fn) {
596 //		printf("Executing grabbed window callback function\n");
597 		if ((*cb_args->callb_fn) (window, cb_args->callb_data))
598 			return TRUE;
599 	}
600 	gtk_grab_remove(window);
601 	gtk_widget_hide(window);
602 //	printf("Delete event on %d\n", window);
603 	return TRUE;
604 }
605 
606 
modal_dialog_showhide_with_titles(GtkWidget * window,GtkWidget * wdg,gchar * title,gint (* ok_callb)(GtkWidget *,gpointer),gchar * ok_title,gint (* cancel_callb)(GtkWidget *,gpointer),gchar * cancel_title,gpointer callb_data,GtkWindowPosition pos,gboolean if_ok_default)607 void modal_dialog_showhide_with_titles (GtkWidget *window,
608 			GtkWidget *wdg, gchar *title,
609 			gint (*ok_callb) (GtkWidget*, gpointer),
610 			gchar *ok_title,
611 			gint (*cancel_callb) (GtkWidget *, gpointer),
612 			gchar *cancel_title,
613 			gpointer callb_data,
614 			GtkWindowPosition pos,
615 			gboolean if_ok_default) {
616 
617 //	Same as modal_dialog, without a new loop
618 //	The dialog is intended to be permanent
619 //	Unrealized parent window must be given by the caller
620 //	"delete_event" hides the window and grab_removes it
621 //	The parent app can reactivate the dialog this way:
622 //		gtk_widget_show(GTK_WIDGET(given_window));
623 //		gtk_grab_add(GTK_WIDGET(given_window));
624 
625 	GtkWidget *button, *okbox, *vbox;
626 	cb_args_struct *args;
627 	args = (cb_args_struct *) x_malloc(sizeof(cb_args_struct), "cbs_args_struct (args in modal_dialog_showhide_with_titles_windows)");
628 	// "title" is not translated here, see the explanations in "my_msg"
629 	gtk_window_set_title (GTK_WINDOW (window), title);
630 	if (pos)
631 		gtk_window_set_position(GTK_WINDOW(window), pos);
632 	gtk_widget_realize(GTK_WIDGET(window));
633 
634 //	Defines a vbox for containing from top to bottom: 1. "wdg"; 2. OK - Cancel
635 	vbox = gtk_vbox_new(FALSE,0);
636 	gtk_widget_show(GTK_WIDGET(vbox));
637 
638 //	OK / cancel buttons appear in a hbox at the bottom
639 	okbox = gtk_hbox_new(TRUE,0);
640 	gtk_widget_show(GTK_WIDGET(okbox));
641 	button = gtk_button_new_with_label(ok_title);
642 	gtk_widget_show(GTK_WIDGET(button));
643 	gtk_container_set_border_width(GTK_CONTAINER(button),DEF_PAD);
644 	if (ok_callb)
645 		gtk_signal_connect(GTK_OBJECT(button), "clicked",
646 			GTK_SIGNAL_FUNC(ok_callb), (gpointer) callb_data);
647 
648 	gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
649 		GTK_SIGNAL_FUNC(gtk_grab_remove), (gpointer) window);
650 	gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
651 		GTK_SIGNAL_FUNC(gtk_widget_hide), (gpointer) window);
652 
653 	gtk_box_pack_start(GTK_BOX(okbox), button, FALSE, FALSE, DEF_PAD);
654 
655 	if (cancel_callb) {
656 		button = gtk_button_new_with_label(cancel_title);
657 		gtk_widget_show(GTK_WIDGET(button));
658 		gtk_container_set_border_width(GTK_CONTAINER(button),DEF_PAD);
659 		gtk_signal_connect(GTK_OBJECT(button), "clicked",
660 			GTK_SIGNAL_FUNC(cancel_callb), (gpointer) callb_data);
661 		gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
662 			GTK_SIGNAL_FUNC(gtk_grab_remove), (gpointer) window);
663 		gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
664 			GTK_SIGNAL_FUNC(gtk_widget_hide), (gpointer) window);
665 		gtk_box_pack_start(GTK_BOX(okbox), button, FALSE, FALSE, DEF_PAD);
666 	}
667 
668 	if (if_ok_default)
669 	//	Closing the window means "OK";
670 		args->callb_fn = ok_callb;
671 	else
672 	//	Closing the window means "Cancel";
673 		args->callb_fn = cancel_callb;
674 
675 	args->callb_data = callb_data;
676 
677 	gtk_signal_connect(GTK_OBJECT(window), "delete_event",
678 		GTK_SIGNAL_FUNC(modal_delete_showhide), (gpointer) args);
679 
680 	gtk_box_pack_start(GTK_BOX(vbox), wdg, TRUE, TRUE, 0);
681 	gtk_box_pack_start(GTK_BOX(vbox), align_widget(okbox,0.5,0.5), FALSE, FALSE, 0);
682 	gtk_container_add(GTK_CONTAINER(window), vbox);
683 
684 	gtk_widget_show(window);
685 	gtk_grab_add(window);
686 }
687 
688 
689 
modal_dialog_showhide(GtkWidget * window,GtkWidget * wdg,gchar * title,gint (* ok_callb)(GtkWidget *,gpointer),gint (* cancel_callb)(GtkWidget *,gpointer),gpointer callb_data,GtkWindowPosition pos,gboolean if_ok_default)690 void modal_dialog_showhide(GtkWidget *window, GtkWidget *wdg, gchar *title,
691 			gint (*ok_callb) (GtkWidget*, gpointer),
692 			gint (*cancel_callb) (GtkWidget *, gpointer),
693 			gpointer callb_data,
694 			GtkWindowPosition pos,
695 			gboolean if_ok_default) {
696 	modal_dialog_showhide_with_titles (window, wdg, title, ok_callb, _("OK"), cancel_callb, _("Cancel"), callb_data, pos, if_ok_default);
697 }
698 
process_yes(GtkWidget * widget,int * yes_no)699 void process_yes (GtkWidget *widget, int *yes_no) {
700 	*yes_no = TRUE;
701 }
process_no(GtkWidget * widget,int * yes_no)702 void process_no (GtkWidget *widget, int *yes_no) {
703 	*yes_no = FALSE;
704 }
process_cancel(GtkWidget * widget,int * yes_no)705 void process_cancel (GtkWidget *widget, int *yes_no) {
706 	*yes_no = CANCEL_YESNO;
707 }
708 
delete_yesno(GtkWidget * widget,GdkEvent * event,gpointer data)709 gboolean delete_yesno (GtkWidget *widget, GdkEvent *event, gpointer data) {
710 	// Do nothing when the users tries to close the window
711 	return TRUE;
712 }
713 
yes_no(gchar * message,int default_choice)714 int yes_no(gchar * message, int default_choice) {
715 
716 	GtkWidget *dialog, *label, *yes, *no;
717 	int yes_no;
718 	GMainLoop *loop;
719 	loop = g_main_new(FALSE);
720 	dialog = gtk_dialog_new();
721 	gtk_widget_realize(GTK_WIDGET(dialog));
722 //	We want to be sure the user sees the dialog...
723 	gtk_window_set_position(GTK_WINDOW(dialog),GTK_WIN_POS_CENTER);
724 	// "message" is not translated here, see the explanations in "my_msg"
725 	label = gtk_label_new(message);
726 	gtk_misc_set_padding(GTK_MISC(label), 10, 10);
727 	yes = gtk_button_new_with_label(_("Yes"));
728 	no = gtk_button_new_with_label(_("No"));
729 	gtk_signal_connect(GTK_OBJECT(yes), "clicked",
730 		GTK_SIGNAL_FUNC(process_yes),&yes_no);
731 	gtk_signal_connect(GTK_OBJECT(no), "clicked",
732 		GTK_SIGNAL_FUNC(process_no), &yes_no);
733 	gtk_signal_connect(GTK_OBJECT(dialog), "delete_event", GTK_SIGNAL_FUNC(delete_yesno), NULL);
734 	gtk_signal_connect_object(GTK_OBJECT(yes), "clicked",
735 		GTK_SIGNAL_FUNC(gtk_grab_remove), GTK_OBJECT(dialog));
736 	gtk_signal_connect_object(GTK_OBJECT(no), "clicked",
737 		GTK_SIGNAL_FUNC(gtk_grab_remove), GTK_OBJECT(dialog));
738 	gtk_signal_connect_object(GTK_OBJECT(yes), "clicked",
739 		GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(dialog));
740 	gtk_signal_connect_object(GTK_OBJECT(no), "clicked",
741 		GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(dialog));
742 	gtk_signal_connect_object(GTK_OBJECT(dialog), "destroy",
743 		GTK_SIGNAL_FUNC(g_main_loop_quit), (void *) loop);
744 	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), yes, TRUE, TRUE, 0);
745 	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), no, TRUE, TRUE, 0);
746 	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
747 	GTK_WIDGET_SET_FLAGS(yes, GTK_CAN_DEFAULT);
748 	GTK_WIDGET_SET_FLAGS(no, GTK_CAN_DEFAULT);
749 	if (default_choice)
750 		gtk_widget_grab_default(yes);
751 	else
752 		gtk_widget_grab_default(no);
753 	gtk_widget_show_all(dialog);
754 	gtk_grab_add(dialog);
755 	g_main_run (loop);
756 	g_main_destroy(loop);
757 	return yes_no;
758 }
759 
yes_no_cancel(gchar * message,int default_choice)760 int yes_no_cancel(gchar * message, int default_choice) {
761 
762 	GtkWidget *dialog, *label, *yes, *no, *cancel;
763 	int yes_no;
764 	GMainLoop *loop;
765 	loop = g_main_new(FALSE);
766 	dialog = gtk_dialog_new();
767 	gtk_widget_realize(GTK_WIDGET(dialog));
768 //	We want to be sure the user sees the dialog...
769 	gtk_window_set_position(GTK_WINDOW(dialog),GTK_WIN_POS_CENTER);
770 //	The message should be already translated, see the explanations in my_msg
771 	label = gtk_label_new(message);
772 	gtk_misc_set_padding(GTK_MISC(label), 10, 10);
773 	yes = gtk_button_new_with_label(_("Yes"));
774 	no = gtk_button_new_with_label(_("No"));
775 	cancel = gtk_button_new_with_label(_("Cancel"));
776 	gtk_signal_connect(GTK_OBJECT(yes), "clicked",
777 		GTK_SIGNAL_FUNC(process_yes),&yes_no);
778 	gtk_signal_connect(GTK_OBJECT(no), "clicked",
779 		GTK_SIGNAL_FUNC(process_no), &yes_no);
780 	gtk_signal_connect(GTK_OBJECT(cancel), "clicked",
781 		GTK_SIGNAL_FUNC(process_cancel), &yes_no);
782 	gtk_signal_connect(GTK_OBJECT(dialog), "delete_event", GTK_SIGNAL_FUNC(delete_yesno), NULL);
783 	gtk_signal_connect_object(GTK_OBJECT(yes), "clicked",
784 		GTK_SIGNAL_FUNC(gtk_grab_remove), GTK_OBJECT(dialog));
785 	gtk_signal_connect_object(GTK_OBJECT(no), "clicked",
786 		GTK_SIGNAL_FUNC(gtk_grab_remove), GTK_OBJECT(dialog));
787 	gtk_signal_connect_object(GTK_OBJECT(cancel), "clicked",
788 		GTK_SIGNAL_FUNC(gtk_grab_remove), GTK_OBJECT(dialog));
789 	gtk_signal_connect_object(GTK_OBJECT(yes), "clicked",
790 		GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(dialog));
791 	gtk_signal_connect_object(GTK_OBJECT(no), "clicked",
792 		GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(dialog));
793 	gtk_signal_connect_object(GTK_OBJECT(cancel), "clicked",
794 		GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(dialog));
795 	gtk_signal_connect_object(GTK_OBJECT(dialog), "destroy",
796 		GTK_SIGNAL_FUNC(g_main_loop_quit), (void *) loop);
797 	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), yes, TRUE, TRUE, 0);
798 	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), no, TRUE, TRUE, 0);
799 	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), cancel, TRUE, TRUE, 0);
800 	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
801 	GTK_WIDGET_SET_FLAGS(yes, GTK_CAN_DEFAULT);
802 	GTK_WIDGET_SET_FLAGS(no, GTK_CAN_DEFAULT);
803 	GTK_WIDGET_SET_FLAGS(cancel, GTK_CAN_DEFAULT);
804 	switch (default_choice) {
805 		case TRUE:
806 			gtk_widget_grab_default(yes);
807 			break;
808 		case FALSE:
809 			gtk_widget_grab_default(no);
810 			break;
811 		case CANCEL_YESNO:
812 			gtk_widget_grab_default(cancel);
813 	}
814 	gtk_widget_show_all(dialog);
815 	gtk_grab_add(dialog);
816 	g_main_run (loop);
817 	g_main_destroy(loop);
818 	return yes_no;
819 }
820 
findnextrec(FILE * file,char * rec)821 int findnextrec (FILE *file,char *rec)
822 {
823 	/* Find next record, skipping comments */
824 	int i;
825 	while (1) {
826 		if (!fgets(rec,250,file))
827 			return FALSE;
828 		/* Find next char which is not blank */
829 		for (i=0;i<strlen(rec);i++)
830 			if (rec[i]!=' ') break;
831 		if (rec[i]!='#')
832 			break;
833 	}
834 	return TRUE;
835 }
836 
remove_spaces_both_ends(char * str)837 char *remove_spaces_both_ends (char *str) {
838 	// Remove spaces at both ends of a string
839 	// Allocates a new pointer
840 	int max_length, i, j;
841 	char *s;
842 	max_length = strlen(str);
843 	if (!max_length)
844 		return str;
845 	i = max_length-1;
846 	// Removing spaces at the end
847 	while ( (i>=0) && (str[i]==' ') ) {
848 		i--;
849 	}
850 
851 	i++;
852 //	printf("STR[%d]: %d\n",i,str[i]);
853 
854 	s = (char *) x_malloc(i+1, "char (s in remove_spaces_both_ends)");
855 	if (i)
856 		strncpy(s,str,i);
857 	s[i]='\0';
858 	if (!i) // empty string
859 		return s;
860 
861 	max_length = i;
862 	// Removing spaces at the beginning
863 	i = 0;
864 	while ( (i<=max_length) && (s[i]==' ') )
865 		i++;
866 
867 	if (i) { // There is something to remove
868 		for (j=0; (j+i)<=(max_length+1) ; j++)
869 			s[j] = s[i+j];
870 		return (char *) x_realloc(s, j+1, "char (s - realloc in remove_spaces_both_ends)");
871 	}
872 	else
873 		return s;
874 }
875 
876 
strupp(char * my_string)877 char *strupp(char *my_string) {
878 //	Converts my_string to uppercase
879 	int i;
880 	char *buf;
881 	buf = (char *) x_malloc(strlen(my_string)+1, "char (buf in strupp)");
882 	for (i=0; i<strlen(my_string); i++)
883 		buf[i]=(char) toupper((int) my_string[i]);
884 	buf[i]='\0';
885 	return buf;
886 }
887 
strlow(char * my_string)888 char *strlow(char *my_string) {
889 //	Converts my_string to lowercase
890 	int i;
891 	char *buf;
892 	buf = (char *) x_malloc(strlen(my_string)+1, "char (buf in strlow)");
893 	for (i=0; i<strlen(my_string); i++)
894  		buf[i]=(char) tolower((int) my_string[i]);
895 	buf[i]='\0';
896 	return buf;
897 }
898 
is_integer(gchar * buf)899 gboolean is_integer(gchar *buf) {
900 	//	Check if buf is a valid integer
901 	gint i;
902 	if (!strlen(buf))
903 		return FALSE;
904 	for (i = 0; i<strlen(buf); i++) {
905 		if ( (!i) && ((*(buf+i))=='-')) // Negative sign
906 			continue;
907 		if (!isdigit(*(buf+i)))
908 			return FALSE;
909 	}
910 	return TRUE;
911 }
912 
is_float(gchar * buf)913 gboolean is_float(gchar *buf) {
914 	//	Check if buf is a valid float in the 9999,9... format
915 	//	Rough test - to be improved
916 	//	Doesn't check the 999 E+99 format
917 	//	We don't consider the locale, but assume
918 	//	that , or . are valid decimal separators
919 	//	No comma allowed for thousands separators!!
920 	gint i;
921 	gboolean beginning_spaces=TRUE, if_comma=FALSE;
922 //	printf("BUF: %s\n",buf);
923 	if (!strlen(buf))
924 		return FALSE;
925 	for (i = 0; i<strlen(buf); i++) {
926 //		printf("%d = %c\n", i, (char) *(buf+i));
927 		if (beginning_spaces) {
928 			if ((*(buf+i))==' ')
929 				continue;
930 		}
931 		if ( beginning_spaces && ((*(buf+i))=='-')) { // Negative sign
932 			beginning_spaces = FALSE;
933 			continue;
934 		}
935 		beginning_spaces = FALSE;
936 		if (!isdigit(*(buf+i))) {
937 			if (if_comma) // 2nd comma...
938 				return FALSE;
939 			if ( ((*(buf+i))!=',') && ( (*(buf+i))!='.') )
940 				return FALSE;
941 			else
942 				if_comma=TRUE;
943 		}
944 	}
945 	return TRUE;
946 }
947 
string_to_double(gchar * buf)948 gdouble string_to_double (gchar *buf) {
949 	// As the title says...
950 	// Added 2005-04-26, for processing the geomorphrc file without
951 	// considering the locale
952 	// We assume that , or . could be decimal separators
953 	// Doesn't work with the 999 E+99 format
954 	gdouble result=0.0;
955 	gint i, digits;
956 	gboolean beginning_spaces=TRUE, if_comma=FALSE, negative = FALSE;
957 	gchar *new_buf;
958 //	printf("BUF: %s\n",buf);
959 	if (!strlen(buf))
960 		return result;
961 
962 	new_buf = (gchar *) x_malloc(1+(sizeof(gchar)*strlen(buf)), "gchar (new_buf in string_to_double)");
963 
964 	digits = 0;
965 	for (i = 0; i<strlen(buf); i++) {
966 //		printf("%d = %c\n", i, (char) *(buf+i));
967 		if (beginning_spaces) {
968 			if ((*(buf+i))==' ')
969 				continue;
970 		}
971 		if ( beginning_spaces && ((*(buf+i))=='-'))  { // Negative sign
972 			beginning_spaces = FALSE;
973 			negative = TRUE;
974 			continue;
975 		}
976 		beginning_spaces = FALSE;
977 		if (!isdigit(*(buf+i))) {
978 			if (if_comma) { // 2nd comma, not supposed to, stop there
979 				x_free(new_buf);
980 				if (negative)
981 					result *= -1;
982 				return result;
983 			}
984 			if ( ((*(buf+i))!=',') && ( (*(buf+i))!='.') ) {
985 				x_free(new_buf);
986 				if (negative)
987 					result *= -1;
988 				return result;
989 			}
990 			else {
991 				if_comma=TRUE;
992 				*(new_buf+digits) = '\0';
993 				result = atof(new_buf);
994 				digits = 0;
995 			}
996 		}
997 		else {
998 			*(new_buf+digits) = *(buf+i);
999 			digits++;
1000 		}
1001 	}
1002 	*(new_buf+digits) = '\0';
1003 	result += atof(new_buf) / pow(10.0,(gdouble)digits);
1004 	x_free(new_buf);
1005 	if (negative)
1006 		result *= -1;
1007 	return result;
1008 }
1009 
define_button_in_table(char * txt,GtkWidget * table,gint colfrom,gint colto,gint linefrom,gint lineto,gint pad)1010 GtkWidget * define_button_in_table (char *txt, GtkWidget *table, gint colfrom,
1011 	gint colto, gint linefrom, gint lineto, gint pad)
1012 {
1013 	GtkWidget *button;
1014 	button = gtk_button_new_with_label (_(txt));
1015 	gtk_table_attach (GTK_TABLE (table), button, colfrom, colto, linefrom, lineto, 0, 0, pad, pad);
1016 	gtk_widget_show(button);
1017 	return button;
1018 }
1019 
define_check_button_in_table(char * txt,GtkWidget * table,gint colfrom,gint colto,gint linefrom,gint lineto,gint pad)1020 GtkWidget * define_check_button_in_table (char *txt, GtkWidget *table, gint colfrom,
1021 	gint colto, gint linefrom, gint lineto, gint pad)
1022 {
1023 	GtkWidget *button;
1024 	button = gtk_check_button_new_with_label (_(txt));
1025 	gtk_table_attach (GTK_TABLE (table), button, colfrom, colto, linefrom, lineto, 0, 0, pad, pad);
1026 	gtk_widget_show(button);
1027 	return button;
1028 }
define_check_button_in_box(char * txt,GtkWidget * box,gint expand,gint fill,gint pad)1029 GtkWidget * define_check_button_in_box (char *txt, GtkWidget *box, gint expand, gint fill, gint pad)
1030 {
1031 	GtkWidget *button;
1032 	button = gtk_check_button_new_with_label (_(txt));
1033 	gtk_box_pack_start(GTK_BOX(box), button, expand, fill, pad);
1034 	gtk_widget_show(button);
1035 	return button;
1036 }
define_label_in_box(char * txt,GtkWidget * box,gint expand,gint fill,gint pad)1037 GtkWidget *define_label_in_box(char *txt, GtkWidget *box, gint expand, gint fill, gint pad)
1038 {
1039 	GtkWidget *label;
1040 	label = gtk_label_new(_(txt));
1041 	gtk_misc_set_alignment(GTK_MISC(label),0,0.5);
1042 	gtk_widget_show (label);
1043 	gtk_box_pack_start(GTK_BOX(box), label, expand, fill, pad);
1044 	return label;
1045 }
1046 
define_scale_in_table(GtkObject * adj,GtkWidget * table,gint colfrom,gint colto,gint linefrom,gint lineto,gint digits,gint pad)1047 GtkWidget * define_scale_in_table(GtkObject *adj, GtkWidget *table, gint colfrom, gint colto,
1048 		gint linefrom, gint lineto, gint digits, gint pad)
1049 {
1050 	GtkWidget *scale;
1051     	scale = gtk_hscale_new (GTK_ADJUSTMENT (adj));
1052 	gtk_scale_set_digits (GTK_SCALE (scale), digits);
1053 	gtk_widget_set_usize(scale,80,0);
1054 //	gtk_table_attach (GTK_TABLE (table), scale, colfrom, colto, linefrom, lineto,
1055 //		GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, pad, pad);
1056 	gtk_table_attach_defaults (GTK_TABLE (table), scale, colfrom, colto, linefrom, lineto);
1057 	gtk_widget_show (scale);
1058 	return(scale);
1059 }
1060 
define_scale_in_box(GtkObject * adj,GtkWidget * box,gint digits,gint pad)1061 GtkWidget * define_scale_in_box(GtkObject *adj, GtkWidget *box,  gint digits, gint pad)
1062 {
1063 	GtkWidget *scale;
1064 	if (GTK_IS_HBOX(GTK_OBJECT(box))) {
1065 	    	scale = gtk_hscale_new (GTK_ADJUSTMENT (adj));
1066 		gtk_widget_set_usize(scale,75,0);
1067 	}
1068 	else {
1069 	    	scale = gtk_vscale_new (GTK_ADJUSTMENT (adj));
1070 		gtk_widget_set_usize(scale,0,75);
1071 	}
1072 	gtk_scale_set_digits (GTK_SCALE (scale), digits);
1073 	gtk_box_pack_start (GTK_BOX (box), scale, TRUE, TRUE, pad);
1074 	gtk_widget_show (scale);
1075 	return(scale);
1076 }
1077 
define_label_in_table_align(char * txt,GtkWidget * table,gint colfrom,gint colto,gint linefrom,gint lineto,gint pad,gfloat horiz,gfloat vertic)1078 GtkWidget *define_label_in_table_align (char *txt,GtkWidget *table, gint colfrom, gint colto,
1079 	gint linefrom, gint lineto, gint pad, gfloat horiz, gfloat vertic)
1080 {
1081 	GtkWidget *label,*lbl;
1082 	label = gtk_label_new(_(txt));
1083 	gtk_widget_show (label);
1084 	gtk_misc_set_alignment(GTK_MISC(label),0,0.5);
1085 	if ((horiz==ALIGN_CENTER) && (vertic==ALIGN_CENTER))
1086 		lbl = label;
1087 	else
1088 		lbl = align_widget(label,horiz,vertic);
1089 	gtk_table_attach (GTK_TABLE (table), lbl, colfrom, colto, linefrom, lineto,
1090 		GTK_FILL, GTK_FILL, pad, pad);
1091 	return label;
1092 }
1093 
define_label_in_table(char * txt,GtkWidget * table,gint colfrom,gint colto,gint linefrom,gint lineto,gint pad)1094 GtkWidget *define_label_in_table(char *txt,GtkWidget *table, gint colfrom, gint colto,
1095 	gint linefrom, gint lineto, gint pad)
1096 {
1097 	return define_label_in_table_align(txt, table, colfrom, colto,
1098 		linefrom, lineto, pad, ALIGN_CENTER, ALIGN_CENTER);
1099 }
1100 
define_entry_in_table_align(char * txt,GtkWidget * table,gint colfrom,gint colto,gint linefrom,gint lineto,int length,int widget_len,gint pad,gfloat horiz,gfloat vertic)1101 GtkWidget * define_entry_in_table_align(char *txt,GtkWidget *table, gint colfrom, gint colto,
1102 	gint linefrom, gint lineto, int length, int widget_len, gint pad, gfloat horiz, gfloat vertic)
1103 {
1104 	// "length" is in characters
1105 	// "widget_len" is in pixels (seems to be)
1106 	GtkWidget *entry, *entr;
1107 	entry = gtk_entry_new_with_max_length(length);
1108 	gtk_widget_show(entry);
1109 	gtk_widget_set_usize(GTK_WIDGET(entry),widget_len,0);
1110 	gtk_entry_set_text(GTK_ENTRY(entry),txt);
1111 	if ((horiz==ALIGN_CENTER) && (vertic==ALIGN_CENTER))
1112 		entr = entry;
1113 	else
1114 		entr = align_widget(entry,horiz,vertic);
1115 	gtk_table_attach (GTK_TABLE (table), entr,
1116 		colfrom, colto, linefrom, lineto,
1117 		GTK_FILL, GTK_FILL, pad, pad);
1118 	return(entry);
1119 }
1120 
define_entry_in_table(char * txt,GtkWidget * table,gint colfrom,gint colto,gint linefrom,gint lineto,int length,int widget_len,gint pad)1121 GtkWidget * define_entry_in_table(char *txt,GtkWidget *table, gint colfrom, gint colto,
1122 	gint linefrom, gint lineto, int length, int widget_len, gint pad)
1123 {
1124 	return define_entry_in_table_align(txt,table,colfrom,colto, linefrom,
1125 		lineto, length,widget_len,pad, ALIGN_CENTER, ALIGN_CENTER);
1126 }
1127 
define_entry_in_box(char * txt,GtkWidget * box,gint expand,gint fill,gint pad,int length,int widget_len)1128 GtkWidget * define_entry_in_box(char *txt, GtkWidget *box, gint expand,
1129 		gint fill, gint pad, int length, int widget_len)
1130 {
1131 	GtkWidget *entry;
1132 	entry = gtk_entry_new_with_max_length(length);
1133 	gtk_widget_set_usize(GTK_WIDGET(entry),widget_len,0);
1134 	gtk_entry_set_text(GTK_ENTRY(entry),txt);
1135 	gtk_box_pack_start(GTK_BOX(box), entry, expand, fill, pad);
1136 	gtk_widget_show(entry);
1137 	return(entry);
1138 }
1139 
define_radio_button_in_box(GtkWidget * box,GSList ** group,char * txt,void (* callback_fn)(GtkWidget *,gpointer),int if_default)1140 GtkWidget * define_radio_button_in_box (GtkWidget *box, GSList **group, char *txt,
1141 	void (*callback_fn) (GtkWidget *, gpointer ),
1142 	int if_default ) {
1143 
1144 //	This form uses the label text as the callback data
1145 //	Data is flowed from the widget to the application through a global variable
1146 //	which is initialized in the callback function, from the label
1147 	GtkWidget *button;
1148 	button = gtk_radio_button_new_with_label (*group, _(txt));
1149     	gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE, 0);
1150 	*group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
1151 	if (if_default)
1152 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
1153 	gtk_widget_show(button);
1154 	if (callback_fn)
1155 		gtk_signal_connect (	GTK_OBJECT (button),
1156 					"toggled",
1157 					GTK_SIGNAL_FUNC(callback_fn),
1158 					(gpointer) txt);
1159 	return button;
1160 }
1161 
define_radio_button_in_box_with_data(GtkWidget * box,GSList ** group,char * txt,void (* callback_fn)(GtkWidget *,gpointer),gpointer callb_data,int if_default)1162 GtkWidget * define_radio_button_in_box_with_data (GtkWidget *box, GSList **group, char *txt,
1163 	void (*callback_fn) (GtkWidget *, gpointer ),
1164 	gpointer callb_data,
1165 	int if_default ) {
1166 
1167 //	This forms implies that the callback data is the structure modified with the
1168 //	information drawed from the radio button label
1169 //	The callback function must tests the radio button label like this:
1170 //		gchar *txt;
1171 //		gtk_label_get(GTK_LABEL(GTK_BIN(radio_button)->child), &txt);
1172 
1173 	GtkWidget *button;
1174 	button = gtk_radio_button_new_with_label (*group, _(txt));
1175     	gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE, 0);
1176 	*group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
1177 	gtk_widget_show(button);
1178 	if (callback_fn)
1179 		gtk_signal_connect (	GTK_OBJECT (button),
1180 					"toggled",
1181 					GTK_SIGNAL_FUNC(callback_fn),
1182 					callb_data);
1183 	if (if_default) {
1184 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
1185 //		printf("Activating %s\n",txt);
1186 	}
1187 	return button;
1188 }
1189 
define_radio_button_in_table_with_data(GtkWidget * table,GSList ** group,char * txt,void (* callback_fn)(GtkWidget *,gpointer),gpointer callb_data,gint if_default,gint colfrom,gint colto,gint linefrom,gint lineto)1190 GtkWidget * define_radio_button_in_table_with_data (GtkWidget *table, GSList **group, char *txt,
1191 	void (*callback_fn) (GtkWidget *, gpointer ),
1192 	gpointer callb_data, gint if_default, gint colfrom, gint colto, gint linefrom, gint lineto ) {
1193 
1194 //	This forms implies that the callback data is the structure modified with the
1195 //	information drawed from the radio button label
1196 //	The callback function must tests the radio button label like this:
1197 //		gchar *txt;
1198 //		gtk_label_get(GTK_LABEL(GTK_BIN(radio_button)->child), &txt);
1199 
1200 	GtkWidget *button;
1201 	button = gtk_radio_button_new_with_label (*group, _(txt));
1202 
1203 	gtk_table_attach (GTK_TABLE (table), button, colfrom, colto, linefrom, lineto, 0, 0, 0, 0);
1204 
1205 	*group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
1206 	if (if_default)
1207 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
1208 	gtk_widget_show(button);
1209 	if (callback_fn)
1210 		gtk_signal_connect (	GTK_OBJECT (button),
1211 					"toggled",
1212 					GTK_SIGNAL_FUNC(callback_fn),
1213 					callb_data);
1214 	return button;
1215 }
1216 
find_omenu_option(omenu_struct_type * omenu,char * label)1217 int find_omenu_option (omenu_struct_type *omenu, char *label) {
1218 //	Finds the option menu index from label
1219 	int i;
1220 	char *buf1, *buf2;
1221 	buf1 = strupp(label);
1222 	for (i=0; i<omenu->max_index; i++) {
1223 		buf2 = strupp(omenu->list[i].lbl);
1224 		if (!strcmp(buf1,buf2)) {
1225 			x_free(buf2);
1226 			break;
1227 		}
1228 		x_free(buf2);
1229 	}
1230 	x_free(buf1);
1231 	if (i == omenu->max_index)
1232 		return 0;
1233 	else
1234 		return i;
1235 }
1236 
find_omenu_option_num(omenu_struct_type * omenu,int value)1237 int find_omenu_option_num(omenu_struct_type *omenu, int value) {
1238 //	Finds the option menu index from the numeric value
1239 	int i;
1240 	for (i=0; i<omenu->max_index; i++)
1241 		if (value == omenu->list[i].num)
1242 			break;
1243 	if (i == omenu->max_index)
1244 		return 0;
1245 	else
1246 		return i;
1247 }
1248 
find_omenu_num(omenu_list_type * list,int value,int max)1249 int find_omenu_num (omenu_list_type *list, int value, int max) {
1250 //	Finds the option menu index from the numeric value
1251 //	Same as preceding, but the omenu_struct_type is not known
1252 	int i;
1253 	for (i=0; i<max; i++) {
1254 		if (value == list[i].num)
1255 			break;
1256 	}
1257 	if (i == max)
1258 		return 0;
1259 	else {
1260 // printf("FIND_OMENU_NUM - valeur cherch�e: %d;  i: %d; v. cour: %d\n",value,i, list[i].num);
1261 		return i;
1262 	}
1263 }
1264 
menu_choice(omenu_list_type * item_list)1265 void menu_choice (omenu_list_type *item_list)
1266 {
1267 	/* Initialise current label and index */
1268 	((omenu_struct_type *) item_list->parent_omenu)->current_lbl = _(item_list->lbl);
1269 	((omenu_struct_type *) item_list->parent_omenu)->current_index =
1270 		find_omenu_option(
1271 			(omenu_struct_type *) item_list->parent_omenu,
1272 			item_list->lbl );
1273 // printf("ITEM_LIST->lbl: %s\n",item_list->lbl);
1274 //	/* Is there a function pointer to execute ? */
1275 //	Done in define_menu_item 2001.12.16
1276 //	if (item_list->callback_fn)
1277 //		(*item_list->callback_fn)((gpointer *) item_list->lbl);
1278 }
1279 
define_menu_item(omenu_struct_type * omenu,omenu_list_type * omenu_list,GSList ** group,GtkWidget * menu)1280 GtkWidget * define_menu_item (omenu_struct_type *omenu, omenu_list_type *omenu_list,
1281 	GSList **group, GtkWidget *menu)
1282 {
1283 	GtkWidget *menuitem;
1284 	menuitem = gtk_radio_menu_item_new_with_label
1285 		(*group,_(omenu_list->lbl));
1286 	*group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM(menuitem));
1287 	gtk_menu_append(GTK_MENU(menu),menuitem);
1288 	gtk_widget_show(menuitem);
1289 	gtk_signal_connect_object(GTK_OBJECT(menuitem), "activate",
1290 		GTK_SIGNAL_FUNC(menu_choice), (gpointer) omenu_list);
1291 	if (omenu_list->callback_fn) {
1292 		// Is there a function pointer to execute ?
1293 		if (!omenu->data)
1294 		// Old version:  the data was the label
1295 			gtk_signal_connect_object(GTK_OBJECT(menuitem), "activate",
1296 				GTK_SIGNAL_FUNC(omenu_list->callback_fn),
1297 				(gpointer) omenu_list->lbl);
1298 		else
1299 			gtk_signal_connect_object(GTK_OBJECT(menuitem), "activate",
1300 				GTK_SIGNAL_FUNC(omenu_list->callback_fn),
1301 				(gpointer) omenu);
1302 	}
1303 	return menuitem;
1304 }
1305 
define_omenu(omenu_struct_type * omenu_str,int max,int def)1306 GtkWidget * define_omenu (omenu_struct_type *omenu_str, int max, int def)
1307 {
1308 	/* Defines an option menu and sets the default value */
1309 	int i,j=0;
1310 	GSList *group=NULL;
1311 	GtkWidget *omenu, *menu;
1312 	omenu = gtk_option_menu_new();
1313 	menu = gtk_menu_new();
1314 
1315 	for(i=0;i<max;i++) {
1316 		if (i==def)
1317 			j=i;
1318 		omenu_str->list[i].menuitem =
1319 			define_menu_item (omenu_str,&omenu_str->list[i], &group, menu);
1320 	}
1321 	gtk_option_menu_set_menu (GTK_OPTION_MENU(omenu),menu);
1322 	gtk_widget_show(omenu);
1323 	/* Toggle, show, initialise default value */
1324 	gtk_option_menu_set_history(GTK_OPTION_MENU(omenu),j);
1325 	gtk_menu_item_activate(GTK_MENU_ITEM(omenu_str->list[j].menuitem));
1326 	omenu_str->current_lbl = _(omenu_str->list[j].lbl);
1327 	return omenu;
1328 }
1329 
create_omenu(omenu_struct_type ** new_omenu,omenu_list_type * list,int max_index,int def_index)1330 int create_omenu (omenu_struct_type **new_omenu,
1331 	omenu_list_type *list,
1332 	int max_index,
1333 	int def_index)
1334 {
1335 
1336 	// Creates an Option Menu Structure from an undefined
1337 	// omenu_struct_type pointer, a defined list of options
1338 	// and a few indexes - maximum + default
1339 
1340 	int i;
1341 	if (NULL == ((*new_omenu) =
1342 		(omenu_struct_type *) x_malloc(sizeof(omenu_struct_type), "omenu_struct_type (new_omenu in create_omenu)")))
1343 		return FALSE;
1344 
1345 	(*new_omenu)->list = list;
1346 
1347 	(*new_omenu)->max_index = max_index;
1348 
1349 	(*new_omenu)->def_index = def_index;
1350 
1351 	(*new_omenu)->data = NULL;
1352 
1353 	// We need to know the parent pointer in the child structure
1354 	for (i=0; i<max_index; i++)
1355 		(*new_omenu)->list[i].parent_omenu = *new_omenu;
1356 
1357 	(*new_omenu)->omenu_ptr = define_omenu(*new_omenu, max_index, def_index);
1358 
1359 	return TRUE;
1360 }
1361 
1362 
create_omenu_with_callb_data(omenu_struct_type ** new_omenu,omenu_list_type * list,int max_index,int def_index,gpointer data)1363 int create_omenu_with_callb_data (omenu_struct_type **new_omenu,
1364 	omenu_list_type *list,
1365 	int max_index,
1366 	int def_index,
1367 	gpointer data)
1368 {
1369 
1370 	// Creates an Option Menu Structure from an undefined
1371 	// omenu_struct_type pointer, a defined list of options
1372 	// and a few indexes - maximum + default
1373 
1374 	int i;
1375 	if (NULL == ((*new_omenu) =
1376 		(omenu_struct_type *) x_malloc(sizeof(omenu_struct_type),"omenu_struct_type (new_omenu in create_omenu_with_callb_data)" )))
1377 		return FALSE;
1378 
1379 	(*new_omenu)->list = list;
1380 
1381 	(*new_omenu)->max_index = max_index;
1382 
1383 	(*new_omenu)->def_index = def_index;
1384 
1385 	(*new_omenu)->data = data;
1386 
1387 	// We need to know the parent pointer in the child structure
1388 	for (i=0; i<max_index; i++)
1389 		(*new_omenu)->list[i].parent_omenu = *new_omenu;
1390 
1391 	(*new_omenu)->omenu_ptr = define_omenu(*new_omenu, max_index, def_index);
1392 
1393 	return TRUE;
1394 }
1395 
set_option_menu_from_label(GtkWidget * omenu,gchar * label)1396 void set_option_menu_from_label (GtkWidget *omenu, gchar *label) {
1397 //	Written 2002.09
1398 //	A lot simpler than the preceding functions
1399 //	(no need of a complex option menu struct, all data can be found
1400 //	in the option menu... when one finally understands the widget :-( )
1401 //	2005-02: seems to work with GTK2 (at least when the menu item is a label!)
1402 	GtkWidget *menu;
1403 	GList *node;
1404 	gchar *txt,*lbl;
1405 	lbl = remove_spaces_both_ends(label);
1406 	if (GTK_IS_LABEL(GTK_BIN(omenu)->child)) {
1407 		gtk_label_get(GTK_LABEL(GTK_BIN(omenu)->child), &txt);
1408 		if (!strcmp(txt,lbl))  // Nothing to do, the label is already set
1409 			return;
1410 	}
1411 	menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(omenu));
1412 	node = GTK_MENU_SHELL(menu)->children;
1413 	while (node) {
1414 		if (GTK_IS_LABEL(GTK_BIN(node->data)->child)) {
1415 			gtk_label_get(GTK_LABEL(GTK_BIN(node->data)->child), &txt);
1416 			if (!strcmp(txt,lbl)) {
1417 				break;
1418 			}
1419 		} // If the child is not a label (typically it would be NULL),
1420 		 // we skip it because the menu item is the current one
1421 		node = node->next;
1422 	}
1423 	if (node)	{	// Label found
1424 		gtk_menu_item_activate(GTK_MENU_ITEM(node->data));
1425 		gtk_option_menu_set_history(GTK_OPTION_MENU(omenu),
1426 			g_list_index(GTK_MENU_SHELL(menu)->children, node->data));
1427 	}
1428 	else {		// Label not found, revert to default
1429 		gtk_menu_item_activate(GTK_MENU_ITEM(GTK_MENU_SHELL(menu)->children->data));
1430 		gtk_option_menu_set_history(GTK_OPTION_MENU(omenu),0);
1431 	}
1432 	free(lbl);
1433 }
1434 
my_exec(char * com,char ** argum,int (* exec_to_use)(const char *,char * arg[]))1435 int my_exec(char *com, char **argum, int (*exec_to_use) (const char *, char *arg[])) {
1436 
1437 /* "Wrapper" for execution of a command with execvp or execv
1438    Control returned to parent process (uses fork)
1439    argum must end with a NULL!!
1440    ... and preferably begin with the command to execute
1441    (we tested it!)
1442 */
1443 
1444 int i=0;
1445 pid_t pid;
1446 char **buf=NULL, *bufmsg=NULL;
1447 
1448 // printf("*Argum: %s == %s : %d\n" ,*argum,com, strcmp(*argum,com));
1449 
1450 // Arguments must begin with the command to execute
1451 if (strcmp(*argum,com)) { // No
1452 	while (*(argum+i)!=NULL) i++;
1453 	buf = (char **) x_calloc((i+2),sizeof(*argum), "*argum (buf in my_exec)");
1454 // printf("Allocation: %d:%d\n",i+2,(i+2)*sizeof(*argum));
1455 	*buf = com;
1456 	while (i+1) {
1457 		*(buf+i+1) = *(argum+i);
1458 // printf("I: %d; BUF: %s; ARGUM: %s\n", i, *(buf+i+1), *(argum+i));
1459 		i--;
1460 	}
1461 }
1462 else {
1463 	buf = argum;
1464 }
1465 
1466 // printf("com: %s; Buf 0: %s, Buf 1: %s, Buf 2: %s, Buf 3: %s, Buf 4: %s; Buf 5: %s\n", com, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
1467 
1468 pid = fork ();
1469 
1470 // printf("PID: %d\n",pid);
1471 
1472 if (pid == 0) {
1473  // Child process OK, execute the command
1474 	if ((*exec_to_use) (com, buf)<0) {  // Command not OK
1475 		bufmsg = (char *) x_malloc(5+strlen(strerror(errno))+
1476 			strlen(com), "char (bufmsg in my_exec)");
1477 		sprintf(bufmsg,"%s: %s",com,strerror(errno));
1478 
1479 		my_msg(bufmsg,FAIL);
1480 
1481 		x_free(bufmsg);
1482 		printf("%s: %s\n", com, strerror(errno));
1483 		_exit(-1);
1484 	}
1485 }
1486 else
1487 	if (pid < 0) {
1488 	/* Error, no child process, Parent process OK */
1489 		my_msg(strerror(errno),FAIL);
1490 	}
1491 	else {	// pid > 0, Parent process OK, child OK
1492 		// Remove zombie process, if any
1493 // printf("PID: %d\n",pid);
1494 		waitpid(pid, NULL, WNOHANG);
1495 	}
1496 
1497 if (buf && (buf != argum)) x_free(buf);
1498 
1499 return pid;
1500 }
1501 
execution(char * file,char ** argum)1502 int execution(char *file, char **argum) {
1503 	return my_exec(file, argum, (gpointer) execvp);
1504 }
1505 
1506 // int execution(char *path, char **argum) {
1507 //	return my_exec(path, argum, (gpointer) execv);
1508 //}
1509 
log2i(gint x)1510 int log2i(gint x) {
1511 	gint i;
1512 	i = 0;
1513 	while (x) {
1514 		i++;
1515 		x = x>>1;
1516 	}
1517 	return(i-1);
1518 }
1519 
set_sensitive_callb(GtkWidget * wdg,gpointer widget)1520 void set_sensitive_callb (GtkWidget *wdg, gpointer widget) {
1521 	// Enable "widget" when an event reaches "wdg"
1522 	gtk_widget_set_sensitive(GTK_WIDGET(widget),TRUE);
1523 }
1524 
unset_sensitive_callb(GtkWidget * wdg,gpointer widget)1525 void unset_sensitive_callb (GtkWidget *wdg, gpointer widget) {
1526 	// Disable "widget" when an event reaches "wdg"
1527 	gtk_widget_set_sensitive(GTK_WIDGET(widget),FALSE);
1528 }
1529 
show_if_true(GtkWidget * check_button,gpointer widget)1530 void show_if_true(GtkWidget *check_button, gpointer widget) {
1531 //	Show widget if button is true, hide if false
1532 	if (GTK_TOGGLE_BUTTON(check_button)->active)
1533 		gtk_widget_show(GTK_WIDGET(widget));
1534 	else
1535 		gtk_widget_hide(GTK_WIDGET(widget));
1536 }
hide_if_true(GtkWidget * check_button,gpointer widget)1537 void hide_if_true(GtkWidget *check_button, gpointer widget) {
1538 //	Hide widget if button is true, show if false
1539 	if (GTK_TOGGLE_BUTTON(check_button)->active)
1540 		gtk_widget_hide(GTK_WIDGET(widget));
1541 	else
1542 		gtk_widget_show(GTK_WIDGET(widget));
1543 }
1544 
sensitive_if_true(GtkWidget * check_button,gpointer widget)1545 void sensitive_if_true(GtkWidget *check_button, gpointer widget) {
1546 //	Make widget sensitive if button is true, make unsensitive if false
1547 	gtk_widget_set_sensitive(GTK_WIDGET(widget), GTK_TOGGLE_BUTTON(check_button)->active);
1548 }
unsensitive_if_true(GtkWidget * check_button,gpointer widget)1549 void unsensitive_if_true(GtkWidget *check_button, gpointer widget) {
1550 //	Make widget sensitive if button is false, make sensitive if true
1551 	gtk_widget_set_sensitive(GTK_WIDGET(widget), !GTK_TOGGLE_BUTTON(check_button)->active);
1552 }
1553 
align_widget(GtkWidget * wdg,gfloat horizontal,gfloat vertical)1554 GtkWidget *align_widget(GtkWidget *wdg, gfloat horizontal, gfloat vertical) {
1555 //	Aligns a widget, returns the GTK_ALIGNMENT created for this purpose
1556 //	No expansion control ("scale")
1557 	GtkWidget *align_wdg;
1558 	align_wdg = gtk_alignment_new(horizontal,vertical,0.0,0.0);
1559 	gtk_container_add(GTK_CONTAINER(align_wdg), wdg);
1560 	gtk_widget_show(GTK_WIDGET(align_wdg));
1561 	return align_wdg;
1562 }
1563 
frame_new(gchar * label,gint pad)1564 GtkWidget *frame_new(gchar *label, gint pad) {
1565 	//	Standard boring frame creation
1566 	GtkWidget *frame;
1567 	frame = gtk_frame_new(_(label));
1568 	gtk_widget_show(GTK_WIDGET(frame));
1569 	gtk_frame_set_label_align(GTK_FRAME(frame),0,0);
1570 	gtk_container_set_border_width(GTK_CONTAINER(frame), pad);
1571 	return frame;
1572 }
1573 
adjust_adj_callb(GtkAdjustment * adj_trigger,gpointer adj_toadjust)1574 gint adjust_adj_callb (GtkAdjustment *adj_trigger, gpointer adj_toadjust) {
1575 	GtkAdjustment *adj;
1576 	adj = (GtkAdjustment *) adj_toadjust;
1577 	gtk_adjustment_set_value (adj, gtk_adjustment_get_value (GTK_ADJUSTMENT(adj_trigger)));
1578 	return TRUE; // Don't trigger other adj. changes
1579 }
1580 
synchro_scr_win(GtkWidget * scr_win1,GtkWidget * scr_win2)1581 void synchro_scr_win (GtkWidget *scr_win1, GtkWidget *scr_win2) {
1582 	// Synchronizes scrolled windows
1583 	// Windows should be of the same size
1584 	GtkAdjustment *vadj1, *vadj2, *hadj1, *hadj2;
1585 	vadj1 = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW(scr_win1));
1586 	hadj1 = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW(scr_win1));
1587 	vadj2 = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW(scr_win2));
1588 	hadj2 = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW(scr_win2));
1589 	gtk_signal_connect (GTK_OBJECT (vadj1), "value_changed",
1590 		(GtkSignalFunc) adjust_adj_callb, (gpointer) vadj2);
1591 	gtk_signal_connect (GTK_OBJECT (vadj2), "value_changed",
1592 		(GtkSignalFunc) adjust_adj_callb, (gpointer) vadj1);
1593 	gtk_signal_connect (GTK_OBJECT (hadj1), "value_changed",
1594 		(GtkSignalFunc) adjust_adj_callb, (gpointer) hadj2);
1595 	gtk_signal_connect (GTK_OBJECT (hadj2), "value_changed",
1596 		(GtkSignalFunc) adjust_adj_callb, (gpointer) hadj1);
1597 }
1598 
1599 /* Create a new hbox with an image and a label packed into it
1600  * and return the box. */
1601 // Adapted from the GTK+ 2.x tutorial
1602 
xpm_label_box(GtkWidget * window,gchar ** xpm,gchar * label_text)1603 GtkWidget *xpm_label_box (GtkWidget *window, gchar **xpm, gchar *label_text )
1604 {
1605     GtkWidget *box;
1606     GtkWidget *label;
1607     GtkWidget *image;
1608 
1609     /* Create box for image and label */
1610     box = gtk_hbox_new (FALSE, 0);
1611     gtk_container_set_border_width (GTK_CONTAINER (box), 2);
1612 
1613     /* Now on to the image stuff */
1614     image = create_widget_from_xpm (window,xpm) ;
1615 
1616     /* Create a label for the button */
1617     label = gtk_label_new (label_text);
1618 
1619     /* Pack the image and label into the box */
1620     gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 3);
1621     gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 3);
1622 
1623     gtk_widget_show (image);
1624     gtk_widget_show (label);
1625 
1626     return box;
1627 }
1628 
1629