summaryrefslogtreecommitdiffstats
path: root/win
diff options
context:
space:
mode:
Diffstat (limited to 'win')
-rw-r--r--win/tkWinWm.c106
1 files changed, 81 insertions, 25 deletions
diff --git a/win/tkWinWm.c b/win/tkWinWm.c
index de4056a..3525b1a 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.54.2.25 2006/04/11 20:23:45 hobbs Exp $
+ * RCS: @(#) $Id: tkWinWm.c,v 1.54.2.26 2006/12/01 19:47:42 hobbs Exp $
*/
#include "tkWinInt.h"
@@ -24,6 +24,9 @@
#ifndef WS_EX_LAYERED
#define WS_EX_LAYERED 0x00080000
#endif
+#ifndef LWA_COLORKEY
+#define LWA_COLORKEY 0x00000001
+#endif
#ifndef LWA_ALPHA
#define LWA_ALPHA 0x00000002
#endif
@@ -238,6 +241,8 @@ typedef struct TkWmInfo {
DWORD style, exStyle; /* Style flags for the wrapper window. */
LONG styleConfig; /* Extra user requested style bits */
LONG exStyleConfig; /* Extra user requested extended style bits */
+ Tcl_Obj *crefObj; /* COLORREF object for transparent handling */
+ COLORREF colorref; /* COLORREF for transparent handling */
double alpha; /* Alpha transparency level
* 0.0 (fully transparent) .. 1.0 (opaque) */
@@ -1910,6 +1915,8 @@ TkWmNewWindow(winPtr)
wmPtr->height = -1;
wmPtr->x = winPtr->changes.x;
wmPtr->y = winPtr->changes.y;
+ wmPtr->crefObj = NULL;
+ wmPtr->colorref = (COLORREF) NULL;
wmPtr->alpha = 1.0;
wmPtr->configWidth = -1;
@@ -2109,13 +2116,17 @@ UpdateWrapper(winPtr)
* Add the 0.5 to round the value.
*/
setLayeredWindowAttributesProc((HWND) wmPtr->wrapper,
- (COLORREF) NULL, (BYTE) (wmPtr->alpha * 255 + 0.5),
- LWA_ALPHA);
+ wmPtr->colorref, (BYTE) (wmPtr->alpha * 255 + 0.5),
+ LWA_ALPHA | (wmPtr->crefObj ? LWA_COLORKEY : 0));
} else {
/*
* Layering not used or supported.
*/
wmPtr->alpha = 1.0;
+ if (wmPtr->crefObj) {
+ Tcl_DecrRefCount(wmPtr->crefObj);
+ wmPtr->crefObj = NULL;
+ }
}
place.length = sizeof(WINDOWPLACEMENT);
@@ -2552,6 +2563,10 @@ TkWmDeadWindow(winPtr)
WmWaitVisibilityOrMapProc, (ClientData) winPtr);
wmPtr->masterPtr = NULL;
}
+ if (wmPtr->crefObj != NULL) {
+ Tcl_DecrRefCount(wmPtr->crefObj);
+ wmPtr->crefObj = NULL;
+ }
/*
* Destroy the decorative frame window.
@@ -2877,6 +2892,7 @@ WmAttributesCmd(tkwin, winPtr, interp, objc, objv)
Tcl_WrongNumArgs(interp, 2, objv,
"window"
" ?-alpha ?double??"
+ " ?-transparentcolor ?color??"
" ?-disabled ?bool??"
" ?-toolwindow ?bool??"
" ?-topmost ?bool??");
@@ -2890,6 +2906,10 @@ WmAttributesCmd(tkwin, winPtr, interp, objc, objv)
Tcl_NewStringObj("-alpha", -1));
Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewDoubleObj(wmPtr->alpha));
Tcl_ListObjAppendElement(NULL, objPtr,
+ Tcl_NewStringObj("-transparentcolor", -1));
+ Tcl_ListObjAppendElement(NULL, objPtr,
+ wmPtr->crefObj ? wmPtr->crefObj : Tcl_NewObj());
+ Tcl_ListObjAppendElement(NULL, objPtr,
Tcl_NewStringObj("-disabled", -1));
Tcl_ListObjAppendElement(NULL, objPtr,
Tcl_NewBooleanObj((style & WS_DISABLED)));
@@ -2912,7 +2932,9 @@ WmAttributesCmd(tkwin, winPtr, interp, objc, objv)
if (strncmp(string, "-disabled", length) == 0) {
stylePtr = &style;
styleBit = WS_DISABLED;
- } else if (strncmp(string, "-alpha", length) == 0) {
+ } else if ((strncmp(string, "-alpha", length) == 0)
+ || ((length > 2) && (strncmp(string, "-transparentcolor",
+ length) == 0))) {
stylePtr = &exStyle;
styleBit = WS_EX_LAYERED;
} else if ((length > 3)
@@ -2933,28 +2955,62 @@ WmAttributesCmd(tkwin, winPtr, interp, objc, objv)
goto configArgs;
}
if (styleBit == WS_EX_LAYERED) {
- double dval;
-
if (objc == 4) {
- Tcl_SetDoubleObj(Tcl_GetObjResult(interp), wmPtr->alpha);
- } else {
- if ((i < objc-1) &&
- (Tcl_GetDoubleFromObj(interp, objv[i+1], &dval)
- != TCL_OK)) {
- return TCL_ERROR;
+ if (string[1] == 'a') { /* -alpha */
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(wmPtr->alpha));
+ } else { /* -transparentcolor */
+ Tcl_SetObjResult(interp,
+ wmPtr->crefObj ? wmPtr->crefObj : Tcl_NewObj());
}
- /*
- * The user should give (transparent) 0 .. 1.0 (opaque),
- * but we ignore the setting of this (it will always be 1)
- * in the case that the API is not available.
- */
- if (dval < 0.0) {
- dval = 0;
- } else if (dval > 1.0) {
- dval = 1;
+ } else {
+ if (string[1] == 'a') { /* -alpha */
+ double dval;
+
+ if (Tcl_GetDoubleFromObj(interp, objv[i+1], &dval)
+ != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * The user should give (transparent) 0 .. 1.0 (opaque),
+ * but we ignore the setting of this (it will always be 1)
+ * in the case that the API is not available.
+ */
+ if (dval < 0.0) {
+ dval = 0;
+ } else if (dval > 1.0) {
+ dval = 1;
+ }
+ wmPtr->alpha = dval;
+ } else { /* -transparentcolor */
+ char *crefstr = Tcl_GetStringFromObj(objv[i+1], &length);
+
+ if (length == 0) {
+ /* reset to no transparent color */
+ if (wmPtr->crefObj) {
+ Tcl_DecrRefCount(wmPtr->crefObj);
+ wmPtr->crefObj = NULL;
+ }
+ } else {
+ XColor *cPtr =
+ Tk_GetColor(interp, tkwin, Tk_GetUid(crefstr));
+ if (cPtr == NULL) {
+ return TCL_ERROR;
+ }
+
+ if (wmPtr->crefObj) {
+ Tcl_DecrRefCount(wmPtr->crefObj);
+ }
+ wmPtr->crefObj = objv[i+1];
+ Tcl_IncrRefCount(wmPtr->crefObj);
+ wmPtr->colorref = RGB((BYTE) (cPtr->red >> 8),
+ (BYTE) (cPtr->green >> 8),
+ (BYTE) (cPtr->blue >> 8));
+ Tk_FreeColor(cPtr);
+ }
}
- wmPtr->alpha = dval;
- if (dval < 1.0) {
+
+ if ((wmPtr->alpha < 1.0) || (wmPtr->crefObj != NULL)) {
*stylePtr |= styleBit;
} else {
*stylePtr &= ~styleBit;
@@ -2968,8 +3024,8 @@ WmAttributesCmd(tkwin, winPtr, interp, objc, objv)
* translation. Add the 0.5 to round the value.
*/
setLayeredWindowAttributesProc((HWND) wmPtr->wrapper,
- (COLORREF) NULL, (BYTE) (wmPtr->alpha * 255 + 0.5),
- LWA_ALPHA);
+ wmPtr->colorref, (BYTE) (wmPtr->alpha * 255 + 0.5),
+ LWA_ALPHA | (wmPtr->crefObj ? LWA_COLORKEY : 0));
}
}
} else {