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 >
C/C++ Source or Header  |  1999-07-27  |  18KB  |  679 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-1998 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.  * Forward declarations for procedures defined in this file:
  19.  */
  20.  
  21. static void             NotifyVisibility _ANSI_ARGS_((XEvent *eventPtr,
  22.                             TkWindow *winPtr));
  23.  
  24. /*
  25.  *----------------------------------------------------------------------
  26.  *
  27.  * TkMakeWindow --
  28.  *
  29.  *    Creates an OS/2 PM window object based on the current attributes
  30.  *    of the specified TkWindow.
  31.  *
  32.  * Results:
  33.  *    Returns a pointer to a new TkOS2Drawable cast to a Window.
  34.  *
  35.  * Side effects:
  36.  *    Creates a new window.
  37.  *
  38.  *----------------------------------------------------------------------
  39.  */
  40.  
  41. Window
  42. TkMakeWindow(winPtr, parent)
  43.     TkWindow *winPtr;
  44.     Window parent;
  45. {
  46.     HWND parentWin;
  47.     ULONG yPos;
  48.     TkOS2Drawable *todPtr;
  49.     int style;
  50.     
  51.     todPtr = (TkOS2Drawable*) ckalloc(sizeof(TkOS2Drawable));
  52.     if (todPtr == NULL) {
  53.     return (Window)None;
  54.     }
  55.  
  56.     todPtr->type = TOD_WINDOW;
  57.     todPtr->window.winPtr = winPtr;
  58.  
  59.     /* Translate Y coordinates to PM */
  60.     if (parent != None) {
  61.     parentWin = TkOS2GetHWND(parent);
  62.     style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
  63.         yPos = TkOS2WindowHeight((TkOS2Drawable *)parent) -
  64.                (  winPtr->changes.y + winPtr->changes.height );
  65.     } else {
  66.     parentWin = HWND_DESKTOP;
  67.     style = WS_CLIPCHILDREN | CS_PARENTCLIP;
  68.         yPos = yScreen - (  winPtr->changes.y + winPtr->changes.height );
  69.     }
  70.  
  71.     /* Use FID_CLIENT in order to get activation right later! */
  72.     todPtr->window.handle = WinCreateWindow(parentWin, TOC_CHILD, "", style,
  73.             winPtr->changes.x, yPos,
  74.             winPtr->changes.width, winPtr->changes.height,
  75.             NULLHANDLE, HWND_TOP, FID_CLIENT, (PVOID)todPtr, NULL);
  76.  
  77.     if (todPtr->window.handle == NULLHANDLE) {
  78.     ckfree((char *) todPtr);
  79.     todPtr = NULL;
  80.     }
  81.  
  82.     return (Window)todPtr;
  83. }
  84.  
  85. /*
  86.  *----------------------------------------------------------------------
  87.  *
  88.  * XDestroyWindow --
  89.  *
  90.  *    Destroys the given window.
  91.  *
  92.  * Results:
  93.  *    None.
  94.  *
  95.  * Side effects:
  96.  *    Sends the WM_DESTROY message to the window and then destroys
  97.  *    the resources associated with the window.
  98.  *
  99.  *----------------------------------------------------------------------
  100.  */
  101.  
  102. void
  103. XDestroyWindow(display, w)
  104.     Display* display;
  105.     Window w;
  106. {
  107.     TkOS2Drawable *todPtr = (TkOS2Drawable *)w;
  108.     TkWindow *winPtr = TkOS2GetWinPtr(w);
  109.     HWND hwnd = TkOS2GetHWND(w);
  110.  
  111.     display->request++;
  112.  
  113.     /*
  114.      * Remove references to the window in the pointer module, and
  115.      * then remove the backpointer from the drawable.
  116.      */
  117.  
  118.     TkOS2PointerDeadWindow(winPtr);
  119.     todPtr->window.winPtr = NULL;
  120.  
  121.     /*
  122.      * Don't bother destroying the window if we are going to destroy
  123.      * the parent later.  Also if the window has already been destroyed
  124.      * then we need to free the drawable now.
  125.      */
  126.  
  127.     if (!hwnd) {
  128.         ckfree((char *)todPtr);
  129.         todPtr= NULL;
  130.     } else if (!(winPtr->flags & TK_PARENT_DESTROYED)) {
  131.         rc = WinDestroyWindow(hwnd);
  132.     }
  133. }
  134.  
  135. /*
  136.  *----------------------------------------------------------------------
  137.  *
  138.  * XMapWindow --
  139.  *
  140.  *    Cause the given window to become visible.
  141.  *
  142.  * Results:
  143.  *    None
  144.  *
  145.  * Side effects:
  146.  *    Causes the window state to change, and generates a MapNotify
  147.  *    event.
  148.  *
  149.  *----------------------------------------------------------------------
  150.  */
  151.  
  152. void
  153. XMapWindow(display, w)
  154.     Display* display;
  155.     Window w;
  156. {
  157.     XEvent event;
  158.     TkWindow *parentPtr;
  159.     TkWindow *winPtr = TkOS2GetWinPtr(w);
  160.  
  161.     display->request++;
  162.  
  163.     WinShowWindow(TkOS2GetHWND(w), TRUE);
  164.     winPtr->flags |= TK_MAPPED;
  165.  
  166.    /*
  167.     * Check to see if this window is visible now.  If all of the parent
  168.     * windows up to the first toplevel are mapped, then this window and
  169.     * its mapped children have just become visible.
  170.     */
  171.  
  172.    if (!(winPtr->flags & TK_TOP_LEVEL)) {
  173.        for (parentPtr = winPtr->parentPtr; ;
  174.                parentPtr = parentPtr->parentPtr) {
  175.            if ((parentPtr == NULL) || !(parentPtr->flags & TK_MAPPED)) {
  176.                return;
  177.            }
  178.            if (parentPtr->flags & TK_TOP_LEVEL) {
  179.                break;
  180.            }
  181.        }
  182.     } else {
  183.         event.type = MapNotify;
  184.         event.xmap.serial = display->request;
  185.         event.xmap.send_event = False;
  186.         event.xmap.display = display;
  187.         event.xmap.event = winPtr->window;
  188.         event.xmap.window = winPtr->window;
  189.         event.xmap.override_redirect = winPtr->atts.override_redirect;
  190.         Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
  191.     }
  192.  
  193.     /*
  194.      * Generate VisibilityNotify events for this window and its mapped
  195.      * children.
  196.      */
  197.  
  198.     event.type = VisibilityNotify;
  199.     event.xvisibility.serial = display->request;
  200.     event.xvisibility.send_event = False;
  201.     event.xvisibility.display = display;
  202.     event.xvisibility.window = winPtr->window;
  203.     event.xvisibility.state = VisibilityUnobscured;
  204.     NotifyVisibility(&event, winPtr);
  205. }
  206.  
  207. /*
  208.  *----------------------------------------------------------------------
  209.  *
  210.  * NotifyVisibility --
  211.  *
  212.  *      This function recursively notifies the mapped children of the
  213.  *      specified window of a change in visibility. A VisibilityNotify
  214.  *    event is generated for each child that returns TRUE for
  215.  *    WinIsWindowShowing(), with the state flag set to
  216.  *    VisibilityUnobscured. No account is taken of the previous state
  217.  *    or the extent of viewabilit/obscuredness, since that would cost
  218.  *    much computation (eg. WinQueryUpdateRect) and memory (field for
  219.  *    last viewability).
  220.  *      The eventPtr argument must point to an event
  221.  *      that has been completely initialized except for the window slot.
  222.  *
  223.  * Results:
  224.  *      None.
  225.  *
  226.  * Side effects:
  227.  *      Generates lots of events.
  228.  *
  229.  *----------------------------------------------------------------------
  230.  */
  231.  
  232. static void
  233. NotifyVisibility(eventPtr, winPtr)
  234.     XEvent *eventPtr;           /* Initialized VisibilityNotify event. */
  235.     TkWindow *winPtr;           /* Window to notify. */
  236. {
  237.     if (winPtr->atts.event_mask & VisibilityChangeMask) {
  238.         eventPtr->xvisibility.window = winPtr->window;
  239.         Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_TAIL);
  240.     }
  241.     Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_TAIL);
  242.     for (winPtr = winPtr->childList; winPtr != NULL;
  243.             winPtr = winPtr->nextPtr) {
  244.         if (winPtr->flags & TK_MAPPED &&
  245.                WinIsWindowShowing(TkOS2GetHWND(winPtr->window))) {
  246.             NotifyVisibility(eventPtr, winPtr);
  247.         }
  248.     }
  249. }
  250.  
  251. /*
  252.  *----------------------------------------------------------------------
  253.  *
  254.  * XUnmapWindow --
  255.  *
  256.  *    Cause the given window to become invisible.
  257.  *
  258.  * Results:
  259.  *    None
  260.  *
  261.  * Side effects:
  262.  *    Causes the window state to change, and generates an UnmapNotify
  263.  *    event.
  264.  *
  265.  *----------------------------------------------------------------------
  266.  */
  267.  
  268. void
  269. XUnmapWindow(display, w)
  270.     Display* display;
  271.     Window w;
  272. {
  273.     XEvent event;
  274.     TkWindow *winPtr = TkOS2GetWinPtr(w);
  275.  
  276.     display->request++;
  277.  
  278.     WinShowWindow(TkOS2GetHWND(w), FALSE);
  279.     winPtr->flags &= ~TK_MAPPED;
  280.  
  281.     if (winPtr->flags & TK_TOP_LEVEL) {
  282.         event.type = UnmapNotify;
  283.         event.xunmap.serial = display->request;
  284.         event.xunmap.send_event = False;
  285.         event.xunmap.display = display;
  286.         event.xunmap.event = winPtr->window;
  287.         event.xunmap.window = winPtr->window;
  288.         event.xunmap.from_configure = False;
  289.         Tk_HandleEvent(&event);
  290.     }
  291. }
  292.  
  293. /*
  294.  *----------------------------------------------------------------------
  295.  *
  296.  * XMoveResizeWindow --
  297.  *
  298.  *    Move and resize a window relative to its parent.
  299.  *
  300.  * Results:
  301.  *    None.
  302.  *
  303.  * Side effects:
  304.  *    Repositions and resizes the specified window.
  305.  *
  306.  *----------------------------------------------------------------------
  307.  */
  308.  
  309. void
  310. XMoveResizeWindow(display, w, x, y, width, height)
  311.     Display* display;
  312.     Window w;
  313.     int x;            /* Position relative to parent. */
  314.     int y;
  315.     unsigned int width;
  316.     unsigned int height;
  317. {
  318.     SWP parPos;
  319.     WinQueryWindowPos(WinQueryWindow(TkOS2GetHWND(w), QW_PARENT), &parPos);
  320.     display->request++;
  321.     /* Translate Y coordinates to PM: relative to parent */
  322.     WinSetWindowPos(TkOS2GetHWND(w), HWND_TOP, x,
  323.                     parPos.cy - height - y,
  324.                     width, height, SWP_MOVE | SWP_SIZE);
  325. }
  326.  
  327. /*
  328.  *----------------------------------------------------------------------
  329.  *
  330.  * XMoveWindow --
  331.  *
  332.  *    Move a window relative to its parent.
  333.  *
  334.  * Results:
  335.  *    None.
  336.  *
  337.  * Side effects:
  338.  *    Repositions the specified window.
  339.  *
  340.  *----------------------------------------------------------------------
  341.  */
  342.  
  343. void
  344. XMoveWindow(display, w, x, y)
  345.     Display* display;
  346.     Window w;
  347.     int x;
  348.     int y;
  349. {
  350.     TkWindow *winPtr = TkOS2GetWinPtr(w);
  351.     SWP parPos;
  352.     WinQueryWindowPos(WinQueryWindow(TkOS2GetHWND(w), QW_PARENT), &parPos);
  353.  
  354.     display->request++;
  355.  
  356.     /* Translate Y coordinates to PM, relative to parent */
  357.     WinSetWindowPos(TkOS2GetHWND(w), HWND_TOP, x,
  358.                     parPos.cy - winPtr->changes.height - y,
  359.                     winPtr->changes.width, winPtr->changes.height,
  360.                     SWP_MOVE /*| SWP_SIZE*/);
  361. }
  362.  
  363. /*
  364.  *----------------------------------------------------------------------
  365.  *
  366.  * XResizeWindow --
  367.  *
  368.  *    Resize a window.
  369.  *
  370.  * Results:
  371.  *    None.
  372.  *
  373.  * Side effects:
  374.  *    Resizes the specified window.
  375.  *
  376.  *----------------------------------------------------------------------
  377.  */
  378.  
  379. void
  380. XResizeWindow(display, w, width, height)
  381.     Display* display;
  382.     Window w;
  383.     unsigned int width;
  384.     unsigned int height;
  385. {
  386.     TkWindow *winPtr = TkOS2GetWinPtr(w);
  387.     SWP parPos;
  388.     WinQueryWindowPos(WinQueryWindow(TkOS2GetHWND(w), QW_PARENT), &parPos);
  389.  
  390.     display->request++;
  391.  
  392.     /* Translate Y coordinates to PM; relative to parent */
  393.     WinSetWindowPos(TkOS2GetHWND(w), HWND_TOP, winPtr->changes.x,
  394.                     parPos.cy - winPtr->changes.height - winPtr->changes.y,
  395.                     winPtr->changes.width, winPtr->changes.height,
  396.                     /*SWP_MOVE |*/ SWP_SIZE);
  397. }
  398.  
  399. /*
  400.  *----------------------------------------------------------------------
  401.  *
  402.  * XRaiseWindow --
  403.  *
  404.  *    Change the stacking order of a window.
  405.  *
  406.  * Results:
  407.  *    None.
  408.  *
  409.  * Side effects:
  410.  *    Changes the stacking order of the specified window.
  411.  *
  412.  *----------------------------------------------------------------------
  413.  */
  414.  
  415. void
  416. XRaiseWindow(display, w)
  417.     Display* display;
  418.     Window w;
  419. {
  420.     HWND window = TkOS2GetHWND(w);
  421.  
  422.     display->request++;
  423.     rc = WinSetWindowPos(window, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER);
  424. }
  425.  
  426. /*
  427.  *----------------------------------------------------------------------
  428.  *
  429.  * XConfigureWindow --
  430.  *
  431.  *    Change the size, position, stacking, or border of the specified
  432.  *    window.
  433.  *
  434.  * Results:
  435.  *    None.
  436.  *
  437.  * Side effects:
  438.  *    Changes the attributes of the specified window.  Note that we
  439.  *    ignore the passed in values and use the values stored in the
  440.  *    TkWindow data structure.
  441.  *
  442.  *----------------------------------------------------------------------
  443.  */
  444.  
  445. void
  446. XConfigureWindow(display, w, value_mask, values)
  447.     Display* display;
  448.     Window w;
  449.     unsigned int value_mask;
  450.     XWindowChanges* values;
  451. {
  452.     TkWindow *winPtr = TkOS2GetWinPtr(w);
  453.     HWND window = TkOS2GetHWND(w);
  454.     HWND insertAfter;
  455.  
  456.     display->request++;
  457.  
  458.     /*
  459.      * Change the shape and/or position of the window.
  460.      */
  461.  
  462.     if (value_mask & (CWX|CWY|CWWidth|CWHeight)) {
  463.         /* Translate Y coordinates to PM */
  464.         WinSetWindowPos(window, HWND_TOP, winPtr->changes.x,
  465.                         TkOS2WindowHeight((TkOS2Drawable *)w)
  466.                                  - winPtr->changes.height - winPtr->changes.y,
  467.                         winPtr->changes.width, winPtr->changes.height,
  468.                         SWP_MOVE | SWP_SIZE);
  469.     }
  470.  
  471.     /*
  472.      * Change the stacking order of the window.
  473.      */
  474.  
  475.     if (value_mask & CWStackMode) {
  476.     if ((value_mask & CWSibling) && (values->sibling != None)) {
  477.         HWND sibling = TkOS2GetHWND(values->sibling);
  478.  
  479.         /*
  480.          * OS/2 PM doesn't support the Above mode, so we insert the
  481.          * window just below the sibling and then swap them.
  482.          */
  483.  
  484.         if (values->stack_mode == Above) {
  485.                 WinSetWindowPos(window, sibling, 0, 0, 0, 0, SWP_ZORDER);
  486.         insertAfter = window;
  487.         window = sibling;
  488.         } else {
  489.         insertAfter = sibling;
  490.         }
  491.     } else {
  492.         insertAfter = (values->stack_mode == Above) ? HWND_TOP
  493.         : HWND_BOTTOM;
  494.     }
  495.         
  496.     WinSetWindowPos(window, insertAfter, 0, 0, 0, 0, SWP_ZORDER);
  497.     } 
  498. }
  499.  
  500. /*
  501.  *----------------------------------------------------------------------
  502.  *
  503.  * XClearWindow --
  504.  *
  505.  *    Clears the entire window to the current background color.
  506.  *
  507.  * Results:
  508.  *    None.
  509.  *
  510.  * Side effects:
  511.  *    Erases the current contents of the window.
  512.  *
  513.  *----------------------------------------------------------------------
  514.  */
  515.  
  516. void
  517. XClearWindow(display, w)
  518.     Display* display;
  519.     Window w;
  520. {
  521.     RECTL rect;
  522.     LONG oldColor, oldPattern;
  523.     HPAL oldPalette, palette;
  524.     TkWindow *winPtr;
  525.     HWND hwnd = TkOS2GetHWND(w);
  526.     HPS hps = WinGetPS(hwnd);
  527.  
  528.     palette = TkOS2GetPalette(display->screens[0].cmap);
  529.     oldPalette = GpiSelectPalette(hps, palette);
  530.  
  531.     display->request++;
  532.  
  533.     winPtr = TkOS2GetWinPtr(w);
  534.     oldColor = GpiQueryColor(hps);
  535.     oldPattern = GpiQueryPattern(hps);
  536.     GpiSetPattern(hps, PATSYM_SOLID);
  537.     WinQueryWindowRect(hwnd, &rect);
  538.     WinFillRect(hps, &rect, winPtr->atts.background_pixel);
  539.     GpiSetPattern(hps, oldPattern);
  540.     GpiSelectPalette(hps, oldPalette);
  541.     WinReleasePS(hps);
  542. }
  543.  
  544. /*
  545.  *----------------------------------------------------------------------
  546.  *
  547.  * XChangeWindowAttributes --
  548.  *
  549.  *      This function is called when the attributes on a window are
  550.  *      updated.  Since Tk maintains all of the window state, the only
  551.  *      relevant value is the cursor.
  552.  *
  553.  * Results:
  554.  *      None.
  555.  *
  556.  * Side effects:
  557.  *      May cause the mouse position to be updated.
  558.  *
  559.  *----------------------------------------------------------------------
  560.  */
  561.  
  562. void
  563. XChangeWindowAttributes(display, w, valueMask, attributes)
  564.     Display* display;
  565.     Window w;
  566.     unsigned long valueMask;
  567.     XSetWindowAttributes* attributes;
  568. {
  569.     if (valueMask & CWCursor) {
  570.         XDefineCursor(display, w, attributes->cursor);
  571.     }
  572. }
  573.  
  574. /*
  575.  *----------------------------------------------------------------------
  576.  *
  577.  * TkOS2WindowHeight --
  578.  *
  579.  *      Determine the height of an OS/2 drawable (of parent for bitmaps).
  580.  *
  581.  * Results:
  582.  *      Height of drawable.
  583.  *
  584.  * Side effects:
  585.  *      None.
  586.  *
  587.  *----------------------------------------------------------------------
  588.  */
  589.  
  590. LONG
  591. TkOS2WindowHeight(todPtr)
  592.     TkOS2Drawable *todPtr;
  593. {
  594.     SWP pos;
  595.     HWND handle;
  596.     HWND parent;
  597.     BOOL rc;
  598.  
  599.     if (todPtr->type == TOD_BITMAP ) {
  600.         SIZEL sizl;
  601.         /* Bitmap */
  602.         handle = todPtr->bitmap.parent;
  603.         parent = handle;
  604.         rc = GpiQueryBitmapDimension(todPtr->bitmap.handle, &sizl);
  605.         return sizl.cy;
  606.     } else {
  607.         handle = todPtr->window.handle;
  608.         parent = WinQueryWindow(handle, QW_PARENT);
  609.     }
  610.     rc = WinQueryWindowPos(handle, &pos);
  611.     if (rc != TRUE) {
  612.         return 0;
  613.     }
  614.     /* Watch out for frames and/or title bars! */
  615.     if (parent == HWND_DESKTOP) {
  616.         if (TkOS2GetWinPtr(todPtr)->wmInfoPtr->exStyle & FCF_SIZEBORDER) {
  617.             pos.cy -= 2 * ySizeBorder;
  618.         } else if (TkOS2GetWinPtr(todPtr)->wmInfoPtr->exStyle & FCF_DLGBORDER) {
  619.             pos.cy -= 2 * yDlgBorder;
  620.         }
  621.         if (TkOS2GetWinPtr(todPtr)->wmInfoPtr->exStyle & FCF_TITLEBAR) {
  622.             pos.cy -= titleBar;
  623.         }
  624.     }
  625.     return pos.cy;
  626. }
  627.  
  628. /*
  629.  *----------------------------------------------------------------------
  630.  *
  631.  * TkOS2WindowWidth --
  632.  *
  633.  *      Determine the width of an OS/2 drawable (of parent for bitmaps).
  634.  *
  635.  * Results:
  636.  *      Width of drawable.
  637.  *
  638.  * Side effects:
  639.  *      None.
  640.  *
  641.  *----------------------------------------------------------------------
  642.  */
  643.  
  644. LONG
  645. TkOS2WindowWidth(todPtr)
  646.     TkOS2Drawable *todPtr;
  647. {
  648.     SWP pos;
  649.     HWND handle;
  650.     HWND parent;
  651.     BOOL rc;
  652.  
  653.     if (todPtr->type == TOD_BITMAP ) {
  654.         SIZEL sizl;
  655.  
  656.         /* Bitmap */
  657.         handle = todPtr->bitmap.parent;
  658.         parent = handle;
  659.         rc = GpiQueryBitmapDimension(todPtr->bitmap.handle, &sizl);
  660.         return sizl.cx;
  661.     } else {
  662.         handle = todPtr->window.handle;
  663.         parent = WinQueryWindow(handle, QW_PARENT);
  664.     }
  665.     rc = WinQueryWindowPos(handle, &pos);
  666.     if (rc != TRUE) return 0;
  667.     /* Watch out for frames and/or title bars! */
  668.     if (parent == HWND_DESKTOP) {
  669.         if (TkOS2GetWinPtr(todPtr)->wmInfoPtr->exStyle & FCF_SIZEBORDER) {
  670.             pos.cx -= 2 * xSizeBorder;
  671.         } else if (TkOS2GetWinPtr(todPtr)->wmInfoPtr->exStyle & FCF_DLGBORDER) {
  672.             pos.cx -= 2 * xDlgBorder;
  673.         } else if (TkOS2GetWinPtr(todPtr)->wmInfoPtr->exStyle & FCF_BORDER) {
  674.                 pos.cx -= 2 * xBorder;
  675.         }
  676.     }
  677.     return pos.cx;
  678. }
  679.