Add NEWS bug entry for previous FvwmForm commit.
[fvwm.git] / fvwm / ewmh_icons.c
blob76bbb22e9f084b9ed00b038ea0e530b9d9507994
1 /* -*-c-*- */
2 /* Copyright (C) 2001 Olivier Chapuis */
3 /* This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 #include "config.h"
20 #include <stdio.h>
22 #include "libs/fvwmlib.h"
23 #include "libs/FShape.h"
24 #include "libs/PictureBase.h"
25 #include "libs/Picture.h"
26 #include "libs/PictureUtils.h"
27 #include "libs/PictureImageLoader.h"
28 #include "libs/FRenderInit.h"
29 #include "libs/Graphics.h"
30 #include "libs/Strings.h"
31 #include "fvwm.h"
32 #include "externs.h"
33 #include "window_flags.h"
34 #include "cursor.h"
35 #include "functions.h"
36 #include "misc.h"
37 #include "screen.h"
38 #include "module_interface.h"
39 #include "borders.h"
40 #include "icons.h"
41 #include "ewmh.h"
42 #include "ewmh_intern.h"
45 * net icon handler
47 int ewmh_WMIcon(EWMH_CMD_ARGS)
49 CARD32 *list = NULL;
50 CARD32 *new_list = NULL;
51 CARD32 *dummy = NULL;
52 int size = 0;
54 if (ev != NULL && HAS_EWMH_WM_ICON_HINT(fw) == EWMH_FVWM_ICON)
56 /* this event has been produced by fvwm itself */
57 return 0;
60 list = ewmh_AtomGetByName(FW_W(fw),"_NET_WM_ICON",
61 EWMH_ATOM_LIST_PROPERTY_NOTIFY, &size);
63 if (list != NULL && HAS_EWMH_WM_ICON_HINT(fw) == EWMH_NO_ICON)
65 /* the application have a true _NET_WM_ICON */
66 SET_HAS_EWMH_WM_ICON_HINT(fw, EWMH_TRUE_ICON);
69 if (list == NULL || HAS_EWMH_WM_ICON_HINT(fw) != EWMH_TRUE_ICON)
71 /* No net icon or we have set the net icon */
72 if (DO_EWMH_DONATE_ICON(fw) &&
73 (new_list =
74 ewmh_SetWmIconFromPixmap(
75 fw, list, &size, False)) != NULL)
77 SET_HAS_EWMH_WM_ICON_HINT(fw, EWMH_FVWM_ICON);
80 else if (ev != NULL && USE_EWMH_ICON(fw))
82 /* client message. the application change its net icon */
83 ChangeIconPixmap(fw);
85 if (FMiniIconsSupported)
87 if (list == NULL ||
88 HAS_EWMH_WM_ICON_HINT(fw) != EWMH_TRUE_ICON)
90 /* No net icon or we have set the net icon */
91 if (DO_EWMH_DONATE_MINI_ICON(fw) &&
92 (dummy = ewmh_SetWmIconFromPixmap(
93 fw, (new_list != NULL)? new_list : list,
94 &size, True)) != NULL)
96 SET_HAS_EWMH_WM_ICON_HINT(
97 fw, EWMH_FVWM_ICON);
98 free(dummy);
101 else
103 /* the application has a true ewmh icon */
104 if (EWMH_SetIconFromWMIcon(fw, list, size, True))
106 SET_HAS_EWMH_MINI_ICON(fw, True);
111 if (list != NULL)
113 free(list);
115 if (new_list != NULL)
117 free(new_list);
119 return 0;
123 * update
125 void EWMH_DoUpdateWmIcon(FvwmWindow *fw, Bool mini_icon, Bool icon)
127 CARD32 *list = NULL;
128 CARD32 *new_list = NULL;
129 CARD32 *dummy = NULL;
130 int size = 0;
131 Bool icon_too = False;
133 if (HAS_EWMH_WM_ICON_HINT(fw) == EWMH_TRUE_ICON)
135 return;
138 /* first see if we have to delete */
139 if (FMiniIconsSupported && mini_icon &&
140 !DO_EWMH_DONATE_MINI_ICON(fw))
142 if (icon && !DO_EWMH_DONATE_ICON(fw))
144 icon_too = True;
146 EWMH_DeleteWmIcon(fw, True, icon_too);
148 if (!icon_too && icon && !DO_EWMH_DONATE_ICON(fw))
150 EWMH_DeleteWmIcon(fw, False, True);
153 /* now set if needed */
154 if ((mini_icon && DO_EWMH_DONATE_MINI_ICON(fw)) ||
155 (icon && DO_EWMH_DONATE_ICON(fw)))
157 list = ewmh_AtomGetByName(
158 FW_W(fw),"_NET_WM_ICON",
159 EWMH_ATOM_LIST_PROPERTY_NOTIFY, &size);
161 else
163 return;
166 /* we have to reset */
167 if (icon && DO_EWMH_DONATE_ICON(fw))
169 if ((new_list = ewmh_SetWmIconFromPixmap(
170 fw, list, &size, False)) != NULL)
172 SET_HAS_EWMH_WM_ICON_HINT(fw, EWMH_FVWM_ICON);
175 if (FMiniIconsSupported && mini_icon && DO_EWMH_DONATE_MINI_ICON(fw))
177 if ((dummy = ewmh_SetWmIconFromPixmap(
178 fw, (new_list != NULL)? new_list : list, &size,
179 True)) != NULL)
181 SET_HAS_EWMH_WM_ICON_HINT(fw, EWMH_FVWM_ICON);
182 free(dummy);
185 if (list != NULL)
187 free(list);
189 if (new_list != NULL)
191 free(new_list);
196 * build and set a net icon from a pixmap
198 CARD32 *ewmh_SetWmIconFromPixmap(
199 FvwmWindow *fw, CARD32 *orig_icon, int *orig_size, Bool is_mini_icon)
201 CARD32 *new_icon = NULL;
202 int keep_start = 0, keep_length = 0;
203 int width = 0, height = 0;
204 int i,j,k,l,m;
205 int s;
206 Pixmap pixmap = None;
207 Pixmap mask = None;
208 Pixmap alpha = None;
209 XImage *image;
210 XImage *m_image = NULL;
211 XImage *a_image = NULL;
212 int save_picture_w_g_width = 0;
213 int save_picture_w_g_height = 0;
214 int save_icon_depth = 0;
215 Pixmap save_icon_pixmap = None;
216 Pixmap save_icon_mask = None;
217 Pixmap save_icon_alpha = None;
218 int save_icon_nalloc_pixels = 0;
219 Pixel *save_icon_alloc_pixels = NULL;
220 int save_icon_no_limit = 0;
221 Window save_icon_pixmap_w = None;
222 Bool is_pixmap_ours = False;
223 Bool is_icon_ours = False;
224 Bool is_icon_shaped = False;
225 Bool destroy_icon_pix = False;
227 s = *orig_size / sizeof(CARD32);
228 *orig_size = 0;
230 if (is_mini_icon)
232 if (FMiniIconsSupported && fw->mini_icon != NULL)
234 pixmap = fw->mini_icon->picture;
235 mask = fw->mini_icon->mask;
236 alpha = fw->mini_icon->alpha;
237 width = fw->mini_icon->width;
238 height = fw->mini_icon->height;
241 else
243 /* should save and restore any iformation modified by
244 * a call to GetIconPicture */
245 save_picture_w_g_width = fw->icon_g.picture_w_g.width;
246 save_picture_w_g_height = fw->icon_g.picture_w_g.height;
247 save_icon_depth = fw->iconDepth;
248 save_icon_pixmap = fw->iconPixmap;
249 save_icon_mask = fw->icon_maskPixmap;
250 save_icon_alpha = fw->icon_alphaPixmap;
251 save_icon_nalloc_pixels = fw->icon_nalloc_pixels;
252 save_icon_alloc_pixels = fw->icon_alloc_pixels;
253 save_icon_no_limit = fw->icon_no_limit;
254 save_icon_pixmap_w = FW_W_ICON_PIXMAP(fw);
255 is_pixmap_ours = IS_PIXMAP_OURS(fw);
256 is_icon_ours = IS_ICON_OURS(fw);
257 is_icon_shaped = IS_ICON_SHAPED(fw);
258 GetIconPicture(fw, True);
259 if (IS_PIXMAP_OURS(fw))
261 destroy_icon_pix = True;
263 pixmap = fw->iconPixmap;
264 mask = fw->icon_maskPixmap;
265 alpha = fw->icon_alphaPixmap;
266 width = fw->icon_g.picture_w_g.width;
267 height = fw->icon_g.picture_w_g.height;
268 if (fw->icon_alloc_pixels != NULL)
270 if (fw->icon_nalloc_pixels != 0)
272 PictureFreeColors(
273 dpy, Pcmap, fw->icon_alloc_pixels,
274 fw->icon_nalloc_pixels, 0,
275 fw->icon_no_limit);
277 free(fw->icon_alloc_pixels);
280 fw->icon_g.picture_w_g.width = save_picture_w_g_width;
281 fw->icon_g.picture_w_g.height = save_picture_w_g_height;
282 fw->iconDepth = save_icon_depth;
283 fw->iconPixmap = save_icon_pixmap;
284 fw->icon_maskPixmap = save_icon_mask;
285 fw->icon_alphaPixmap = save_icon_alpha;
286 fw->icon_nalloc_pixels = save_icon_nalloc_pixels;
287 fw->icon_alloc_pixels = save_icon_alloc_pixels;
288 fw->icon_no_limit = save_icon_no_limit;
289 FW_W_ICON_PIXMAP(fw) = save_icon_pixmap_w;
290 SET_ICON_OURS(fw, is_icon_ours);
291 SET_PIXMAP_OURS(fw, is_pixmap_ours);
292 SET_ICON_SHAPED(fw, is_icon_shaped);
295 if (pixmap == None)
297 return NULL;
300 if (FMiniIconsSupported && orig_icon != NULL)
302 int k_width = (is_mini_icon)?
303 fw->ewmh_icon_width : fw->ewmh_mini_icon_width;
304 int k_height = (is_mini_icon)?
305 fw->ewmh_icon_height : fw->ewmh_mini_icon_height;
307 for (i = 0; i < s - 1 && i >= 0; )
309 if (i + 1 + orig_icon[i]*orig_icon[i+1] < s)
311 if (orig_icon[i] == k_width &&
312 orig_icon[i+1] == k_height)
314 keep_start = i;
315 keep_length = 2 +
316 orig_icon[i] * orig_icon[i+1];
317 i = s;
320 if (i != s && orig_icon[i]*orig_icon[i+1] > 0)
322 i = i + 2 + orig_icon[i]*orig_icon[i+1];
324 else
326 i = s;
331 image = XGetImage(
332 dpy, pixmap, 0, 0, width, height, AllPlanes, ZPixmap);
333 if (image == NULL)
335 fvwm_msg(
336 ERR, "EWMH_SetWmIconFromPixmap",
337 "cannot create XImage\n");
338 if (destroy_icon_pix)
340 XFreePixmap(dpy, pixmap);
341 if (mask != None)
343 XFreePixmap(dpy, mask);
345 if (alpha != None)
347 XFreePixmap(dpy, alpha);
350 return NULL;
353 if (mask != None)
355 m_image = XGetImage(dpy, mask, 0, 0, width, height,
356 AllPlanes, ZPixmap);
358 if (alpha != None)
360 a_image = XGetImage(dpy, alpha, 0, 0, width, height,
361 AllPlanes, ZPixmap);
363 *orig_size = (height*width + 2 + keep_length) * sizeof(CARD32);
364 new_icon = (CARD32 *)safemalloc(*orig_size);
365 if (keep_length > 0)
367 memcpy(new_icon, &orig_icon[keep_start],
368 keep_length * sizeof(CARD32));
370 new_icon[keep_length] = width;
371 new_icon[1+keep_length] = height;
373 k = 0;
374 l = (2 + keep_length);
375 m = 0;
377 switch(image->depth)
379 case 1:
381 XColor colors[2];
382 CARD32 fg, bg;
384 colors[0].pixel = fw->colors.fore;
385 colors[1].pixel = fw->colors.back;
386 XQueryColors(dpy, Pcmap, colors, 2);
387 fg = 0xff000000 + (((colors[0].red >> 8) & 0xff) << 16) +
388 (((colors[0].green >> 8) & 0xff) << 8) +
389 ((colors[0].blue >> 8) & 0xff);
390 bg = 0xff000000 + (((colors[1].red >> 8) & 0xff) << 16) +
391 (((colors[1].green >> 8) & 0xff) << 8) +
392 ((colors[1].blue >> 8) & 0xff);
393 for (j = 0; j < height; j++)
395 for (i = 0; i < width; i++)
397 if (m_image != NULL &&
398 (XGetPixel(m_image, i, j) == 0))
400 new_icon[l++] = 0;
402 else if (XGetPixel(image, i, j) == 0)
404 new_icon[l++] = bg;
406 else
408 new_icon[l++] = fg;
412 break;
415 default: /* depth = Pdepth */
417 unsigned char *cm;
418 XColor *colors;
420 colors = (XColor *)safemalloc(width * height * sizeof(XColor));
421 cm = (unsigned char *)safemalloc(
422 width * height * sizeof(char));
423 for (j = 0; j < height; j++)
425 for (i = 0; i < width; i++)
427 if (m_image != NULL &&
428 (XGetPixel(m_image, i, j) == 0))
430 cm[m++] = 0;
432 else if (a_image != NULL)
434 cm[m++] = (unsigned char)XGetPixel(
435 a_image, i, j);
436 colors[k++].pixel = XGetPixel(
437 image, i, j);
439 else
441 cm[m++] = 255;
442 colors[k++].pixel = XGetPixel(
443 image, i, j);
447 for (i = 0; i < k; i += 256)
448 XQueryColors(dpy, Pcmap, &colors[i], min(k - i, 256));
450 k = 0;m = 0;
451 for (j = 0; j < height; j++)
453 for (i = 0; i < width; i++)
455 if (cm[m] > 0)
457 new_icon[l++] =
458 ((cm[m] & 0xff) << 24) +
459 (((colors[k].red >> 8) & 0xff)
460 << 16) +
461 (((colors[k].green >> 8) &
462 0xff) << 8) +
463 ((colors[k].blue >> 8) & 0xff);
464 k++;
466 else
468 new_icon[l++] = 0;
470 m++;
473 free(colors);
474 free(cm);
475 break;
477 } /* switch */
480 if (is_mini_icon)
482 fw->ewmh_mini_icon_width = width;
483 fw->ewmh_mini_icon_height = height;
485 else
487 fw->ewmh_icon_width = width;
488 fw->ewmh_icon_height = height;
491 ewmh_ChangeProperty(
492 FW_W(fw), "_NET_WM_ICON", EWMH_ATOM_LIST_PROPERTY_NOTIFY,
493 (unsigned char *)new_icon, height*width + 2 + keep_length);
495 if (destroy_icon_pix)
497 XFreePixmap(dpy, pixmap);
498 if (mask != None)
500 XFreePixmap(dpy, mask);
502 if (alpha != None)
504 XFreePixmap(dpy, alpha);
508 XDestroyImage(image);
509 if (m_image != None)
511 XDestroyImage(m_image);
513 if (a_image != None)
515 XDestroyImage(a_image);
518 return new_icon;
522 * delete the mini icon and/or the icon from a ewmh icon
524 void EWMH_DeleteWmIcon(FvwmWindow *fw, Bool mini_icon, Bool icon)
526 CARD32 *list;
527 CARD32 *new_list = NULL;
528 int keep_start = 0, keep_length = 0;
529 int s;
530 int i;
532 if (mini_icon && icon)
534 ewmh_DeleteProperty(
535 FW_W(fw), "_NET_WM_ICON",
536 EWMH_ATOM_LIST_PROPERTY_NOTIFY);
537 fw->ewmh_mini_icon_width = 0;
538 fw->ewmh_mini_icon_height = 0;
539 fw->ewmh_icon_width = 0;
540 fw->ewmh_icon_height = 0;
541 /*SET_HAS_EWMH_WM_ICON_HINT(fw, EWMH_NO_ICON);*/
542 return;
545 list = ewmh_AtomGetByName(
546 FW_W(fw),"_NET_WM_ICON", EWMH_ATOM_LIST_PROPERTY_NOTIFY, &s);
547 if (list == NULL)
549 return;
551 s = s / sizeof(CARD32);
553 if (FMiniIconsSupported && list != NULL)
555 int k_width = (mini_icon) ? fw->ewmh_icon_width :
556 fw->ewmh_mini_icon_width;
557 int k_height = (mini_icon) ? fw->ewmh_icon_height :
558 fw->ewmh_mini_icon_height;
560 for (i = 0; i < s - 1; )
562 if (i + 1 + list[i]*list[i+1] < s)
564 if (list[i] == k_width &&
565 list[i+1] == k_height)
567 keep_start = i;
568 keep_length = 2 + list[i]*list[i+1];
569 i = s;
572 if (i != s && list[i]*list[i+1] > 0)
574 i = i + 2 + list[i]*list[i+1];
576 else
578 i = s;
583 if (keep_length > 0)
585 new_list = (CARD32 *)safemalloc(keep_length * sizeof(CARD32));
586 memcpy(
587 new_list, &list[keep_start],
588 keep_length * sizeof(CARD32));
591 if (new_list != NULL)
593 ewmh_ChangeProperty(
594 FW_W(fw),"_NET_WM_ICON",
595 EWMH_ATOM_LIST_PROPERTY_NOTIFY,
596 (unsigned char *)new_list, keep_length);
598 else
600 /*SET_HAS_EWMH_WM_ICON_HINT(fw, EWMH_NO_ICON);*/
601 ewmh_DeleteProperty(
602 FW_W(fw), "_NET_WM_ICON",
603 EWMH_ATOM_LIST_PROPERTY_NOTIFY);
606 if (mini_icon)
608 fw->ewmh_mini_icon_width = 0;
609 fw->ewmh_mini_icon_height = 0;
611 if (icon)
613 fw->ewmh_icon_width = 0;
614 fw->ewmh_icon_height = 0;
616 if (new_list != NULL)
618 free(new_list);
620 free(list);
624 * Create an x image from a NET icon
627 #define SQUARE(X) ((X)*(X))
628 static
629 void extract_wm_icon(
630 CARD32 *list, int size, int wanted_w, int wanted_h,
631 int *start_best, int *best_w, int *best_h)
633 int i;
634 int dist = 0;
636 *start_best = 0;
637 *best_w = 0;
638 *best_h = 0;
639 size = size / (sizeof(CARD32));
641 for (i = 0; i < size - 1; )
643 if (i + 1 + list[i]*list[i+1] < size)
645 if (*best_w == 0 && *best_h == 0)
647 *start_best = i+2;
648 *best_w = list[i];
649 *best_h = list[i+1];
650 dist = SQUARE(
651 list[i]-wanted_w) +
652 SQUARE(list[i+1]-wanted_h);
654 else if (SQUARE(list[i]-wanted_w) +
655 SQUARE(list[i+1]-wanted_h) < dist)
657 *start_best = i+2;
658 *best_w = list[i];
659 *best_h = list[i+1];
660 dist = SQUARE(
661 list[i]-wanted_w) +
662 SQUARE(list[i+1]-wanted_h);
665 if (list[i]*list[i+1] > 0)
667 i = i + 2 + list[i]*list[i+1];
669 else
671 i = size;
675 return;
678 #define MINI_ICON_WANTED_WIDTH 16
679 #define MINI_ICON_WANTED_HEIGHT 16
680 #define MINI_ICON_MAX_WIDTH 22
681 #define MINI_ICON_MAX_HEIGHT 22
682 #define ICON_WANTED_WIDTH 56
683 #define ICON_WANTED_HEIGHT 56
684 #define ICON_MAX_WIDTH 100
685 #define ICON_MAX_HEIGHT 100
687 int EWMH_SetIconFromWMIcon(
688 FvwmWindow *fw, CARD32 *list, int size, Bool is_mini_icon)
690 int start, width, height;
691 int wanted_w, wanted_h;
692 int max_w, max_h;
693 Pixmap pixmap = None;
694 Pixmap mask = None;
695 Pixmap alpha = None;
696 Bool free_list = False;
697 int nalloc_pixels;
698 Pixel *alloc_pixels;
699 int no_limit;
700 FvwmPictureAttributes fpa;
702 if (list == NULL)
704 /* we are called from icons.c or update.c */
705 list = ewmh_AtomGetByName(
706 FW_W(fw),"_NET_WM_ICON",
707 EWMH_ATOM_LIST_PROPERTY_NOTIFY, &size);
708 free_list = True;
709 if (list == NULL)
711 return 0;
715 if (is_mini_icon)
717 wanted_w = MINI_ICON_WANTED_WIDTH;
718 wanted_h = MINI_ICON_WANTED_HEIGHT;
719 max_w = MINI_ICON_MAX_WIDTH;
720 max_h = ICON_MAX_HEIGHT;
721 fpa.mask = 0;
723 else
725 wanted_w = ICON_WANTED_WIDTH;
726 wanted_h = ICON_WANTED_HEIGHT;
727 max_w = ICON_MAX_WIDTH;
728 max_h = ICON_MAX_HEIGHT;
729 if (fw->cs >= 0 && Colorset[fw->cs].do_dither_icon)
731 fpa.mask = FPAM_DITHER;
733 else
735 fpa.mask = 0;
739 extract_wm_icon(
740 list, size, wanted_w, wanted_h, &start, &width, &height);
741 if (width == 0 || height == 0)
743 if (free_list)
745 free(list);
747 return 0;
750 if (!PImageCreatePixmapFromArgbData(
751 dpy, Scr.NoFocusWin, list, start, width, height,
752 &pixmap, &mask, &alpha, &nalloc_pixels,
753 &alloc_pixels, &no_limit, fpa))
755 fvwm_msg(ERR, "EWMH_SetIconFromWMIcon",
756 "fail to create a pixmap\n");
757 if (free_list)
759 free(list);
761 return 0;
764 if (width > max_w || height > max_h)
766 Pixmap np = None,nm =None, na = None;
768 if (pixmap)
770 np = CreateStretchPixmap(
771 dpy, pixmap, width, height, Pdepth, wanted_w,
772 wanted_h, Scr.TitleGC);
773 XFreePixmap(dpy, pixmap);
774 pixmap = np;
776 if (mask)
778 nm = CreateStretchPixmap(
779 dpy, mask, width, height, 1, wanted_w,
780 wanted_h, Scr.MonoGC);
781 XFreePixmap(dpy, mask);
782 mask = nm;
784 if (alpha)
786 na = CreateStretchPixmap(
787 dpy, alpha, width, height,
788 FRenderGetAlphaDepth(), wanted_w, wanted_h,
789 Scr.AlphaGC);
790 XFreePixmap(dpy, alpha);
791 alpha = na;
793 width = wanted_w;
794 height = wanted_h;
796 if (FMiniIconsSupported && is_mini_icon &&
797 !DO_EWMH_MINI_ICON_OVERRIDE(fw))
799 char *name = NULL;
801 CopyString(&name,"ewmh_mini_icon");
802 if (fw->mini_icon)
804 PDestroyFvwmPicture(dpy,fw->mini_icon);
805 fw->mini_icon = 0;
807 fw->mini_icon = PCacheFvwmPictureFromPixmap(
808 dpy, Scr.NoFocusWin, name, pixmap,mask,alpha, width,
809 height, nalloc_pixels, alloc_pixels, no_limit);
810 if (fw->mini_icon != NULL)
812 fw->mini_pixmap_file = name;
813 BroadcastFvwmPicture(
814 M_MINI_ICON, FW_W(fw), FW_W_FRAME(fw),
815 (unsigned long)fw, fw->mini_icon,
816 fw->mini_pixmap_file);
817 border_redraw_decorations(fw);
820 if (!is_mini_icon)
822 fw->iconPixmap = pixmap;
823 fw->icon_maskPixmap = mask;
824 fw->icon_alphaPixmap = alpha;
825 fw->icon_nalloc_pixels = nalloc_pixels;
826 fw->icon_alloc_pixels = alloc_pixels;
827 fw->icon_no_limit = no_limit;
828 fw->icon_g.picture_w_g.width = width;
829 fw->icon_g.picture_w_g.height = height;
830 fw->iconDepth = Pdepth;
831 SET_PIXMAP_OURS(fw, 1);
832 if (FShapesSupported && mask)
834 SET_ICON_SHAPED(fw, 1);
837 if (free_list)
839 free(list);
841 return 1;