diff options
author | marha <marha@users.sourceforge.net> | 2012-08-07 07:51:02 +0200 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2012-08-07 07:51:02 +0200 |
commit | f8e35ebbe71eed74ccf68af8ccda4182f1edc7f0 (patch) | |
tree | 0451299b4aaaaf6d2423d1faf07dc9f35c9f80d8 /xorg-server/hw/xwin/winmultiwindowicons.c | |
parent | 18e75aa6ae27a6e44d93babd96afbbe0cd6077c8 (diff) | |
download | vcxsrv-f8e35ebbe71eed74ccf68af8ccda4182f1edc7f0.tar.gz vcxsrv-f8e35ebbe71eed74ccf68af8ccda4182f1edc7f0.tar.bz2 vcxsrv-f8e35ebbe71eed74ccf68af8ccda4182f1edc7f0.zip |
mesa xserver xkeyboard-config git update 7 Aug 2012
Diffstat (limited to 'xorg-server/hw/xwin/winmultiwindowicons.c')
-rw-r--r-- | xorg-server/hw/xwin/winmultiwindowicons.c | 392 |
1 files changed, 193 insertions, 199 deletions
diff --git a/xorg-server/hw/xwin/winmultiwindowicons.c b/xorg-server/hw/xwin/winmultiwindowicons.c index df59f6066..b8357e72d 100644 --- a/xorg-server/hw/xwin/winmultiwindowicons.c +++ b/xorg-server/hw/xwin/winmultiwindowicons.c @@ -31,75 +31,65 @@ #ifdef HAVE_XWIN_CONFIG_H #include <xwin-config.h> #endif -#include "win.h" -#include "dixevents.h" -#include "winmultiwindowclass.h" -#include "winprefs.h" -#include "propertyst.h" -#include "windowstr.h" +#ifndef WINVER +#define WINVER 0x0500 +#endif + +#include <X11/Xwindows.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include "winresource.h" +#include "winprefs.h" +#include "winmsg.h" +#include "winmultiwindowicons.h" +#include "winglobals.h" /* - * Prototypes for local functions + * global variables */ - -static void - -winScaleXBitmapToWindows(int iconSize, int effBPP, - PixmapPtr pixmap, unsigned char *image); +extern HINSTANCE g_hInstance; /* - * Scale an X icon bitmap into a Windoze icon bitmap + * Scale an X icon ZPixmap into a Windoze icon bitmap */ static void -winScaleXBitmapToWindows(int iconSize, - int effBPP, PixmapPtr pixmap, unsigned char *image) +winScaleXImageToWindowsIcon(int iconSize, + int effBPP, + int stride, XImage * pixmap, unsigned char *image) { int row, column, effXBPP, effXDepth; unsigned char *outPtr; - char *iconData = 0; - int stride, xStride; + unsigned char *iconData = 0; + int xStride; float factX, factY; int posX, posY; unsigned char *ptr; unsigned int zero; unsigned int color; - effXBPP = BitsPerPixel(pixmap->drawable.depth); - effXDepth = pixmap->drawable.depth; - - if (pixmap->drawable.bitsPerPixel == 15) + effXBPP = pixmap->bits_per_pixel; + if (pixmap->bits_per_pixel == 15) effXBPP = 16; - if (pixmap->drawable.depth == 15) + effXDepth = pixmap->depth; + if (pixmap->depth == 15) effXDepth = 16; - /* Need 16-bit aligned rows for DDBitmaps */ - stride = ((iconSize * effBPP + 15) & (~15)) / 8; - xStride = PixmapBytePad(pixmap->drawable.width, pixmap->drawable.depth); + xStride = pixmap->bytes_per_line; if (stride == 0 || xStride == 0) { ErrorF("winScaleXBitmapToWindows - stride or xStride is zero. " "Bailing.\n"); return; } - /* Allocate memory for icon data */ - iconData = malloc(xStride * pixmap->drawable.height); - if (!iconData) { - ErrorF("winScaleXBitmapToWindows - malloc failed for iconData. " - "Bailing.\n"); - return; - } - /* Get icon data */ - miGetImage((DrawablePtr) &(pixmap->drawable), 0, 0, - pixmap->drawable.width, pixmap->drawable.height, - ZPixmap, 0xffffffff, iconData); + iconData = (unsigned char *) pixmap->data; /* Keep aspect ratio */ - factX = ((float) pixmap->drawable.width) / ((float) iconSize); - factY = ((float) pixmap->drawable.height) / ((float) iconSize); + factX = ((float) pixmap->width) / ((float) iconSize); + factY = ((float) pixmap->height) / ((float) iconSize); if (factX > factY) factY = factX; else @@ -119,8 +109,7 @@ winScaleXBitmapToWindows(int iconSize, ptr += posX / 8; /* Out of X icon bounds, leave space blank */ - if (posX >= pixmap->drawable.width - || posY >= pixmap->drawable.height) + if (posX >= pixmap->width || posY >= pixmap->height) ptr = (unsigned char *) &zero; if ((*ptr) & (1 << (posX & 7))) @@ -162,8 +151,7 @@ winScaleXBitmapToWindows(int iconSize, ptr += posX * (effXBPP / 8); /* Out of X icon bounds, leave space blank */ - if (posX >= pixmap->drawable.width - || posY >= pixmap->drawable.height) + if (posX >= pixmap->width || posY >= pixmap->height) ptr = (unsigned char *) &zero; color = (((*ptr) << 16) + ((*(ptr + 1)) << 8) @@ -203,8 +191,7 @@ winScaleXBitmapToWindows(int iconSize, ptr += posX * (effXBPP / 8); /* Out of X icon bounds, leave space blank */ - if (posX >= pixmap->drawable.width - || posY >= pixmap->drawable.height) + if (posX >= pixmap->width || posY >= pixmap->height) ptr = (unsigned char *) &zero; color = ((*ptr) << 8) + (*(ptr + 1)); switch (effBPP) { @@ -238,7 +225,6 @@ winScaleXBitmapToWindows(int iconSize, } /* end if effxbpp==16) */ } /* end for column */ } /* end for row */ - free(iconData); } static HICON @@ -250,7 +236,7 @@ NetWMToWinIconAlpha(uint32_t * icon) HICON result; HDC hdc = GetDC(NULL); uint32_t *DIB_pixels; - ICONINFO ii = { TRUE }; + ICONINFO ii; BITMAPV4HEADER bmh = { sizeof(bmh) }; /* Define an ARGB pixel format used for Color+Alpha icons */ @@ -264,6 +250,9 @@ NetWMToWinIconAlpha(uint32_t * icon) bmh.bV4GreenMask = 0x0000FF00; bmh.bV4BlueMask = 0x000000FF; + ii.fIcon = TRUE; + ii.xHotspot = 0; /* ignored */ + ii.yHotspot = 0; /* ignored */ ii.hbmColor = CreateDIBSection(hdc, (BITMAPINFO *) & bmh, DIB_RGB_COLORS, (void **) &DIB_pixels, NULL, 0); @@ -291,12 +280,15 @@ NetWMToWinIconThreshold(uint32_t * icon) uint32_t *pixels = &icon[2]; int row, col; HICON result; - ICONINFO ii = { TRUE }; + ICONINFO ii; HDC hdc = GetDC(NULL); HDC xorDC = CreateCompatibleDC(hdc); HDC andDC = CreateCompatibleDC(hdc); + ii.fIcon = TRUE; + ii.xHotspot = 0; /* ignored */ + ii.yHotspot = 0; /* ignored */ ii.hbmColor = CreateCompatibleBitmap(hdc, width, height); ii.hbmMask = CreateCompatibleBitmap(hdc, width, height); ReleaseDC(NULL, hdc); @@ -365,202 +357,220 @@ NetWMToWinIcon(int bpp, uint32_t * icon) return NetWMToWinIconThreshold(icon); } -static pointer -GetWindowProp(WindowPtr pWin, Atom name, long int *size_return) -{ - struct _Window *pwin; - struct _Property *prop; - - if (!pWin || !name) { - ErrorF("GetWindowProp - pWin or name was NULL\n"); - return 0; - } - pwin = (struct _Window *) pWin; - if (!pwin->optional) - return NULL; - for (prop = (struct _Property *) pwin->optional->userProps; - prop; prop = prop->next) { - if (prop->propertyName == name) { - *size_return = prop->size; - return prop->data; - } - } - return NULL; -} - /* * Attempt to create a custom icon from the WM_HINTS bitmaps */ -HICON -winXIconToHICON(WindowPtr pWin, int iconSize) +static + HICON +winXIconToHICON(Display * pDisplay, Window id, int iconSize) { - unsigned char *mask, *image, *imageMask; + unsigned char *mask, *image = NULL, *imageMask; unsigned char *dst, *src; - PixmapPtr iconPtr; - PixmapPtr maskPtr; - int planes, bpp, effBPP, stride, maskStride, i; + int planes, bpp, i; int biggest_size = 0; HDC hDC; ICONINFO ii; - WinXWMHints hints; + XWMHints *hints; HICON hIcon = NULL; uint32_t *biggest_icon = NULL; - /* Try to get _NET_WM_ICON icons first */ static Atom _XA_NET_WM_ICON; static int generation; uint32_t *icon, *icon_data = NULL; - long int size = 0; + unsigned long int size; + unsigned long int type; + int format; + unsigned long int left; hDC = GetDC(GetDesktopWindow()); planes = GetDeviceCaps(hDC, PLANES); bpp = GetDeviceCaps(hDC, BITSPIXEL); ReleaseDC(GetDesktopWindow(), hDC); + /* Always prefer _NET_WM_ICON icons */ if (generation != serverGeneration) { generation = serverGeneration; - _XA_NET_WM_ICON = MakeAtom("_NET_WM_ICON", 12, TRUE); + _XA_NET_WM_ICON = XInternAtom(pDisplay, "_NET_WM_ICON", FALSE); } - if (_XA_NET_WM_ICON) - icon_data = GetWindowProp(pWin, _XA_NET_WM_ICON, &size); - if (icon_data) { - for (icon = icon_data; - icon < &icon_data[size] && *icon; + if ((XGetWindowProperty(pDisplay, id, _XA_NET_WM_ICON, + 0, MAXINT, FALSE, + AnyPropertyType, &type, &format, &size, &left, + (unsigned char **) &icon_data) == Success) && + (icon_data != NULL)) { + for (icon = icon_data; icon < &icon_data[size] && *icon; icon = &icon[icon[0] * icon[1] + 2]) { - if (icon[0] == iconSize && icon[1] == iconSize) - return NetWMToWinIcon(bpp, icon); - /* Find the biggest icon and let Windows scale the size */ + /* Find an exact match to the size we require... */ + if (icon[0] == iconSize && icon[1] == iconSize) { + winDebug("winXIconToHICON: found %lu x %lu NetIcon\n", icon[0], + icon[1]); + hIcon = NetWMToWinIcon(bpp, icon); + break; + } + /* Otherwise, find the biggest icon and let Windows scale the size */ else if (biggest_size < icon[0]) { biggest_icon = icon; biggest_size = icon[0]; } } - if (biggest_icon) - return NetWMToWinIcon(bpp, biggest_icon); - } - winDebug("winXIconToHICON - pWin %x: no suitable NetIcon\n", (int) pWin, - iconSize); - winMultiWindowGetWMHints(pWin, &hints); - if (!hints.icon_pixmap) - return NULL; + if (!hIcon && biggest_icon) { + winDebug + ("winXIconToHICON: selected %lu x %lu NetIcon for scaling to %u x %u\n", + biggest_icon[0], biggest_icon[1], iconSize, iconSize); + + hIcon = NetWMToWinIcon(bpp, biggest_icon); + } - dixLookupResourceByType((pointer) &iconPtr, hints.icon_pixmap, RT_PIXMAP, - NullClient, DixUnknownAccess); + XFree(icon_data); + } - if (!iconPtr) - return NULL; + if (!hIcon) { + winDebug("winXIconToHICON: no suitable NetIcon\n"); + + hints = XGetWMHints(pDisplay, id); + if (hints) { + winDebug("winXIconToHICON: id 0x%x icon_pixmap hint %x\n", id, + hints->icon_pixmap); + + if (hints->icon_pixmap) { + Window root; + int x, y; + unsigned int width, height, border_width, depth; + XImage *xImageIcon; + XImage *xImageMask = NULL; + + XGetGeometry(pDisplay, hints->icon_pixmap, &root, &x, &y, + &width, &height, &border_width, &depth); + + xImageIcon = + XGetImage(pDisplay, hints->icon_pixmap, 0, 0, width, height, + 0xFFFFFFFF, ZPixmap); + winDebug("winXIconToHICON: id 0x%x icon Ximage 0x%x\n", id, + xImageIcon); + + if (hints->icon_mask) + xImageMask = + XGetImage(pDisplay, hints->icon_mask, 0, 0, width, + height, 0xFFFFFFFF, ZPixmap); + + if (xImageIcon) { + int effBPP, stride, maskStride; + + /* 15 BPP is really 16BPP as far as we care */ + if (bpp == 15) + effBPP = 16; + else + effBPP = bpp; - /* 15 BPP is really 16BPP as far as we care */ - if (bpp == 15) - effBPP = 16; - else - effBPP = bpp; + /* Need 16-bit aligned rows for DDBitmaps */ + stride = ((iconSize * effBPP + 15) & (~15)) / 8; - /* Need 16-bit aligned rows for DDBitmaps */ - stride = ((iconSize * effBPP + 15) & (~15)) / 8; + /* Mask is 1-bit deep */ + maskStride = ((iconSize * 1 + 15) & (~15)) / 8; - /* Mask is 1-bit deep */ - maskStride = ((iconSize * 1 + 15) & (~15)) / 8; + image = malloc(stride * iconSize); + imageMask = malloc(stride * iconSize); + mask = malloc(maskStride * iconSize); - image = malloc(stride * iconSize); - imageMask = malloc(stride * iconSize); - /* Default to a completely black mask */ - mask = calloc(maskStride, iconSize); + /* Default to a completely black mask */ + memset(imageMask, 0, stride * iconSize); + memset(mask, 0, maskStride * iconSize); - winScaleXBitmapToWindows(iconSize, effBPP, iconPtr, image); - dixLookupResourceByType((pointer) &maskPtr, hints.icon_mask, RT_PIXMAP, - NullClient, DixUnknownAccess); + winScaleXImageToWindowsIcon(iconSize, effBPP, stride, + xImageIcon, image); - if (maskPtr) { - winScaleXBitmapToWindows(iconSize, 1, maskPtr, mask); + if (xImageMask) { + winScaleXImageToWindowsIcon(iconSize, 1, maskStride, + xImageMask, mask); + winScaleXImageToWindowsIcon(iconSize, effBPP, stride, + xImageMask, imageMask); + } - winScaleXBitmapToWindows(iconSize, effBPP, maskPtr, imageMask); + /* Now we need to set all bits of the icon which are not masked */ + /* on to 0 because Color is really an XOR, not an OR function */ + dst = image; + src = imageMask; - /* Now we need to set all bits of the icon which are not masked */ - /* on to 0 because Color is really an XOR, not an OR function */ - dst = image; - src = imageMask; + for (i = 0; i < (stride * iconSize); i++) + if ((*(src++))) + *(dst++) = 0; + else + dst++; - for (i = 0; i < (stride * iconSize); i++) - if ((*(src++))) - *(dst++) = 0; - else - dst++; - } + ii.fIcon = TRUE; + ii.xHotspot = 0; /* ignored */ + ii.yHotspot = 0; /* ignored */ - ii.fIcon = TRUE; - ii.xHotspot = 0; /* ignored */ - ii.yHotspot = 0; /* ignored */ + /* Create Win32 mask from pixmap shape */ + ii.hbmMask = + CreateBitmap(iconSize, iconSize, planes, 1, mask); - /* Create Win32 mask from pixmap shape */ - ii.hbmMask = CreateBitmap(iconSize, iconSize, planes, 1, mask); + /* Create Win32 bitmap from pixmap */ + ii.hbmColor = + CreateBitmap(iconSize, iconSize, planes, bpp, image); - /* Create Win32 bitmap from pixmap */ - ii.hbmColor = CreateBitmap(iconSize, iconSize, planes, bpp, image); + /* Merge Win32 mask and bitmap into icon */ + hIcon = CreateIconIndirect(&ii); - /* Merge Win32 mask and bitmap into icon */ - hIcon = CreateIconIndirect(&ii); + /* Release Win32 mask and bitmap */ + DeleteObject(ii.hbmMask); + DeleteObject(ii.hbmColor); - /* Release Win32 mask and bitmap */ - DeleteObject(ii.hbmMask); - DeleteObject(ii.hbmColor); + /* Free X mask and bitmap */ + free(mask); + free(image); + free(imageMask); - /* Free X mask and bitmap */ - free(mask); - free(image); - free(imageMask); + if (xImageMask) + XDestroyImage(xImageMask); + XDestroyImage(xImageIcon); + } + } + XFree(hints); + } + } return hIcon; } /* - * Change the Windows window icon + * Change the Windows window icon */ #ifdef XWIN_MULTIWINDOW void -winUpdateIcon(Window id) +winUpdateIcon(HWND hWnd, Display * pDisplay, Window id, HICON hIconNew) { - WindowPtr pWin; HICON hIcon, hIconSmall = NULL, hIconOld; - dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, - DixUnknownAccess); - if (pWin) { - winWindowPriv(pWin); - if (pWinPriv->hWnd) { - hIcon = winOverrideIcon((unsigned long) pWin); - if (!hIcon) { - hIcon = winXIconToHICON(pWin, GetSystemMetrics(SM_CXICON)); - if (!hIcon) { - hIcon = g_hIconX; - hIconSmall = g_hSmallIconX; - } - else { - /* Leave undefined if not found */ - hIconSmall = - winXIconToHICON(pWin, GetSystemMetrics(SM_CXSMICON)); - } - } + /* Start with the icon from preferences, if any */ + hIcon = hIconNew; + hIconSmall = hIconNew; - /* Set the large icon */ - hIconOld = (HICON) SendMessage(pWinPriv->hWnd, - WM_SETICON, ICON_BIG, - (LPARAM) hIcon); + /* If we still need an icon, try and get the icon from WM_HINTS */ + if (!hIcon) + hIcon = winXIconToHICON(pDisplay, id, GetSystemMetrics(SM_CXICON)); + if (!hIconSmall) + hIconSmall = + winXIconToHICON(pDisplay, id, GetSystemMetrics(SM_CXSMICON)); - /* Delete the icon if its not the default */ - winDestroyIcon(hIconOld); - - /* Same for the small icon */ - hIconOld = (HICON) SendMessage(pWinPriv->hWnd, - WM_SETICON, ICON_SMALL, - (LPARAM) hIconSmall); - winDestroyIcon(hIconOld); - } + /* If we got the small, but not the large one swap them */ + if (!hIcon && hIconSmall) { + hIcon = hIconSmall; + hIconSmall = NULL; } + + /* Set the large icon */ + hIconOld = (HICON) SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM) hIcon); + /* Delete the old icon if its not the default */ + winDestroyIcon(hIconOld); + + /* Same for the small icon */ + hIconOld = + (HICON) SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall); + winDestroyIcon(hIconOld); } void @@ -591,37 +601,21 @@ winInitGlobalIcons(void) } void -winSelectIcons(WindowPtr pWin, HICON * pIcon, HICON * pSmallIcon) +winSelectIcons(HICON * pIcon, HICON * pSmallIcon) { HICON hIcon, hSmallIcon; winInitGlobalIcons(); - /* Try and get the icon from WM_HINTS */ - hIcon = winXIconToHICON(pWin, GetSystemMetrics(SM_CXICON)); - hSmallIcon = winXIconToHICON(pWin, GetSystemMetrics(SM_CXSMICON)); - - /* If we got the small, but not the large one swap them */ - if (!hIcon && hSmallIcon) { - hIcon = hSmallIcon; - hSmallIcon = NULL; - } - - /* Use default X icon if no icon loaded from WM_HINTS */ - if (!hIcon) { - hIcon = g_hIconX; - hSmallIcon = g_hSmallIconX; - } + /* Use default X icon */ + hIcon = g_hIconX; + hSmallIcon = g_hSmallIconX; if (pIcon) *pIcon = hIcon; - else - winDestroyIcon(hIcon); if (pSmallIcon) *pSmallIcon = hSmallIcon; - else - winDestroyIcon(hSmallIcon); } void |