/*
* tkWinWm.c --
*
* This module takes care of the interactions between a Tk-based
* application and the window manager. Among other things, it
* implements the "wm" command and passes geometry information
* to the window manager.
*
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
* Copyright (c) 1998-2000 by Scriptics Corporation.
*
* 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.27 2007/06/10 00:15:35 hobbs Exp $
*/
#include "tkWinInt.h"
#include <shellapi.h>
/*
* These next two defines are only valid on Win2K/XP+.
*/
#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
/*
* Event structure for synthetic activation events. These events are
* placed on the event queue whenever a toplevel gets a WM_MOUSEACTIVATE
* message.
*/
typedef struct ActivateEvent {
Tcl_Event ev;
TkWindow *winPtr;
} ActivateEvent;
/*
* A data structure of the following type holds information for
* each window manager protocol (such as WM_DELETE_WINDOW) for
* which a handler (i.e. a Tcl command) has been defined for a
* particular top-level window.
*/
typedef struct ProtocolHandler {
Atom protocol; /* Identifies the protocol. */
struct ProtocolHandler *nextPtr;
/* Next in list of protocol handlers for
* the same top-level window, or NULL for
* end of list. */
Tcl_Interp *interp; /* Interpreter in which to invoke command. */
char command[4]; /* Tcl command to invoke when a client
* message for this protocol arrives.
* The actual size of the structure varies
* to accommodate the needs of the actual
* command. THIS MUST BE THE LAST FIELD OF
* THE STRUCTURE. */
} ProtocolHandler;
#define HANDLER_SIZE(cmdLength) \
((unsigned) (sizeof(ProtocolHandler) - 3 + cmdLength))
/*
* Helper type passed via lParam to TkWmStackorderToplevelEnumProc
*/
typedef struct TkWmStackorderToplevelPair {
Tcl_HashTable *table;
TkWindow **window_ptr;
} TkWmStackorderToplevelPair;
/*
* This structure represents the contents of a icon, in terms of its
* image. The HICON is an internal Windows format. Most of these
* icon-specific-structures originated with the Winico extension.
* We stripped out unused parts of that code, and integrated the
* code more naturally with Tcl.
*/
typedef struct {
UINT Width, Height, Colors; /* Width, Height and bpp */
LPBYTE lpBits; /* ptr to DIB bits */
DWORD dwNumBytes; /* how many bytes? */
LPBITMAPINFO lpbi; /* ptr to header */
LPBYTE lpXOR; /* ptr to XOR image bits */
LPBYTE lpAND; /* ptr to AND image bits */
HICON hIcon; /* DAS ICON */
} ICONIMAGE, *LPICONIMAGE;
/*
* This structure is how we represent a block of the above
* items. We will reallocate these structures according to
* how many images they need to contain.
*/
typedef struct {
int nNumImages; /* How many images? */
ICONIMAGE IconImages[1]; /* Image entries */
} BlockOfIconImages, *BlockOfIconImagesPtr;
/*
* These two structures are used to read in icons from an
* 'icon directory' (i.e. the contents of a .icr file, say).
* We only use these structures temporarily, since we copy
* the information we want into a BlockOfIconImages.
*/
typedef struct {
BYTE bWidth; /* Width of the image */
BYTE bHeight; /* Height of the image (times 2) */
BYTE bColorCount; /* Number of colors in image (0 if >=8bpp) */
BYTE bReserved; /* Reserved */
WORD wPlanes; /* Color Planes */
WORD wBitCount; /* Bits per pixel */
DWORD dwBytesInRes; /* how many bytes in this resource? */
DWORD dwImageOffset; /* where in the file is this image */
} ICONDIRENTRY, *LPICONDIRENTRY;
typedef struct {
WORD idReserved; /* Reserved */
WORD idType; /* resource type (1 for icons) */
WORD idCount; /* how many images? */
ICONDIRENTRY idEntries[1]; /* the entries for each image */
} ICONDIR, *LPICONDIR;
/*
* A pointer to one of these strucutures is associated with each
* toplevel. This allows us to free up all memory associated with icon
* resources when a window is deleted or if the window's icon is
* changed. They are simply reference counted according to:
*
* (i) how many WmInfo structures point to this object
* (ii) whether the ThreadSpecificData defined in this file contains
* a pointer to this object.
*
* The former count is for windows whose icons are individually
* set, and the latter is for the global default icon choice.
*
* Icons loaded from .icr/.icr use the iconBlock field, icons
* loaded from .exe/.dll use the hIcon field.
*/
typedef struct WinIconInstance {
int refCount; /* Number of instances that share this
* data structure. */
BlockOfIconImagesPtr iconBlock;
/* Pointer to icon resource data for
* image. */
} WinIconInstance;
typedef struct WinIconInstance *WinIconPtr;
/*
* A data structure of the following type holds window-manager-related
* information for each top-level window in an application.
*/
typedef struct TkWmInfo {
TkWindow *winPtr; /* Pointer to main Tk information for
* this window. */
HWND wrapper; /* This is the decorative frame window
* created by the window manager to wrap
* a toplevel window. This window is
* a direct child of the root window. */
char *title; /* Title to display in window caption. If
* NULL, use name of widget. Malloced. */
char *iconName; /* Name to display in icon. Malloced. */
XWMHints hints; /* Various pieces of information for
* window manager. */
char *leaderName; /* Path name of leader of window group
* (corresponds to hints.window_group).
* Malloc-ed. Note: this field doesn't
* get updated if leader is destroyed. */
TkWindow *masterPtr; /* Master window for TRANSIENT_FOR property,
* or NULL. */
Tk_Window icon; /* Window to use as icon for this window,
* or NULL. */
Tk_Window iconFor; /* Window for which this window is icon, or
* NULL if this isn't an icon for anyone. */
/*
* Information used to construct an XSizeHints structure for
* the window manager:
*/
int defMinWidth, defMinHeight, defMaxWidth, defMaxHeight;
/* Default resize limits given by system. */
int sizeHintsFlags; /* Flags word for XSizeHints structure.
* If the PBaseSize flag is set then the
* window is gridded; otherwise it isn't
* gridded. */
int minWidth, minHeight; /* Minimum dimensions of window, in
* pixels or grid units. */
int maxWidth, maxHeight; /* Maximum dimensions of window, in
* pixels or grid units. 0 to default. */
Tk_Window gridWin; /* Identifies the window that controls
* gridding for this top-level, or NULL if
* the top-level isn't currently gridded. */
int widthInc, heightInc; /* Increments for size changes (# pixels
* per step). */
struct {
int x; /* numerator */
int y; /* denominator */
} minAspect, maxAspect; /* Min/max aspect ratios for window. */
int reqGridWidth, reqGridHeight;
/* The dimensions of the window (in
* grid units) requested through
* the geometry manager. */
int gravity; /* Desired window gravity. */
/*
* Information used to manage the size and location of a window.
*/
int width, height; /* Desired dimensions of window, specified
* in pixels or grid units. These values are
* set by the "wm geometry" command and by
* ConfigureNotify events (for when wm
* resize