Mostly minor fixes up until version 0.8.10.
[irreco.git] / irreco / src / util / irreco_misc.c
blob418a06cca93a9766cd97b3bd01b372a938a34074
1 /*
2 * irreco - Ir Remote Control
3 * Copyright (C) 2007 Arto Karppinen (arto.karppinen@iki.fi),
4 * Harri Vattulainen (t5vaha01@students.oamk.fi)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
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.
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 Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 #include "irreco_util.h"
24 #include <sys/socket.h>
25 #include <errno.h>
27 /**
28 * @addtogroup IrrecoMisc
29 * @ingroup IrrecoUtil
31 * All kinds of usefull stuff that isnt really part of Irreco. Does not
32 * pull any other Irreco headers, so it can be safely included inside backends.
34 * @{
37 /**
38 * @file
39 * Source file of @ref IrrecoMisc.
42 * Utility functions.
44 * All kinds of usefull stuff that isnt really part of Irreco. Does not pull
45 * any other Irreco headers, so it can be safely included inside backends.
48 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
49 /* Prototypes */
50 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
51 void irreco_remove_layouts(IrrecoDirForeachData *dir_data);
54 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
55 /* Public Functions */
56 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
60 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
61 /* Files and directories. */
62 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
64 /**
65 * @name Files and directories
66 * @{
69 /**
70 * Check if the given filename is a directory.
72 int irreco_is_dir(const char *filename)
74 int rval;
75 struct stat buf;
76 char *realpath = canonicalize_file_name(filename);
77 rval = (realpath != NULL) &&
78 (stat(filename, &buf) == 0) &&
79 S_ISDIR(buf.st_mode);
80 free(realpath);
81 return rval;
84 /**
85 * Check if a given file is a regular file.
87 int irreco_is_file(const char *filename)
89 int rval;
90 struct stat buf;
91 char *realpath = canonicalize_file_name(filename);
92 rval = (realpath != NULL) &&
93 (stat(filename, &buf) == 0) &&
94 S_ISREG(buf.st_mode);
95 free(realpath);
96 return rval;
99 /**
100 * Does the the file or dir exists.
102 int irreco_file_exists(const char *filename)
104 struct stat struct_stat;
105 if (stat(filename, &struct_stat) == 0) {
106 return TRUE;
108 return FALSE;
112 * Return length of file
113 * Return 0 if file doesn't exist
115 gint irreco_file_length(const gchar *filename)
117 struct stat struct_stat;
119 if(!irreco_file_exists(filename)) {
120 return 0;
123 stat(filename, &struct_stat);
124 return struct_stat.st_size;
128 * Write data to file.
130 gboolean irreco_write_file(const gchar * file, const gchar * data,
131 gsize data_size)
133 FILE *handle;
134 size_t written;
135 IRRECO_ENTER
137 if ((handle = fopen(file, "w")) == NULL) {
138 IRRECO_ERROR("Failed to open \"%s\" for writing.\n", file);
139 IRRECO_RETURN_BOOL(FALSE);
142 written = fwrite(data, sizeof(gchar), data_size, handle);
143 fclose(handle);
145 if (written != data_size) {
146 IRRECO_ERROR("Failed to write data to \"%s\". "
147 "Data size \"%u\", wrote \"%u\".\n",
148 file, data_size, written);
149 IRRECO_RETURN_BOOL(FALSE);
151 IRRECO_RETURN_BOOL(TRUE);
155 * Read contents of file into a buffer, or at least as much of the file the
156 * buffer can contain.
158 gboolean irreco_read_text_file(const gchar * file, gchar *buffer,
159 gsize buffer_size)
161 gint count;
162 FILE *fd;
164 buffer[0] = '\0';
165 if ((fd = fopen(file, "r")) == NULL) return FALSE;
166 count = fread(buffer, 1, buffer_size, fd);
167 buffer[count] = '\0';
168 if (count < 1) return FALSE;
169 return TRUE;
173 * Read contents of binary file into a buffer, or at least as much of the file the
174 * buffer can contain.
176 gboolean irreco_read_binary_file(const gchar *file, guchar *buffer,
177 gsize buffer_size, gint *binlen)
179 gint count;
180 FILE *fd;
182 if ((fd = g_fopen(file, "rb")) == NULL) return FALSE;
183 count = (gint) fread(buffer, 1, buffer_size, fd);
184 fclose(fd);
185 if (count < 1) return FALSE;
186 *binlen = count;
187 return TRUE;
191 * Read a line of text from file to buffer.
193 gboolean irreco_read_line(const gchar * file, gchar *buffer,
194 gsize buffer_size)
196 gint i;
198 if (!irreco_read_text_file(file, buffer, buffer_size)) return FALSE;
199 for (i = 0; i < buffer_size; i++) {
200 if (buffer[i] == '\0' || buffer[i] == '\n') {
201 buffer[i] = '\0';
202 return TRUE;
205 return TRUE;
209 * Write GKeyFile contents to file.
211 gboolean irreco_write_keyfile(GKeyFile * keyfile, const gchar * file)
213 gchar *data;
214 gsize data_size;
215 GError *error = NULL;
216 gboolean success;
217 IRRECO_ENTER
219 data = g_key_file_to_data(keyfile, &data_size, &error);
220 if (irreco_gerror_check_print(&error)) {
221 IRRECO_RETURN_BOOL(FALSE);
224 success = irreco_write_file(file, data, data_size);
225 g_free(data);
226 IRRECO_RETURN_BOOL(success);
230 * Read all filenames that match suffix from directory.
232 gboolean irreco_dir_foreach(IrrecoDirForeachData *dir_data,
233 IrrecoDirForeachCallback callback)
235 GError *error = NULL;
236 GDir* dir = NULL;
237 IRRECO_ENTER
239 /* Open Dir. */
240 dir = g_dir_open(dir_data->directory, 0, &error);
241 if (irreco_gerror_check_print(&error)) {
242 IRRECO_ERROR("Could not read directory: \"%s\"\n",
243 dir_data->directory);
244 if(dir != NULL){
245 g_dir_close(dir);
247 IRRECO_RETURN_BOOL(FALSE);
250 /* Read dir. */
251 while ((dir_data->filename = g_dir_read_name(dir)) != NULL) {
252 if (g_str_has_suffix(dir_data->filename,
253 dir_data->filesuffix)) {
254 dir_data->filepath = g_build_path("/",
255 dir_data->directory, dir_data->filename, NULL);
256 callback(dir_data);
257 g_free((void*)dir_data->filepath);
260 g_dir_close(dir);
261 IRRECO_RETURN_BOOL(TRUE);
267 * Read all filenames that match suffix.
268 * Searches ONLY thru subdirectories.
270 gboolean irreco_dir_foreach_subdirectories(IrrecoDirForeachData *dir_data,
271 IrrecoDirForeachCallback callback)
273 GError *error = NULL;
274 GDir *dir = NULL;
275 GDir *subdir = NULL;
276 gchar *subpath = NULL;
277 const gchar *buttonsdir;
278 const gchar *directorykeeper = dir_data->directory;
279 IRRECO_ENTER
281 /* Open Dir. */
282 dir = g_dir_open(dir_data->directory, 0, &error);
283 if (irreco_gerror_check_print(&error)) {
284 IRRECO_ERROR("Could not read directory: \"%s\"\n",
285 dir_data->directory);
286 IRRECO_RETURN_BOOL(FALSE);
289 /* Read buttons dir file by file (also directories) */
290 while ((buttonsdir = g_dir_read_name(dir)) != NULL) {
292 /* Create possible subpath from readed files */
293 subpath = g_build_path("/", dir_data->directory,
294 buttonsdir, NULL);
296 /* Test if subpath is folder */
297 if(g_file_test(subpath, G_FILE_TEST_IS_DIR)) {
299 /* Create GDir from directory or multifail instantly */
300 subdir = g_dir_open(subpath, 0, &error);
301 if (irreco_gerror_check_print(&error)) {
302 IRRECO_ERROR("Could not read dir: \"%s\"\n",
303 subpath);
304 g_free(subpath);
305 g_dir_close(dir);
306 IRRECO_RETURN_BOOL(FALSE);
309 /* Start reading files from subdirectory */
310 while ((dir_data->filename = g_dir_read_name(subdir))
311 != NULL) {
313 /* Find files with wanted suffix */
314 if (g_str_has_suffix(dir_data->filename,
315 dir_data->filesuffix)) {
317 dir_data->filepath = g_build_path("/",
318 subpath,
319 dir_data->filename,
320 NULL);
321 dir_data->directory = subpath;
322 callback(dir_data);
323 dir_data->directory = directorykeeper;
324 g_free((void*)dir_data->filepath);
328 g_free(subpath);
329 subpath = NULL;
330 g_dir_close(subdir);
331 subdir = NULL;
333 if(dir != NULL) g_dir_close(dir);
334 if(subdir != NULL) g_dir_close(subdir);
335 if(subpath != NULL) g_free(subpath);
336 IRRECO_RETURN_BOOL(TRUE);
340 * Create path to directory $HOME/.APP_NAME, and attempt to create the
341 * directory if it does not exists.
343 * @return Directory path inside a newly allocated string,
344 * or NULL if the directory could not be created.
346 gchar * irreco_get_config_dir(const gchar * app_name)
348 GString *app_name_with_dot;
349 gchar *home;
350 gchar *apphome;
351 IRRECO_ENTER
353 if ((home = getenv("HOME")) == NULL) IRRECO_RETURN_PTR(NULL);
355 app_name_with_dot = g_string_new(".");
356 g_string_append(app_name_with_dot, app_name);
357 apphome = g_build_path("/", home, app_name_with_dot->str, NULL);
358 g_string_free(app_name_with_dot, TRUE);
360 if (irreco_is_dir(apphome) == TRUE
361 || g_mkdir(apphome, 0700) == 0)
362 IRRECO_RETURN_PTR(apphome);
364 g_free(apphome);
365 IRRECO_RETURN_PTR(NULL);
369 * Get path to $HOME/.APP_NAME/FILE
371 * @return Newly allocated string which contains path to config file or NULL.
373 gchar * irreco_get_config_file(const gchar * app_name, const gchar * file)
375 gchar *config_dir;
376 gchar *config_file;
377 IRRECO_ENTER
379 if ((config_dir = irreco_get_config_dir(app_name)) != NULL) {
380 config_file = g_build_path("/", config_dir, file, NULL);
381 g_free(config_dir);
382 IRRECO_RETURN_PTR(config_file);
384 IRRECO_RETURN_PTR(NULL);
388 * Check that given filename is valid layout conf filename or create new one
390 * @return Newly allocated string containing valid layout filename
392 gchar *irreco_create_uniq_layout_filename(const gchar* filename)
394 gint i;
396 IRRECO_ENTER
398 /* Check existing file */
399 if(strlen(filename) > 11) {
400 gchar *fname;
401 fname = irreco_get_config_file("irreco",
402 filename);
403 if(irreco_file_exists(fname)) {
404 IRRECO_DEBUG("Valid and existing\n");
405 g_free(fname);
406 IRRECO_RETURN_PTR(g_strdup(filename));
407 } else {
408 g_free(fname);
409 /* Should never happen */
410 /* Conf removed while using irreco */
414 /* Create new layout[n].conf filename that doesn't already exist */
415 for(i=1; i<100; i++) {
416 gchar *fname = g_malloc0(sizeof(gchar)*25);
417 gchar *fullfname;
418 g_sprintf(fname, "layout%d.conf", i);
419 fullfname = irreco_get_config_file("irreco", fname);
420 if(irreco_file_exists(fullfname)) {
421 /* File exists */
422 g_free(fullfname);
423 g_free(fname);
424 } else {
425 IRRECO_DEBUG("Created uniq name: %s\n", fname);
426 g_free(fullfname);
427 IRRECO_RETURN_PTR(fname);
431 IRRECO_RETURN_PTR(NULL)
435 * Removes layout*.conf files, exept those on Glist
436 * Frees gchar* type data from list, not the list itself
438 gboolean irreco_remove_layouts_exept_glist(GList *list)
440 IrrecoDirForeachData dir_data;
442 IRRECO_ENTER
444 dir_data.directory = irreco_get_config_dir("irreco");
445 dir_data.filesuffix = ".conf";
446 dir_data.user_data_1 = list;
448 irreco_dir_foreach(&dir_data, irreco_remove_layouts);
450 /* Release data in glist */
451 list = g_list_first(list);
452 while(list) {
453 g_free(list->data);
454 list = list->next;
457 /* TODO get return value from somewhere */
458 IRRECO_RETURN_BOOL(TRUE)
461 /** @} */
465 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
466 /* Strings. */
467 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
470 * @name Strings
471 * @{
475 * Replace characters.
477 void irreco_char_replace(gchar * string, gchar what, gchar with)
479 gint i;
480 IRRECO_ENTER
481 for (i = 0; string[i] != '\0'; i++) {
482 if (string[i] == what) {
483 string[i] = with;
486 IRRECO_RETURN
490 * Find first occurrence of character inside string.
492 * @return Position of character or -1.
494 gint irreco_char_pos(const gchar * string, gchar what)
496 gint i;
497 IRRECO_ENTER
499 for (i = 0; string[i] != '\0'; i++) {
500 if (string[i] == what) {
501 IRRECO_RETURN_INT(i);
504 IRRECO_RETURN_INT(-1);
508 * Check if the string is empty.
510 * String is empty if it is:
511 * @li NULL
512 * @li ""
513 * @li Full of space characters.
515 gboolean irreco_str_isempty(const gchar * string)
517 IRRECO_ENTER
519 if (string == NULL || string[0] == '\0') IRRECO_RETURN_BOOL(TRUE);
520 do {
521 if (g_unichar_isspace(g_utf8_get_char(string)) == FALSE) {
522 IRRECO_RETURN_BOOL(FALSE);
524 printf("\"%s\" %p\n", string, string);
525 } while ((string = g_utf8_find_next_char(string, NULL)) != NULL
526 && string[0] != '\0');
528 IRRECO_RETURN_BOOL(TRUE);
532 * Copy C-string into GString.
534 void irreco_gstring_set(GString * g_str, const gchar * c_str)
536 IRRECO_ENTER
538 if (c_str == NULL) {
539 g_string_assign(g_str, "");
540 } else {
541 g_string_assign(g_str, c_str);
544 IRRECO_RETURN
548 * Copy C-string into GString and free C-string.
550 void irreco_gstring_set_and_free(GString * g_str, gchar * c_str)
552 IRRECO_ENTER
554 if (c_str == NULL) {
555 g_string_assign(g_str, "");
556 } else {
557 g_string_assign(g_str, c_str);
558 g_free(c_str);
561 IRRECO_RETURN
564 /** @} */
567 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
568 /* Error handling. */
569 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
572 * @name Error handling
573 * @{
578 * If GError is set, print message, release GError, and return TRUE.
579 * Otherwise returns FALSE.
581 gboolean irreco_gerror_check_print(GError ** error)
583 if (*error != NULL) {
584 IRRECO_PRINTF("GError: %s\n", (*error)->message);
585 g_error_free(*error);
586 *error = NULL;
587 return TRUE;
589 return FALSE;
593 * If GError is set, free it, and return TRUE.
594 * Otherwise returns FALSE.
596 gboolean irreco_gerror_check_free(GError ** error)
598 if (*error != NULL) {
599 g_error_free(*error);
600 *error = NULL;
601 return TRUE;
603 return FALSE;
606 /** @} */
608 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
609 /* GTK. */
610 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
613 * @name GTK
614 * @{
618 * Show info popup.
620 void irreco_info_dlg(GtkWindow * parent_window, const gchar * message)
622 GtkWidget* dialog;
623 IRRECO_ENTER
625 dialog = gtk_message_dialog_new(parent_window,
626 GTK_DIALOG_DESTROY_WITH_PARENT,
627 GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "%s", message);
628 gtk_dialog_run(GTK_DIALOG(dialog));
629 gtk_widget_destroy(dialog);
631 IRRECO_RETURN
635 * Show error popup.
637 void irreco_error_dlg(GtkWindow * parent_window, const gchar * message)
639 GtkWidget* dialog;
640 IRRECO_ENTER
642 dialog = gtk_message_dialog_new(parent_window,
643 GTK_DIALOG_DESTROY_WITH_PARENT,
644 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", message);
645 gtk_dialog_run(GTK_DIALOG(dialog));
646 gtk_widget_destroy(dialog);
648 IRRECO_RETURN
652 * Format message, and show error popup.
654 void irreco_info_dlg_printf(GtkWindow * parent_window,
655 const gchar * format, ...)
657 gint rvalue;
658 va_list args;
659 gchar *message = NULL;
660 IRRECO_ENTER
662 va_start(args, format);
663 rvalue = g_vasprintf(&message, format, args);
664 va_end(args);
666 if (rvalue > 0) {
667 irreco_info_dlg(parent_window, message);
668 g_free(message);
669 } else {
670 IRRECO_ERROR("Could not format message.\n");
673 IRRECO_RETURN
677 * Format message, and show error popup.
679 void irreco_error_dlg_printf(GtkWindow * parent_window,
680 const gchar * format, ...)
682 gint rvalue;
683 va_list args;
684 gchar *message = NULL;
685 IRRECO_ENTER
687 va_start(args, format);
688 rvalue = g_vasprintf(&message, format, args);
689 va_end(args);
691 if (rvalue > 0) {
692 irreco_error_dlg(parent_window, message);
693 g_free(message);
694 } else {
695 IRRECO_ERROR("Could not format message.\n");
698 IRRECO_RETURN
702 * Popup yes / no dialog.
704 * Returns: TRUE if user click YES, FALSE otherwise.
706 gboolean irreco_yes_no_dlg(GtkWindow * parent_window, const gchar * message)
708 gint responce;
709 GtkWidget* dialog;
710 IRRECO_ENTER
712 dialog = gtk_message_dialog_new(parent_window,
713 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION,
714 GTK_BUTTONS_YES_NO, "%s", message);
715 responce = gtk_dialog_run(GTK_DIALOG(dialog));
716 gtk_widget_destroy(dialog);
717 IRRECO_RETURN_BOOL(responce == GTK_RESPONSE_YES);
721 * Convenience frapper of gtk_alignment_new().
723 GtkWidget *irreco_gtk_align(GtkWidget *child,
724 gfloat xalign,
725 gfloat yalign,
726 gfloat xscale,
727 gfloat yscale,
728 guint padding_top,
729 guint padding_bottom,
730 guint padding_left,
731 guint padding_right)
733 GtkWidget *align;
734 IRRECO_ENTER
736 align = gtk_alignment_new(xalign, yalign, xscale, yscale);
737 gtk_alignment_set_padding(GTK_ALIGNMENT(align), padding_top,
738 padding_bottom, padding_left, padding_right);
739 gtk_container_add(GTK_CONTAINER(align), child);
740 IRRECO_RETURN_PTR(align);
744 * Create, align, and pad label.
746 GtkWidget *irreco_gtk_label(const gchar * str,
747 gfloat xalign,
748 gfloat yalign,
749 guint padding_top,
750 guint padding_bottom,
751 guint padding_left,
752 guint padding_right)
754 GtkWidget *label;
755 IRRECO_ENTER
757 label = gtk_label_new(str);
758 gtk_misc_set_alignment(GTK_MISC(label), xalign, yalign);
759 IRRECO_RETURN_PTR(irreco_gtk_pad(label, padding_top, padding_bottom,
760 padding_left, padding_right));
764 * Create, align, and pad a label with bold text.
766 GtkWidget *irreco_gtk_label_bold(const gchar * str,
767 gfloat xalign,
768 gfloat yalign,
769 guint padding_top,
770 guint padding_bottom,
771 guint padding_left,
772 guint padding_right)
774 gchar* markup;
775 GtkWidget *label;
776 IRRECO_ENTER
778 label = irreco_gtk_label(NULL, xalign, yalign, padding_top,
779 padding_bottom, padding_left, padding_right);
780 markup = g_markup_printf_escaped("<b>%s</b>", str);
781 gtk_label_set_markup(GTK_LABEL(gtk_bin_get_child(GTK_BIN(label))),
782 markup);
783 g_free(markup);
784 IRRECO_RETURN_PTR(label);
788 * Get button widget for dialog buttons.
790 * @param dialog GtkDialog
791 * @param n Index of button to get.
793 GtkWidget *irreco_gtk_dialog_get_button(GtkWidget *dialog, guint n)
796 GtkBox *action_area;
797 GtkBoxChild *box_child;
798 guint length;
799 IRRECO_ENTER
801 action_area = GTK_BOX(GTK_DIALOG(dialog)->action_area);
802 length = g_list_length(action_area->children);
804 if (n >= length) {
805 IRRECO_ERROR("Cant get button \"%i\". "
806 "Dialog has only \"%i\" buttons", n, length);
807 IRRECO_RETURN_PTR(NULL);
810 box_child = (GtkBoxChild *) g_list_nth_data(g_list_first(
811 action_area->children), n);
812 IRRECO_RETURN_PTR(box_child->widget);
815 GtkWindow *irreco_gtk_get_parent_window(GtkWidget *widget)
817 GtkWidget *parent;
818 IRRECO_ENTER
820 parent = gtk_widget_get_toplevel(widget);
821 if (GTK_WIDGET_TOPLEVEL(parent) != TRUE
822 || GTK_IS_WINDOW(parent) != TRUE) {
823 IRRECO_RETURN_PTR(GTK_WINDOW(parent));
825 IRRECO_RETURN_PTR(NULL);
829 * This function is a modified version of gtk_dialog_new_empty() from GTK
830 * sources, which is used to by gtk_dialog_new_with_buttons() to set the
831 * settings of a dialog.
833 void irreco_gtk_dialog_set(GtkDialog *dialog,
834 const gchar *title,
835 GtkWindow *parent,
836 GtkDialogFlags flags)
838 IRRECO_ENTER
840 if (title)
841 gtk_window_set_title(GTK_WINDOW (dialog), title);
843 if (parent)
844 gtk_window_set_transient_for(GTK_WINDOW (dialog), parent);
846 if (flags & GTK_DIALOG_MODAL)
847 gtk_window_set_modal(GTK_WINDOW (dialog), TRUE);
849 if (flags & GTK_DIALOG_DESTROY_WITH_PARENT)
850 gtk_window_set_destroy_with_parent(GTK_WINDOW (dialog), TRUE);
852 if (flags & GTK_DIALOG_NO_SEPARATOR)
853 gtk_dialog_set_has_separator(dialog, FALSE);
855 IRRECO_RETURN
858 /** @} */
860 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
861 /* Time. */
862 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
865 * @name Time
866 * @{
871 * Do not use, use GTimer instead.
873 * @deprecated
875 * Difference of time in microseconds between two GTimeVals.
876 * This works fine as long as the difference is no more than 2146 seconds.
878 glong irreco_time_diff(GTimeVal *start, GTimeVal *end)
880 GTimeVal diff;
881 IRRECO_ENTER
883 diff.tv_sec = end->tv_sec - start->tv_sec;
884 diff.tv_usec = end->tv_usec - start->tv_usec;
886 /* We run out of space in ulong after 2147 seconds. */
887 if (diff.tv_sec >= G_MAXLONG / IRRECO_SECOND_IN_USEC) {
888 IRRECO_RETURN_LONG((G_MAXLONG / IRRECO_SECOND_IN_USEC)
889 * IRRECO_SECOND_IN_USEC);
892 IRRECO_RETURN_LONG(diff.tv_sec * IRRECO_SECOND_IN_USEC + diff.tv_usec);
895 /** @} */
897 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
898 /* Socket. */
899 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
902 * @name Socket
903 * @{
907 * Check if the socket is valid.
909 gboolean irreco_is_socket_valid(int socket)
911 gint optval;
912 socklen_t optlen;
913 gint rvalue;
914 IRRECO_ENTER
916 /* This should succeed if socket is valid. */
917 rvalue = getsockopt(socket, SOL_SOCKET, SOCK_STREAM, &optval, &optlen);
919 if (rvalue == 0) {
920 IRRECO_RETURN_BOOL(TRUE);
921 } else {
923 /* glibc docs say these are the possible error values. */
924 switch (errno) {
925 case EBADF: IRRECO_PRINTF("Error: EBADF\n"); break;
926 case ENOTSOCK: IRRECO_PRINTF("Error: ENOTSOCK\n"); break;
927 case ENOPROTOOPT: IRRECO_PRINTF("Error: ENOPROTOOPT\n"); break;
928 default: IRRECO_PRINTF("Error: Unknown\n"); break;
931 IRRECO_RETURN_BOOL(FALSE);
935 /** @} */
938 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
939 /* Private Functions */
940 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
942 * @name Private
943 * @{
947 * Removes layout* files that are not in (GList) dir_data->user_data_1
950 void irreco_remove_layouts(IrrecoDirForeachData *dir_data)
952 GList *list = NULL;
953 gchar *rm_cmd;
955 IRRECO_ENTER
957 if(!g_str_has_prefix(dir_data->filename, "layout")) {
958 IRRECO_DEBUG("Not layout file: %s\n", dir_data->filename);
959 IRRECO_RETURN
962 list = g_list_first(dir_data->user_data_1);
964 while(list) {
965 IRRECO_DEBUG("file in list: %s file to remove: %s\n",
966 (gchar*) list->data,
967 dir_data->filename);
968 if(strcmp((gchar*) list->data, dir_data->filename) == 0) {
969 IRRECO_DEBUG("File in use, break\n");
970 IRRECO_RETURN
972 list = list->next;
975 IRRECO_DEBUG("Removing unused conf: %s\n", dir_data->filename);
977 /* Build remove command */
978 rm_cmd = g_strconcat("rm -r ",
979 irreco_get_config_dir("irreco"),
980 "/",
981 dir_data->filename,
982 NULL);
984 /* Execute remove */
985 system(rm_cmd);
987 g_free(rm_cmd);
989 IRRECO_RETURN
992 /** @} */
994 /** @} */