diff options
Diffstat (limited to 'win')
-rw-r--r-- | win/tkWinWm.c | 106 |
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 { |