Merge remote-tracking branch 'jturney/master'

This commit is contained in:
Keith Packard 2012-08-06 15:11:13 -07:00
commit 7d87545ba7
16 changed files with 473 additions and 417 deletions

View File

@ -87,7 +87,7 @@ static const struct extension_info known_glx_extensions[] = {
{ GLX(SGIX_fbconfig), VER(1,3), Y, }, { GLX(SGIX_fbconfig), VER(1,3), Y, },
{ GLX(SGIX_pbuffer), VER(1,3), Y, }, { GLX(SGIX_pbuffer), VER(1,3), Y, },
{ GLX(SGIX_visual_select_group), VER(0,0), Y, }, { GLX(SGIX_visual_select_group), VER(0,0), Y, },
{ GLX(INTEL_swap_event), VER(1,4), N, }, { GLX(INTEL_swap_event), VER(0,0), N, },
{ NULL } { NULL }
/* *INDENT-ON* */ /* *INDENT-ON* */
}; };

View File

@ -174,7 +174,7 @@ static char GLXServerExtensions[] =
"GLX_SGIS_multisample " "GLX_SGIS_multisample "
#endif #endif
"GLX_SGIX_fbconfig " "GLX_SGIX_fbconfig "
"GLX_SGIX_pbuffer " "GLX_MESA_copy_sub_buffer " "GLX_INTEL_swap_event"; "GLX_SGIX_pbuffer " "GLX_MESA_copy_sub_buffer ";
static Bool static Bool
glxCloseScreen(ScreenPtr pScreen) glxCloseScreen(ScreenPtr pScreen)

View File

@ -1625,6 +1625,18 @@ glxWinCreateContext(__GLXscreen * screen,
* Utility functions * Utility functions
*/ */
static int
GetShift(int Mask)
{
int Shift = 0;
while ((Mask &1) == 0) {
Shift++;
Mask >>=1;
}
return Shift;
}
static int static int
fbConfigToPixelFormat(__GLXconfig * mode, PIXELFORMATDESCRIPTOR * pfdret, fbConfigToPixelFormat(__GLXconfig * mode, PIXELFORMATDESCRIPTOR * pfdret,
int drawableTypeOverride) int drawableTypeOverride)
@ -1661,16 +1673,26 @@ fbConfigToPixelFormat(__GLXconfig * mode, PIXELFORMATDESCRIPTOR * pfdret,
pfd.dwFlags |= PFD_DOUBLEBUFFER; pfd.dwFlags |= PFD_DOUBLEBUFFER;
} }
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = mode->redBits + mode->greenBits + mode->blueBits; pfd.cColorBits = mode->redBits + mode->greenBits + mode->blueBits;
pfd.cRedBits = mode->redBits; pfd.cRedBits = mode->redBits;
pfd.cRedShift = 0; /* FIXME */ pfd.cRedShift = GetShift(mode->redMask);
pfd.cGreenBits = mode->greenBits; pfd.cGreenBits = mode->greenBits;
pfd.cGreenShift = 0; /* FIXME */ pfd.cGreenShift = GetShift(mode->greenMask);
pfd.cBlueBits = mode->blueBits; pfd.cBlueBits = mode->blueBits;
pfd.cBlueShift = 0; /* FIXME */ pfd.cBlueShift = GetShift(mode->blueMask);
pfd.cAlphaBits = mode->alphaBits; pfd.cAlphaBits = mode->alphaBits;
pfd.cAlphaShift = 0; /* FIXME */ pfd.cAlphaShift = GetShift(mode->alphaMask);
if (mode->visualType == GLX_TRUE_COLOR) {
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.dwVisibleMask =
(pfd.cRedBits << pfd.cRedShift) | (pfd.cGreenBits << pfd.cGreenShift) |
(pfd.cBlueBits << pfd.cBlueShift) | (pfd.cAlphaBits << pfd.cAlphaShift);
}
else {
pfd.iPixelType = PFD_TYPE_COLORINDEX;
pfd.dwVisibleMask = mode->transparentIndex;
}
pfd.cAccumBits = pfd.cAccumBits =
mode->accumRedBits + mode->accumGreenBits + mode->accumBlueBits + mode->accumRedBits + mode->accumGreenBits + mode->accumBlueBits +
@ -1910,25 +1932,27 @@ glxWinCreateConfigs(HDC hdc, glxWinScreen * screen)
/* EXT_visual_info / GLX 1.2 */ /* EXT_visual_info / GLX 1.2 */
if (pfd.iPixelType == PFD_TYPE_COLORINDEX) { if (pfd.iPixelType == PFD_TYPE_COLORINDEX) {
c->base.visualType = GLX_STATIC_COLOR; c->base.visualType = GLX_STATIC_COLOR;
c->base.transparentRed = GLX_NONE;
if (!getenv("GLWIN_ENABLE_COLORINDEX_FBCONFIGS")) { c->base.transparentGreen = GLX_NONE;
GLWIN_DEBUG_MSG c->base.transparentBlue = GLX_NONE;
("pixelFormat %d is PFD_TYPE_COLORINDEX, skipping", i + 1); c->base.transparentAlpha = GLX_NONE;
continue; c->base.transparentIndex = pfd.dwVisibleMask;
} c->base.transparentPixel = GLX_TRANSPARENT_INDEX;
} }
else { else {
c->base.visualType = GLX_TRUE_COLOR; c->base.visualType = GLX_TRUE_COLOR;
c->base.transparentRed =
(pfd.dwVisibleMask & c->base.redMask) >> pfd.cRedShift;
c->base.transparentGreen =
(pfd.dwVisibleMask & c->base.greenMask) >> pfd.cGreenShift;
c->base.transparentBlue =
(pfd.dwVisibleMask & c->base.blueMask) >> pfd.cBlueShift;
c->base.transparentAlpha =
(pfd.dwVisibleMask & c->base.alphaMask) >> pfd.cAlphaShift;
c->base.transparentIndex = GLX_NONE;
c->base.transparentPixel = GLX_TRANSPARENT_RGB;
} }
// pfd.dwVisibleMask; ???
c->base.transparentPixel = GLX_NONE;
c->base.transparentRed = GLX_NONE;
c->base.transparentGreen = GLX_NONE;
c->base.transparentBlue = GLX_NONE;
c->base.transparentAlpha = GLX_NONE;
c->base.transparentIndex = GLX_NONE;
/* ARB_multisample / SGIS_multisample */ /* ARB_multisample / SGIS_multisample */
c->base.sampleBuffers = 0; c->base.sampleBuffers = 0;
c->base.samples = 0; c->base.samples = 0;
@ -2180,14 +2204,6 @@ glxWinCreateConfigsExt(HDC hdc, glxWinScreen * screen)
c->base.indexBits = ATTR_VALUE(WGL_COLOR_BITS_ARB, 0); c->base.indexBits = ATTR_VALUE(WGL_COLOR_BITS_ARB, 0);
c->base.rgbBits = 0; c->base.rgbBits = 0;
c->base.visualType = GLX_STATIC_COLOR; c->base.visualType = GLX_STATIC_COLOR;
if (!getenv("GLWIN_ENABLE_COLORINDEX_FBCONFIGS")) {
GLWIN_DEBUG_MSG
("pixelFormat %d is WGL_TYPE_COLORINDEX_ARB, skipping",
i + 1);
continue;
}
break; break;
case WGL_TYPE_RGBA_FLOAT_ARB: case WGL_TYPE_RGBA_FLOAT_ARB:

