home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tcltk805.zip / tcl805s.zip / tk8.0.5 / os2 / tkOS2Window.c < prev    next >
C/C++ Source or Header  |  2000-04-16  |  32KB  |  1,181 lines

  1. /* 
  2.  * tkOS2Window.c --
  3.  *
  4.  *    Xlib emulation routines for OS/2 Presentation Manager related to
  5.  *    creating, displaying and destroying windows.
  6.  *
  7.  * Copyright (c) 1996-2000 Illya Vaes
  8.  * Copyright (c) 1995 Sun Microsystems, Inc.
  9.  *
  10.  * See the file "license.terms" for information on usage and redistribution
  11.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  12.  */
  13.  
  14.  
  15. #include "tkOS2Int.h"
  16.  
  17. /*
  18.  * The windowTable maps from HWND to Tk_Window handles.
  19.  */
  20.  
  21. static Tcl_HashTable windowTable;
  22.  
  23. /*
  24.  * Have statics in this module been initialized?
  25.  */
  26.  
  27. static int initialized = 0;
  28.  
  29. /*
  30.  * Forward declarations for procedures defined in this file:
  31.  */
  32.  
  33. static void             NotifyVisibility _ANSI_ARGS_((XEvent *eventPtr,
  34.                             TkWindow *winPtr));
  35.  
  36. /*
  37.  *----------------------------------------------------------------------
  38.  *
  39.  * Tk_AttachHWND --
  40.  *
  41.  *      This function binds an HWND and a reflection procedure to
  42.  *      the specified Tk_Window.
  43.  *
  44.  * Results:
  45.  *      Returns an X Window that encapsulates the HWND.
  46.  *
  47.  * Side effects:
  48.  *      May allocate a new X Window.  Also enters the HWND into the
  49.  *      global window table.
  50.  *
  51.  *----------------------------------------------------------------------
  52.  */
  53.  
  54. Window
  55. Tk_AttachHWND(tkwin, hwnd)
  56.     Tk_Window tkwin;
  57.     HWND hwnd;
  58. {
  59.     int new;
  60.     Tcl_HashEntry *entryPtr;
  61.     TkOS2Drawable *todPtr = (TkOS2Drawable *) Tk_WindowId(tkwin);
  62.  
  63. #ifdef VERBOSE
  64.     printf("Tk_AttachHWND tkwin %x, hwnd %x\n", tkwin, hwnd);
  65. #endif
  66.  
  67.     if (!initialized) {
  68.         Tcl_InitHashTable(&windowTable, TCL_ONE_WORD_KEYS);
  69.         initialized = 1;
  70.     }
  71.  
  72.     /*
  73.      * Allocate a new drawable if necessary.  Otherwise, remove the
  74.      * previous HWND from the window table.
  75.      */
  76.  
  77.     if (todPtr == NULL) {
  78.         todPtr = (TkOS2Drawable*) ckalloc(sizeof(TkOS2Drawable));
  79. #ifdef VERBOSE
  80.         printf("    new todPtr (drawable) %x\n", todPtr);
  81. #endif
  82.         todPtr->type = TOD_WINDOW;
  83.         todPtr->window.winPtr = (TkWindow *) tkwin;
  84.     } else if (todPtr->window.handle != NULLHANDLE) {
  85.         entryPtr = Tcl_FindHashEntry(&windowTable,
  86.                 (char *)todPtr->window.handle);
  87.         Tcl_DeleteHashEntry(entryPtr);
  88.     }
  89.  
  90.     /*
  91.      * Insert the new HWND into the window table.
  92.      */
  93.  
  94.     todPtr->window.handle = hwnd;
  95.     entryPtr = Tcl_CreateHashEntry(&windowTable, (char *)hwnd, &new);
  96. #ifdef VERBOSE
  97.     printf("inserting hwnd %x (tkwin %x) into windowTable, entryPtr %x\n", hwnd,
  98.            tkwin, entryPtr);
  99. #endif
  100.     Tcl_SetHashValue(entryPtr, (ClientData)tkwin);
  101.  
  102.     return (Window)todPtr;
  103. }
  104.  
  105. /*
  106.  *----------------------------------------------------------------------
  107.  *
  108.  * Tk_HWNDToWindow --
  109.  *
  110.  *      This function retrieves a Tk_Window from the window table
  111.  *      given an HWND.
  112.  *
  113.  * Results:
  114.  *      Returns the matching Tk_Window.
  115.  *
  116.  * Side effects:
  117.  *      None.
  118.  *
  119.  *----------------------------------------------------------------------
  120.  */
  121.  
  122. Tk_Window
  123. Tk_HWNDToWindow(hwnd)
  124.     HWND hwnd;
  125. {
  126.     Tcl_HashEntry *entryPtr;
  127.     if (!initialized) {
  128.         Tcl_InitHashTable(&windowTable, TCL_ONE_WORD_KEYS);
  129.         initialized = 1;
  130.     }
  131.     entryPtr = Tcl_FindHashEntry(&windowTable, (char*)hwnd);
  132.     if (entryPtr != NULL) {
  133. #ifdef VERBOSE
  134.     printf("Tk_HWNDToWindow hwnd %x => %x\n", hwnd, Tcl_GetHashValue(entryPtr));
  135. #endif
  136.         return (Tk_Window) Tcl_GetHashValue(entryPtr);
  137.     }
  138. #ifdef VERBOSE
  139.     printf("Tk_HWNDToWindow hwnd %x => NULL\n", hwnd);
  140. #endif
  141.     return NULL;
  142. }
  143.  
  144. /*
  145.  *----------------------------------------------------------------------
  146.  *
  147.  * Tk_GetHWND --
  148.  *
  149.  *      This function extracts the HWND from an X Window.
  150.  *
  151.  * Results:
  152.  *      Returns the HWND associated with the Window.
  153.  *
  154.  * Side effects:
  155.  *      None.
  156.  *
  157.  *----------------------------------------------------------------------
  158.  */
  159.  
  160. HWND
  161. Tk_GetHWND(window)
  162.     Window window;
  163. {
  164.     TkOS2Drawable *todPtr = (TkOS2Drawable *) window;
  165. #ifdef VERBOSE
  166.     printf("Tk_GetHWND window %x => hwnd %x\n", window, todPtr->window.handle);
  167. #endif
  168.     return todPtr->window.handle;
  169. }
  170.  
  171. /*
  172.  *----------------------------------------------------------------------
  173.  *
  174.  * TkpPrintWindowId --
  175.  *
  176.  *      This routine stores the string representation of the
  177.  *      platform dependent window handle for an X Window in the
  178.  *      given buffer.
  179.  *
  180.  * Results:
  181.  *      Returns the result in the specified buffer.
  182.  *
  183.  * Side effects:
  184.  *      None.
  185.  *
  186.  *----------------------------------------------------------------------
  187.  */
  188.  
  189. void
  190. TkpPrintWindowId(buf, window)
  191.     char *buf;                  /* Pointer to string large enough to hold
  192.                                  * the hex representation of a pointer. */
  193.     Window window;              /* Window to be printed into buffer. */
  194. {
  195.     HWND hwnd = (window) ? Tk_GetHWND(window) : 0;
  196. #ifdef VERBOSE
  197.     printf("TkpPrintWindowID window %x => 0x%x\n", window, hwnd);
  198. #endif
  199.     sprintf(buf, "0x%x", (unsigned int) hwnd);
  200. }
  201.  
  202. /*
  203.  *----------------------------------------------------------------------
  204.  *
  205.  * TkpScanWindowId --
  206.  *
  207.  *      Given a string which represents the platform dependent window
  208.  *      handle, produce the X Window id for the window.
  209.  *
  210.  * Results:
  211.  *      The return value is normally TCL_OK;  in this case *idPtr
  212.  *      will be set to the X Window id equivalent to string.  If
  213.  *      string is improperly formed then TCL_ERROR is returned and
  214.  *      an error message will be left in interp->result.  If the
  215.  *      number does not correspond to a Tk Window, then *idPtr will
  216.  *      be set to None.
  217.  *
  218.  * Side effects:
  219.  *      None.
  220.  *
  221.  *----------------------------------------------------------------------
  222.  */
  223.  
  224. int
  225. TkpScanWindowId(interp, string, idPtr)
  226.     Tcl_Interp *interp;         /* Interpreter to use for error reporting. */
  227.     char *string;               /* String containing a (possibly signed)
  228.                                  * integer in a form acceptable to strtol. */
  229.     int *idPtr;                 /* Place to store converted result. */
  230. {
  231.     int number;
  232.     Tk_Window tkwin;
  233.  
  234. #ifdef VERBOSE
  235.     printf("TkpScanWindowId [%s]\n", string);
  236. #endif
  237.     if (Tcl_GetInt(interp, string, &number) != TCL_OK) {
  238.         return TCL_ERROR;
  239.     }
  240.     tkwin = Tk_HWNDToWindow((HWND)number);
  241. #ifdef VERBOSE
  242.     printf("Tk_HWNDToWindow(%x) tkwin %x\n", number, tkwin);
  243. #endif
  244.     if (tkwin) {
  245.         *idPtr = Tk_WindowId(tkwin);
  246.     } else {
  247.         *idPtr = None;
  248.     }
  249.     return TCL_OK;
  250. }
  251.  
  252. /*
  253.  *----------------------------------------------------------------------
  254.  *
  255.  * TkpMakeWindow --
  256.  *
  257.  *    Creates an OS/2 PM window object based on the current attributes
  258.  *    of the specified TkWindow.
  259.  *
  260.  * Results:
  261.  *    Returns a pointer to a new TkOS2Drawable cast to a Window.
  262.  *
  263.  * Side effects:
  264.  *    Creates a new window.
  265.  *
  266.  *----------------------------------------------------------------------
  267.  */
  268.  
  269. Window
  270. TkpMakeWindow(winPtr, parent)
  271.     TkWindow *winPtr;
  272.     Window parent;
  273. {
  274.     HWND parentWin;
  275.     LONG yPos;
  276.     int style;
  277.     HWND hwnd;
  278.     
  279. #ifdef VERBOSE
  280.     printf("TkpMakeWindow winPtr %x, parent %x; (%d,%d) %dx%d\n", winPtr,
  281.            parent, Tk_X(winPtr), Tk_Y(winPtr), Tk_Width(winPtr),
  282.        Tk_Height(winPtr));
  283.     if (Tk_IsEmbedded(winPtr)) {
  284.         printf("Embedded!\n");
  285.     }
  286. #endif
  287.  
  288.     /* Translate Y coordinates to PM */
  289.     if (parent != None) {
  290.         SWP parPos;
  291.     parentWin = Tk_GetHWND(parent);
  292.     style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
  293.         rc = WinQueryWindowPos(parentWin, &parPos);
  294.         yPos = parPos.cy - Tk_Y(winPtr) - Tk_Height(winPtr);
  295.     } else {
  296.     parentWin = HWND_DESKTOP;
  297.     style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
  298.         yPos = yScreen -  Tk_Y(winPtr) - Tk_Height(winPtr);
  299.     }
  300.  
  301.     /*
  302.      * Create the window, then ensure that it is at the top of the
  303.      * stacking order.
  304.      * Use FID_CLIENT in order to get activation right later!
  305.      */
  306.     hwnd = WinCreateWindow(parentWin, TOC_CHILD, "", style, Tk_X(winPtr),
  307.                            yPos, Tk_Width(winPtr), Tk_Height(winPtr),
  308.                            NULLHANDLE, HWND_TOP, FID_CLIENT, (PVOID)winPtr,
  309.                            NULL);
  310. #ifdef VERBOSE
  311.     if (hwnd == NULLHANDLE) {
  312.         printf("TkpMakeWindow: WinCreateWindow (parent %x) ERROR %x\n",
  313.            parentWin, WinGetLastError(TclOS2GetHAB()));
  314.     } else {
  315.         printf("TkpMakeWindow: WinCreateWindow: %x (parent %x) (%d,%d) %dx%d\n",
  316.                hwnd, parentWin, Tk_X(winPtr), yPos, Tk_Width(winPtr),
  317.                Tk_Height(winPtr));
  318.     }
  319. #endif
  320.  
  321.     return Tk_AttachHWND((Tk_Window)winPtr, hwnd);
  322. }
  323.  
  324. /*
  325.  *----------------------------------------------------------------------
  326.  *
  327.  * XDestroyWindow --
  328.  *
  329.  *    Destroys the given window.
  330.  *
  331.  * Results:
  332.  *    None.
  333.  *
  334.  * Side effects:
  335.  *    Sends the WM_DESTROY message to the window and then destroys
  336.  *    the resources associated with the window.
  337.  *
  338.  *----------------------------------------------------------------------
  339.  */
  340.  
  341. void
  342. XDestroyWindow(display, w)
  343.     Display* display;
  344.     Window w;
  345. {
  346.     Tcl_HashEntry *entryPtr;
  347.     TkOS2Drawable *todPtr = (TkOS2Drawable *)w;
  348.     TkWindow *winPtr = TkOS2GetWinPtr(w);
  349.     HWND hwnd = Tk_GetHWND(w);
  350.  
  351. #ifdef VERBOSE
  352.     printf("XDestroyWindow handle %x, winPtr->flags %x, winPtr %x\n", hwnd,
  353.            winPtr->flags, winPtr);
  354. #endif
  355.  
  356.     display->request++;
  357.  
  358.     /*
  359.      * Remove references to the window in the pointer module then
  360.      * release the drawable.
  361.      */
  362.  
  363.     TkPointerDeadWindow(winPtr);
  364.  
  365.     entryPtr = Tcl_FindHashEntry(&windowTable, (char*)hwnd);
  366.     if (entryPtr != NULL) {
  367. #ifdef VERBOSE
  368.         printf("removing hwnd %x from windowTable\n", hwnd);
  369. #endif
  370.         Tcl_DeleteHashEntry(entryPtr);
  371.     }
  372.  
  373.     ckfree((char *)todPtr);
  374.  
  375.     /*
  376.      * Don't bother destroying the window if we are going to destroy
  377.      * the parent later.
  378.      * Due to difference in destroying order, this function can be
  379.      * called for an already destroyed hwnd, so check that.
  380.      */
  381.  
  382.     if (hwnd != NULLHANDLE && !(winPtr->flags & TK_DONT_DESTROY_WINDOW)
  383.         && WinIsWindow(TclOS2GetHAB(), hwnd)) {
  384.         rc = WinDestroyWindow(hwnd);
  385. #ifdef VERBOSE
  386.         if (rc != TRUE) {
  387.             printf("WinDestroyWindow hwnd %x ERROR %x\n", hwnd,
  388.                    WinGetLastError(TclOS2GetHAB()));
  389.         } else {
  390.             printf("WinDestroyWindow hwnd %x OK\n", hwnd);
  391.         }
  392. #endif
  393.     }
  394. }
  395.  
  396. /*
  397.  *----------------------------------------------------------------------
  398.  *
  399.  * XMapWindow --
  400.  *
  401.  *    Cause the given window to become visible.
  402.  *
  403.  * Results:
  404.  *    None
  405.  *
  406.  * Side effects:
  407.  *    Causes the window state to change, and generates a MapNotify
  408.  *    event.
  409.  *
  410.  *----------------------------------------------------------------------
  411.  */
  412.  
  413. void
  414. XMapWindow(display, w)
  415.     Display* display;
  416.     Window w;
  417. {
  418.     XEvent event;
  419.     TkWindow *parentPtr;
  420.     TkWindow *winPtr = TkOS2GetWinPtr(w);
  421.  
  422.     display->request++;
  423.  
  424.     rc = WinShowWindow(TkOS2GetHWND(w), TRUE);
  425. #ifdef VERBOSE
  426.     if (rc != TRUE) {
  427.         printf("XMapWindow: WinShowWindow %x ERROR %x\n", TkOS2GetHWND(w),
  428.            WinGetLastError(TclOS2GetHAB()));
  429.     } else {
  430.         printf("XMapWindow: WinShowWindow %x OK\n", TkOS2GetHWND(w));
  431.     }
  432. #endif
  433.     winPtr->flags |= TK_MAPPED;
  434.  
  435.    /*
  436.     * Check to see if this window is visible now.  If all of the parent
  437.     * windows up to the first toplevel are mapped, then this window and
  438.     * its mapped children have just become visible.
  439.     */
  440.  
  441.    if (!(winPtr->flags & TK_TOP_LEVEL)) {
  442.        for (parentPtr = winPtr->parentPtr; ;
  443.                parentPtr = parentPtr->parentPtr) {
  444.            if ((parentPtr == NULL) || !(parentPtr->flags & TK_MAPPED)) {
  445.                return;
  446.            }
  447.            if (parentPtr->flags & TK_TOP_LEVEL) {
  448.                break;
  449.            }
  450.        }
  451.     } else {
  452.         event.type = MapNotify;
  453.         event.xmap.serial = display->request;
  454.         event.xmap.send_event = False;
  455.         event.xmap.display = display;
  456.         event.xmap.event = winPtr->window;
  457.         event.xmap.window = winPtr->window;
  458.         event.xmap.override_redirect = winPtr->atts.override_redirect;
  459. #ifdef VERBOSE
  460.         printf("MapNotify\n");
  461. #endif
  462.         Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
  463.         display->request++;
  464.     }
  465.  
  466.     /*
  467.      * Generate VisibilityNotify events for this window and its mapped
  468.      * children.
  469.      */
  470.  
  471.     event.type = VisibilityNotify;
  472.     event.xvisibility.serial = display->request;
  473.     event.xvisibility.send_event = False;
  474.     event.xvisibility.display = display;
  475.     event.xvisibility.window = winPtr->window;
  476.     event.xvisibility.state = VisibilityUnobscured;
  477.     NotifyVisibility(&event, winPtr);
  478. }
  479.  
  480. /*
  481.  *----------------------------------------------------------------------
  482.  *
  483.  * NotifyVisibility --
  484.  *
  485.  *      This function recursively notifies the mapped children of the
  486.  *      specified window of a change in visibility. A VisibilityNotify
  487.  *    event is generated for each child that returns TRUE for
  488.  *    WinIsWindowShowing(), with the state flag set to
  489.  *    VisibilityUnobscured. No account is taken of the previous state
  490.  *    or the extent of viewabilit/obscuredness, since that would cost
  491.  *    much computation (eg. WinQueryUpdateRect) and memory (field for
  492.  *    last viewability).
  493.  *      The eventPtr argument must point to an event
  494.  *      that has been completely initialized except for the window slot.
  495.  *
  496.  * Results:
  497.  *      None.
  498.  *
  499.  * Side effects:
  500.  *      Generates lots of events.
  501.  *
  502.  *----------------------------------------------------------------------
  503.  */
  504.  
  505. static void
  506. NotifyVisibility(eventPtr, winPtr)
  507.     XEvent *eventPtr;           /* Initialized VisibilityNotify event. */
  508.     TkWindow *winPtr;           /* Window to notify. */
  509. {
  510. #ifdef VERBOSE
  511.     printf("NotifyVisibility\n");
  512. #endif
  513.     if (winPtr->atts.event_mask & VisibilityChangeMask) {
  514.         eventPtr->xvisibility.window = winPtr->window;
  515.         Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_TAIL);
  516.     }
  517.     for (winPtr = winPtr->childList; winPtr != NULL;
  518.             winPtr = winPtr->nextPtr) {
  519.         if (winPtr->flags & TK_MAPPED) {
  520.             NotifyVisibility(eventPtr, winPtr);
  521.         }
  522.     }
  523. }
  524.  
  525. /*
  526.  *----------------------------------------------------------------------
  527.  *
  528.  * XUnmapWindow --
  529.  *
  530.  *    Cause the given window to become invisible.
  531.  *
  532.  * Results:
  533.  *    None
  534.  *
  535.  * Side effects:
  536.  *    Causes the window state to change, and generates an UnmapNotify
  537.  *    event.
  538.  *
  539.  *----------------------------------------------------------------------
  540.  */
  541.  
  542. void
  543. XUnmapWindow(display, w)
  544.     Display* display;
  545.     Window w;
  546. {
  547.     XEvent event;
  548.     TkWindow *winPtr = TkOS2GetWinPtr(w);
  549. #ifdef VERBOSE
  550.     printf("XUnmapWindow hwnd %x\n", TkOS2GetHWND(w));
  551. #endif
  552.  
  553.     display->request++;
  554.  
  555.     /*
  556.      * Bug fix: Don't short circuit this routine based on TK_MAPPED because
  557.      * it will be cleared before XUnmapWindow is called.
  558.      */
  559.  
  560.     WinShowWindow(TkOS2GetHWND(w), FALSE);
  561.     winPtr->flags &= ~TK_MAPPED;
  562.  
  563.     if (winPtr->flags & TK_TOP_LEVEL) {
  564.         event.type = UnmapNotify;
  565.         event.xunmap.serial = display->request;
  566.         event.xunmap.send_event = False;
  567. #ifdef VERBOSE
  568.         printf("    display %x\n", display);
  569. #endif
  570.         event.xunmap.display = display;
  571.         event.xunmap.event = winPtr->window;
  572.         event.xunmap.window = winPtr->window;
  573.         event.xunmap.from_configure = False;
  574. #ifdef VERBOSE
  575.         printf("UnmapNotify\n");
  576. #endif
  577.         Tk_HandleEvent(&event);
  578.     }
  579. }
  580.  
  581. /*
  582.  *----------------------------------------------------------------------
  583.  *
  584.  * XMoveResizeWindow --
  585.  *
  586.  *    Move and resize a window relative to its parent.
  587.  *
  588.  * Results:
  589.  *    None.
  590.  *
  591.  * Side effects:
  592.  *    Repositions and resizes the specified window.
  593.  *
  594.  *----------------------------------------------------------------------
  595.  */
  596.  
  597. void
  598. XMoveResizeWindow(display, w, x, y, width, height)
  599.     Display* display;
  600.     Window w;
  601.     int x;            /* Position relative to parent. */
  602.     int y;
  603.     unsigned int width;
  604.     unsigned int height;
  605. {
  606. #ifdef VERBOSE
  607.     SWP pos;
  608.     WinQueryWindowPos(TkOS2GetHWND(w), &pos);
  609.     printf("XMoveResizeWindow %x (%d,%d) %dx%d PM %d, oldpos PM(%d,%d) %dx%d\n",
  610.            TkOS2GetHWND(w), x, y, width, height,
  611.            TkOS2TranslateY(TkOS2GetHWND(w),y,height), pos.x, pos.y, pos.cx,
  612.            pos.cy);
  613. #endif
  614.     display->request++;
  615.     /*
  616.      * Translate Y coordinates to PM: relative to parent
  617.      */
  618.     WinSetWindowPos(TkOS2GetHWND(w), HWND_TOP, x,
  619.                     TkOS2TranslateY(TkOS2GetHWND(w), y, height),
  620.                     width, height, SWP_MOVE | SWP_SIZE);
  621. #ifdef VERBOSE
  622.     printf("XMoveResizeWindow hwnd %x, (%d,%d) %dx%d (x11y %d)\n",
  623.            TkOS2GetHWND(w), x,
  624.            TkOS2TranslateY(TkOS2GetHWND(w), y, height), width, height, y);
  625. #endif
  626. }
  627.  
  628. /*
  629.  *----------------------------------------------------------------------
  630.  *
  631.  * XMoveWindow --
  632.  *
  633.  *    Move a window relative to its parent.
  634.  *
  635.  * Results:
  636.  *    None.
  637.  *
  638.  * Side effects:
  639.  *    Repositions the specified window.
  640.  *
  641.  *----------------------------------------------------------------------
  642.  */
  643.  
  644. void
  645. XMoveWindow(display, w, x, y)
  646.     Display* display;
  647.     Window w;
  648.     int x;
  649.     int y;
  650. {
  651.     TkWindow *winPtr = TkOS2GetWinPtr(w);
  652. #ifdef VERBOSE
  653.     SWP pos;
  654.     WinQueryWindowPos(TkOS2GetHWND(w), &pos);
  655.     printf("XMoveWindow %x, oldpos (%d,%d;%dx%d)\n", TkOS2GetHWND(w),
  656.            pos.x, pos.y, pos.cx, pos.cy);
  657. #endif
  658.  
  659.     display->request++;
  660.  
  661.     /* Translate Y coordinates to PM, relative to parent */
  662.     WinSetWindowPos(TkOS2GetHWND(w), HWND_TOP, x,
  663.                     TkOS2TranslateY(TkOS2GetHWND(w), y, winPtr->changes.height),
  664.                     winPtr->changes.width, winPtr->changes.height,
  665.                     SWP_MOVE /*| SWP_SIZE*/ | SWP_NOADJUST);
  666. #ifdef VERBOSE
  667.     printf("XMoveWindow hwnd %x, x %d, y %d, w %d, h %d\n", TkOS2GetHWND(w),
  668.            x, TkOS2TranslateY(TkOS2GetHWND(w), y, winPtr->changes.height),
  669.            winPtr->changes.width, winPtr->changes.height);
  670. #endif
  671. }
  672.  
  673. /*
  674.  *----------------------------------------------------------------------
  675.  *
  676.  * XResizeWindow --
  677.  *
  678.  *    Resize a window.
  679.  *
  680.  * Results:
  681.  *    None.
  682.  *
  683.  * Side effects:
  684.  *    Resizes the specified window.
  685.  *
  686.  *----------------------------------------------------------------------
  687.  */
  688.  
  689. void
  690. XResizeWindow(display, w, width, height)
  691.     Display* display;
  692.     Window w;
  693.     unsigned int width;
  694.     unsigned int height;
  695. {
  696. /*
  697.     TkWindow *winPtr = TkOS2GetWinPtr(w);
  698. */
  699.     SWP oldPos;
  700.     WinQueryWindowPos(TkOS2GetHWND(w), &oldPos);
  701. #ifdef VERBOSE
  702.     printf("XResizeWindow %x, oldpos (%d,%d;%dx%d)\n", TkOS2GetHWND(w),
  703.            oldPos.x, oldPos.y, oldPos.cx, oldPos.cy);
  704. #endif
  705.  
  706.     display->request++;
  707.  
  708.     /*
  709.      * Translate Y coordinates to PM; relative to parent
  710.      * The *top* must stay at the same position, so use SWP_MOVE too.
  711.      */
  712.     WinSetWindowPos(TkOS2GetHWND(w), HWND_TOP, oldPos.x,
  713.                     oldPos.y - height, width, height,
  714.                     SWP_MOVE | SWP_SIZE | SWP_NOADJUST);
  715. #ifdef VERBOSE
  716.     printf("XResizeWindow hwnd %x, x %d, y %d, w %d, h %d\n", TkOS2GetHWND(w),
  717.            oldPos.y + oldPos.cy - height, width, height);
  718. #endif
  719. }
  720.  
  721. /*
  722.  *----------------------------------------------------------------------
  723.  *
  724.  * XRaiseWindow --
  725.  *
  726.  *    Change the stacking order of a window.
  727.  *
  728.  * Results:
  729.  *    None.
  730.  *
  731.  * Side effects:
  732.  *    Changes the stacking order of the specified window.
  733.  *
  734.  *----------------------------------------------------------------------
  735.  */
  736.  
  737. void
  738. XRaiseWindow(display, w)
  739.     Display* display;
  740.     Window w;
  741. {
  742.     HWND window = TkOS2GetHWND(w);
  743.  
  744. #ifdef VERBOSE
  745.     printf("XRaiseWindow hwnd %x\n", window);
  746. #endif
  747.  
  748.     display->request++;
  749.     rc = WinSetWindowPos(window, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER);
  750. #ifdef VERBOSE
  751.     if (rc!=TRUE) {
  752.         printf("    WinSetWindowPos HWND_TOP ERROR %x\n",
  753.                WinGetLastError(TclOS2GetHAB()));
  754.     } else {
  755.         printf("    WinSetWindowPos HWND_TOP OK\n");
  756.     }
  757. #endif
  758. }
  759.  
  760. /*
  761.  *----------------------------------------------------------------------
  762.  *
  763.  * XConfigureWindow --
  764.  *
  765.  *    Change the size, position, stacking, or border of the specified
  766.  *    window.
  767.  *
  768.  * Results:
  769.  *    None.
  770.  *
  771.  * Side effects:
  772.  *    Changes the attributes of the specified window.  Note that we
  773.  *    ignore the passed in values and use the values stored in the
  774.  *    TkWindow data structure.
  775.  *
  776.  *----------------------------------------------------------------------
  777.  */
  778.  
  779. void
  780. XConfigureWindow(display, w, value_mask, values)
  781.     Display* display;
  782.     Window w;
  783.     unsigned int value_mask;
  784.     XWindowChanges* values;
  785. {
  786.     TkWindow *winPtr = TkOS2GetWinPtr(w);
  787.     HWND hwnd = TkOS2GetHWND(w);
  788.  
  789. #ifdef VERBOSE
  790.     SWP pos;
  791.     WinQueryWindowPos(hwnd, &pos);
  792.     printf("XConfigureWindow %x, pos (%d,%d;%dx%d)\n", hwnd, pos.x, pos.y,
  793.            pos.cx, pos.cy);
  794. #endif
  795.  
  796.     display->request++;
  797.  
  798.     /*
  799.      * Change the shape and/or position of the window.
  800.      */
  801.  
  802.     if (value_mask & (CWX|CWY|CWWidth|CWHeight)) {
  803.         /* Translate Y coordinates to PM */
  804.         WinSetWindowPos(hwnd, HWND_TOP, winPtr->changes.x,
  805.                         TkOS2TranslateY(hwnd, winPtr->changes.y,
  806.                                         winPtr->changes.height),
  807.                         winPtr->changes.width, winPtr->changes.height,
  808.                         SWP_MOVE | SWP_SIZE | SWP_NOADJUST);
  809. #ifdef VERBOSE
  810.         printf("    WinSetWindowPos CWX/CWY   hwnd %x, (%d,%d) %dx%d\n", hwnd,
  811.                winPtr->changes.x,
  812.                TkOS2TranslateY(hwnd, winPtr->changes.y, winPtr->changes.height),
  813.                winPtr->changes.width, winPtr->changes.height);
  814. #endif
  815.     }
  816.  
  817.     /*
  818.      * Change the stacking order of the window.
  819.      */
  820.  
  821.     if (value_mask & CWStackMode) {
  822.     HWND sibling;
  823. #ifdef VERBOSE
  824.         printf("    CWStackMode\n");
  825. #endif
  826.     if ((value_mask & CWSibling) && (values->sibling != None)) {
  827.         sibling = Tk_GetHWND(values->sibling);
  828.     } else {
  829.         sibling = NULLHANDLE;
  830.     }
  831.     TkOS2SetWindowPos(hwnd, sibling, values->stack_mode);
  832.     } 
  833. #ifdef VERBOSE
  834.     WinQueryWindowPos(hwnd, &pos);
  835.     printf("After XConfigureWindow %x, pos (%d,%d;%dx%d)\n", hwnd,
  836.            pos.x, pos.y, pos.cx, pos.cy);
  837. #endif
  838. }
  839.  
  840. /*
  841.  *----------------------------------------------------------------------
  842.  *
  843.  * XClearWindow --
  844.  *
  845.  *    Clears the entire window to the current background color.
  846.  *
  847.  * Results:
  848.  *    None.
  849.  *
  850.  * Side effects:
  851.  *    Erases the current contents of the window.
  852.  *
  853.  *----------------------------------------------------------------------
  854.  */
  855.  
  856. void
  857. XClearWindow(display, w)
  858.     Display* display;
  859.     Window w;
  860. {
  861.     RECTL rect;
  862.     LONG oldColor, oldPattern;
  863.     HPAL oldPalette, palette;
  864.     TkWindow *winPtr;
  865.     HWND hwnd = TkOS2GetHWND(w);
  866.     HPS hps = WinGetPS(hwnd);
  867.  
  868. #ifdef VERBOSE
  869.     printf("XClearWindow\n");
  870. #endif
  871.  
  872.     palette = TkOS2GetPalette(display->screens[0].cmap);
  873.     oldPalette = GpiSelectPalette(hps, palette);
  874.  
  875.     display->request++;
  876.  
  877.     winPtr = TkOS2GetWinPtr(w);
  878.     oldColor = GpiQueryColor(hps);
  879.     oldPattern = GpiQueryPattern(hps);
  880.     GpiSetPattern(hps, PATSYM_SOLID);
  881.     WinQueryWindowRect(hwnd, &rect);
  882.     WinFillRect(hps, &rect, winPtr->atts.background_pixel);
  883. #ifdef VERBOSE
  884.     printf("WinFillRect in XClearWindow\n");
  885. #endif
  886.     GpiSetPattern(hps, oldPattern);
  887.     GpiSelectPalette(hps, oldPalette);
  888.     WinReleasePS(hps);
  889. }
  890.  
  891. /*
  892.  *----------------------------------------------------------------------
  893.  *
  894.  * XChangeWindowAttributes --
  895.  *
  896.  *      This function is called when the attributes on a window are
  897.  *      updated.  Since Tk maintains all of the window state, the only
  898.  *      relevant value is the cursor.
  899.  *
  900.  * Results:
  901.  *      None.
  902.  *
  903.  * Side effects:
  904.  *      May cause the mouse position to be updated.
  905.  *
  906.  *----------------------------------------------------------------------
  907.  */
  908.  
  909. void
  910. XChangeWindowAttributes(display, w, valueMask, attributes)
  911.     Display* display;
  912.     Window w;
  913.     unsigned long valueMask;
  914.     XSetWindowAttributes* attributes;
  915. {
  916. #ifdef VERBOSE
  917.     printf("XChangeWindowAttributes\n");
  918. #endif
  919.     if (valueMask & CWCursor) {
  920.         XDefineCursor(display, w, attributes->cursor);
  921.     }
  922. }
  923.  
  924. /*
  925.  *----------------------------------------------------------------------
  926.  *
  927.  * TkOS2SetWindowPos --
  928.  *
  929.  *      Adjust the stacking order of a window relative to a second
  930.  *      window (or NULLHANDLE).
  931.  *
  932.  * Results:
  933.  *      None.
  934.  *
  935.  * Side effects:
  936.  *      Moves the specified window in the stacking order.
  937.  *
  938.  *----------------------------------------------------------------------
  939.  */
  940.  
  941. void
  942. TkOS2SetWindowPos(hwnd, siblingHwnd, pos)
  943.     HWND hwnd;                  /* Window to restack. */
  944.     HWND siblingHwnd;           /* Sibling window. */
  945.     int pos;                    /* One of Above or Below. */
  946. {
  947.     HWND temp;
  948.  
  949. #ifdef VERBOSE
  950.     printf("TkOS2SetWindowPos hwnd %x sibling %x pos %s\n", hwnd, siblingHwnd,
  951.            pos == Above ? "Above" : "Below");
  952. #endif
  953.  
  954.     /*
  955.      * Since OS/2 does not support Above mode, we place the
  956.      * specified window below the sibling and then swap them.
  957.      */
  958.  
  959.     if (siblingHwnd != NULLHANDLE) {
  960.         if (pos == Above) {
  961.             WinSetWindowPos(hwnd, siblingHwnd, 0, 0, 0, 0, SWP_ZORDER);
  962.             temp = hwnd;
  963.             hwnd = siblingHwnd;
  964.             siblingHwnd = temp;
  965.         }
  966.     } else {
  967.         siblingHwnd = (pos == Above) ? HWND_TOP : HWND_BOTTOM;
  968.     }
  969.  
  970.     WinSetWindowPos(hwnd, siblingHwnd, 0, 0, 0, 0, SWP_ZORDER);
  971. }
  972.  
  973. /*
  974.  *----------------------------------------------------------------------
  975.  *
  976.  * TkpWindowWasRecentlyDeleted --
  977.  *
  978.  *      Determines whether we know if the window given as argument was
  979.  *      recently deleted. Called by the generic code error handler to
  980.  *      handle BadWindow events.
  981.  *
  982.  * Results:
  983.  *      Always 0. We do not keep this information on OS/2.
  984.  *
  985.  * Side effects:
  986.  *      None.
  987.  *
  988.  *----------------------------------------------------------------------
  989.  */
  990.  
  991. int
  992. TkpWindowWasRecentlyDeleted(win, dispPtr)
  993.     Window win;
  994.     TkDisplay *dispPtr;
  995. {
  996.     return 0;
  997. }
  998.  
  999. /*
  1000.  *----------------------------------------------------------------------
  1001.  *
  1002.  * TkOS2WindowHeight --
  1003.  *
  1004.  *      Determine the height of an OS/2 drawable (or parent for bitmaps).
  1005.  *
  1006.  * Results:
  1007.  *      Height of drawable.
  1008.  *
  1009.  * Side effects:
  1010.  *      None.
  1011.  *
  1012.  *----------------------------------------------------------------------
  1013.  */
  1014.  
  1015. LONG
  1016. TkOS2WindowHeight(todPtr)
  1017.     TkOS2Drawable *todPtr;
  1018. {
  1019.     SWP pos;
  1020.     BOOL rc;
  1021.  
  1022. #ifdef VERBOSE
  1023.     printf("TkOS2WindowHeight todPtr %x\n", todPtr);
  1024. #endif
  1025.  
  1026.     if (todPtr->type == TOD_BITMAP) {
  1027.         BITMAPINFOHEADER2 info;
  1028.         /* Bitmap */
  1029.         info.cbFix = sizeof(BITMAPINFOHEADER2);
  1030.         rc = GpiQueryBitmapInfoHeader(todPtr->bitmap.handle, &info);
  1031. #ifdef VERBOSE
  1032.         printf("TkOS2WindowHeight todPtr %x (bitmap %x) returning %d\n", todPtr,
  1033.            todPtr->bitmap.handle, info.cy);
  1034. #endif
  1035.         return info.cy;
  1036.     } else if (todPtr->type == TOD_OS2PS) {
  1037. #ifdef VERBOSE
  1038.         printf("TkOS2WindowHeight todPtr %x hps %x hwnd %x\n",
  1039.                todPtr, todPtr->os2PS.hps, todPtr->os2PS.hwnd);
  1040. #endif
  1041.         rc = WinQueryWindowPos(todPtr->os2PS.hwnd, &pos);
  1042.         if (rc != TRUE) {
  1043. #ifdef VERBOSE
  1044.             printf("    WinQueryWindowPos ERROR %x\n",
  1045.                    WinGetLastError(TclOS2GetHAB()));
  1046. #endif
  1047.             return 0;
  1048.         }
  1049. #ifdef VERBOSE
  1050.         printf("TkOS2WindowHeight hwnd %x (os2PS) returning %d\n",
  1051.                todPtr->os2PS.hwnd, pos.cy);
  1052. #endif
  1053.         return pos.cy;
  1054.     }
  1055.     return TkOS2HwndHeight(todPtr->window.handle);
  1056. }
  1057.  
  1058. /*
  1059.  *----------------------------------------------------------------------
  1060.  *
  1061.  * TkOS2HwndHeight --
  1062.  *
  1063.  *      Determine the height of a window.
  1064.  *
  1065.  * Results:
  1066.  *      Height of drawable.
  1067.  *
  1068.  * Side effects:
  1069.  *      None.
  1070.  *
  1071.  *----------------------------------------------------------------------
  1072.  */
  1073.  
  1074. LONG
  1075. TkOS2HwndHeight(hwnd)
  1076.     HWND hwnd;
  1077. {
  1078.     SWP pos;
  1079.     HWND parent;
  1080.     HWND desktop;
  1081.     BOOL rc;
  1082.  
  1083. #ifdef VERBOSE
  1084.     printf("TkOS2HwndHeight hwnd %x\n", hwnd);
  1085. #endif
  1086.  
  1087.     rc = WinQueryWindowPos(hwnd, &pos);
  1088.     if (rc != TRUE) {
  1089. #ifdef VERBOSE
  1090.         printf(" WinQueryWindowPos hwnd %x ERROR %x\n", hwnd,
  1091.                WinGetLastError(TclOS2GetHAB()));
  1092. #endif
  1093.         return 0;
  1094.     }
  1095. #ifdef VERBOSE
  1096.     printf("    pos hwnd %x (%d,%d) %dx%d\n", hwnd, pos.x, pos.y, pos.cx,
  1097.            pos.cy);
  1098. #endif
  1099.  
  1100.     /* Take toplevel frames' decorations (borders etc.) into account */
  1101.     desktop = WinQueryDesktopWindow(TclOS2GetHAB(), NULLHANDLE);
  1102.     parent = WinQueryWindow(hwnd, QW_PARENT);
  1103. #ifdef VERBOSE
  1104.     printf("    parent %x, desktop %x\n", parent, desktop);
  1105. #endif
  1106.     if (hwnd != desktop && parent == desktop) {
  1107.     RECTL rectl;
  1108.         rectl.xLeft = pos.x;
  1109.         rectl.xRight = pos.x + pos.cx;
  1110.         rectl.yBottom = pos.y;
  1111.     rectl.yTop = pos.y + pos.cy;
  1112. #ifdef VERBOSE
  1113.         printf("    rectl before WinCalcFrameRect (%d,%d) (%d,%d)\n",
  1114.            rectl.xLeft, rectl.yBottom, rectl.xRight, rectl.yTop);
  1115. #endif
  1116.     rc = WinCalcFrameRect(hwnd, &rectl, TRUE);
  1117. #ifdef VERBOSE
  1118.         printf("    rectl after WinCalcFrameRect (%d,%d) (%d,%d)\n",
  1119.            rectl.xLeft, rectl.yBottom, rectl.xRight, rectl.yTop);
  1120. #endif
  1121.         if (rc != TRUE) {
  1122. #ifdef VERBOSE
  1123.             printf("TkOS2HwndHeight: WinCalcFrameRect hwnd %x ERROR %x\n",
  1124.                    hwnd, WinGetLastError(TclOS2GetHAB()));
  1125. #endif
  1126.             return pos.cy;
  1127.         }
  1128. #ifdef VERBOSE
  1129.         printf("TkOS2HwndHeight hwnd %x (frame) returning %d\n", hwnd,
  1130.            rectl.yTop - rectl.yBottom);
  1131. #endif
  1132.         return rectl.yTop - rectl.yBottom;
  1133.     } else {
  1134. #ifdef VERBOSE
  1135.         printf("TkOS2HwndHeight hwnd %x (parent %x) returning %d\n",
  1136.                hwnd, parent, pos.cy);
  1137. #endif
  1138.         return pos.cy;
  1139.     }
  1140. }
  1141.  
  1142. /*
  1143.  *----------------------------------------------------------------------
  1144.  *
  1145.  * TkOS2TranslateY --
  1146.  *
  1147.  *      Translate PM y coordinate (from bottom of screen) into X Window
  1148.  *      System y coordinate (from top of screen) or the other way around.
  1149.  *      The height argument is needed for the window position of a window,
  1150.  *      it should be 0 for translating just a coordinate instead of a
  1151.  *      window position.
  1152.  *      The y position of a window in PM coordinates is the height of the
  1153.  *      parent window minus the y position in X coordinates and the height
  1154.  *      of the window (and vice versa).
  1155.  *      Since X Window System coordinates are always ints, use that instead
  1156.  *      of LONG.
  1157.  *
  1158.  * Results:
  1159.  *      Translated y coordinate.
  1160.  *
  1161.  * Side effects:
  1162.  *      None.
  1163.  *
  1164.  *----------------------------------------------------------------------
  1165.  */
  1166.  
  1167. int
  1168. TkOS2TranslateY(hwnd, y, height)
  1169.     HWND hwnd;    /* Window for which the translation is meant */
  1170.     int y;    /* y coordinate to be translated */
  1171.     int height; /*  height the window is going to have, 0 for position */
  1172. {
  1173.     LONG parHeight = TkOS2HwndHeight(WinQueryWindow(hwnd, QW_PARENT));
  1174. #ifdef VERBOSE
  1175.     printf("TkOS2TranslateY hwnd %x y %d height %d (%d-%d-%d = %d)\n", hwnd, y,
  1176.            height, parHeight, y, height, parHeight - y - height);
  1177. #endif
  1178.  
  1179.     return (int) parHeight - y - height;
  1180. }
  1181.