/* * tkWinWindow.c -- * * Xlib emulation routines for Windows related to creating, * displaying and destroying windows. * * Copyright (c) 1995 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tkWinWindow.c 1.13 96/04/11 17:52:20 */ #include "tkWinInt.h" /* * Forward declarations for procedures defined in this file: */ static void NotifyVisibility _ANSI_ARGS_((XEvent *eventPtr, TkWindow *winPtr)); static void StackWindow _ANSI_ARGS_((Window w, Window sibling, int stack_mode)); /* *---------------------------------------------------------------------- * * TkMakeWindow -- * * Creates a Windows window object based on the current attributes * of the specified TkWindow. * * Results: * Returns a pointer to a new TkWinDrawable cast to a Window. * * Side effects: * Creates a new window. * *---------------------------------------------------------------------- */ Window TkMakeWindow(winPtr, parent) TkWindow *winPtr; Window parent; { HWND parentWin; TkWinDrawable *twdPtr; int style; twdPtr = (TkWinDrawable*) ckalloc(sizeof(TkWinDrawable)); if (twdPtr == NULL) { return None; } twdPtr->type = TWD_WINDOW; twdPtr->window.winPtr = winPtr; if (parent != None) { parentWin = TkWinGetHWND(parent); style = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; } else { parentWin = NULL; style = WS_POPUP | WS_CLIPCHILDREN; } twdPtr->window.handle = CreateWindow(TK_WIN_CHILD_CLASS_NAME, "", style, winPtr->changes.x, winPtr->changes.y, winPtr->changes.width, winPtr->changes.height, parentWin, NULL, TkWinGetAppInstance(), twdPtr); if (twdPtr->window.handle == NULL) { ckfree((char *) twdPtr); twdPtr = NULL; } return (Window)twdPtr; } /* *---------------------------------------------------------------------- * * XDestroyWindow -- * * Destroys the given window. * * Results: * None. * * Side effects: * Sends the WM_DESTROY message to the window and then destroys * it the Win32 resources associated with the window. * *---------------------------------------------------------------------- */ void XDestroyWindow(display, w) Display* display; Window w; { TkWinDrawable *twdPtr = (TkWinDrawable *)w; TkWindow *winPtr = TkWinGetWinPtr(w); HWND hwnd = TkWinGetHWND(w); display->request++; /* * Remove references to the window in the pointer module, and * then remove the backpointer from the drawable. */ TkWinPointerDeadWindow(winPtr); twdPtr->window.winPtr = NULL; /* * Don't bother destroying the window if we are going to destroy * the parent later. Also if the window has already been destroyed * then we need to free the drawable now. */ if (!hwnd) { ckfree((char *)twdPtr); } else if (!(winPtr->flags & TK_PARENT_DESTROYED)) { DestroyWindow(hwnd); } } /* *---------------------------------------------------------------------- * * XMapWindow -- * * Cause the given window to become visible. * * Results: * None * * Side effects: * Causes the window state to change, and generates a MapNotify * event. * *---------------------------------------------------------------------- */ void XMapWindow(display, w) Display* display; Window w; { XEvent event; TkWindow *parentPtr; TkWindow *winPtr = TkWinGetWinPtr(w); display->request++; ShowWindow(TkWinGetHWND(w), SW_SHOWNORMAL); winPtr->flags |= TK_MAPPED; event.type = MapNotify; event.xmap.serial = display->request; event.xmap.send_event = False; event.xmap.display = display; event.xmap.event = winPtr->window; event.xmap.window = winPtr->window; event.xmap.override_redirect = winPtr->atts.override_redirect; Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); /* * Check to see if this window is visible now. If all of the parent * windows up to the first toplevel are mapped, then this window and * its mapped children have just become visible. */ if (!(winPtr->flags & TK_TOP_LEVEL)) { for (parentPtr = winPtr->parentPtr; ; parentPtr = parentPtr->parentPtr) { if ((parentPtr == NULL) || !(parentPtr->flags & TK_MAPPED)) { return; } if (parentPtr->flags & TK_TOP_LEVEL) { break; } } } /* * Generate VisibilityNotify events for this window and its mapped * children. */ event.type = VisibilityNotify; event.xvisibility.state = VisibilityUnobscured; NotifyVisibility(&event, winPtr); } /* *---------------------------------------------------------------------- * * NotifyVisibility -- * * This function recursively notifies the mapped children of the * specified window of a change in visibility. Note that we don't * properly report the visibility state, since Windows does not * provide that info. The eventPtr argument must point to an event * that has been completely initialized except for the window slot. * * Results: * None. * * Side effects: * Generates lots of events. * *---------------------------------------------------------------------- */ static void NotifyVisibility(eventPtr, winPtr) XEvent *eventPtr; /* Initialized VisibilityNotify event. */ TkWindow *winPtr; /* Window to notify. */ { eventPtr->xvisibility.window = winPtr->window; Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_TAIL); for (winPtr = winPtr->childList; winPtr != NULL; winPtr = winPtr->nextPtr) { if (winPtr->flags & TK_MAPPED) { NotifyVisibility(eventPtr, winPtr); } } } /* *---------------------------------------------------------------------- * * XUnmapWindow -- * * Cause the given window to become invisible. * * Results: * None * * Side effects: * Causes the window state to change, and generates an UnmapNotify * event. * *---------------------------------------------------------------------- */ void XUnmapWindow(display, w) Display* display; Window w; { XEvent event; TkWindow *winPtr = TkWinGetWinPtr(w); display->request++; ShowWindow(TkWinGetHWND(w), SW_HIDE); winPtr->flags &= ~TK_MAPPED; event.type = UnmapNotify; event.xunmap.serial = display->request; event.xunmap.send_event = False; event.xunmap.display = display; event.xunmap.event = winPtr->window; event.xunmap.window = winPtr->window; event.xunmap.from_configure = False; Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); } /* *---------------------------------------------------------------------- * * XMoveResizeWindow -- * * Move and resize a window relative to its parent. * * Results: * None. * * Side effects: * Repositions and resizes the specified window. * *---------------------------------------------------------------------- */ void XMoveResizeWindow(display, w, x, y, width, height) Display* display; Window w; int x; /* Position relative to parent. */ int y; unsigned int width; unsigned int height; { display->request++; MoveWindow(TkWinGetHWND(w), x, y, width, height, TRUE); } /* *---------------------------------------------------------------------- * * XMoveWindow -- * * Move a window relative to its parent. * * Results: * None. * * Side effects: * Repositions the specified window. * *---------------------------------------------------------------------- */ void XMoveWindow(display, w, x, y) Display* display; Window w; int x; int y; { TkWindow *winPtr = TkWinGetWinPtr(w); display->request++; MoveWindow(TkWinGetHWND(w), x, y, winPtr->changes.width, winPtr->changes.height, TRUE); } /* *---------------------------------------------------------------------- * * XResizeWindow -- * * Resize a window. * * Results: * None. * * Side effects: * Resizes the specified window. * *---------------------------------------------------------------------- */ void XResizeWindow(display, w, width, height) Display* display; Window w; unsigned int width; unsigned int height; { TkWindow *winPtr = TkWinGetWinPtr(w); display->request++; MoveWindow(TkWinGetHWND(w), winPtr->changes.x, winPtr->changes.y, width, height, TRUE); } /* *---------------------------------------------------------------------- * * XRaiseWindow -- * * Change the stacking order of a window. * * Results: * None. * * Side effects: * Changes the stacking order of the specified window. * *---------------------------------------------------------------------- */ void XRaiseWindow(display, w) Display* display; Window w; { HWND window = TkWinGetHWND(w); display->request++; SetWindowPos(window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); } /* *---------------------------------------------------------------------- * * XConfigureWindow -- * * Change the size, position, stacking, or border of the specified * window. * * Results: * None. * * Side effects: * Changes the attributes of the specified window. Note that we * ignore the passed in values and use the values stored in the * TkWindow data structure. * *---------------------------------------------------------------------- */ void XConfigureWindow(display, w, value_mask, values) Display* display; Window w; unsigned int value_mask; XWindowChanges* values; { TkWindow *winPtr = TkWinGetWinPtr(w); HWND window = TkWinGetHWND(w); HWND insertAfter; display->request++; /* * Change the shape and/or position of the window. */ if (value_mask & (CWX|CWY|CWWidth|CWHeight)) { MoveWindow(window, winPtr->changes.x, winPtr->changes.y, winPtr->changes.width, winPtr->changes.height, TRUE); } /* * Change the stacking order of the window. */ if (value_mask & CWStackMode) { if ((value_mask & CWSibling) && (values->sibling != None)) { HWND sibling = TkWinGetHWND(values->sibling); /* * Windows doesn't support the Above mode, so we insert the * window just below the sibling and then swap them. */ if (values->stack_mode == Above) { SetWindowPos(window, sibling, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); insertAfter = window; window = sibling; } else { insertAfter = sibling; } } else { insertAfter = (values->stack_mode == Above) ? HWND_TOP : HWND_BOTTOM; } SetWindowPos(window, insertAfter, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); } } /* *---------------------------------------------------------------------- * * XClearWindow -- * * Clears the entire window to the current background color. * * Results: * None. * * Side effects: * Erases the current contents of the window. * *---------------------------------------------------------------------- */ void XClearWindow(display, w) Display* display; Window w; { RECT rc; HBRUSH brush; HPALETTE oldPalette, palette; TkWindow *winPtr; HWND hwnd = TkWinGetHWND(w); HDC dc = GetDC(hwnd); palette = TkWinGetPalette(display->screens[0].cmap); oldPalette = SelectPalette(dc, palette, FALSE); display->request++; winPtr = TkWinGetWinPtr(w); brush = CreateSolidBrush(winPtr->atts.background_pixel); GetWindowRect(hwnd, &rc); rc.right = rc.right - rc.left; rc.bottom = rc.bottom - rc.top; rc.left = rc.top = 0; FillRect(dc, &rc, brush); DeleteObject(brush); SelectPalette(dc, oldPalette, TRUE); ReleaseDC(hwnd, dc); } /* *---------------------------------------------------------------------- * * XChangeWindowAttributes -- * * This function is called when the attributes on a window are * updated. Since Tk maintains all of the window state, the only * relevant value is the cursor. * * Results: * None. * * Side effects: * May cause the mouse position to be updated. * *---------------------------------------------------------------------- */ void XChangeWindowAttributes(display, w, valueMask, attributes) Display* display; Window w; unsigned long valueMask; XSetWindowAttributes* attributes; { if (valueMask & CWCursor) { XDefineCursor(display, w, attributes->cursor); } }