View File

@ -1174,15 +1174,6 @@ Bool
void void
winSetShapeRootless(WindowPtr pWindow, int kind); winSetShapeRootless(WindowPtr pWindow, int kind);
/*
* winmultiwindowicons.c - Used by both multi-window and Win32Rootless
*/
HICON winXIconToHICON(WindowPtr pWin, int iconSize);
void
winSelectIcons(WindowPtr pWin, HICON * pIcon, HICON * pSmallIcon);
#ifdef XWIN_MULTIWINDOW #ifdef XWIN_MULTIWINDOW
/* /*
* winmultiwindowshape.c * winmultiwindowshape.c

View File

@ -74,10 +74,10 @@ winProcessXEventsTimeout(HWND hwnd, int iWindow, Display * pDisplay,
int iConnNumber; int iConnNumber;
struct timeval tv; struct timeval tv;
int iReturn; int iReturn;
DWORD dwStopTime = (GetTickCount() / 1000) + iTimeoutSec; DWORD dwStopTime = GetTickCount() + iTimeoutSec * 1000;
/* We need to ensure that all pending events are processed */ winDebug("winProcessXEventsTimeout () - pumping X events for %d seconds\n",
XSync(pDisplay, FALSE); iTimeoutSec);
/* Get our connection number */ /* Get our connection number */
iConnNumber = ConnectionNumber(pDisplay); iConnNumber = ConnectionNumber(pDisplay);
@ -85,17 +85,24 @@ winProcessXEventsTimeout(HWND hwnd, int iWindow, Display * pDisplay,
/* Loop for X events */ /* Loop for X events */
while (1) { while (1) {
fd_set fdsRead; fd_set fdsRead;
long remainingTime;
/* We need to ensure that all pending events are processed */
XSync(pDisplay, FALSE);
/* Setup the file descriptor set */ /* Setup the file descriptor set */
FD_ZERO(&fdsRead); FD_ZERO(&fdsRead);
FD_SET(iConnNumber, &fdsRead); FD_SET(iConnNumber, &fdsRead);
/* Adjust timeout */ /* Adjust timeout */
tv.tv_sec = dwStopTime - (GetTickCount() / 1000); remainingTime = dwStopTime - GetTickCount();
tv.tv_usec = 0; tv.tv_sec = remainingTime / 1000;
tv.tv_usec = (remainingTime % 1000) * 1000;
winDebug("winProcessXEventsTimeout () - %d milliseconds left\n",
remainingTime);
/* Break out if no time left */ /* Break out if no time left */
if (tv.tv_sec < 0) if (remainingTime <= 0)
return WIN_XEVENTS_SUCCESS; return WIN_XEVENTS_SUCCESS;
/* Wait for an X event */ /* Wait for an X event */
@ -103,7 +110,7 @@ winProcessXEventsTimeout(HWND hwnd, int iWindow, Display * pDisplay,
&fdsRead, /* Read mask */ &fdsRead, /* Read mask */
NULL, /* No write mask */ NULL, /* No write mask */
NULL, /* No exception mask */ NULL, /* No exception mask */
&tv); /* No timeout */ &tv); /* Timeout */
if (iReturn < 0) { if (iReturn < 0) {
ErrorF("winProcessXEventsTimeout - Call to select () failed: %d. " ErrorF("winProcessXEventsTimeout - Call to select () failed: %d. "
"Bailing.\n", iReturn); "Bailing.\n", iReturn);
@ -116,11 +123,19 @@ winProcessXEventsTimeout(HWND hwnd, int iWindow, Display * pDisplay,
/* Exit when we see that server is shutting down */ /* Exit when we see that server is shutting down */
iReturn = winClipboardFlushXEvents(hwnd, iReturn = winClipboardFlushXEvents(hwnd,
iWindow, pDisplay, fUseUnicode); iWindow, pDisplay, fUseUnicode);
winDebug
("winProcessXEventsTimeout () - winClipboardFlushXEvents returned %d\n",
iReturn);
if (WIN_XEVENTS_NOTIFY == iReturn) { if (WIN_XEVENTS_NOTIFY == iReturn) {
/* Bail out if notify processed */ /* Bail out if notify processed */
return iReturn; return iReturn;
} }
} }
else {
winDebug("winProcessXEventsTimeout - Spurious wake\n");
}
} }
return WIN_XEVENTS_SUCCESS; return WIN_XEVENTS_SUCCESS;

View File

@ -31,75 +31,65 @@
#ifdef HAVE_XWIN_CONFIG_H #ifdef HAVE_XWIN_CONFIG_H
#include <xwin-config.h> #include <xwin-config.h>
#endif #endif
#include "win.h"
#include "dixevents.h" #ifndef WINVER
#include "winmultiwindowclass.h" #define WINVER 0x0500
#endif
#include <X11/Xwindows.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "winresource.h"
#include "winprefs.h" #include "winprefs.h"
#include "winmsg.h"
#include "propertyst.h" #include "winmultiwindowicons.h"
#include "windowstr.h" #include "winglobals.h"
/*
* global variables
*/
extern HINSTANCE g_hInstance;
/* /*
* Prototypes for local functions * Scale an X icon ZPixmap into a Windoze icon bitmap
*/ */
static void static void
winScaleXImageToWindowsIcon(int iconSize,
winScaleXBitmapToWindows(int iconSize, int effBPP, int effBPP,
PixmapPtr pixmap, unsigned char *image); int stride, XImage * pixmap, unsigned char *image)
/*
* Scale an X icon bitmap into a Windoze icon bitmap
*/
static void
winScaleXBitmapToWindows(int iconSize,
int effBPP, PixmapPtr pixmap, unsigned char *image)
{ {
int row, column, effXBPP, effXDepth; int row, column, effXBPP, effXDepth;
unsigned char *outPtr; unsigned char *outPtr;
char *iconData = 0; unsigned char *iconData = 0;
int stride, xStride; int xStride;
float factX, factY; float factX, factY;
int posX, posY; int posX, posY;
unsigned char *ptr; unsigned char *ptr;
unsigned int zero; unsigned int zero;
unsigned int color; unsigned int color;
effXBPP = BitsPerPixel(pixmap->drawable.depth); effXBPP = pixmap->bits_per_pixel;
effXDepth = pixmap->drawable.depth; if (pixmap->bits_per_pixel == 15)
if (pixmap->drawable.bitsPerPixel == 15)
effXBPP = 16; effXBPP = 16;
if (pixmap->drawable.depth == 15) effXDepth = pixmap->depth;
if (pixmap->depth == 15)
effXDepth = 16; effXDepth = 16;
/* Need 16-bit aligned rows for DDBitmaps */ xStride = pixmap->bytes_per_line;
stride = ((iconSize * effBPP + 15) & (~15)) / 8;
xStride = PixmapBytePad(pixmap->drawable.width, pixmap->drawable.depth);
if (stride == 0 || xStride == 0) { if (stride == 0 || xStride == 0) {
ErrorF("winScaleXBitmapToWindows - stride or xStride is zero. " ErrorF("winScaleXBitmapToWindows - stride or xStride is zero. "
"Bailing.\n"); "Bailing.\n");
return; 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 */ /* Get icon data */
miGetImage((DrawablePtr) &(pixmap->drawable), 0, 0, iconData = (unsigned char *) pixmap->data;
pixmap->drawable.width, pixmap->drawable.height,
ZPixmap, 0xffffffff, iconData);
/* Keep aspect ratio */ /* Keep aspect ratio */
factX = ((float) pixmap->drawable.width) / ((float) iconSize); factX = ((float) pixmap->width) / ((float) iconSize);
factY = ((float) pixmap->drawable.height) / ((float) iconSize); factY = ((float) pixmap->height) / ((float) iconSize);
if (factX > factY) if (factX > factY)
factY = factX; factY = factX;
else else
@ -119,8 +109,7 @@ winScaleXBitmapToWindows(int iconSize,
ptr += posX / 8; ptr += posX / 8;
/* Out of X icon bounds, leave space blank */ /* Out of X icon bounds, leave space blank */
if (posX >= pixmap->drawable.width if (posX >= pixmap->width || posY >= pixmap->height)
|| posY >= pixmap->drawable.height)
ptr = (unsigned char *) &zero; ptr = (unsigned char *) &zero;
if ((*ptr) & (1 << (posX & 7))) if ((*ptr) & (1 << (posX & 7)))
@ -162,8 +151,7 @@ winScaleXBitmapToWindows(int iconSize,
ptr += posX * (effXBPP / 8); ptr += posX * (effXBPP / 8);
/* Out of X icon bounds, leave space blank */ /* Out of X icon bounds, leave space blank */
if (posX >= pixmap->drawable.width if (posX >= pixmap->width || posY >= pixmap->height)
|| posY >= pixmap->drawable.height)
ptr = (unsigned char *) &zero; ptr = (unsigned char *) &zero;
color = (((*ptr) << 16) color = (((*ptr) << 16)
+ ((*(ptr + 1)) << 8) + ((*(ptr + 1)) << 8)
@ -203,8 +191,7 @@ winScaleXBitmapToWindows(int iconSize,
ptr += posX * (effXBPP / 8); ptr += posX * (effXBPP / 8);
/* Out of X icon bounds, leave space blank */ /* Out of X icon bounds, leave space blank */
if (posX >= pixmap->drawable.width if (posX >= pixmap->width || posY >= pixmap->height)
|| posY >= pixmap->drawable.height)
ptr = (unsigned char *) &zero; ptr = (unsigned char *) &zero;
color = ((*ptr) << 8) + (*(ptr + 1)); color = ((*ptr) << 8) + (*(ptr + 1));
switch (effBPP) { switch (effBPP) {
@ -238,7 +225,6 @@ winScaleXBitmapToWindows(int iconSize,
} /* end if effxbpp==16) */ } /* end if effxbpp==16) */
} /* end for column */ } /* end for column */
} /* end for row */ } /* end for row */
free(iconData);
} }
static HICON static HICON
@ -250,7 +236,7 @@ NetWMToWinIconAlpha(uint32_t * icon)
HICON result; HICON result;
HDC hdc = GetDC(NULL); HDC hdc = GetDC(NULL);
uint32_t *DIB_pixels; uint32_t *DIB_pixels;
ICONINFO ii = { TRUE }; ICONINFO ii;
BITMAPV4HEADER bmh = { sizeof(bmh) }; BITMAPV4HEADER bmh = { sizeof(bmh) };
/* Define an ARGB pixel format used for Color+Alpha icons */ /* Define an ARGB pixel format used for Color+Alpha icons */
@ -264,6 +250,9 @@ NetWMToWinIconAlpha(uint32_t * icon)
bmh.bV4GreenMask = 0x0000FF00; bmh.bV4GreenMask = 0x0000FF00;
bmh.bV4BlueMask = 0x000000FF; bmh.bV4BlueMask = 0x000000FF;
ii.fIcon = TRUE;
ii.xHotspot = 0; /* ignored */
ii.yHotspot = 0; /* ignored */
ii.hbmColor = CreateDIBSection(hdc, (BITMAPINFO *) & bmh, ii.hbmColor = CreateDIBSection(hdc, (BITMAPINFO *) & bmh,
DIB_RGB_COLORS, (void **) &DIB_pixels, NULL, DIB_RGB_COLORS, (void **) &DIB_pixels, NULL,
0); 0);
@ -291,12 +280,15 @@ NetWMToWinIconThreshold(uint32_t * icon)
uint32_t *pixels = &icon[2]; uint32_t *pixels = &icon[2];
int row, col; int row, col;
HICON result; HICON result;
ICONINFO ii = { TRUE }; ICONINFO ii;
HDC hdc = GetDC(NULL); HDC hdc = GetDC(NULL);
HDC xorDC = CreateCompatibleDC(hdc); HDC xorDC = CreateCompatibleDC(hdc);
HDC andDC = CreateCompatibleDC(hdc); HDC andDC = CreateCompatibleDC(hdc);
ii.fIcon = TRUE;
ii.xHotspot = 0; /* ignored */
ii.yHotspot = 0; /* ignored */
ii.hbmColor = CreateCompatibleBitmap(hdc, width, height); ii.hbmColor = CreateCompatibleBitmap(hdc, width, height);
ii.hbmMask = CreateCompatibleBitmap(hdc, width, height); ii.hbmMask = CreateCompatibleBitmap(hdc, width, height);
ReleaseDC(NULL, hdc); ReleaseDC(NULL, hdc);
@ -365,202 +357,220 @@ NetWMToWinIcon(int bpp, uint32_t * icon)
return NetWMToWinIconThreshold(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 * Attempt to create a custom icon from the WM_HINTS bitmaps
*/ */
HICON static
winXIconToHICON(WindowPtr pWin, int iconSize) HICON
winXIconToHICON(Display * pDisplay, Window id, int iconSize)
{ {
unsigned char *mask, *image, *imageMask; unsigned char *mask, *image = NULL, *imageMask;
unsigned char *dst, *src; unsigned char *dst, *src;
PixmapPtr iconPtr; int planes, bpp, i;
PixmapPtr maskPtr;
int planes, bpp, effBPP, stride, maskStride, i;
int biggest_size = 0; int biggest_size = 0;
HDC hDC; HDC hDC;
ICONINFO ii; ICONINFO ii;
WinXWMHints hints; XWMHints *hints;
HICON hIcon = NULL; HICON hIcon = NULL;
uint32_t *biggest_icon = NULL; uint32_t *biggest_icon = NULL;
/* Try to get _NET_WM_ICON icons first */
static Atom _XA_NET_WM_ICON; static Atom _XA_NET_WM_ICON;
static int generation; static int generation;
uint32_t *icon, *icon_data = NULL; 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()); hDC = GetDC(GetDesktopWindow());
planes = GetDeviceCaps(hDC, PLANES); planes = GetDeviceCaps(hDC, PLANES);
bpp = GetDeviceCaps(hDC, BITSPIXEL); bpp = GetDeviceCaps(hDC, BITSPIXEL);
ReleaseDC(GetDesktopWindow(), hDC); ReleaseDC(GetDesktopWindow(), hDC);
/* Always prefer _NET_WM_ICON icons */
if (generation != serverGeneration) { if (generation != serverGeneration) {
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) if ((XGetWindowProperty(pDisplay, id, _XA_NET_WM_ICON,
icon_data = GetWindowProp(pWin, _XA_NET_WM_ICON, &size); 0, MAXINT, FALSE,
if (icon_data) { AnyPropertyType, &type, &format, &size, &left,
for (icon = icon_data; (unsigned char **) &icon_data) == Success) &&
icon < &icon_data[size] && *icon; (icon_data != NULL)) {
for (icon = icon_data; icon < &icon_data[size] && *icon;
icon = &icon[icon[0] * icon[1] + 2]) { icon = &icon[icon[0] * icon[1] + 2]) {
if (icon[0] == iconSize && icon[1] == iconSize) /* Find an exact match to the size we require... */
return NetWMToWinIcon(bpp, icon); if (icon[0] == iconSize && icon[1] == iconSize) {
/* Find the biggest icon and let Windows scale the size */ 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]) { else if (biggest_size < icon[0]) {
biggest_icon = icon; biggest_icon = icon;
biggest_size = icon[0]; 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 (!hIcon && biggest_icon) {
if (!hints.icon_pixmap) winDebug
return NULL; ("winXIconToHICON: selected %lu x %lu NetIcon for scaling to %u x %u\n",
biggest_icon[0], biggest_icon[1], iconSize, iconSize);
dixLookupResourceByType((pointer) &iconPtr, hints.icon_pixmap, RT_PIXMAP, hIcon = NetWMToWinIcon(bpp, biggest_icon);
NullClient, DixUnknownAccess); }
if (!iconPtr) XFree(icon_data);
return NULL;
/* 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;
/* Mask is 1-bit deep */
maskStride = ((iconSize * 1 + 15) & (~15)) / 8;
image = malloc(stride * iconSize);
imageMask = malloc(stride * iconSize);
/* Default to a completely black mask */
mask = calloc(maskStride, iconSize);
winScaleXBitmapToWindows(iconSize, effBPP, iconPtr, image);
dixLookupResourceByType((pointer) &maskPtr, hints.icon_mask, RT_PIXMAP,
NullClient, DixUnknownAccess);
if (maskPtr) {
winScaleXBitmapToWindows(iconSize, 1, maskPtr, mask);
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;
for (i = 0; i < (stride * iconSize); i++)
if ((*(src++)))
*(dst++) = 0;
else
dst++;
} }
ii.fIcon = TRUE; if (!hIcon) {
ii.xHotspot = 0; /* ignored */ winDebug("winXIconToHICON: no suitable NetIcon\n");
ii.yHotspot = 0; /* ignored */
/* Create Win32 mask from pixmap shape */ hints = XGetWMHints(pDisplay, id);
ii.hbmMask = CreateBitmap(iconSize, iconSize, planes, 1, mask); if (hints) {
winDebug("winXIconToHICON: id 0x%x icon_pixmap hint %x\n", id,
hints->icon_pixmap);
/* Create Win32 bitmap from pixmap */ if (hints->icon_pixmap) {
ii.hbmColor = CreateBitmap(iconSize, iconSize, planes, bpp, image); Window root;
int x, y;
unsigned int width, height, border_width, depth;
XImage *xImageIcon;
XImage *xImageMask = NULL;
/* Merge Win32 mask and bitmap into icon */ XGetGeometry(pDisplay, hints->icon_pixmap, &root, &x, &y,
hIcon = CreateIconIndirect(&ii); &width, &height, &border_width, &depth);
/* Release Win32 mask and bitmap */ xImageIcon =
DeleteObject(ii.hbmMask); XGetImage(pDisplay, hints->icon_pixmap, 0, 0, width, height,
DeleteObject(ii.hbmColor); 0xFFFFFFFF, ZPixmap);
winDebug("winXIconToHICON: id 0x%x icon Ximage 0x%x\n", id,
xImageIcon);
/* Free X mask and bitmap */ if (hints->icon_mask)
free(mask); xImageMask =
free(image); XGetImage(pDisplay, hints->icon_mask, 0, 0, width,
free(imageMask); 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;
/* Need 16-bit aligned rows for DDBitmaps */
stride = ((iconSize * effBPP + 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);
/* Default to a completely black mask */
memset(imageMask, 0, stride * iconSize);
memset(mask, 0, maskStride * iconSize);
winScaleXImageToWindowsIcon(iconSize, effBPP, stride,
xImageIcon, image);
if (xImageMask) {
winScaleXImageToWindowsIcon(iconSize, 1, maskStride,
xImageMask, mask);
winScaleXImageToWindowsIcon(iconSize, effBPP, stride,
xImageMask, 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++;
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 bitmap from pixmap */
ii.hbmColor =
CreateBitmap(iconSize, iconSize, planes, bpp, image);
/* Merge Win32 mask and bitmap into icon */
hIcon = CreateIconIndirect(&ii);
/* Release Win32 mask and bitmap */
DeleteObject(ii.hbmMask);
DeleteObject(ii.hbmColor);
/* Free X mask and bitmap */
free(mask);
free(image);
free(imageMask);
if (xImageMask)
XDestroyImage(xImageMask);
XDestroyImage(xImageIcon);
}
}
XFree(hints);
}
}
return hIcon; return hIcon;
} }
/* /*
* Change the Windows window icon * Change the Windows window icon
*/ */
#ifdef XWIN_MULTIWINDOW #ifdef XWIN_MULTIWINDOW
void void
winUpdateIcon(Window id) winUpdateIcon(HWND hWnd, Display * pDisplay, Window id, HICON hIconNew)
{ {
WindowPtr pWin;
HICON hIcon, hIconSmall = NULL, hIconOld; HICON hIcon, hIconSmall = NULL, hIconOld;
dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, /* Start with the icon from preferences, if any */
DixUnknownAccess); hIcon = hIconNew;
if (pWin) { hIconSmall = hIconNew;
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));
}
}
/* Set the large icon */ /* If we still need an icon, try and get the icon from WM_HINTS */
hIconOld = (HICON) SendMessage(pWinPriv->hWnd, if (!hIcon)
WM_SETICON, ICON_BIG, hIcon = winXIconToHICON(pDisplay, id, GetSystemMetrics(SM_CXICON));
(LPARAM) hIcon); if (!hIconSmall)
hIconSmall =
winXIconToHICON(pDisplay, id, GetSystemMetrics(SM_CXSMICON));
/* Delete the icon if its not the default */ /* If we got the small, but not the large one swap them */
winDestroyIcon(hIconOld); if (!hIcon && hIconSmall) {
hIcon = hIconSmall;
/* Same for the small icon */ hIconSmall = NULL;
hIconOld = (HICON) SendMessage(pWinPriv->hWnd,
WM_SETICON, ICON_SMALL,
(LPARAM) hIconSmall);
winDestroyIcon(hIconOld);
}
} }
/* 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 void
@ -591,37 +601,21 @@ winInitGlobalIcons(void)
} }
void void
winSelectIcons(WindowPtr pWin, HICON * pIcon, HICON * pSmallIcon) winSelectIcons(HICON * pIcon, HICON * pSmallIcon)
{ {
HICON hIcon, hSmallIcon; HICON hIcon, hSmallIcon;
winInitGlobalIcons(); winInitGlobalIcons();
/* Try and get the icon from WM_HINTS */ /* Use default X icon */
hIcon = winXIconToHICON(pWin, GetSystemMetrics(SM_CXICON)); hIcon = g_hIconX;
hSmallIcon = winXIconToHICON(pWin, GetSystemMetrics(SM_CXSMICON)); hSmallIcon = g_hSmallIconX;
/* 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;
}
if (pIcon) if (pIcon)
*pIcon = hIcon; *pIcon = hIcon;
else
winDestroyIcon(hIcon);
if (pSmallIcon) if (pSmallIcon)
*pSmallIcon = hSmallIcon; *pSmallIcon = hSmallIcon;
else
winDestroyIcon(hSmallIcon);
} }
void void

View File

@ -0,0 +1,42 @@
/*
* File: winmultiwindowicons.h
* Purpose: interface for multiwindow mode icon functions
*
* Copyright (c) Jon TURNEY 2012
*
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef WINMULTIWINDOWICONS_H
#define WINMULTIWINDOWICONS_H
void
winUpdateIcon(HWND hWnd, Display * pDisplay, Window id, HICON hIconNew);
void
winInitGlobalIcons(void);
void
winDestroyIcon(HICON hIcon);
void
winSelectIcons(HICON * pIcon, HICON * pSmallIcon);
#endif /* WINMULTIWINDOWICONS_H */

View File

@ -63,6 +63,11 @@ winInitMultiWindowClass(void)
WNDCLASSEX wcx; WNDCLASSEX wcx;
if (atomXWinClass == 0) { if (atomXWinClass == 0) {
HICON hIcon, hIconSmall;
/* Load the default icons */
winSelectIcons(&hIcon, &hIconSmall);
/* Setup our window class */ /* Setup our window class */
wcx.cbSize = sizeof(WNDCLASSEX); wcx.cbSize = sizeof(WNDCLASSEX);
wcx.style = CS_HREDRAW | CS_VREDRAW | (g_fNativeGl ? CS_OWNDC : 0); wcx.style = CS_HREDRAW | CS_VREDRAW | (g_fNativeGl ? CS_OWNDC : 0);
@ -70,12 +75,12 @@ winInitMultiWindowClass(void)
wcx.cbClsExtra = 0; wcx.cbClsExtra = 0;
wcx.cbWndExtra = 0; wcx.cbWndExtra = 0;
wcx.hInstance = g_hInstance; wcx.hInstance = g_hInstance;
wcx.hIcon = g_hIconX; wcx.hIcon = hIcon;
wcx.hCursor = 0; wcx.hCursor = 0;
wcx.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wcx.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wcx.lpszMenuName = NULL; wcx.lpszMenuName = NULL;
wcx.lpszClassName = WINDOW_CLASS_X; wcx.lpszClassName = WINDOW_CLASS_X;
wcx.hIconSm = g_hSmallIconX; wcx.hIconSm = hIconSmall;
#if CYGMULTIWINDOW_DEBUG #if CYGMULTIWINDOW_DEBUG
ErrorF("winCreateWindowsWindow - Creating class: %s\n", WINDOW_CLASS_X); ErrorF("winCreateWindowsWindow - Creating class: %s\n", WINDOW_CLASS_X);
@ -479,8 +484,6 @@ winCreateWindowsWindow(WindowPtr pWin)
HWND hFore = NULL; HWND hFore = NULL;
winWindowPriv(pWin); winWindowPriv(pWin);
HICON hIcon;
HICON hIconSmall;
winPrivScreenPtr pScreenPriv = pWinPriv->pScreenPriv; winPrivScreenPtr pScreenPriv = pWinPriv->pScreenPriv;
WinXSizeHints hints; WinXSizeHints hints;
WindowPtr pDaddy; WindowPtr pDaddy;
@ -574,13 +577,6 @@ winCreateWindowsWindow(WindowPtr pWin)
} }
pWinPriv->hWnd = hWnd; pWinPriv->hWnd = hWnd;
/* Set application or .XWinrc defined Icons */
winSelectIcons(pWin, &hIcon, &hIconSmall);
if (hIcon)
SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM) hIcon);
if (hIconSmall)
SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall);
/* Change style back to popup, already placed... */ /* Change style back to popup, already placed... */
SetWindowLongPtr(hWnd, GWL_STYLE, SetWindowLongPtr(hWnd, GWL_STYLE,
WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);

View File

@ -151,7 +151,7 @@ static Bool
InitQueue(WMMsgQueuePtr pQueue); InitQueue(WMMsgQueuePtr pQueue);
static void static void
GetWindowName(Display * pDpy, Window iWin, wchar_t ** ppName); GetWindowName(Display * pDpy, Window iWin, char **ppWindowName);
static int static int
SendXMessage(Display * pDisplay, Window iWin, Atom atmType, long nData); SendXMessage(Display * pDisplay, Window iWin, Atom atmType, long nData);
@ -399,38 +399,19 @@ InitQueue(WMMsgQueuePtr pQueue)
return TRUE; return TRUE;
} }
/* static
* GetWindowName - Retrieve the title of an X Window char *
*/ Xutf8TextPropertyToString(Display * pDisplay, XTextProperty * xtp)
static void
GetWindowName(Display * pDisplay, Window iWin, wchar_t ** ppName)
{ {
int nResult, nNum; int nNum;
char **ppList; char **ppList;
char *pszReturnData; char *pszReturnData;
int iLen, i;
XTextProperty xtpName;
#if CYGMULTIWINDOW_DEBUG if (Xutf8TextPropertyToTextList(pDisplay, xtp, &ppList, &nNum) >= Success &&
ErrorF("GetWindowName\n"); nNum > 0 && *ppList) {
#endif int i;
int iLen = 0;
/* Intialize ppName to NULL */
*ppName = NULL;
/* Try to get --- */
nResult = XGetWMName(pDisplay, iWin, &xtpName);
if (!nResult || !xtpName.value || !xtpName.nitems) {
#if CYGMULTIWINDOW_DEBUG
ErrorF("GetWindowName - XGetWMName failed. No name.\n");
#endif
return;
}
if (Xutf8TextPropertyToTextList(pDisplay, &xtpName, &ppList, &nNum) >=
Success && nNum > 0 && *ppList) {
iLen = 0;
for (i = 0; i < nNum; i++) for (i = 0; i < nNum; i++)
iLen += strlen(ppList[i]); iLen += strlen(ppList[i]);
pszReturnData = (char *) malloc(iLen + 1); pszReturnData = (char *) malloc(iLen + 1);
@ -444,15 +425,40 @@ GetWindowName(Display * pDisplay, Window iWin, wchar_t ** ppName)
pszReturnData = (char *) malloc(1); pszReturnData = (char *) malloc(1);
pszReturnData[0] = '\0'; pszReturnData[0] = '\0';
} }
iLen = MultiByteToWideChar(CP_UTF8, 0, pszReturnData, -1, NULL, 0);
*ppName = (wchar_t *) malloc(sizeof(wchar_t) * (iLen + 1)); return pszReturnData;
MultiByteToWideChar(CP_UTF8, 0, pszReturnData, -1, *ppName, iLen); }
XFree(xtpName.value);
free(pszReturnData); /*
* GetWindowName - Retrieve the title of an X Window
*/
static void
GetWindowName(Display * pDisplay, Window iWin, char **ppWindowName)
{
int nResult;
XTextProperty xtpWindowName;
char *pszWindowName;
#if CYGMULTIWINDOW_DEBUG #if CYGMULTIWINDOW_DEBUG
ErrorF("GetWindowName - Returning\n"); ErrorF("GetWindowName\n");
#endif #endif
/* Intialize ppWindowName to NULL */
*ppWindowName = NULL;
/* Try to get window name */
nResult = XGetWMName(pDisplay, iWin, &xtpWindowName);
if (!nResult || !xtpWindowName.value || !xtpWindowName.nitems) {
#if CYGMULTIWINDOW_DEBUG
ErrorF("GetWindowName - XGetWMName failed. No name.\n");
#endif
return;
}
pszWindowName = Xutf8TextPropertyToString(pDisplay, &xtpWindowName);
XFree(xtpWindowName.value);
*ppWindowName = pszWindowName;
} }
/* /*
@ -528,20 +534,72 @@ UpdateName(WMInfoPtr pWMInfo, Window iWindow)
if (!hWnd) if (!hWnd)
return; return;
/* Set the Windows window name */ /* If window isn't override-redirect */
GetWindowName(pWMInfo->pDisplay, iWindow, &pszName); XGetWindowAttributes(pWMInfo->pDisplay, iWindow, &attr);
if (pszName) { if (!attr.override_redirect) {
/* Get the window attributes */ char *pszWindowName;
XGetWindowAttributes(pWMInfo->pDisplay, iWindow, &attr);
if (!attr.override_redirect) {
SetWindowTextW(hWnd, pszName);
winUpdateIcon(iWindow);
}
free(pszName); /* Get the X windows window name */
GetWindowName(pWMInfo->pDisplay, iWindow, &pszWindowName);
if (pszWindowName) {
/* Convert from UTF-8 to wide char */
int iLen =
MultiByteToWideChar(CP_UTF8, 0, pszWindowName, -1, NULL, 0);
wchar_t *pwszWideWindowName =
(wchar_t *) malloc(sizeof(wchar_t) * (iLen + 1));
MultiByteToWideChar(CP_UTF8, 0, pszWindowName, -1,
pwszWideWindowName, iLen);
/* Set the Windows window name */
SetWindowTextW(hWnd, pwszWideWindowName);
free(pwszWideWindowName);
free(pszWindowName);
}
} }
} }
/*
* Updates the icon of a HWND according to its X icon properties
*/
static void
UpdateIcon(WMInfoPtr pWMInfo, Window iWindow)
{
HWND hWnd;
HICON hIconNew = NULL;
XWindowAttributes attr;
hWnd = getHwnd(pWMInfo, iWindow);
if (!hWnd)
return;
/* If window isn't override-redirect */
XGetWindowAttributes(pWMInfo->pDisplay, iWindow, &attr);
if (!attr.override_redirect) {
XClassHint class_hint = { 0, 0 };
char *window_name = 0;
if (XGetClassHint(pWMInfo->pDisplay, iWindow, &class_hint)) {
XFetchName(pWMInfo->pDisplay, iWindow, &window_name);
hIconNew =
(HICON) winOverrideIcon(class_hint.res_name,
class_hint.res_class, window_name);
if (class_hint.res_name)
XFree(class_hint.res_name);
if (class_hint.res_class)
XFree(class_hint.res_class);
if (window_name)
XFree(window_name);
}
}
winUpdateIcon(hWnd, pWMInfo->pDisplay, iWindow, hIconNew);
}
#if 0 #if 0
/* /*
* Fix up any differences between the X11 and Win32 window stacks * Fix up any differences between the X11 and Win32 window stacks
@ -665,7 +723,7 @@ winMultiWindowWMProc(void *pArg)
PropModeReplace, PropModeReplace,
(unsigned char *) &(pNode->msg.hwndWindow), 1); (unsigned char *) &(pNode->msg.hwndWindow), 1);
UpdateName(pWMInfo, pNode->msg.iWindow); UpdateName(pWMInfo, pNode->msg.iWindow);
winUpdateIcon(pNode->msg.iWindow); UpdateIcon(pWMInfo, pNode->msg.iWindow);
break; break;
case WM_WM_MAP2: case WM_WM_MAP2:
@ -688,7 +746,7 @@ winMultiWindowWMProc(void *pArg)
PropModeReplace, PropModeReplace,
(unsigned char *) &(pNode->msg.hwndWindow), 1); (unsigned char *) &(pNode->msg.hwndWindow), 1);
UpdateName(pWMInfo, pNode->msg.iWindow); UpdateName(pWMInfo, pNode->msg.iWindow);
winUpdateIcon(pNode->msg.iWindow); UpdateIcon(pWMInfo, pNode->msg.iWindow);
{ {
HWND zstyle = HWND_NOTOPMOST; HWND zstyle = HWND_NOTOPMOST;
@ -750,8 +808,8 @@ winMultiWindowWMProc(void *pArg)
UpdateName(pWMInfo, pNode->msg.iWindow); UpdateName(pWMInfo, pNode->msg.iWindow);
break; break;
case WM_WM_HINTS_EVENT: case WM_WM_ICON_EVENT:
winUpdateIcon(pNode->msg.iWindow); UpdateIcon(pWMInfo, pNode->msg.iWindow);
break; break;
case WM_WM_CHANGE_STATE: case WM_WM_CHANGE_STATE:
@ -802,6 +860,7 @@ winMultiWindowXMsgProc(void *pArg)
Atom atmWmName; Atom atmWmName;
Atom atmWmHints; Atom atmWmHints;
Atom atmWmChange; Atom atmWmChange;
Atom atmNetWmIcon;
int iReturn; int iReturn;
XIconSize *xis; XIconSize *xis;
@ -927,6 +986,7 @@ winMultiWindowXMsgProc(void *pArg)
atmWmName = XInternAtom(pProcArg->pDisplay, "WM_NAME", False); atmWmName = XInternAtom(pProcArg->pDisplay, "WM_NAME", False);
atmWmHints = XInternAtom(pProcArg->pDisplay, "WM_HINTS", False); atmWmHints = XInternAtom(pProcArg->pDisplay, "WM_HINTS", False);
atmWmChange = XInternAtom(pProcArg->pDisplay, "WM_CHANGE_STATE", False); atmWmChange = XInternAtom(pProcArg->pDisplay, "WM_CHANGE_STATE", False);
atmNetWmIcon = XInternAtom(pProcArg->pDisplay, "_NET_WM_ICON", False);
/* /*
iiimxcf had a bug until 2009-04-27, assuming that the iiimxcf had a bug until 2009-04-27, assuming that the
@ -1054,25 +1114,25 @@ winMultiWindowXMsgProc(void *pArg)
True, StructureNotifyMask, &event_send); True, StructureNotifyMask, &event_send);
} }
} }
else if (event.type == PropertyNotify else if (event.type == PropertyNotify) {
&& event.xproperty.atom == atmWmName) { if (event.xproperty.atom == atmWmName) {
memset(&msg, 0, sizeof(msg)); memset(&msg, 0, sizeof(msg));
msg.msg = WM_WM_NAME_EVENT; msg.msg = WM_WM_NAME_EVENT;
msg.iWindow = event.xproperty.window; msg.iWindow = event.xproperty.window;
/* Other fields ignored */ /* Other fields ignored */
winSendMessageToWM(pProcArg->pWMInfo, &msg); winSendMessageToWM(pProcArg->pWMInfo, &msg);
} }
else if (event.type == PropertyNotify else if ((event.xproperty.atom == atmWmHints) ||
&& event.xproperty.atom == atmWmHints) { (event.xproperty.atom == atmNetWmIcon)) {
memset(&msg, 0, sizeof(msg)); memset(&msg, 0, sizeof(msg));
msg.msg = WM_WM_ICON_EVENT;
msg.iWindow = event.xproperty.window;
msg.msg = WM_WM_HINTS_EVENT; /* Other fields ignored */
msg.iWindow = event.xproperty.window; winSendMessageToWM(pProcArg->pWMInfo, &msg);
}
/* Other fields ignored */
winSendMessageToWM(pProcArg->pWMInfo, &msg);
} }
else if (event.type == ClientMessage else if (event.type == ClientMessage
&& event.xclient.message_type == atmWmChange && event.xclient.message_type == atmWmChange
@ -1683,13 +1743,11 @@ winUpdateWindowPosition(HWND hWnd, Bool reshape, HWND * zstyle)
/* Setup a rectangle with the X window position and size */ /* Setup a rectangle with the X window position and size */
SetRect(&rcNew, iX, iY, iX + iWidth, iY + iHeight); SetRect(&rcNew, iX, iY, iX + iWidth, iY + iHeight);
#if 0 winDebug("winUpdateWindowPosition - drawable extent (%d, %d)-(%d, %d)\n",
ErrorF("winUpdateWindowPosition - (%d, %d)-(%d, %d)\n", rcNew.left, rcNew.top, rcNew.right, rcNew.bottom);
rcNew.left, rcNew.top, rcNew.right, rcNew.bottom);
#endif
AdjustWindowRectEx(&rcNew, GetWindowLongPtr(hWnd, GWL_STYLE), FALSE, AdjustWindowRectEx(&rcNew, GetWindowLongPtr(hWnd, GWL_STYLE), FALSE,
WS_EX_APPWINDOW); GetWindowLongPtr(hWnd, GWL_EXSTYLE));
/* Don't allow window decoration to disappear off to top-left as a result of this adjustment */ /* Don't allow window decoration to disappear off to top-left as a result of this adjustment */
if (rcNew.left < GetSystemMetrics(SM_XVIRTUALSCREEN)) { if (rcNew.left < GetSystemMetrics(SM_XVIRTUALSCREEN)) {
@ -1704,10 +1762,8 @@ winUpdateWindowPosition(HWND hWnd, Bool reshape, HWND * zstyle)
rcNew.bottom += iDy; rcNew.bottom += iDy;
} }
#if 0 winDebug("winUpdateWindowPosition - Window extent (%d, %d)-(%d, %d)\n",
ErrorF("winUpdateWindowPosition - (%d, %d)-(%d, %d)\n", rcNew.left, rcNew.top, rcNew.right, rcNew.bottom);
rcNew.left, rcNew.top, rcNew.right, rcNew.bottom);
#endif
/* Position the Windows window */ /* Position the Windows window */
SetWindowPos(hWnd, *zstyle, rcNew.left, rcNew.top, SetWindowPos(hWnd, *zstyle, rcNew.left, rcNew.top,

View File

@ -148,7 +148,6 @@ static wBOOL CALLBACK
ReloadEnumWindowsProc(HWND hwnd, LPARAM lParam) ReloadEnumWindowsProc(HWND hwnd, LPARAM lParam)
{ {
HICON hicon; HICON hicon;
Window wid;
if (!hwnd) { if (!hwnd) {
ErrorF("ReloadEnumWindowsProc: hwnd==NULL!\n"); ErrorF("ReloadEnumWindowsProc: hwnd==NULL!\n");
@ -173,10 +172,23 @@ ReloadEnumWindowsProc(HWND hwnd, LPARAM lParam)
/* This window is now clean of our taint (but with undefined icons) */ /* This window is now clean of our taint (but with undefined icons) */
} }
else { else {
/* winUpdateIcon() will set the icon default, dynamic, or from xwinrc */ /* Send a message to WM thread telling it re-evaluate the icon for this window */
wid = (Window) GetProp(hwnd, WIN_WID_PROP); {
if (wid) winWMMessageRec wmMsg;
winUpdateIcon(wid);
WindowPtr pWin = GetProp(hwnd, WIN_WINDOW_PROP);
if (pWin) {
winPrivWinPtr pWinPriv = winGetWindowPriv(pWin);
winPrivScreenPtr s_pScreenPriv = pWinPriv->pScreenPriv;
wmMsg.msg = WM_WM_ICON_EVENT;
wmMsg.hwndWindow = hwnd;
wmMsg.iWindow = (Window) GetProp(hwnd, WIN_WID_PROP);
winSendMessageToWM(s_pScreenPriv->pWMInfo, &wmMsg);
}
}
/* Update the system menu for this window */ /* Update the system menu for this window */
SetupSysMenu((unsigned long) hwnd); SetupSysMenu((unsigned long) hwnd);
@ -577,31 +589,15 @@ LoadImageComma(char *fname, int sx, int sy, int flags)
* ICONS{} section in the prefs file, and load the icon from a file * ICONS{} section in the prefs file, and load the icon from a file
*/ */
HICON HICON
winOverrideIcon(unsigned long longWin) winOverrideIcon(char *res_name, char *res_class, char *wmName)
{ {
WindowPtr pWin = (WindowPtr) longWin;
char *res_name, *res_class;
int i; int i;
HICON hicon; HICON hicon;
char *wmName;
if (pWin == NULL)
return 0;
/* If we can't find the class, we can't override from default! */
if (!winMultiWindowGetClassHint(pWin, &res_name, &res_class))
return 0;
winMultiWindowGetWMName(pWin, &wmName);
for (i = 0; i < pref.iconItems; i++) { for (i = 0; i < pref.iconItems; i++) {
if (!strcmp(pref.icon[i].match, res_name) || if ((res_name && !strcmp(pref.icon[i].match, res_name)) ||
!strcmp(pref.icon[i].match, res_class) || (res_class && !strcmp(pref.icon[i].match, res_class)) ||
(wmName && strstr(wmName, pref.icon[i].match))) { (wmName && strstr(wmName, pref.icon[i].match))) {
free(res_name);
free(res_class);
free(wmName);
if (pref.icon[i].hicon) if (pref.icon[i].hicon)
return pref.icon[i].hicon; return pref.icon[i].hicon;
@ -616,10 +612,6 @@ winOverrideIcon(unsigned long longWin)
} }
/* Didn't find the icon, fail gracefully */ /* Didn't find the icon, fail gracefully */
free(res_name);
free(res_class);
free(wmName);
return 0; return 0;
} }

View File

@ -164,7 +164,7 @@ Bool
int int
winIconIsOverride(unsigned hiconIn); winIconIsOverride(unsigned hiconIn);
HICON winOverrideIcon(unsigned long longpWin); HICON winOverrideIcon(char *res_name, char *res_class, char *wmName);
unsigned long unsigned long
winOverrideStyle(char *res_name, char *res_class, char *wmName); winOverrideStyle(char *res_name, char *res_class, char *wmName);

View File

@ -231,7 +231,7 @@ winMWExtWMCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
// Store the implementation private frame ID // Store the implementation private frame ID
pFrame->wid = (RootlessFrameID) pRLWinPriv; pFrame->wid = (RootlessFrameID) pRLWinPriv;
winSelectIcons(pFrame->win, &hIcon, &hIconSmall); winSelectIcons(&hIcon, &hIconSmall);
/* Set standard class name prefix so we can identify window easily */ /* Set standard class name prefix so we can identify window easily */
strncpy(pszClass, WINDOW_CLASS_X, sizeof(pszClass)); strncpy(pszClass, WINDOW_CLASS_X, sizeof(pszClass));

View File

@ -147,39 +147,8 @@ winMWExtWMMoveResizeXWindow(WindowPtr pWin, int x, int y, int w, int h)
} }
/* /*
* winMWExtWMUpdateIcon
* Change the Windows window icon
*/
void
winMWExtWMUpdateIcon(Window id)
{
WindowPtr pWin;
HICON hIcon, hiconOld;
dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient,
DixUnknownAccess);
hIcon = winOverrideIcon((unsigned long) pWin);
if (!hIcon)
hIcon = winXIconToHICON(pWin, GetSystemMetrics(SM_CXICON));
if (hIcon) {
win32RootlessWindowPtr pRLWinPriv
= (win32RootlessWindowPtr) RootlessFrameForWindow(pWin, FALSE);
if (pRLWinPriv->hWnd) {
hiconOld = (HICON) SendMessage(pRLWinPriv->hWnd,
WM_SETICON, ICON_BIG,
(LPARAM) hIcon);
winDestroyIcon(hiconOld);
}
hIcon = NULL;
}
}
/*
* winMWExtWMDecorateWindow - Update window style. Called by EnumWindows. * winMWExtWMDecorateWindow - Update window style. Called by EnumWindows.
*/ */

View File

@ -115,7 +115,7 @@ typedef struct _winWMMessageRec {
#define WM_WM_KILL (WM_USER + 7) #define WM_WM_KILL (WM_USER + 7)
#define WM_WM_ACTIVATE (WM_USER + 8) #define WM_WM_ACTIVATE (WM_USER + 8)
#define WM_WM_NAME_EVENT (WM_USER + 9) #define WM_WM_NAME_EVENT (WM_USER + 9)
#define WM_WM_HINTS_EVENT (WM_USER + 10) #define WM_WM_ICON_EVENT (WM_USER + 10)
#define WM_WM_CHANGE_STATE (WM_USER + 11) #define WM_WM_CHANGE_STATE (WM_USER + 11)
#define WM_WM_MAP2 (WM_USER + 12) #define WM_WM_MAP2 (WM_USER + 12)
#define WM_WM_MAP3 (WM_USER + 13) #define WM_WM_MAP3 (WM_USER + 13)
@ -157,18 +157,5 @@ void
void void
winMinimizeWindow(Window id); winMinimizeWindow(Window id);
/*
* winmultiwindowicons.c
*/
void
winUpdateIcon(Window id);
void
winInitGlobalIcons(void);
void
winDestroyIcon(HICON hIcon);
#endif /* XWIN_MULTIWINDOW */ #endif /* XWIN_MULTIWINDOW */
#endif #endif

View File

@ -439,8 +439,6 @@ ProcWindowsWMFrameDraw(ClientPtr client)
ShowWindow(pRLWinPriv->hWnd, nCmdShow); ShowWindow(pRLWinPriv->hWnd, nCmdShow);
winMWExtWMUpdateIcon(pWin->drawable.id);
if (wBoundingShape(pWin) != NULL) { if (wBoundingShape(pWin) != NULL) {
/* wBoundingShape is relative to *inner* origin of window. /* wBoundingShape is relative to *inner* origin of window.
Translate by borderWidth to get the outside-relative position. */ Translate by borderWidth to get the outside-relative position. */

View File

@ -1583,7 +1583,7 @@ Win32TempDir()
if (getenv("TEMP") != NULL) if (getenv("TEMP") != NULL)
return getenv("TEMP"); return getenv("TEMP");
else if (getenv("TMP") != NULL) else if (getenv("TMP") != NULL)
return getenv("TEMP"); return getenv("TMP");
else else
return "/tmp"; return "/tmp";
} }