home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
tk42r2s.zip
/
tk4.2
/
os2
/
tkOS2Window.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-07-27
|
18KB
|
679 lines
/*
* tkOS2Window.c --
*
* Xlib emulation routines for OS/2 Presentation Manager related to
* creating, displaying and destroying windows.
*
* Copyright (c) 1996-1998 Illya Vaes
* 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.
*/
#include "tkOS2Int.h"
/*
* Forward declarations for procedures defined in this file:
*/
static void NotifyVisibility _ANSI_ARGS_((XEvent *eventPtr,
TkWindow *winPtr));
/*
*----------------------------------------------------------------------
*
* TkMakeWindow --
*
* Creates an OS/2 PM window object based on the current attributes
* of the specified TkWindow.
*
* Results:
* Returns a pointer to a new TkOS2Drawable cast to a Window.
*
* Side effects:
* Creates a new window.
*
*----------------------------------------------------------------------
*/
Window
TkMakeWindow(winPtr, parent)
TkWindow *winPtr;
Window parent;
{
HWND parentWin;
ULONG yPos;
TkOS2Drawable *todPtr;
int style;
todPtr = (TkOS2Drawable*) ckalloc(sizeof(TkOS2Drawable));
if (todPtr == NULL) {
return (Window)None;
}
todPtr->type = TOD_WINDOW;
todPtr->window.winPtr = winPtr;
/* Translate Y coordinates to PM */
if (parent != None) {
parentWin = TkOS2GetHWND(parent);
style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
yPos = TkOS2WindowHeight((TkOS2Drawable *)parent) -
( winPtr->changes.y + winPtr->changes.height );
} else {
parentWin = HWND_DESKTOP;
style = WS_CLIPCHILDREN | CS_PARENTCLIP;
yPos = yScreen - ( winPtr->changes.y + winPtr->changes.height );
}
/* Use FID_CLIENT in order to get activation right later! */
todPtr->window.handle = WinCreateWindow(parentWin, TOC_CHILD, "", style,
winPtr->changes.x, yPos,
winPtr->changes.width, winPtr->changes.height,
NULLHANDLE, HWND_TOP, FID_CLIENT, (PVOID)todPtr, NULL);
if (todPtr->window.handle == NULLHANDLE) {
ckfree((char *) todPtr);
todPtr = NULL;
}
return (Window)todPtr;
}
/*
*----------------------------------------------------------------------
*
* XDestroyWindow --
*
* Destroys the given window.
*
* Results:
* None.
*
* Side effects:
* Sends the WM_DESTROY message to the window and then destroys
* the resources associated with the window.
*
*----------------------------------------------------------------------
*/
void
XDestroyWindow(display, w)
Display* display;
Window w;
{
TkOS2Drawable *todPtr = (TkOS2Drawable *)w;
TkWindow *winPtr = TkOS2GetWinPtr(w);
HWND hwnd = TkOS2GetHWND(w);
display->request++;
/*
* Remove references to the window in the pointer module, and
* then remove the backpointer from the drawable.
*/
TkOS2PointerDeadWindow(winPtr);
todPtr->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 *)todPtr);
todPtr= NULL;
} else if (!(winPtr->flags & TK_PARENT_DESTROYED)) {
rc = WinDestroyWindow(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 = TkOS2GetWinPtr(w);
display->request++;
WinShowWindow(TkOS2GetHWND(w), TRUE);
winPtr->flags |= TK_MAPPED;
/*
* 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;
}
}
} else {
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);
}
/*
* Generate VisibilityNotify events for this window and its mapped
* children.
*/
event.type = VisibilityNotify;
event.xvisibility.serial = display->request;
event.xvisibility.send_event = False;
event.xvisibility.display = display;
event.xvisibility.window = winPtr->window;
event.xvisibility.state = VisibilityUnobscured;
NotifyVisibility(&event, winPtr);
}
/*
*----------------------------------------------------------------------
*
* NotifyVisibility --
*
* This function recursively notifies the mapped children of the
* specified window of a change in visibility. A VisibilityNotify
* event is generated for each child that returns TRUE for
* WinIsWindowShowing(), with the state flag set to
* VisibilityUnobscured. No account is taken of the previous state
* or the extent of viewabilit/obscuredness, since that would cost
* much computation (eg. WinQueryUpdateRect) and memory (field for
* last viewability).
* 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. */
{
if (winPtr->atts.event_mask & VisibilityChangeMask) {
eventPtr->xvisibility.window = winPtr->window;
Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_TAIL);
}
Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_TAIL);
for (winPtr = winPtr->childList; winPtr != NULL;
winPtr = winPtr->nextPtr) {
if (winPtr->flags & TK_MAPPED &&
WinIsWindowShowing(TkOS2GetHWND(winPtr->window))) {
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 = TkOS2GetWinPtr(w);
display->request++;
WinShowWindow(TkOS2GetHWND(w), FALSE);
winPtr->flags &= ~TK_MAPPED;
if (winPtr->flags & TK_TOP_LEVEL) {
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_HandleEvent(&event);
}
}
/*
*----------------------------------------------------------------------
*
* 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;
{
SWP parPos;
WinQueryWindowPos(WinQueryWindow(TkOS2GetHWND(w), QW_PARENT), &parPos);
display->request++;
/* Translate Y coordinates to PM: relative to parent */
WinSetWindowPos(TkOS2GetHWND(w), HWND_TOP, x,
parPos.cy - height - y,
width, height, SWP_MOVE | SWP_SIZE);
}
/*
*----------------------------------------------------------------------
*
* 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 = TkOS2GetWinPtr(w);
SWP parPos;
WinQueryWindowPos(WinQueryWindow(TkOS2GetHWND(w), QW_PARENT), &parPos);
display->request++;
/* Translate Y coordinates to PM, relative to parent */
WinSetWindowPos(TkOS2GetHWND(w), HWND_TOP, x,
parPos.cy - winPtr->changes.height - y,
winPtr->changes.width, winPtr->changes.height,
SWP_MOVE /*| SWP_SIZE*/);
}
/*
*----------------------------------------------------------------------
*
* 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 = TkOS2GetWinPtr(w);
SWP parPos;
WinQueryWindowPos(WinQueryWindow(TkOS2GetHWND(w), QW_PARENT), &parPos);
display->request++;
/* Translate Y coordinates to PM; relative to parent */
WinSetWindowPos(TkOS2GetHWND(w), HWND_TOP, winPtr->changes.x,
parPos.cy - winPtr->changes.height - winPtr->changes.y,
winPtr->changes.width, winPtr->changes.height,
/*SWP_MOVE |*/ SWP_SIZE);
}
/*
*----------------------------------------------------------------------
*
* 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 = TkOS2GetHWND(w);
display->request++;
rc = WinSetWindowPos(window, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER);
}
/*
*----------------------------------------------------------------------
*
* 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 = TkOS2GetWinPtr(w);
HWND window = TkOS2GetHWND(w);
HWND insertAfter;
display->request++;
/*
* Change the shape and/or position of the window.
*/
if (value_mask & (CWX|CWY|CWWidth|CWHeight)) {
/* Translate Y coordinates to PM */
WinSetWindowPos(window, HWND_TOP, winPtr->changes.x,
TkOS2WindowHeight((TkOS2Drawable *)w)
- winPtr->changes.height - winPtr->changes.y,
winPtr->changes.width, winPtr->changes.height,
SWP_MOVE | SWP_SIZE);
}
/*
* Change the stacking order of the window.
*/
if (value_mask & CWStackMode) {
if ((value_mask & CWSibling) && (values->sibling != None)) {
HWND sibling = TkOS2GetHWND(values->sibling);
/*
* OS/2 PM doesn't support the Above mode, so we insert the
* window just below the sibling and then swap them.
*/
if (values->stack_mode == Above) {
WinSetWindowPos(window, sibling, 0, 0, 0, 0, SWP_ZORDER);
insertAfter = window;
window = sibling;
} else {
insertAfter = sibling;
}
} else {
insertAfter = (values->stack_mode == Above) ? HWND_TOP
: HWND_BOTTOM;
}
WinSetWindowPos(window, insertAfter, 0, 0, 0, 0, SWP_ZORDER);
}
}
/*
*----------------------------------------------------------------------
*
* 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;
{
RECTL rect;
LONG oldColor, oldPattern;
HPAL oldPalette, palette;
TkWindow *winPtr;
HWND hwnd = TkOS2GetHWND(w);
HPS hps = WinGetPS(hwnd);
palette = TkOS2GetPalette(display->screens[0].cmap);
oldPalette = GpiSelectPalette(hps, palette);
display->request++;
winPtr = TkOS2GetWinPtr(w);
oldColor = GpiQueryColor(hps);
oldPattern = GpiQueryPattern(hps);
GpiSetPattern(hps, PATSYM_SOLID);
WinQueryWindowRect(hwnd, &rect);
WinFillRect(hps, &rect, winPtr->atts.background_pixel);
GpiSetPattern(hps, oldPattern);
GpiSelectPalette(hps, oldPalette);
WinReleasePS(hps);
}
/*
*----------------------------------------------------------------------
*
* 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);
}
}
/*
*----------------------------------------------------------------------
*
* TkOS2WindowHeight --
*
* Determine the height of an OS/2 drawable (of parent for bitmaps).
*
* Results:
* Height of drawable.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
LONG
TkOS2WindowHeight(todPtr)
TkOS2Drawable *todPtr;
{
SWP pos;
HWND handle;
HWND parent;
BOOL rc;
if (todPtr->type == TOD_BITMAP ) {
SIZEL sizl;
/* Bitmap */
handle = todPtr->bitmap.parent;
parent = handle;
rc = GpiQueryBitmapDimension(todPtr->bitmap.handle, &sizl);
return sizl.cy;
} else {
handle = todPtr->window.handle;
parent = WinQueryWindow(handle, QW_PARENT);
}
rc = WinQueryWindowPos(handle, &pos);
if (rc != TRUE) {
return 0;
}
/* Watch out for frames and/or title bars! */
if (parent == HWND_DESKTOP) {
if (TkOS2GetWinPtr(todPtr)->wmInfoPtr->exStyle & FCF_SIZEBORDER) {
pos.cy -= 2 * ySizeBorder;
} else if (TkOS2GetWinPtr(todPtr)->wmInfoPtr->exStyle & FCF_DLGBORDER) {
pos.cy -= 2 * yDlgBorder;
}
if (TkOS2GetWinPtr(todPtr)->wmInfoPtr->exStyle & FCF_TITLEBAR) {
pos.cy -= titleBar;
}
}
return pos.cy;
}
/*
*----------------------------------------------------------------------
*
* TkOS2WindowWidth --
*
* Determine the width of an OS/2 drawable (of parent for bitmaps).
*
* Results:
* Width of drawable.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
LONG
TkOS2WindowWidth(todPtr)
TkOS2Drawable *todPtr;
{
SWP pos;
HWND handle;
HWND parent;
BOOL rc;
if (todPtr->type == TOD_BITMAP ) {
SIZEL sizl;
/* Bitmap */
handle = todPtr->bitmap.parent;
parent = handle;
rc = GpiQueryBitmapDimension(todPtr->bitmap.handle, &sizl);
return sizl.cx;
} else {
handle = todPtr->window.handle;
parent = WinQueryWindow(handle, QW_PARENT);
}
rc = WinQueryWindowPos(handle, &pos);
if (rc != TRUE) return 0;
/* Watch out for frames and/or title bars! */
if (parent == HWND_DESKTOP) {
if (TkOS2GetWinPtr(todPtr)->wmInfoPtr->exStyle & FCF_SIZEBORDER) {
pos.cx -= 2 * xSizeBorder;
} else if (TkOS2GetWinPtr(todPtr)->wmInfoPtr->exStyle & FCF_DLGBORDER) {
pos.cx -= 2 * xDlgBorder;
} else if (TkOS2GetWinPtr(todPtr)->wmInfoPtr->exStyle & FCF_BORDER) {
pos.cx -= 2 * xBorder;
}
}
return pos.cx;
}