/* *--------------------------------------------------------------------------- * * Blt_MakeTransparentWindowExist -- * * Similar to Tk_MakeWindowExist but instead creates a transparent window * to block for user events from sibling windows. * * Differences from Tk_MakeWindowExist. * * 1. This is always a "busy" window. There's never a platform-specific * class procedure to execute. * * 2. The window is transparent and never will have children, so * colormap information is irrelevant. * * Results: * None. * * Side effects: * When the procedure returns, the internal window associated with tkwin * is guaranteed to exist. This may require the window's ancestors to be * created too. * *--------------------------------------------------------------------------- */ void Blt_MakeTransparentWindowExist( Tk_Window tkwin, /* Token for window. */ Window parent, /* Parent window. */ int isBusy) /* */ { TkWindow *winPtr = (TkWindow *) tkwin; TkWindow *winPtr2; Tcl_HashEntry *hPtr; int notUsed; TkDisplay *dispPtr; HWND hParent; int style; DWORD exStyle; HWND hWnd; if (winPtr->window != None) { return; /* Window already exists. */ } /* Create a transparent window and put it on top. */ hParent = (HWND) parent; style = (WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); exStyle = (WS_EX_TRANSPARENT | WS_EX_TOPMOST); #define TK_WIN_CHILD_CLASS_NAME "TkChild" hWnd = CreateWindowEx(exStyle, TK_WIN_CHILD_CLASS_NAME, NULL, style, Tk_X(tkwin), Tk_Y(tkwin), Tk_Width(tkwin), Tk_Height(tkwin), hParent, NULL, (HINSTANCE)Tk_GetHINSTANCE(), NULL); winPtr->window = Tk_AttachHWND(tkwin, hWnd); dispPtr = winPtr->dispPtr; hPtr = Tcl_CreateHashEntry(&dispPtr->winTable, (char *)winPtr->window, ¬Used); Tcl_SetHashValue(hPtr, winPtr); winPtr->dirtyAtts = 0; winPtr->dirtyChanges = 0; #ifdef TK_USE_INPUT_METHODS winPtr->inputContext = NULL; #endif /* TK_USE_INPUT_METHODS */ if (!(winPtr->flags & TK_TOP_LEVEL)) { /* * If any siblings higher up in the stacking order have already been * created then move this window to its rightful position in the * stacking order. * * NOTE: this code ignores any changes anyone might have made to the * sibling and stack_mode field of the window's attributes, so it * really isn't safe for these to be manipulated except by calling * Tk_RestackWindow. */ for (winPtr2 = winPtr->nextPtr; winPtr2 != NULL; winPtr2 = winPtr2->nextPtr) { if ((winPtr2->window != None) && !(winPtr2->flags & TK_TOP_LEVEL)) { XWindowChanges changes; changes.sibling = winPtr2->window; changes.stack_mode = Below; XConfigureWindow(winPtr->display, winPtr->window, CWSibling | CWStackMode, &changes); break; } } } /* * Issue a ConfigureNotify event if there were deferred configuration * changes (but skip it if the window is being deleted; the * ConfigureNotify event could cause problems if we're being called from * Tk_DestroyWindow under some conditions). */ if ((winPtr->flags & TK_NEED_CONFIG_NOTIFY) && !(winPtr->flags & TK_ALREADY_DEAD)) { winPtr->flags &= ~TK_NEED_CONFIG_NOTIFY; DoConfigureNotify((Tk_FakeWin *)tkwin); } }
static void MakeTransparentWindowExist( Tk_Window tkwin, /* Token for window. */ Window parent) /* Parent window. */ { TkWindow *winPtr = (TkWindow *) tkwin; Tcl_HashEntry *hPtr; int notUsed; TkDisplay *dispPtr; if (winPtr->window != None) { return; /* Window already exists. */ } /* * Create a transparent window and put it on top. */ TkpMakeTransparentWindowExist(tkwin, parent); dispPtr = winPtr->dispPtr; hPtr = Tcl_CreateHashEntry(&dispPtr->winTable, (char *) winPtr->window, ¬Used); Tcl_SetHashValue(hPtr, winPtr); winPtr->dirtyAtts = 0; winPtr->dirtyChanges = 0; if (!(winPtr->flags & TK_TOP_HIERARCHY)) { TkWindow *winPtr2; /* * If any siblings higher up in the stacking order have already been * created then move this window to its rightful position in the * stacking order. * * NOTE: this code ignores any changes anyone might have made to the * sibling and stack_mode field of the window's attributes, so it * really isn't safe for these to be manipulated except by calling * Tk_RestackWindow. */ for (winPtr2 = winPtr->nextPtr; winPtr2 != NULL; winPtr2 = winPtr2->nextPtr) { if ((winPtr2->window != None) && !(winPtr2->flags & (TK_TOP_HIERARCHY|TK_REPARENTED))) { XWindowChanges changes; changes.sibling = winPtr2->window; changes.stack_mode = Below; XConfigureWindow(winPtr->display, winPtr->window, CWSibling | CWStackMode, &changes); break; } } } /* * Issue a ConfigureNotify event if there were deferred configuration * changes (but skip it if the window is being deleted; the * ConfigureNotify event could cause problems if we're being called from * Tk_DestroyWindow under some conditions). */ if ((winPtr->flags & TK_NEED_CONFIG_NOTIFY) && !(winPtr->flags & TK_ALREADY_DEAD)) { winPtr->flags &= ~TK_NEED_CONFIG_NOTIFY; DoConfigureNotify((Tk_FakeWin *) tkwin); } }