summaryrefslogtreecommitdiffstats
path: root/win/tkWinWm.c
diff options
context:
space:
mode:
Diffstat (limited to 'win/tkWinWm.c')
-rw-r--r--win/tkWinWm.c77
1 files changed, 66 insertions, 11 deletions
diff --git a/win/tkWinWm.c b/win/tkWinWm.c
index 1f4fea5..cb6e797 100644
--- a/win/tkWinWm.c
+++ b/win/tkWinWm.c
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkWinWm.c,v 1.136 2009/01/28 20:47:49 nijtmans Exp $
+ * RCS: @(#) $Id: tkWinWm.c,v 1.137 2009/04/30 14:46:36 patthoyts Exp $
*/
#include "tkWinInt.h"
@@ -4308,11 +4308,13 @@ WmIconphotoCmd(
Tk_PhotoHandle photo;
Tk_PhotoImageBlock block;
int i, width, height, idx, bufferSize, startObj = 3;
- unsigned char *bgraPixelPtr;
+ unsigned char *bgraPixelPtr, *bgraMaskPtr;
BlockOfIconImagesPtr lpIR;
WinIconPtr titlebaricon = NULL;
HICON hIcon;
unsigned size;
+ BITMAPINFO bmInfo;
+ ICONINFO iconInfo;
if (objc < 4) {
Tcl_WrongNumArgs(interp, 2, objv,
@@ -4348,39 +4350,91 @@ WmIconphotoCmd(
*/
size = sizeof(BlockOfIconImages) + (sizeof(ICONIMAGE) * (objc-startObj-1));
- lpIR = (BlockOfIconImagesPtr) Tcl_AttemptAlloc(size);
+ lpIR = (BlockOfIconImagesPtr) attemptckalloc(size);
if (lpIR == NULL) {
return TCL_ERROR;
}
ZeroMemory(lpIR, size);
lpIR->nNumImages = objc - startObj;
+
for (i = startObj; i < objc; i++) {
photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i]));
Tk_PhotoGetSize(photo, &width, &height);
Tk_PhotoGetImage(photo, &block);
/*
- * Convert the image data into BGRA format (RGBQUAD) and then
- * encode the image data into an HICON.
+ * Don't use CreateIcon to create the icon, as it requires color
+ * bitmap data in device-dependent format. Instead we use
+ * CreateIconIndirect which takes device-independent bitmaps
+ * and converts them as required. Initialise icon info structure.
+ */
+
+ ZeroMemory( &iconInfo, sizeof iconInfo );
+ iconInfo.fIcon = TRUE;
+
+ /*
+ * Create device-independant color bitmap.
+ */
+ ZeroMemory(&bmInfo,sizeof bmInfo);
+ bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmInfo.bmiHeader.biWidth = width;
+ bmInfo.bmiHeader.biHeight = -height;
+ bmInfo.bmiHeader.biPlanes = 1;
+ bmInfo.bmiHeader.biBitCount = 32;
+ bmInfo.bmiHeader.biCompression = BI_RGB;
+
+ iconInfo.hbmColor = CreateDIBSection( NULL, &bmInfo,
+ DIB_RGB_COLORS, &bgraPixelPtr, NULL, 0 );
+ if ( !iconInfo.hbmColor ) {
+ ckfree((char *) lpIR);
+ Tcl_AppendResult(interp, "failed to create color bitmap for \"",
+ Tcl_GetString(objv[i]), "\"", NULL);
+ return TCL_ERROR;
+ }
+
+ /*
+ * Convert the photo image data into BGRA format (RGBQUAD).
*/
- bufferSize = height * width * block.pixelSize;
- bgraPixelPtr = ckalloc(bufferSize);
+ bufferSize = height * width * 4;
for (idx = 0 ; idx < bufferSize ; idx += 4) {
bgraPixelPtr[idx] = block.pixelPtr[idx+2];
bgraPixelPtr[idx+1] = block.pixelPtr[idx+1];
bgraPixelPtr[idx+2] = block.pixelPtr[idx+0];
bgraPixelPtr[idx+3] = block.pixelPtr[idx+3];
}
- hIcon = CreateIcon(Tk_GetHINSTANCE(), width, height, 1, 32,
- NULL, (BYTE *) bgraPixelPtr);
- ckfree(bgraPixelPtr);
+
+ /*
+ * Create a dummy mask bitmap. The contents of this don't
+ * appear to matter, as CreateIconIndirect will setup the icon
+ * mask based on the alpha channel in our color bitmap.
+ */
+ bmInfo.bmiHeader.biBitCount = 1;
+
+ iconInfo.hbmMask = CreateDIBSection( NULL, &bmInfo,
+ DIB_RGB_COLORS, &bgraMaskPtr, NULL, 0 );
+ if ( !iconInfo.hbmMask ) {
+ DeleteObject(iconInfo.hbmColor);
+ ckfree((char *) lpIR);
+ Tcl_AppendResult(interp, "failed to create mask bitmap for \"",
+ Tcl_GetString(objv[i]), "\"", NULL);
+ return TCL_ERROR;
+ }
+
+ ZeroMemory( bgraMaskPtr, width*height/8 );
+
+ /*
+ * Create an icon from the bitmaps.
+ */
+ hIcon = CreateIconIndirect( &iconInfo);
+ DeleteObject(iconInfo.hbmColor);
+ DeleteObject(iconInfo.hbmMask);
if (hIcon == NULL) {
/*
* XXX should free up created icons.
*/
- Tcl_Free((char *) lpIR);
+ ckfree((char *) lpIR);
Tcl_AppendResult(interp, "failed to create icon for \"",
Tcl_GetString(objv[i]), "\"", NULL);
return TCL_ERROR;
@@ -4390,6 +4444,7 @@ WmIconphotoCmd(
lpIR->IconImages[i-startObj].Colors = 4;
lpIR->IconImages[i-startObj].hIcon = hIcon;
}
+
titlebaricon = (WinIconPtr) ckalloc(sizeof(WinIconInstance));
titlebaricon->iconBlock = lpIR;
titlebaricon->refCount = 1;