00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <config.h>
00025 #include "iconcache.h"
00026 #include "ui.h"
00027 #include "errors.h"
00028
00029 #include <X11/Xatom.h>
00030
00031
00032
00033 static void
00034 get_fallback_icons (MetaScreen *screen,
00035 GdkPixbuf **iconp,
00036 int ideal_width,
00037 int ideal_height,
00038 GdkPixbuf **mini_iconp,
00039 int ideal_mini_width,
00040 int ideal_mini_height)
00041 {
00042
00043
00044
00045 *iconp = meta_ui_get_default_window_icon (screen->ui);
00046 *mini_iconp = meta_ui_get_default_mini_icon (screen->ui);
00047 }
00048
00049 static gboolean
00050 find_largest_sizes (gulong *data,
00051 gulong nitems,
00052 int *width,
00053 int *height)
00054 {
00055 *width = 0;
00056 *height = 0;
00057
00058 while (nitems > 0)
00059 {
00060 int w, h;
00061
00062 if (nitems < 3)
00063 return FALSE;
00064
00065 w = data[0];
00066 h = data[1];
00067
00068 if (nitems < ((gulong)(w * h) + 2))
00069 return FALSE;
00070
00071 *width = MAX (w, *width);
00072 *height = MAX (h, *height);
00073
00074 data += (w * h) + 2;
00075 nitems -= (w * h) + 2;
00076 }
00077
00078 return TRUE;
00079 }
00080
00081 static gboolean
00082 find_best_size (gulong *data,
00083 gulong nitems,
00084 int ideal_width,
00085 int ideal_height,
00086 int *width,
00087 int *height,
00088 gulong **start)
00089 {
00090 int best_w;
00091 int best_h;
00092 gulong *best_start;
00093 int max_width, max_height;
00094
00095 *width = 0;
00096 *height = 0;
00097 *start = NULL;
00098
00099 if (!find_largest_sizes (data, nitems, &max_width, &max_height))
00100 return FALSE;
00101
00102 if (ideal_width < 0)
00103 ideal_width = max_width;
00104 if (ideal_height < 0)
00105 ideal_height = max_height;
00106
00107 best_w = 0;
00108 best_h = 0;
00109 best_start = NULL;
00110
00111 while (nitems > 0)
00112 {
00113 int w, h;
00114 gboolean replace;
00115
00116 replace = FALSE;
00117
00118 if (nitems < 3)
00119 return FALSE;
00120
00121 w = data[0];
00122 h = data[1];
00123
00124 if (nitems < ((gulong)(w * h) + 2))
00125 break;
00126
00127 if (best_start == NULL)
00128 {
00129 replace = TRUE;
00130 }
00131 else
00132 {
00133
00134 const int ideal_size = (ideal_width + ideal_height) / 2;
00135 int best_size = (best_w + best_h) / 2;
00136 int this_size = (w + h) / 2;
00137
00138
00139 if (best_size < ideal_size &&
00140 this_size >= ideal_size)
00141 replace = TRUE;
00142
00143 else if (best_size < ideal_size &&
00144 this_size > best_size)
00145 replace = TRUE;
00146
00147
00148
00149 else if (best_size > ideal_size &&
00150 this_size >= ideal_size &&
00151 this_size < best_size)
00152 replace = TRUE;
00153 }
00154
00155 if (replace)
00156 {
00157 best_start = data + 2;
00158 best_w = w;
00159 best_h = h;
00160 }
00161
00162 data += (w * h) + 2;
00163 nitems -= (w * h) + 2;
00164 }
00165
00166 if (best_start)
00167 {
00168 *start = best_start;
00169 *width = best_w;
00170 *height = best_h;
00171 return TRUE;
00172 }
00173 else
00174 return FALSE;
00175 }
00176
00177 static void
00178 argbdata_to_pixdata (gulong *argb_data, int len, guchar **pixdata)
00179 {
00180 guchar *p;
00181 int i;
00182
00183 *pixdata = g_new (guchar, len * 4);
00184 p = *pixdata;
00185
00186
00187 i = 0;
00188 while (i < len)
00189 {
00190 guint argb;
00191 guint rgba;
00192
00193 argb = argb_data[i];
00194 rgba = (argb << 8) | (argb >> 24);
00195
00196 *p = rgba >> 24;
00197 ++p;
00198 *p = (rgba >> 16) & 0xff;
00199 ++p;
00200 *p = (rgba >> 8) & 0xff;
00201 ++p;
00202 *p = rgba & 0xff;
00203 ++p;
00204
00205 ++i;
00206 }
00207 }
00208
00209 static gboolean
00210 read_rgb_icon (MetaDisplay *display,
00211 Window xwindow,
00212 int ideal_width,
00213 int ideal_height,
00214 int ideal_mini_width,
00215 int ideal_mini_height,
00216 int *width,
00217 int *height,
00218 guchar **pixdata,
00219 int *mini_width,
00220 int *mini_height,
00221 guchar **mini_pixdata)
00222 {
00223 Atom type;
00224 int format;
00225 gulong nitems;
00226 gulong bytes_after;
00227 int result, err;
00228 gulong *data;
00229 gulong *best;
00230 int w, h;
00231 gulong *best_mini;
00232 int mini_w, mini_h;
00233
00234 meta_error_trap_push_with_return (display);
00235 type = None;
00236 data = NULL;
00237 result = XGetWindowProperty (display->xdisplay,
00238 xwindow,
00239 display->atom__NET_WM_ICON,
00240 0, G_MAXLONG,
00241 False, XA_CARDINAL, &type, &format, &nitems,
00242 &bytes_after, ((guchar **)&data));
00243
00244 err = meta_error_trap_pop_with_return (display, TRUE);
00245
00246 if (err != Success ||
00247 result != Success)
00248 return FALSE;
00249
00250 if (type != XA_CARDINAL)
00251 {
00252 XFree (data);
00253 return FALSE;
00254 }
00255
00256 if (!find_best_size (data, nitems,
00257 ideal_width, ideal_height,
00258 &w, &h, &best))
00259 {
00260 XFree (data);
00261 return FALSE;
00262 }
00263
00264 if (!find_best_size (data, nitems,
00265 ideal_mini_width, ideal_mini_height,
00266 &mini_w, &mini_h, &best_mini))
00267 {
00268 XFree (data);
00269 return FALSE;
00270 }
00271
00272 *width = w;
00273 *height = h;
00274
00275 *mini_width = mini_w;
00276 *mini_height = mini_h;
00277
00278 argbdata_to_pixdata (best, w * h, pixdata);
00279 argbdata_to_pixdata (best_mini, mini_w * mini_h, mini_pixdata);
00280
00281 XFree (data);
00282
00283 return TRUE;
00284 }
00285
00286 static void
00287 free_pixels (guchar *pixels, gpointer data)
00288 {
00289 g_free (pixels);
00290 }
00291
00292 static void
00293 get_pixmap_geometry (MetaDisplay *display,
00294 Pixmap pixmap,
00295 int *w,
00296 int *h,
00297 int *d)
00298 {
00299 Window root_ignored;
00300 int x_ignored, y_ignored;
00301 guint width, height;
00302 guint border_width_ignored;
00303 guint depth;
00304
00305 if (w)
00306 *w = 1;
00307 if (h)
00308 *h = 1;
00309 if (d)
00310 *d = 1;
00311
00312 XGetGeometry (display->xdisplay,
00313 pixmap, &root_ignored, &x_ignored, &y_ignored,
00314 &width, &height, &border_width_ignored, &depth);
00315
00316 if (w)
00317 *w = width;
00318 if (h)
00319 *h = height;
00320 if (d)
00321 *d = depth;
00322 }
00323
00324 static GdkPixbuf*
00325 apply_mask (GdkPixbuf *pixbuf,
00326 GdkPixbuf *mask)
00327 {
00328 int w, h;
00329 int i, j;
00330 GdkPixbuf *with_alpha;
00331 guchar *src;
00332 guchar *dest;
00333 int src_stride;
00334 int dest_stride;
00335
00336 w = MIN (gdk_pixbuf_get_width (mask), gdk_pixbuf_get_width (pixbuf));
00337 h = MIN (gdk_pixbuf_get_height (mask), gdk_pixbuf_get_height (pixbuf));
00338
00339 with_alpha = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
00340
00341 dest = gdk_pixbuf_get_pixels (with_alpha);
00342 src = gdk_pixbuf_get_pixels (mask);
00343
00344 dest_stride = gdk_pixbuf_get_rowstride (with_alpha);
00345 src_stride = gdk_pixbuf_get_rowstride (mask);
00346
00347 i = 0;
00348 while (i < h)
00349 {
00350 j = 0;
00351 while (j < w)
00352 {
00353 guchar *s = src + i * src_stride + j * 3;
00354 guchar *d = dest + i * dest_stride + j * 4;
00355
00356
00357
00358
00359 if (s[0] == 0)
00360 d[3] = 0;
00361 else
00362 d[3] = 255;
00363
00364 ++j;
00365 }
00366
00367 ++i;
00368 }
00369
00370 return with_alpha;
00371 }
00372
00373 static gboolean
00374 try_pixmap_and_mask (MetaDisplay *display,
00375 Pixmap src_pixmap,
00376 Pixmap src_mask,
00377 GdkPixbuf **iconp,
00378 int ideal_width,
00379 int ideal_height,
00380 GdkPixbuf **mini_iconp,
00381 int ideal_mini_width,
00382 int ideal_mini_height)
00383 {
00384 GdkPixbuf *unscaled = NULL;
00385 GdkPixbuf *mask = NULL;
00386 int w, h;
00387
00388 if (src_pixmap == None)
00389 return FALSE;
00390
00391 meta_error_trap_push (display);
00392
00393 get_pixmap_geometry (display, src_pixmap, &w, &h, NULL);
00394
00395 unscaled = meta_gdk_pixbuf_get_from_pixmap (NULL,
00396 src_pixmap,
00397 0, 0, 0, 0,
00398 w, h);
00399
00400 if (unscaled && src_mask != None)
00401 {
00402 get_pixmap_geometry (display, src_mask, &w, &h, NULL);
00403 mask = meta_gdk_pixbuf_get_from_pixmap (NULL,
00404 src_mask,
00405 0, 0, 0, 0,
00406 w, h);
00407 }
00408
00409 meta_error_trap_pop (display, FALSE);
00410
00411 if (mask)
00412 {
00413 GdkPixbuf *masked;
00414
00415 masked = apply_mask (unscaled, mask);
00416 g_object_unref (G_OBJECT (unscaled));
00417 unscaled = masked;
00418
00419 g_object_unref (G_OBJECT (mask));
00420 mask = NULL;
00421 }
00422
00423 if (unscaled)
00424 {
00425 *iconp =
00426 gdk_pixbuf_scale_simple (unscaled,
00427 ideal_width > 0 ? ideal_width :
00428 gdk_pixbuf_get_width (unscaled),
00429 ideal_height > 0 ? ideal_height :
00430 gdk_pixbuf_get_height (unscaled),
00431 GDK_INTERP_BILINEAR);
00432 *mini_iconp =
00433 gdk_pixbuf_scale_simple (unscaled,
00434 ideal_mini_width > 0 ? ideal_mini_width :
00435 gdk_pixbuf_get_width (unscaled),
00436 ideal_mini_height > 0 ? ideal_mini_height :
00437 gdk_pixbuf_get_height (unscaled),
00438 GDK_INTERP_BILINEAR);
00439
00440 g_object_unref (G_OBJECT (unscaled));
00441
00442 if (*iconp && *mini_iconp)
00443 return TRUE;
00444 else
00445 {
00446 if (*iconp)
00447 g_object_unref (G_OBJECT (*iconp));
00448 if (*mini_iconp)
00449 g_object_unref (G_OBJECT (*mini_iconp));
00450 return FALSE;
00451 }
00452 }
00453 else
00454 return FALSE;
00455 }
00456
00457 static void
00458 get_kwm_win_icon (MetaDisplay *display,
00459 Window xwindow,
00460 Pixmap *pixmap,
00461 Pixmap *mask)
00462 {
00463 Atom type;
00464 int format;
00465 gulong nitems;
00466 gulong bytes_after;
00467 Pixmap *icons;
00468 int err, result;
00469
00470 *pixmap = None;
00471 *mask = None;
00472
00473 meta_error_trap_push_with_return (display);
00474 icons = NULL;
00475 result = XGetWindowProperty (display->xdisplay, xwindow,
00476 display->atom__KWM_WIN_ICON,
00477 0, G_MAXLONG,
00478 False,
00479 display->atom__KWM_WIN_ICON,
00480 &type, &format, &nitems,
00481 &bytes_after, (guchar **)&icons);
00482
00483 err = meta_error_trap_pop_with_return (display, TRUE);
00484 if (err != Success ||
00485 result != Success)
00486 return;
00487
00488 if (type != display->atom__KWM_WIN_ICON)
00489 {
00490 XFree (icons);
00491 return;
00492 }
00493
00494 *pixmap = icons[0];
00495 *mask = icons[1];
00496
00497 XFree (icons);
00498
00499 return;
00500 }
00501
00502 void
00503 meta_icon_cache_init (MetaIconCache *icon_cache)
00504 {
00505 g_return_if_fail (icon_cache != NULL);
00506
00507 icon_cache->origin = USING_NO_ICON;
00508 icon_cache->prev_pixmap = None;
00509 icon_cache->prev_mask = None;
00510 #if 0
00511 icon_cache->icon = NULL;
00512 icon_cache->mini_icon = NULL;
00513 icon_cache->ideal_width = -1;
00514 icon_cache->ideal_height = -1;
00515 icon_cache->ideal_mini_width = -1;
00516 icon_cache->ideal_mini_height = -1;
00517 #endif
00518 icon_cache->want_fallback = TRUE;
00519 icon_cache->wm_hints_dirty = TRUE;
00520 icon_cache->kwm_win_icon_dirty = TRUE;
00521 icon_cache->net_wm_icon_dirty = TRUE;
00522 }
00523
00524 static void
00525 clear_icon_cache (MetaIconCache *icon_cache,
00526 gboolean dirty_all)
00527 {
00528 #if 0
00529 if (icon_cache->icon)
00530 g_object_unref (G_OBJECT (icon_cache->icon));
00531 icon_cache->icon = NULL;
00532
00533 if (icon_cache->mini_icon)
00534 g_object_unref (G_OBJECT (icon_cache->mini_icon));
00535 icon_cache->mini_icon = NULL;
00536 #endif
00537
00538 icon_cache->origin = USING_NO_ICON;
00539
00540 if (dirty_all)
00541 {
00542 icon_cache->wm_hints_dirty = TRUE;
00543 icon_cache->kwm_win_icon_dirty = TRUE;
00544 icon_cache->net_wm_icon_dirty = TRUE;
00545 }
00546 }
00547
00548 void
00549 meta_icon_cache_free (MetaIconCache *icon_cache)
00550 {
00551 clear_icon_cache (icon_cache, FALSE);
00552 }
00553
00554 void
00555 meta_icon_cache_property_changed (MetaIconCache *icon_cache,
00556 MetaDisplay *display,
00557 Atom atom)
00558 {
00559 if (atom == display->atom__NET_WM_ICON)
00560 icon_cache->net_wm_icon_dirty = TRUE;
00561 else if (atom == display->atom__KWM_WIN_ICON)
00562 icon_cache->kwm_win_icon_dirty = TRUE;
00563 else if (atom == XA_WM_HINTS)
00564 icon_cache->wm_hints_dirty = TRUE;
00565 }
00566
00567 gboolean
00568 meta_icon_cache_get_icon_invalidated (MetaIconCache *icon_cache)
00569 {
00570 if (icon_cache->origin <= USING_KWM_WIN_ICON &&
00571 icon_cache->kwm_win_icon_dirty)
00572 return TRUE;
00573 else if (icon_cache->origin <= USING_WM_HINTS &&
00574 icon_cache->wm_hints_dirty)
00575 return TRUE;
00576 else if (icon_cache->origin <= USING_NET_WM_ICON &&
00577 icon_cache->net_wm_icon_dirty)
00578 return TRUE;
00579 else if (icon_cache->origin < USING_FALLBACK_ICON &&
00580 icon_cache->want_fallback)
00581 return TRUE;
00582 else if (icon_cache->origin == USING_NO_ICON)
00583 return TRUE;
00584 else if (icon_cache->origin == USING_FALLBACK_ICON &&
00585 !icon_cache->want_fallback)
00586 return TRUE;
00587 else
00588 return FALSE;
00589 }
00590
00591 static void
00592 replace_cache (MetaIconCache *icon_cache,
00593 IconOrigin origin,
00594 GdkPixbuf *new_icon,
00595 GdkPixbuf *new_mini_icon)
00596 {
00597 clear_icon_cache (icon_cache, FALSE);
00598
00599 icon_cache->origin = origin;
00600
00601 #if 0
00602 if (new_icon)
00603 g_object_ref (G_OBJECT (new_icon));
00604
00605 icon_cache->icon = new_icon;
00606
00607 if (new_mini_icon)
00608 g_object_ref (G_OBJECT (new_mini_icon));
00609
00610 icon_cache->mini_icon = new_mini_icon;
00611 #endif
00612 }
00613
00614 static GdkPixbuf*
00615 scaled_from_pixdata (guchar *pixdata,
00616 int w,
00617 int h,
00618 int new_w,
00619 int new_h)
00620 {
00621 GdkPixbuf *src;
00622 GdkPixbuf *dest;
00623
00624 src = gdk_pixbuf_new_from_data (pixdata,
00625 GDK_COLORSPACE_RGB,
00626 TRUE,
00627 8,
00628 w, h, w * 4,
00629 free_pixels,
00630 NULL);
00631
00632 if (src == NULL)
00633 return NULL;
00634
00635 if (w != h)
00636 {
00637 GdkPixbuf *tmp;
00638 int size;
00639
00640 size = MAX (w, h);
00641
00642 tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, size, size);
00643
00644 if (tmp)
00645 {
00646 gdk_pixbuf_fill (tmp, 0);
00647 gdk_pixbuf_copy_area (src, 0, 0, w, h,
00648 tmp,
00649 (size - w) / 2, (size - h) / 2);
00650
00651 g_object_unref (src);
00652 src = tmp;
00653 }
00654 }
00655
00656 if (w != new_w || h != new_h)
00657 {
00658 dest = gdk_pixbuf_scale_simple (src, new_w, new_h, GDK_INTERP_BILINEAR);
00659
00660 g_object_unref (G_OBJECT (src));
00661 }
00662 else
00663 {
00664 dest = src;
00665 }
00666
00667 return dest;
00668 }
00669
00670 gboolean
00671 meta_read_icons (MetaScreen *screen,
00672 Window xwindow,
00673 MetaIconCache *icon_cache,
00674 Pixmap wm_hints_pixmap,
00675 Pixmap wm_hints_mask,
00676 GdkPixbuf **iconp,
00677 int ideal_width,
00678 int ideal_height,
00679 GdkPixbuf **mini_iconp,
00680 int ideal_mini_width,
00681 int ideal_mini_height)
00682 {
00683 guchar *pixdata;
00684 int w, h;
00685 guchar *mini_pixdata;
00686 int mini_w, mini_h;
00687 Pixmap pixmap;
00688 Pixmap mask;
00689
00690
00691
00692 g_return_val_if_fail (icon_cache != NULL, FALSE);
00693
00694 *iconp = NULL;
00695 *mini_iconp = NULL;
00696
00697 #if 0
00698 if (ideal_width != icon_cache->ideal_width ||
00699 ideal_height != icon_cache->ideal_height ||
00700 ideal_mini_width != icon_cache->ideal_mini_width ||
00701 ideal_mini_height != icon_cache->ideal_mini_height)
00702 clear_icon_cache (icon_cache, TRUE);
00703
00704 icon_cache->ideal_width = ideal_width;
00705 icon_cache->ideal_height = ideal_height;
00706 icon_cache->ideal_mini_width = ideal_mini_width;
00707 icon_cache->ideal_mini_height = ideal_mini_height;
00708 #endif
00709
00710 if (!meta_icon_cache_get_icon_invalidated (icon_cache))
00711 return FALSE;
00712
00713 pixdata = NULL;
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724 if (icon_cache->origin <= USING_NET_WM_ICON &&
00725 icon_cache->net_wm_icon_dirty)
00726
00727 {
00728 icon_cache->net_wm_icon_dirty = FALSE;
00729
00730 if (read_rgb_icon (screen->display, xwindow,
00731 ideal_width, ideal_height,
00732 ideal_mini_width, ideal_mini_height,
00733 &w, &h, &pixdata,
00734 &mini_w, &mini_h, &mini_pixdata))
00735 {
00736 *iconp = scaled_from_pixdata (pixdata, w, h,
00737 ideal_width, ideal_height);
00738
00739 *mini_iconp = scaled_from_pixdata (mini_pixdata, mini_w, mini_h,
00740 ideal_mini_width, ideal_mini_height);
00741
00742 if (*iconp && *mini_iconp)
00743 {
00744 replace_cache (icon_cache, USING_NET_WM_ICON,
00745 *iconp, *mini_iconp);
00746
00747 return TRUE;
00748 }
00749 else
00750 {
00751 if (*iconp)
00752 g_object_unref (G_OBJECT (*iconp));
00753 if (*mini_iconp)
00754 g_object_unref (G_OBJECT (*mini_iconp));
00755 }
00756 }
00757 }
00758
00759 if (icon_cache->origin <= USING_WM_HINTS &&
00760 icon_cache->wm_hints_dirty)
00761 {
00762 icon_cache->wm_hints_dirty = FALSE;
00763
00764 pixmap = wm_hints_pixmap;
00765 mask = wm_hints_mask;
00766
00767
00768
00769
00770
00771 if ((pixmap != icon_cache->prev_pixmap ||
00772 mask != icon_cache->prev_mask) &&
00773 pixmap != None)
00774 {
00775 if (try_pixmap_and_mask (screen->display,
00776 pixmap, mask,
00777 iconp, ideal_width, ideal_height,
00778 mini_iconp, ideal_mini_width, ideal_mini_height))
00779 {
00780 icon_cache->prev_pixmap = pixmap;
00781 icon_cache->prev_mask = mask;
00782
00783 replace_cache (icon_cache, USING_WM_HINTS,
00784 *iconp, *mini_iconp);
00785
00786 return TRUE;
00787 }
00788 }
00789 }
00790
00791 if (icon_cache->origin <= USING_KWM_WIN_ICON &&
00792 icon_cache->kwm_win_icon_dirty)
00793 {
00794 icon_cache->kwm_win_icon_dirty = FALSE;
00795
00796 get_kwm_win_icon (screen->display, xwindow, &pixmap, &mask);
00797
00798 if ((pixmap != icon_cache->prev_pixmap ||
00799 mask != icon_cache->prev_mask) &&
00800 pixmap != None)
00801 {
00802 if (try_pixmap_and_mask (screen->display, pixmap, mask,
00803 iconp, ideal_width, ideal_height,
00804 mini_iconp, ideal_mini_width, ideal_mini_height))
00805 {
00806 icon_cache->prev_pixmap = pixmap;
00807 icon_cache->prev_mask = mask;
00808
00809 replace_cache (icon_cache, USING_KWM_WIN_ICON,
00810 *iconp, *mini_iconp);
00811
00812 return TRUE;
00813 }
00814 }
00815 }
00816
00817 if (icon_cache->want_fallback &&
00818 icon_cache->origin < USING_FALLBACK_ICON)
00819 {
00820 GdkPixbuf *fallback_icon;
00821 GdkPixbuf *fallback_mini_icon;
00822
00823 fallback_icon = NULL;
00824 fallback_mini_icon = NULL;
00825
00826 meta_ui_get_fallback_icons(&fallback_icon, &fallback_mini_icon);
00827
00828 if (fallback_icon == NULL || fallback_mini_icon == NULL)
00829 {
00830 get_fallback_icons (screen,
00831 iconp,
00832 ideal_width,
00833 ideal_height,
00834 mini_iconp,
00835 ideal_mini_width,
00836 ideal_mini_height);
00837 }
00838
00839 if (fallback_icon != NULL)
00840 *iconp = fallback_icon;
00841 if (fallback_mini_icon != NULL)
00842 *mini_iconp = fallback_mini_icon;
00843
00844 replace_cache (icon_cache, USING_FALLBACK_ICON,
00845 *iconp, *mini_iconp);
00846
00847 return TRUE;
00848 }
00849
00850 if (!icon_cache->want_fallback &&
00851 icon_cache->origin == USING_FALLBACK_ICON)
00852 {
00853
00854 clear_icon_cache (icon_cache, FALSE);
00855
00856 return TRUE;
00857 }
00858
00859
00860 return FALSE;
00861 }