diff options
Diffstat (limited to 'win/tkWinWm.c')
-rw-r--r-- | win/tkWinWm.c | 107 |
1 files changed, 80 insertions, 27 deletions
diff --git a/win/tkWinWm.c b/win/tkWinWm.c index c9a8777..86360fb 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.109 2006/04/05 20:56:40 hobbs Exp $ + * RCS: @(#) $Id: tkWinWm.c,v 1.110 2006/12/01 19:48:00 hobbs Exp $ */ #include "tkWinInt.h" @@ -25,6 +25,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 @@ -244,6 +247,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) */ @@ -2045,6 +2050,8 @@ TkWmNewWindow( 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; @@ -2264,13 +2271,17 @@ UpdateWrapper( */ 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); @@ -2808,6 +2819,10 @@ TkWmDeadWindow( WmWaitVisibilityOrMapProc, (ClientData) winPtr); wmPtr->masterPtr = NULL; } + if (wmPtr->crefObj != NULL) { + Tcl_DecrRefCount(wmPtr->crefObj); + wmPtr->crefObj = NULL; + } /* * Destroy the decorative frame window. @@ -3140,6 +3155,7 @@ WmAttributesCmd( Tcl_WrongNumArgs(interp, 2, objv, "window" " ?-alpha ?double??" + " ?-transparentcolor ?color??" " ?-disabled ?bool??" " ?-fullscreen ?bool??" " ?-toolwindow ?bool??" @@ -3154,6 +3170,10 @@ WmAttributesCmd( 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))); @@ -3180,7 +3200,9 @@ WmAttributesCmd( 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 (strncmp(string, "-fullscreen", length) == 0) { @@ -3203,30 +3225,62 @@ WmAttributesCmd( 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()); } + } else { + if (string[1] == 'a') { /* -alpha */ + double dval; - /* - * 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 (Tcl_GetDoubleFromObj(interp, objv[i+1], &dval) + != TCL_OK) { + return TCL_ERROR; + } - if (dval < 0.0) { - dval = 0; - } else if (dval > 1.0) { - dval = 1; + /* + * 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; @@ -3237,12 +3291,11 @@ WmAttributesCmd( * Set the window directly regardless of UpdateWrapper. * The user supplies a double from [0..1], but Windows * wants an int (transparent) 0..255 (opaque), so do the - * translation. Add the 0.5 to round the value. + * 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 { |