winmultiwindowicons.c revision 05b261ec
105b261ecSmrg/*
205b261ecSmrg *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
305b261ecSmrg *
405b261ecSmrg *Permission is hereby granted, free of charge, to any person obtaining
505b261ecSmrg * a copy of this software and associated documentation files (the
605b261ecSmrg *"Software"), to deal in the Software without restriction, including
705b261ecSmrg *without limitation the rights to use, copy, modify, merge, publish,
805b261ecSmrg *distribute, sublicense, and/or sell copies of the Software, and to
905b261ecSmrg *permit persons to whom the Software is furnished to do so, subject to
1005b261ecSmrg *the following conditions:
1105b261ecSmrg *
1205b261ecSmrg *The above copyright notice and this permission notice shall be
1305b261ecSmrg *included in all copies or substantial portions of the Software.
1405b261ecSmrg *
1505b261ecSmrg *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1605b261ecSmrg *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1705b261ecSmrg *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1805b261ecSmrg *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
1905b261ecSmrg *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
2005b261ecSmrg *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
2105b261ecSmrg *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2205b261ecSmrg *
2305b261ecSmrg *Except as contained in this notice, the name of the XFree86 Project
2405b261ecSmrg *shall not be used in advertising or otherwise to promote the sale, use
2505b261ecSmrg *or other dealings in this Software without prior written authorization
2605b261ecSmrg *from the XFree86 Project.
2705b261ecSmrg *
2805b261ecSmrg * Authors:	Earle F. Philhower, III
2905b261ecSmrg */
3005b261ecSmrg
3105b261ecSmrg#ifdef HAVE_XWIN_CONFIG_H
3205b261ecSmrg#include <xwin-config.h>
3305b261ecSmrg#endif
3405b261ecSmrg#include "win.h"
3505b261ecSmrg#include "dixevents.h"
3605b261ecSmrg#include "winmultiwindowclass.h"
3705b261ecSmrg#include "winprefs.h"
3805b261ecSmrg
3905b261ecSmrg
4005b261ecSmrg/*
4105b261ecSmrg * External global variables
4205b261ecSmrg */
4305b261ecSmrg
4405b261ecSmrgextern HICON		g_hIconX;
4505b261ecSmrgextern HICON		g_hSmallIconX;
4605b261ecSmrg
4705b261ecSmrg
4805b261ecSmrg/*
4905b261ecSmrg * Prototypes for local functions
5005b261ecSmrg */
5105b261ecSmrg
5205b261ecSmrgstatic void
5305b261ecSmrgwinScaleXBitmapToWindows (int iconSize, int effBPP,
5405b261ecSmrg			  PixmapPtr pixmap, unsigned char *image);
5505b261ecSmrg
5605b261ecSmrg
5705b261ecSmrg/*
5805b261ecSmrg * Scale an X icon bitmap into a Windoze icon bitmap
5905b261ecSmrg */
6005b261ecSmrg
6105b261ecSmrgstatic void
6205b261ecSmrgwinScaleXBitmapToWindows (int iconSize,
6305b261ecSmrg			  int effBPP,
6405b261ecSmrg			  PixmapPtr pixmap,
6505b261ecSmrg			  unsigned char *image)
6605b261ecSmrg{
6705b261ecSmrg  int			row, column, effXBPP, effXDepth;
6805b261ecSmrg  unsigned char		*outPtr;
6905b261ecSmrg  unsigned char		*iconData = 0;
7005b261ecSmrg  int			stride, xStride;
7105b261ecSmrg  float			factX, factY;
7205b261ecSmrg  int			posX, posY;
7305b261ecSmrg  unsigned char		*ptr;
7405b261ecSmrg  unsigned int		zero;
7505b261ecSmrg  unsigned int		color;
7605b261ecSmrg
7705b261ecSmrg  effXBPP = BitsPerPixel(pixmap->drawable.depth);
7805b261ecSmrg  effXDepth = pixmap->drawable.depth;
7905b261ecSmrg
8005b261ecSmrg  if (pixmap->drawable.bitsPerPixel == 15)
8105b261ecSmrg    effXBPP = 16;
8205b261ecSmrg
8305b261ecSmrg  if (pixmap->drawable.depth == 15)
8405b261ecSmrg    effXDepth = 16;
8505b261ecSmrg
8605b261ecSmrg  /* Need 32-bit aligned rows */
8705b261ecSmrg  stride = ((iconSize * effBPP + 31) & (~31)) / 8;
8805b261ecSmrg  xStride = PixmapBytePad (pixmap->drawable.width, pixmap->drawable.depth);
8905b261ecSmrg  if (stride == 0 || xStride == 0)
9005b261ecSmrg    {
9105b261ecSmrg      ErrorF ("winScaleXBitmapToWindows - stride or xStride is zero.  "
9205b261ecSmrg	      "Bailing.\n");
9305b261ecSmrg      return;
9405b261ecSmrg    }
9505b261ecSmrg
9605b261ecSmrg  /* Allocate memory for icon data */
9705b261ecSmrg  iconData = malloc (xStride * pixmap->drawable.height);
9805b261ecSmrg  if (!iconData)
9905b261ecSmrg    {
10005b261ecSmrg      ErrorF ("winScaleXBitmapToWindows - malloc failed for iconData.  "
10105b261ecSmrg	      "Bailing.\n");
10205b261ecSmrg      return;
10305b261ecSmrg    }
10405b261ecSmrg
10505b261ecSmrg  /* Get icon data */
10605b261ecSmrg  miGetImage ((DrawablePtr) &(pixmap->drawable), 0, 0,
10705b261ecSmrg	      pixmap->drawable.width, pixmap->drawable.height,
10805b261ecSmrg	      ZPixmap, 0xffffffff, iconData);
10905b261ecSmrg
11005b261ecSmrg  /* Keep aspect ratio */
11105b261ecSmrg  factX = ((float)pixmap->drawable.width) / ((float)iconSize);
11205b261ecSmrg  factY = ((float)pixmap->drawable.height) / ((float)iconSize);
11305b261ecSmrg  if (factX > factY)
11405b261ecSmrg    factY = factX;
11505b261ecSmrg  else
11605b261ecSmrg    factX = factY;
11705b261ecSmrg
11805b261ecSmrg  /* Out-of-bounds, fill icon with zero */
11905b261ecSmrg  zero = 0;
12005b261ecSmrg
12105b261ecSmrg  for (row = 0; row < iconSize; row++)
12205b261ecSmrg    {
12305b261ecSmrg      outPtr = image + stride * row;
12405b261ecSmrg      for (column = 0; column < iconSize; column++)
12505b261ecSmrg	{
12605b261ecSmrg	  posX = factX * column;
12705b261ecSmrg	  posY = factY * row;
12805b261ecSmrg
12905b261ecSmrg	  ptr = iconData + posY*xStride;
13005b261ecSmrg	  if (effXBPP == 1)
13105b261ecSmrg	    {
13205b261ecSmrg	      ptr += posX / 8;
13305b261ecSmrg
13405b261ecSmrg	      /* Out of X icon bounds, leave space blank */
13505b261ecSmrg	      if (posX >= pixmap->drawable.width
13605b261ecSmrg		  || posY >= pixmap->drawable.height)
13705b261ecSmrg		ptr = (unsigned char *) &zero;
13805b261ecSmrg
13905b261ecSmrg	      if ((*ptr) & (1 << (posX & 7)))
14005b261ecSmrg		switch (effBPP)
14105b261ecSmrg		  {
14205b261ecSmrg		  case 32:
14305b261ecSmrg		    *(outPtr++) = 0;
14405b261ecSmrg		  case 24:
14505b261ecSmrg		    *(outPtr++) = 0;
14605b261ecSmrg		  case 16:
14705b261ecSmrg		    *(outPtr++) = 0;
14805b261ecSmrg		  case 8:
14905b261ecSmrg		    *(outPtr++) = 0;
15005b261ecSmrg		    break;
15105b261ecSmrg		  case 1:
15205b261ecSmrg		    outPtr[column / 8] &= ~(1 << (7 - (column & 7)));
15305b261ecSmrg		    break;
15405b261ecSmrg		  }
15505b261ecSmrg	      else
15605b261ecSmrg		switch (effBPP)
15705b261ecSmrg		  {
15805b261ecSmrg		  case 32:
15905b261ecSmrg		    *(outPtr++) = 255;
16005b261ecSmrg		    *(outPtr++) = 255;
16105b261ecSmrg		    *(outPtr++) = 255;
16205b261ecSmrg		    *(outPtr++) = 0;
16305b261ecSmrg		    break;
16405b261ecSmrg		  case 24:
16505b261ecSmrg		    *(outPtr++) = 255;
16605b261ecSmrg		  case 16:
16705b261ecSmrg		    *(outPtr++) = 255;
16805b261ecSmrg		  case 8:
16905b261ecSmrg		    *(outPtr++) = 255;
17005b261ecSmrg		    break;
17105b261ecSmrg		  case 1:
17205b261ecSmrg		    outPtr[column / 8] |= (1 << (7 - (column & 7)));
17305b261ecSmrg		    break;
17405b261ecSmrg		  }
17505b261ecSmrg	    }
17605b261ecSmrg	  else if (effXDepth == 24 || effXDepth == 32)
17705b261ecSmrg	    {
17805b261ecSmrg	      ptr += posX * (effXBPP / 8);
17905b261ecSmrg
18005b261ecSmrg	      /* Out of X icon bounds, leave space blank */
18105b261ecSmrg	      if (posX >= pixmap->drawable.width
18205b261ecSmrg		  || posY >= pixmap->drawable.height)
18305b261ecSmrg		ptr = (unsigned char *) &zero;
18405b261ecSmrg	      color = (((*ptr) << 16)
18505b261ecSmrg		       + ((*(ptr + 1)) << 8)
18605b261ecSmrg		       + ((*(ptr + 2)) << 0));
18705b261ecSmrg	      switch (effBPP)
18805b261ecSmrg		{
18905b261ecSmrg		case 32:
19005b261ecSmrg		  *(outPtr++) = *(ptr++); // b
19105b261ecSmrg		  *(outPtr++) = *(ptr++); // g
19205b261ecSmrg		  *(outPtr++) = *(ptr++); // r
19305b261ecSmrg		  *(outPtr++) = 0; // resvd
19405b261ecSmrg		  break;
19505b261ecSmrg		case 24:
19605b261ecSmrg		  *(outPtr++) = *(ptr++);
19705b261ecSmrg		  *(outPtr++) = *(ptr++);
19805b261ecSmrg		  *(outPtr++) = *(ptr++);
19905b261ecSmrg		  break;
20005b261ecSmrg		case 16:
20105b261ecSmrg		  color = ((((*ptr) >> 2) << 10)
20205b261ecSmrg			   + (((*(ptr + 1)) >> 2) << 5)
20305b261ecSmrg			   + (((*(ptr + 2)) >> 2)));
20405b261ecSmrg		  *(outPtr++) = (color >> 8);
20505b261ecSmrg		  *(outPtr++) = (color & 255);
20605b261ecSmrg		  break;
20705b261ecSmrg		case 8:
20805b261ecSmrg		  color = (((*ptr))) + (((*(ptr + 1)))) + (((*(ptr + 2))));
20905b261ecSmrg		  color /= 3;
21005b261ecSmrg		  *(outPtr++) = color;
21105b261ecSmrg		  break;
21205b261ecSmrg		case 1:
21305b261ecSmrg		  if (color)
21405b261ecSmrg		    outPtr[column / 8] |= (1 << (7 - (column & 7)));
21505b261ecSmrg		  else
21605b261ecSmrg		    outPtr[column / 8] &= ~(1 << (7 - (column & 7)));
21705b261ecSmrg		}
21805b261ecSmrg	    }
21905b261ecSmrg	  else if (effXDepth == 16)
22005b261ecSmrg	    {
22105b261ecSmrg	      ptr += posX * (effXBPP / 8);
22205b261ecSmrg
22305b261ecSmrg	      /* Out of X icon bounds, leave space blank */
22405b261ecSmrg	      if (posX >= pixmap->drawable.width
22505b261ecSmrg		  || posY >= pixmap->drawable.height)
22605b261ecSmrg		ptr = (unsigned char *) &zero;
22705b261ecSmrg	      color = ((*ptr) << 8) + (*(ptr + 1));
22805b261ecSmrg	      switch (effBPP)
22905b261ecSmrg		{
23005b261ecSmrg		case 32:
23105b261ecSmrg		  *(outPtr++) = (color & 31) << 2;
23205b261ecSmrg		  *(outPtr++) = ((color >> 5) & 31) << 2;
23305b261ecSmrg		  *(outPtr++) = ((color >> 10) & 31) << 2;
23405b261ecSmrg		  *(outPtr++) = 0; // resvd
23505b261ecSmrg		  break;
23605b261ecSmrg		case 24:
23705b261ecSmrg		  *(outPtr++) = (color & 31) << 2;
23805b261ecSmrg		  *(outPtr++) = ((color >> 5) & 31) << 2;
23905b261ecSmrg		  *(outPtr++) = ((color >> 10) & 31) << 2;
24005b261ecSmrg		  break;
24105b261ecSmrg		case 16:
24205b261ecSmrg		  *(outPtr++) = *(ptr++);
24305b261ecSmrg		  *(outPtr++) = *(ptr++);
24405b261ecSmrg		  break;
24505b261ecSmrg		case 8:
24605b261ecSmrg		  *(outPtr++) = (((color & 31)
24705b261ecSmrg				  + ((color >> 5) & 31)
24805b261ecSmrg				  + ((color >> 10) & 31)) / 3) << 2;
24905b261ecSmrg		  break;
25005b261ecSmrg		case 1:
25105b261ecSmrg		  if (color)
25205b261ecSmrg		    outPtr[column / 8] |= (1 << (7 - (column & 7)));
25305b261ecSmrg		  else
25405b261ecSmrg		    outPtr[column / 8] &= ~(1 << (7 - (column & 7)));
25505b261ecSmrg		  break;
25605b261ecSmrg		} /* end switch(effbpp) */
25705b261ecSmrg	    } /* end if effxbpp==16) */
25805b261ecSmrg	} /* end for column */
25905b261ecSmrg    } /* end for row */
26005b261ecSmrg  free (iconData);
26105b261ecSmrg}
26205b261ecSmrg
26305b261ecSmrg
26405b261ecSmrg/*
26505b261ecSmrg * Attempt to create a custom icon from the WM_HINTS bitmaps
26605b261ecSmrg */
26705b261ecSmrg
26805b261ecSmrgHICON
26905b261ecSmrgwinXIconToHICON (WindowPtr pWin, int iconSize)
27005b261ecSmrg{
27105b261ecSmrg  unsigned char		*mask, *image, *imageMask;
27205b261ecSmrg  unsigned char		*dst, *src;
27305b261ecSmrg  PixmapPtr		iconPtr;
27405b261ecSmrg  PixmapPtr		maskPtr;
27505b261ecSmrg  int			planes, bpp, effBPP, stride, maskStride, i;
27605b261ecSmrg  HDC			hDC;
27705b261ecSmrg  ICONINFO		ii;
27805b261ecSmrg  WinXWMHints		hints;
27905b261ecSmrg  HICON			hIcon;
28005b261ecSmrg
28105b261ecSmrg  winMultiWindowGetWMHints (pWin, &hints);
28205b261ecSmrg  if (!hints.icon_pixmap) return NULL;
28305b261ecSmrg
28405b261ecSmrg  iconPtr = (PixmapPtr) LookupIDByType (hints.icon_pixmap, RT_PIXMAP);
28505b261ecSmrg
28605b261ecSmrg  if (!iconPtr) return NULL;
28705b261ecSmrg
28805b261ecSmrg  hDC = GetDC (GetDesktopWindow ());
28905b261ecSmrg  planes = GetDeviceCaps (hDC, PLANES);
29005b261ecSmrg  bpp = GetDeviceCaps (hDC, BITSPIXEL);
29105b261ecSmrg  ReleaseDC (GetDesktopWindow (), hDC);
29205b261ecSmrg
29305b261ecSmrg  /* 15 BPP is really 16BPP as far as we care */
29405b261ecSmrg  if (bpp == 15)
29505b261ecSmrg    effBPP = 16;
29605b261ecSmrg  else
29705b261ecSmrg    effBPP = bpp;
29805b261ecSmrg
29905b261ecSmrg  /* Need 32-bit aligned rows */
30005b261ecSmrg  stride = ((iconSize * effBPP + 31) & (~31)) / 8;
30105b261ecSmrg
30205b261ecSmrg  /* Mask is 1-bit deep */
30305b261ecSmrg  maskStride = ((iconSize * 1 + 31) & (~31)) / 8;
30405b261ecSmrg
30505b261ecSmrg  image = (unsigned char * ) malloc (stride * iconSize);
30605b261ecSmrg  imageMask = (unsigned char *) malloc (stride * iconSize);
30705b261ecSmrg  mask = (unsigned char *) malloc (maskStride * iconSize);
30805b261ecSmrg
30905b261ecSmrg  /* Default to a completely black mask */
31005b261ecSmrg  memset (mask, 0, maskStride * iconSize);
31105b261ecSmrg
31205b261ecSmrg  winScaleXBitmapToWindows (iconSize, effBPP, iconPtr, image);
31305b261ecSmrg  maskPtr = (PixmapPtr) LookupIDByType (hints.icon_mask, RT_PIXMAP);
31405b261ecSmrg
31505b261ecSmrg  if (maskPtr)
31605b261ecSmrg    {
31705b261ecSmrg      winScaleXBitmapToWindows (iconSize, 1, maskPtr, mask);
31805b261ecSmrg
31905b261ecSmrg      winScaleXBitmapToWindows (iconSize, effBPP, maskPtr, imageMask);
32005b261ecSmrg
32105b261ecSmrg      /* Now we need to set all bits of the icon which are not masked */
32205b261ecSmrg      /* on to 0 because Color is really an XOR, not an OR function */
32305b261ecSmrg      dst = image;
32405b261ecSmrg      src = imageMask;
32505b261ecSmrg
32605b261ecSmrg      for (i = 0; i < (stride * iconSize); i++)
32705b261ecSmrg	if ((*(src++)))
32805b261ecSmrg	  *(dst++) = 0;
32905b261ecSmrg	else
33005b261ecSmrg	  dst++;
33105b261ecSmrg    }
33205b261ecSmrg
33305b261ecSmrg  ii.fIcon = TRUE;
33405b261ecSmrg  ii.xHotspot = 0; /* ignored */
33505b261ecSmrg  ii.yHotspot = 0; /* ignored */
33605b261ecSmrg
33705b261ecSmrg  /* Create Win32 mask from pixmap shape */
33805b261ecSmrg  ii.hbmMask = CreateBitmap (iconSize, iconSize, planes, 1, mask);
33905b261ecSmrg
34005b261ecSmrg  /* Create Win32 bitmap from pixmap */
34105b261ecSmrg  ii.hbmColor = CreateBitmap (iconSize, iconSize, planes, bpp, image);
34205b261ecSmrg
34305b261ecSmrg  /* Merge Win32 mask and bitmap into icon */
34405b261ecSmrg  hIcon = CreateIconIndirect (&ii);
34505b261ecSmrg
34605b261ecSmrg  /* Release Win32 mask and bitmap */
34705b261ecSmrg  DeleteObject (ii.hbmMask);
34805b261ecSmrg  DeleteObject (ii.hbmColor);
34905b261ecSmrg
35005b261ecSmrg  /* Free X mask and bitmap */
35105b261ecSmrg  free (mask);
35205b261ecSmrg  free (image);
35305b261ecSmrg  free (imageMask);
35405b261ecSmrg
35505b261ecSmrg  return hIcon;
35605b261ecSmrg}
35705b261ecSmrg
35805b261ecSmrg
35905b261ecSmrg
36005b261ecSmrg/*
36105b261ecSmrg * Change the Windows window icon
36205b261ecSmrg */
36305b261ecSmrg
36405b261ecSmrg#ifdef XWIN_MULTIWINDOW
36505b261ecSmrgvoid
36605b261ecSmrgwinUpdateIcon (Window id)
36705b261ecSmrg{
36805b261ecSmrg  WindowPtr		pWin;
36905b261ecSmrg  HICON			hIcon, hiconOld;
37005b261ecSmrg
37105b261ecSmrg  pWin = (WindowPtr) LookupIDByType (id, RT_WINDOW);
37205b261ecSmrg  if (!pWin) return;
37305b261ecSmrg  hIcon = (HICON)winOverrideIcon ((unsigned long)pWin);
37405b261ecSmrg
37505b261ecSmrg  if (!hIcon)
37605b261ecSmrg    hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON));
37705b261ecSmrg
37805b261ecSmrg  if (hIcon)
37905b261ecSmrg    {
38005b261ecSmrg      winWindowPriv(pWin);
38105b261ecSmrg
38205b261ecSmrg      if (pWinPriv->hWnd)
38305b261ecSmrg	{
38405b261ecSmrg	  hiconOld = (HICON) SetClassLong (pWinPriv->hWnd,
38505b261ecSmrg					   GCL_HICON,
38605b261ecSmrg					   (int) hIcon);
38705b261ecSmrg
38805b261ecSmrg	  /* Delete the icon if its not the default */
38905b261ecSmrg	  winDestroyIcon(hiconOld);
39005b261ecSmrg	}
39105b261ecSmrg    }
39205b261ecSmrg
39305b261ecSmrg  hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXSMICON));
39405b261ecSmrg  if (hIcon)
39505b261ecSmrg    {
39605b261ecSmrg      winWindowPriv(pWin);
39705b261ecSmrg
39805b261ecSmrg      if (pWinPriv->hWnd)
39905b261ecSmrg	{
40005b261ecSmrg	  hiconOld = (HICON) SetClassLong (pWinPriv->hWnd,
40105b261ecSmrg					   GCL_HICONSM,
40205b261ecSmrg					   (int) hIcon);
40305b261ecSmrg	  winDestroyIcon (hiconOld);
40405b261ecSmrg	}
40505b261ecSmrg    }
40605b261ecSmrg}
40705b261ecSmrg
40805b261ecSmrgvoid winInitGlobalIcons (void)
40905b261ecSmrg{
41005b261ecSmrg  int sm_cx = GetSystemMetrics(SM_CXICON);
41105b261ecSmrg  int sm_cxsm = GetSystemMetrics(SM_CXSMICON);
41205b261ecSmrg  /* Load default X icon in case it's not ready yet */
41305b261ecSmrg  if (!g_hIconX)
41405b261ecSmrg    {
41505b261ecSmrg      g_hIconX = (HICON)winOverrideDefaultIcon(sm_cx);
41605b261ecSmrg      g_hSmallIconX = (HICON)winOverrideDefaultIcon(sm_cxsm);
41705b261ecSmrg    }
41805b261ecSmrg
41905b261ecSmrg  if (!g_hIconX)
42005b261ecSmrg    {
42105b261ecSmrg      g_hIconX = (HICON)LoadImage (g_hInstance,
42205b261ecSmrg	      MAKEINTRESOURCE(IDI_XWIN),
42305b261ecSmrg	      IMAGE_ICON,
42405b261ecSmrg	      GetSystemMetrics(SM_CXICON),
42505b261ecSmrg	      GetSystemMetrics(SM_CYICON),
42605b261ecSmrg	      0);
42705b261ecSmrg      g_hSmallIconX = (HICON)LoadImage (g_hInstance,
42805b261ecSmrg	      MAKEINTRESOURCE(IDI_XWIN),
42905b261ecSmrg	      IMAGE_ICON,
43005b261ecSmrg	      GetSystemMetrics(SM_CXSMICON),
43105b261ecSmrg	      GetSystemMetrics(SM_CYSMICON),
43205b261ecSmrg	      LR_DEFAULTSIZE);
43305b261ecSmrg    }
43405b261ecSmrg}
43505b261ecSmrg
43605b261ecSmrgvoid winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon)
43705b261ecSmrg{
43805b261ecSmrg  HICON hIcon, hSmallIcon;
43905b261ecSmrg
44005b261ecSmrg  winInitGlobalIcons();
44105b261ecSmrg
44205b261ecSmrg  /* Try and get the icon from WM_HINTS */
44305b261ecSmrg  hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON));
44405b261ecSmrg  hSmallIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXSMICON));
44505b261ecSmrg
44605b261ecSmrg  /* If we got the small, but not the large one swap them */
44705b261ecSmrg  if (!hIcon && hSmallIcon)
44805b261ecSmrg  {
44905b261ecSmrg      hIcon = hSmallIcon;
45005b261ecSmrg      hSmallIcon = NULL;
45105b261ecSmrg  }
45205b261ecSmrg
45305b261ecSmrg  /* Use default X icon if no icon loaded from WM_HINTS */
45405b261ecSmrg  if (!hIcon) {
45505b261ecSmrg    hIcon = g_hIconX;
45605b261ecSmrg    hSmallIcon = g_hSmallIconX;
45705b261ecSmrg  }
45805b261ecSmrg
45905b261ecSmrg  if (pIcon)
46005b261ecSmrg    *pIcon = hIcon;
46105b261ecSmrg  else
46205b261ecSmrg    winDestroyIcon(hIcon);
46305b261ecSmrg  if (pSmallIcon)
46405b261ecSmrg    *pSmallIcon = hSmallIcon;
46505b261ecSmrg  else
46605b261ecSmrg    winDestroyIcon(hSmallIcon);
46705b261ecSmrg}
46805b261ecSmrg
46905b261ecSmrgvoid winDestroyIcon(HICON hIcon)
47005b261ecSmrg{
47105b261ecSmrg  /* Delete the icon if its not the default */
47205b261ecSmrg  if (hIcon &&
47305b261ecSmrg      hIcon != g_hIconX &&
47405b261ecSmrg      hIcon != g_hSmallIconX &&
47505b261ecSmrg      !winIconIsOverride((unsigned long)hIcon))
47605b261ecSmrg    DestroyIcon (hIcon);
47705b261ecSmrg}
47805b261ecSmrg#endif
479