source: trunk/third/gnome-core/panel/panel-util.c @ 17152

Revision 17152, 18.4 KB checked in by ghudson, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r17151, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * GNOME panel utils
3 * (C) 1997, 1998, 1999, 2000 The Free Software Foundation
4 * Copyright 2000 Helix Code, Inc.
5 * Copyright 2000,2001 Eazel, Inc.
6 * Copyright 2001 George Lebl
7 *
8 * Authors: George Lebl
9 *          Jacob Berkman
10 */
11
12#include <config.h>
13#include <string.h>
14#include <glib.h>
15#include <sys/types.h>
16#include <fcntl.h>
17#include <dirent.h>
18
19#include "panel-include.h"
20
21#include "icon-entry-hack.h"
22
23extern GlobalConfig global_config;
24
25extern GSList *applets;
26extern GSList *applets_last;
27
28void
29panel_show_help (const char *path)
30{
31        GnomeHelpMenuEntry help_entry = { "panel" };
32        help_entry.path = (char *)path;
33        gnome_help_display (NULL, &help_entry);
34}
35
36static char *
37panel_gnome_help_path (const char *docpath)
38{
39        char *fullpath, *app, *p, *path, *uri;
40
41        app = g_strdup (docpath);
42
43        p = strchr (app, '/');
44
45        if (p == NULL) {
46                g_free (app);
47                return NULL;
48        }
49
50        path = p+1;
51        *p = '\0';
52
53        fullpath = gnome_help_file_path (app, path);
54
55        g_free (app);
56
57        if ( ! panel_file_exists (fullpath)) {
58                g_free (fullpath);
59                fullpath = NULL;
60        }
61
62        uri = g_strconcat ("ghelp:", fullpath, NULL);
63        g_free (fullpath);
64
65        return uri;
66}
67
68static char *
69panel_kde_help_path (const char *docpath)
70{
71        GList *li;
72
73        if ( ! panel_file_exists (KDE_DOCDIR))
74                return NULL;
75
76        for (li = gnome_i18n_get_language_list ("LC_MESSAGES");
77             li != NULL;
78             li = li->next) {
79                char *fullpath = g_strdup_printf ("%s/HTML/%s/%s",
80                                                  KDE_DOCDIR,
81                                                  (char *)li->data,
82                                                  docpath);
83                if (panel_file_exists (fullpath)) {
84                        char *uri = g_strconcat ("ghelp:", fullpath, NULL);
85                        g_free (fullpath);
86                        return uri;
87                }
88                g_free (fullpath);
89        }
90        return NULL;
91}
92
93char *
94panel_gnome_kde_help_path (const char *docpath)
95{
96        char *path;
97
98        if (string_empty (docpath))
99                return NULL;
100
101        if (panel_is_url (docpath))
102                return g_strdup (docpath);
103
104        path = panel_gnome_help_path (docpath);
105
106        if (path == NULL)
107                path = panel_kde_help_path (docpath);
108
109        return path;
110}
111
112gboolean
113string_is_in_list(const GSList *list, const char *text)
114{
115        for(;list != NULL; list = list->next)
116                if(strcmp(text,(char *)list->data) == 0)
117                        return TRUE;
118        return FALSE;
119}
120
121static void
122updated (GtkWidget *w, gpointer data)
123{
124        UpdateFunction func = gtk_object_get_data (GTK_OBJECT (w), "update_function");
125
126        func (data);
127}
128
129GtkWidget *
130create_text_entry(GtkWidget *table,
131                  const char *history_id,
132                  int row,
133                  const char *label,
134                  const char *text,
135                  UpdateFunction func,
136                  gpointer data)
137{
138        GtkWidget *wlabel;
139        GtkWidget *entry;
140        GtkWidget *t;
141
142        wlabel = gtk_label_new(label);
143        gtk_misc_set_alignment(GTK_MISC(wlabel), 0.0, 0.5);
144        gtk_table_attach(GTK_TABLE(table), wlabel,
145                         0, 1, row, row + 1,
146                         GTK_EXPAND | GTK_FILL | GTK_SHRINK,
147                         GTK_FILL | GTK_SHRINK,
148                         GNOME_PAD_SMALL, GNOME_PAD_SMALL);
149        gtk_widget_show(wlabel);
150
151        entry = gnome_entry_new(history_id);
152        t = gnome_entry_gtk_entry (GNOME_ENTRY (entry));
153        if (text)
154                gtk_entry_set_text(GTK_ENTRY(t), text);
155        gtk_table_attach(GTK_TABLE(table), entry,
156                         1, 2, row, row + 1,
157                         GTK_EXPAND | GTK_FILL | GTK_SHRINK,
158                         GTK_FILL | GTK_SHRINK,
159                         GNOME_PAD_SMALL, GNOME_PAD_SMALL);
160
161        if(func) {
162                gtk_object_set_data (GTK_OBJECT (t), "update_function", func);
163                gtk_signal_connect (GTK_OBJECT (t), "changed",
164                                    GTK_SIGNAL_FUNC (updated),
165                                    data);
166        }
167        return entry;
168}
169
170GtkWidget *
171create_icon_entry(GtkWidget *table,
172                  const char *history_id,
173                  int cols, int cole,
174                  const char *label,
175                  const char *subdir,
176                  const char *text,
177                  UpdateFunction func,
178                  gpointer data)
179{
180        GtkWidget *wlabel;
181        GtkWidget *entry;
182        GtkWidget *t;
183
184        wlabel = gtk_label_new(label);
185        gtk_misc_set_alignment(GTK_MISC(wlabel), 0.0, 0.5);
186        gtk_table_attach(GTK_TABLE(table), wlabel,
187                         cols, cole, 2, 3,
188                         GTK_SHRINK,
189                         GTK_EXPAND | GTK_FILL | GTK_SHRINK,
190                         GNOME_PAD_SMALL, GNOME_PAD_SMALL);
191        gtk_widget_show(wlabel);
192
193        entry = gnome_icon_entry_new(history_id,_("Browse"));
194        hack_icon_entry (GNOME_ICON_ENTRY (entry));
195
196        gnome_icon_entry_set_pixmap_subdir(GNOME_ICON_ENTRY(entry), subdir);
197        if (text)
198                hack_icon_entry_set_icon(GNOME_ICON_ENTRY(entry),text);
199
200        t = gnome_icon_entry_gtk_entry (GNOME_ICON_ENTRY (entry));
201        gtk_table_attach(GTK_TABLE(table), entry,
202                         cols, cole, 1, 2,
203                         GTK_EXPAND | GTK_FILL | GTK_SHRINK,
204                         GTK_FILL | GTK_SHRINK,
205                         GNOME_PAD_SMALL, GNOME_PAD_SMALL);
206
207        if(func) {
208                gtk_object_set_data (GTK_OBJECT (t), "update_function", func);
209                gtk_signal_connect (GTK_OBJECT (t), "changed",
210                                    GTK_SIGNAL_FUNC (updated),
211                                    data);
212        }
213
214        return entry;
215}
216
217GList *
218my_g_list_swap_next (GList *list, GList *dl)
219{
220        GList *t;
221
222        if(!dl->next)
223                return list;
224        if(dl->prev)
225                dl->prev->next = dl->next;
226        t = dl->prev;
227        dl->prev = dl->next;
228        dl->next->prev = t;
229        if(dl->next->next)
230                dl->next->next->prev = dl;
231        t = dl->next->next;
232        dl->next->next = dl;
233        dl->next = t;
234
235        if(list == dl)
236                return dl->prev;
237        return list;
238}
239
240GList *
241my_g_list_swap_prev (GList *list, GList *dl)
242{
243        GList *t;
244
245        if(!dl->prev)
246                return list;
247        if(dl->next)
248                dl->next->prev = dl->prev;
249        t = dl->next;
250        dl->next = dl->prev;
251        dl->prev->next = t;
252        if(dl->prev->prev)
253                dl->prev->prev->next = dl;
254        t = dl->prev->prev;
255        dl->prev->prev = dl;
256        dl->prev = t;
257
258        if(list == dl->next)
259                return dl;
260        return list;
261}
262
263/*maybe this should be a glib function?
264 it resorts a single item in the list*/
265GList *
266my_g_list_resort_item(GList *list, gpointer data, GCompareFunc func)
267{
268        GList *dl;
269
270        if(!list)
271                return NULL;
272
273        dl = g_list_find(list,data);
274
275        g_return_val_if_fail(dl!=NULL,list);
276
277        while(dl->next &&
278              (*func)(dl->data,dl->next->data)>0)
279                list=my_g_list_swap_next(list,dl);
280        while(dl->prev &&
281              (*func)(dl->data,dl->prev->data)<0)
282                list=my_g_list_swap_prev(list,dl);
283        return list;
284}
285
286/*following code shamelessly stolen from gtk*/
287static void
288rgb_to_hls (gdouble *r,
289            gdouble *g,
290            gdouble *b)
291{
292  gdouble min;
293  gdouble max;
294  gdouble red;
295  gdouble green;
296  gdouble blue;
297  gdouble h, l, s;
298  gdouble delta;
299
300  red = *r;
301  green = *g;
302  blue = *b;
303
304  if (red > green)
305    {
306      if (red > blue)
307        max = red;
308      else
309        max = blue;
310
311      if (green < blue)
312        min = green;
313      else
314        min = blue;
315    }
316  else
317    {
318      if (green > blue)
319        max = green;
320      else
321        max = blue;
322
323      if (red < blue)
324        min = red;
325      else
326        min = blue;
327    }
328
329  l = (max + min) / 2;
330  s = 0;
331  h = 0;
332
333  if (max != min)
334    {
335      if (l <= 0.5)
336        s = (max - min) / (max + min);
337      else
338        s = (max - min) / (2 - max - min);
339
340      delta = max -min;
341      if (red == max)
342        h = (green - blue) / delta;
343      else if (green == max)
344        h = 2 + (blue - red) / delta;
345      else if (blue == max)
346        h = 4 + (red - green) / delta;
347
348      h *= 60;
349      if (h < 0.0)
350        h += 360;
351    }
352
353  *r = h;
354  *g = l;
355  *b = s;
356}
357
358static void
359hls_to_rgb (gdouble *h,
360            gdouble *l,
361            gdouble *s)
362{
363  gdouble hue;
364  gdouble lightness;
365  gdouble saturation;
366  gdouble m1, m2;
367  gdouble r, g, b;
368
369  lightness = *l;
370  saturation = *s;
371
372  if (lightness <= 0.5)
373    m2 = lightness * (1 + saturation);
374  else
375    m2 = lightness + saturation - lightness * saturation;
376  m1 = 2 * lightness - m2;
377
378  if (saturation == 0)
379    {
380      *h = lightness;
381      *l = lightness;
382      *s = lightness;
383    }
384  else
385    {
386      hue = *h + 120;
387      while (hue > 360)
388        hue -= 360;
389      while (hue < 0)
390        hue += 360;
391
392      if (hue < 60)
393        r = m1 + (m2 - m1) * hue / 60;
394      else if (hue < 180)
395        r = m2;
396      else if (hue < 240)
397        r = m1 + (m2 - m1) * (240 - hue) / 60;
398      else
399        r = m1;
400
401      hue = *h;
402      while (hue > 360)
403        hue -= 360;
404      while (hue < 0)
405        hue += 360;
406
407      if (hue < 60)
408        g = m1 + (m2 - m1) * hue / 60;
409      else if (hue < 180)
410        g = m2;
411      else if (hue < 240)
412        g = m1 + (m2 - m1) * (240 - hue) / 60;
413      else
414        g = m1;
415
416      hue = *h - 120;
417      while (hue > 360)
418        hue -= 360;
419      while (hue < 0)
420        hue += 360;
421
422      if (hue < 60)
423        b = m1 + (m2 - m1) * hue / 60;
424      else if (hue < 180)
425        b = m2;
426      else if (hue < 240)
427        b = m1 + (m2 - m1) * (240 - hue) / 60;
428      else
429        b = m1;
430
431      *h = r;
432      *l = g;
433      *s = b;
434    }
435}
436
437static void
438gtk_style_shade (GdkColor *a,
439                 GdkColor *b,
440                 gdouble   k)
441{
442  gdouble red;
443  gdouble green;
444  gdouble blue;
445
446  red = (gdouble) a->red / 65535.0;
447  green = (gdouble) a->green / 65535.0;
448  blue = (gdouble) a->blue / 65535.0;
449
450  rgb_to_hls (&red, &green, &blue);
451
452  green *= k;
453  if (green > 1.0)
454    green = 1.0;
455  else if (green < 0.0)
456    green = 0.0;
457
458  blue *= k;
459  if (blue > 1.0)
460    blue = 1.0;
461  else if (blue < 0.0)
462    blue = 0.0;
463
464  hls_to_rgb (&red, &green, &blue);
465
466  b->red = red * 65535.0;
467  b->green = green * 65535.0;
468  b->blue = blue * 65535.0;
469}
470
471#define LIGHTNESS_MULT  1.3
472#define DARKNESS_MULT   0.7
473
474static void
475set_color_back (GtkWidget *widget, PanelWidget *panel)
476{
477        GtkStyle *ns;
478        int i;
479
480        gtk_widget_set_rc_style (widget);
481        ns = gtk_style_copy (gtk_widget_get_style (widget));
482
483        ns->bg[GTK_STATE_NORMAL] =
484                panel->back_color;
485        gtk_style_shade (&panel->back_color,
486                         &ns->bg[GTK_STATE_PRELIGHT],1.5);
487        gtk_style_shade (&panel->back_color,
488                         &ns->bg[GTK_STATE_ACTIVE],0.8);
489        ns->bg[GTK_STATE_INSENSITIVE] =
490                panel->back_color;
491
492        for (i = 0; i < 5; i++) {
493                gtk_style_shade (&ns->bg[i], &ns->light[i], LIGHTNESS_MULT);
494                gtk_style_shade (&ns->bg[i], &ns->dark[i], DARKNESS_MULT);
495
496                ns->mid[i].red = (ns->light[i].red + ns->dark[i].red) / 2;
497                ns->mid[i].green = (ns->light[i].green + ns->dark[i].green) / 2;
498                ns->mid[i].blue = (ns->light[i].blue + ns->dark[i].blue) / 2;
499        }
500        gtk_widget_set_style (widget, ns);
501        gtk_style_unref (ns);
502}
503
504void
505set_frame_colors (PanelWidget *panel, GtkWidget *frame,
506                  GtkWidget *but1, GtkWidget *but2,
507                  GtkWidget *but3, GtkWidget *but4)
508{
509        if (panel->back_type == PANEL_BACK_COLOR) {
510                set_color_back (frame, panel);
511                set_color_back (but1, panel);
512                set_color_back (but2, panel);
513                set_color_back (but3, panel);
514                set_color_back (but4, panel);
515        } else {
516                gtk_widget_set_rc_style (frame);
517                gtk_widget_set_rc_style (but1);
518                gtk_widget_set_rc_style (but2);
519                gtk_widget_set_rc_style (but3);
520                gtk_widget_set_rc_style (but4);
521        }
522}
523
524
525void
526remove_directory(const char *dirname, gboolean just_clean)
527{
528        DIR *dir;
529        struct dirent *dent;
530        char *oldcwd;
531
532        dir = opendir (dirname);
533        if(!dir) return;
534        oldcwd = g_get_current_dir();
535
536        chdir(dirname);
537        while((dent = readdir (dir)) != NULL) {
538                if(strcmp(dent->d_name,".")==0 ||
539                   strcmp(dent->d_name,"..")==0)
540                        continue;
541                if(g_file_test(dent->d_name,G_FILE_TEST_ISDIR))
542                        remove_directory(dent->d_name, FALSE);
543                else
544                        unlink(dent->d_name);
545        }
546        closedir(dir);
547        chdir(oldcwd);
548
549        if(!just_clean)
550                rmdir(dirname);
551        g_free(oldcwd);
552}
553
554char *
555strtok_with_escape(char *string, const char *seps, gboolean empty)
556{
557        char *our_string;
558        static char *p = NULL;
559
560        g_return_val_if_fail(seps != NULL, NULL);
561
562        if(string)
563                p = string;
564        else if(!p)
565                return NULL;
566
567        our_string = p;
568        while(*p) {
569                if(*p == '\\' && *(p+1)) {
570                        strcpy(p,p+1);
571                } else if(strchr(seps,*p)) {
572                        *p = '\0';
573                        if(empty || *our_string) {
574                                p++;
575                                return our_string;
576                        }
577
578                        /* this was an empty part and
579                           we don't want to return empty
580                           parts, so skip it */
581                        our_string = p+1;
582                }
583                p++;
584        }
585        p = NULL;
586
587        if(!empty && !*our_string)
588                return NULL;
589        return our_string;
590}
591
592/* return a newly allocated string that escapes / and 'special' */
593char *
594escape_string(const char *string, const char *special)
595{
596        int count;
597        const char *p;
598        char *ret;
599        int i;
600
601        if(!string) return NULL;
602
603        g_return_val_if_fail(special != NULL, NULL);
604
605        for(p=string,count=0; *p; p++,count++) {
606                if(*p == '\\' ||
607                   strchr(special,*p))
608                        count++;
609        }
610
611        ret = g_new(char,count+1);
612        i = 0;
613        for(p=string; *p; p++) {
614                if(*p == '\\' ||
615                   strchr(special,*p))
616                        ret[i++] = '\\';
617                ret[i++] = *p;
618        }
619        ret[i] = '\0';
620
621        return ret;
622}
623
624gboolean
625convert_string_to_keysym_state(const char *string,
626                               guint *keysym,
627                               guint *state)
628{
629        char *s, *p;
630
631        g_return_val_if_fail (keysym != NULL, FALSE);
632        g_return_val_if_fail (state != NULL, FALSE);
633       
634        *state = 0;
635        *keysym = 0;
636
637        if(string_empty (string) ||
638           strcmp (string, "Disabled") == 0 ||
639           strcmp (string, _("Disabled")) == 0)
640                return FALSE;
641
642        s = g_strdup (string);
643
644        gdk_error_trap_push ();
645
646        p = strtok (s, "-");
647        while (p != NULL) {
648                if(strcmp(p, "Control")==0) {
649                        *state |= GDK_CONTROL_MASK;
650                } else if(strcmp(p, "Lock")==0) {
651                        *state |= GDK_LOCK_MASK;
652                } else if(strcmp(p, "Shift")==0) {
653                        *state |= GDK_SHIFT_MASK;
654                } else if(strcmp(p, "Mod1")==0) {
655                        *state |= GDK_MOD1_MASK;
656                } else if(strcmp(p, "Mod2")==0) {
657                        *state |= GDK_MOD2_MASK;
658                } else if(strcmp(p, "Mod3")==0) {
659                        *state |= GDK_MOD3_MASK;
660                } else if(strcmp(p, "Mod4")==0) {
661                        *state |= GDK_MOD4_MASK;
662                } else if(strcmp(p, "Mod5")==0) {
663                        *state |= GDK_MOD5_MASK;
664                } else {
665                        *keysym = gdk_keyval_from_name(p);
666                        if(*keysym == 0) {
667                                gdk_flush();
668                                gdk_error_trap_pop();
669                                g_free(s);
670                                return FALSE;
671                        }
672                }
673                p = strtok(NULL, "-");
674        }
675
676        gdk_flush ();
677        gdk_error_trap_pop ();
678
679        g_free (s);
680
681        if (*keysym == 0)
682                return FALSE;
683
684        return TRUE;
685}
686
687char *
688convert_keysym_state_to_string(guint keysym,
689                               guint state)
690{
691        GString *gs;
692        char *sep = "";
693        char *key;
694
695        if(keysym == 0)
696                return g_strdup(_("Disabled"));
697
698        gdk_error_trap_push();
699        key = gdk_keyval_name(keysym);
700        gdk_flush();
701        gdk_error_trap_pop();
702        if(!key) return NULL;
703
704        gs = g_string_new(NULL);
705
706        if(state & GDK_CONTROL_MASK) {
707                /*g_string_append(gs, sep);*/
708                g_string_append(gs, "Control");
709                sep = "-";
710        }
711        if(state & GDK_LOCK_MASK) {
712                g_string_append(gs, sep);
713                g_string_append(gs, "Lock");
714                sep = "-";
715        }
716        if(state & GDK_SHIFT_MASK) {
717                g_string_append(gs, sep);
718                g_string_append(gs, "Shift");
719                sep = "-";
720        }
721        if(state & GDK_MOD1_MASK) {
722                g_string_append(gs, sep);
723                g_string_append(gs, "Mod1");
724                sep = "-";
725        }
726        if(state & GDK_MOD2_MASK) {
727                g_string_append(gs, sep);
728                g_string_append(gs, "Mod2");
729                sep = "-";
730        }
731        if(state & GDK_MOD3_MASK) {
732                g_string_append(gs, sep);
733                g_string_append(gs, "Mod3");
734                sep = "-";
735        }
736        if(state & GDK_MOD4_MASK) {
737                g_string_append(gs, sep);
738                g_string_append(gs, "Mod4");
739                sep = "-";
740        }
741        if(state & GDK_MOD5_MASK) {
742                g_string_append(gs, sep);
743                g_string_append(gs, "Mod5");
744                sep = "-";
745        }
746
747        g_string_append(gs, sep);
748        g_string_append(gs, key);
749
750        {
751                char *ret = gs->str;
752                g_string_free(gs, FALSE);
753                return ret;
754        }
755}
756
757static GSList *layered_dialogs = NULL;
758
759static void
760panel_dialog_realized (GtkWidget *dialog)
761{
762        if ( ! global_config.keep_bottom &&
763             ! global_config.normal_layer)
764                gnome_win_hints_set_layer (GTK_WIDGET(dialog),
765                                           WIN_LAYER_ABOVE_DOCK);
766        else
767                gnome_win_hints_set_layer (GTK_WIDGET (dialog),
768                                           WIN_LAYER_NORMAL);
769}
770
771static void
772remove_from_layered (GtkWidget *w)
773{
774        layered_dialogs = g_slist_remove (layered_dialogs, w);
775}
776
777void
778panel_set_dialog_layer (GtkWidget *dialog)
779{
780        if (g_slist_find (layered_dialogs, dialog) == NULL) {
781                layered_dialogs = g_slist_prepend (layered_dialogs, dialog);
782                gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
783                                    GTK_SIGNAL_FUNC (remove_from_layered),
784                                    NULL);
785        }
786
787        if (GTK_WIDGET_REALIZED (dialog) &&
788            ! global_config.normal_layer &&
789            ! global_config.keep_bottom)
790                gnome_win_hints_set_layer (GTK_WIDGET (dialog),
791                                           WIN_LAYER_ABOVE_DOCK);
792
793        gtk_signal_connect (GTK_OBJECT (dialog), "realize",
794                            GTK_SIGNAL_FUNC (panel_dialog_realized),
795                            NULL);
796}
797
798void
799panel_reset_dialog_layers (void)
800{
801        GSList *li;
802
803        for (li = layered_dialogs; li != NULL; li = li->next) {
804                GtkWidget *dialog = li->data;
805
806                if ( ! GTK_WIDGET_REALIZED (dialog))
807                        continue;
808
809                if ( ! global_config.normal_layer &&
810                     ! global_config.keep_bottom)
811                        gnome_win_hints_set_layer (GTK_WIDGET (dialog),
812                                                   WIN_LAYER_ABOVE_DOCK);
813                else
814                        gnome_win_hints_set_layer (GTK_WIDGET (dialog),
815                                                   WIN_LAYER_NORMAL);
816        }
817}
818
819GtkWidget *
820panel_error_dialog (const char *format, ...)
821{
822        GtkWidget *w;
823        char *s;
824        va_list ap;
825
826        if (format == NULL) {
827                g_warning ("NULL error dialog");
828                s = g_strdup ("(null)");
829        } else {
830                va_start (ap, format);
831                s = g_strdup_vprintf (format, ap);
832                va_end (ap);
833        }
834
835        w = gnome_error_dialog (s);
836        g_free (s);
837
838        panel_set_dialog_layer (w);
839
840        return w;
841}
842
843gboolean
844string_empty (const char *string)
845{
846        if (string == NULL ||
847            string[0] == '\0')
848                return TRUE;
849        else
850                return FALSE;
851}
852
853gboolean
854is_ext (const char *file, const char *ext)
855{
856        const char *p = strrchr (file, '.');
857
858        if (p != NULL &&
859            strcmp (p, ext) == 0)
860                return TRUE;
861        else
862                return FALSE;
863}
864
865/* Do strcasecmp but ignore locale */
866int
867strcasecmp_no_locale (const char *s1, const char *s2)
868{
869        int i;
870
871        /* Error, but don't make them equal then */
872        g_return_val_if_fail (s1 != NULL, G_MAXINT);
873        g_return_val_if_fail (s2 != NULL, G_MININT);
874
875        for (i = 0; s1[i] != '\0' && s2[i] != '\0'; i++) {
876                char a = s1[i];
877                char b = s2[i];
878
879                if (a >= 'A' && a <= 'Z')
880                        a -= 'A' - 'a';
881                if (b >= 'A' && b <= 'Z')
882                        b -= 'A' - 'a';
883
884                if (a < b)
885                        return -1;
886                else if (a > b)
887                        return 1;
888        }
889
890        /* find out which string is smaller */
891        if (s2[i] != '\0')
892                return -1; /* s1 is smaller */
893        else if (s1[i] != '\0')
894                return 1; /* s2 is smaller */
895        else
896                return 0; /* equal */
897}
898
899/* stolen from gnome-libs head as they are faster and don't use "stat" */
900gboolean
901panel_file_exists (const char *filename)
902{
903        g_return_val_if_fail (filename != NULL, FALSE);
904       
905        return (access (filename, F_OK) == 0);
906}
907
908char *
909panel_is_program_in_path (const char *program)
910{
911        static char **paths = NULL;
912        char **p;
913       
914        if (paths == NULL)
915                paths = g_strsplit(g_getenv("PATH"), ":", -1);
916
917        for (p = paths; *p != NULL; p++){
918                char *f = g_strconcat (*p, "/", program, NULL);
919                if (access (f, X_OK) == 0)
920                        return f;
921                g_free (f);
922        }
923        return 0;
924}
925
926int
927find_applet (GtkWidget *widget)
928{
929        int i;
930        GSList *li;
931
932        for (i = 0, li = applets; li != NULL; i++, li = li->next) {
933                AppletInfo *info = li->data;
934
935                if (info->widget == widget)
936                        return i;
937        }
938
939        return i;
940}
941
942int
943get_requisition_width (GtkWidget *widget)
944{
945        GtkRequisition req;
946
947        gtk_widget_get_child_requisition (widget, &req);
948
949        return req.width;
950}
951
952int
953get_requisition_height (GtkWidget *widget)
954{
955        GtkRequisition req;
956
957        gtk_widget_get_child_requisition (widget, &req);
958
959        return req.height;
960}
961
962/* is url showable by gnome_url_show */
963gboolean
964panel_is_url (const char *url)
965{
966        if (strncmp (url, "http://", strlen ("http://")) == 0 ||
967            strncmp (url, "https://", strlen ("https://")) == 0 ||
968            strncmp (url, "gopher://", strlen ("gopher://")) == 0 ||
969            strncmp (url, "ftp://", strlen ("ftp://")) == 0 ||
970            strncmp (url, "file:", strlen ("file:")) == 0 ||
971            strncmp (url, "ghelp:", strlen ("ghelp:")) == 0 ||
972            strncmp (url, "help:", strlen ("help:")) == 0 ||
973            strncmp (url, "man:", strlen ("man:")) == 0 ||
974            strncmp (url, "info:", strlen ("info:")) == 0)
975                return TRUE;
976        else
977                return FALSE;
978}
Note: See TracBrowser for help on using the repository browser.