home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume3 / awm2 / part02 / NewIconify.c < prev   
Encoding:
C/C++ Source or Header  |  1989-02-17  |  10.7 KB  |  380 lines

  1.  
  2.  
  3.  
  4. #ifndef lint
  5. static char *rcsid_NewIconify_c = "$Header: /usr/graph2/X11.3/contrib/windowmgrs/awm/RCS/NewIconify.c,v 1.2 89/02/07 21:23:10 jkh Exp $";
  6. #endif  lint
  7.  
  8. #include "X11/copyright.h"
  9. /*
  10.  *
  11.  * Copyright 1987, 1988 by Ardent Computer Corporation, Sunnyvale, Ca.
  12.  *
  13.  * Copyright 1987 by Jordan Hubbard.
  14.  *
  15.  *
  16.  *                         All Rights Reserved
  17.  *
  18.  * Permission to use, copy, modify, and distribute this software and its
  19.  * documentation for any purpose and without fee is hereby granted,
  20.  * provided that the above copyright notice appear in all copies and that
  21.  * both that copyright notice and this permission notice appear in
  22.  * supporting documentation, and that the name of Ardent Computer
  23.  * Corporation or Jordan Hubbard not be used in advertising or publicity
  24.  * pertaining to distribution of the software without specific, written
  25.  * prior permission.
  26.  *
  27.  */
  28.  
  29. /*
  30.  * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
  31.  *
  32.  *                         All Rights Reserved
  33.  *
  34.  * Permission to use, copy, modify, and distribute this software and its
  35.  * documentation for any purpose and without fee is hereby granted,
  36.  * provided that the above copyright notice appear in all copies and that
  37.  * both that copyright notice and this permission notice appear in
  38.  * supporting documentation, and that the name of Digital Equipment
  39.  * Corporation not be used in advertising or publicity pertaining to
  40.  * distribution of the software without specific, written prior permission.
  41.  *
  42.  *
  43.  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  44.  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  45.  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  46.  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  47.  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  48.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  49.  * SOFTWARE.
  50.  */
  51.  
  52. /*
  53.  * MODIFICATION HISTORY
  54.  *
  55.  * 000 -- M. Gancarz, DEC Ultrix Engineering Group
  56.  * 001 -- Loretta Guarino Reid, DEC Ultrix Engineering Group,
  57.  *  Western Software Lab. Port to X11.
  58.  */
  59.  
  60. #include "awm.h"
  61.  
  62. /*ARGSUSED*/
  63. Boolean NewIconify(window, mask, button, x, y)
  64. Window window;                          /* Event window. */
  65. int mask;                               /* Button/key mask. */
  66. int button;                             /* Button event detail. */
  67. int x, y;                               /* Event mouse position. */
  68. {
  69.      XWindowAttributes fromInfo;    /* from window info. */
  70.      XWindowAttributes toInfo;        /* to window info. */
  71.      Window from, to;
  72.      int mse_x, mse_y;            /* Mouse X and Y coordinates. */
  73.      int new_x, new_y;            /* To U. L. X and Y coordinates. */
  74.      int new_w, new_h;            /* To width and height. */
  75.      int bdw;                /* border width */
  76.      int prev_x;            /* Previous event window X location. */
  77.      int prev_y;            /* Previous event window Y location. */
  78.      int cur_x;                /* Current event window X location. */
  79.      int cur_y;                /* Current event window Y location. */
  80.      int root_x;            /* Root window X location. */
  81.      int root_y;            /* Root window Y location. */
  82.      int ulx, uly;            /* Event window upper left X and Y. */
  83.      int lrx, lry;            /* Event window lower right X and Y. */
  84.      int num_vectors;            /* Number of vectors in box. */
  85.      int status;                /* Routine call return status. */
  86.      int ptrmask;            /* pointer query state. */
  87.      Window root;            /* Mouse root window. */
  88.      Window sub_win;            /* Mouse position sub-window. */
  89.      XEvent button_event;        /* Button event packet. */
  90.      XSegment box[MAX_BOX_VECTORS];    /* Box vertex buffer. */
  91.      XSegment zap[MAX_ZAP_VECTORS];    /* Zap effect vertex buffer. */
  92.      int (*storegrid_func)();        /* Function to use for grid */
  93.      int (*storebox_func)();        /* Function to use for box */
  94.      AwmInfoPtr awi;
  95.      extern Window MakeIcon();
  96.      extern void ungrab_pointer();
  97.      extern void grab_pointer();
  98.      
  99.      Entry("NewIconify")
  100.       
  101.      /*
  102.       * Do not lower or iconify the root window.
  103.       */
  104.      if (window == RootWindow(dpy, scr))
  105.       Leave(FALSE)
  106.      
  107.      /*
  108.       * Change the cursor to the icon cursor.
  109.       */
  110.      grab_pointer();
  111.      
  112.      /*
  113.       * Clear the vector buffers.
  114.       */
  115.      bzero(box, sizeof(box));
  116.      if (Zap)
  117.       bzero(zap, sizeof(zap));
  118.      
  119.      /*
  120.       * Get info on the event window.
  121.       */
  122.      awi = GetAwmInfo(window);
  123.      if (!awi)
  124.       Leave(FALSE)
  125.      /*
  126.       * Are we iconifying or de-iconifying?
  127.       */
  128.      if (awi->state & ST_ICON) {
  129.           from = awi->icon;
  130.           to = (awi->frame) ? awi->frame : awi->client;
  131.      }
  132.      else if (awi->state & ST_WINDOW) {
  133.           from = (awi->frame) ? awi->frame : awi->client;
  134.           to = (awi->icon) ? awi->icon : MakeIcon(window, x, y, FALSE);
  135.      }
  136.      else {
  137.           fprintf(stderr, "NewIconify: Window %x has unknown state '%x'\n",
  138.          awi->client, awi->state);
  139.       Leave(FALSE)
  140.      }
  141.      status = XGetWindowAttributes(dpy, from, &fromInfo);
  142.      if (status == FAILURE)
  143.           Leave(FALSE)
  144.  
  145.      status = XGetWindowAttributes(dpy, to, &toInfo);
  146.      if (status == FAILURE)
  147.           Leave(FALSE)
  148.  
  149.      /*
  150.       * Initialize the movement variables.
  151.       */
  152.      ulx = x - (toInfo.width >> 1) - toInfo.border_width;
  153.      uly = y - (toInfo.height >> 1) - toInfo.border_width;
  154.      lrx = x + (toInfo.width >> 1) + toInfo.border_width - 1;
  155.      lry = y + (toInfo.height >> 1) + toInfo.border_width - 1;
  156.      prev_x = x;
  157.      prev_y = y;
  158.  
  159.      if (awi->frame && awi->state & ST_ICON) {
  160.       storegrid_func = StoreTitleGridBox;
  161.       storebox_func = StoreTitleBox;
  162.      }
  163.      else {
  164.       storegrid_func = StoreGridBox;
  165.       storebox_func = StoreBox;
  166.      }
  167.      
  168.      /*
  169.       * Store the box.
  170.       */
  171.      if (Grid)
  172.       num_vectors = storegrid_func(box, ulx, uly, lrx, lry);
  173.      else
  174.       num_vectors = storebox_func(box, ulx, uly, lrx, lry);
  175.      
  176.      /*
  177.       * Freeze the server, if requested by the user.
  178.       * This results in a solid box instead of a flickering one.
  179.       */
  180.      if (Freeze)
  181.       XGrabServer(dpy);
  182.      
  183.      /*
  184.       * Process any outstanding events before drawing the box.
  185.       */
  186.      while (QLength(dpy) > 0) {
  187.       XPeekEvent(dpy, &button_event);
  188.       if (((XAnyEvent *)&button_event)->window == RootWindow(dpy, scr))
  189.            break;
  190.       GetButton(&button_event);
  191.      }
  192.      
  193.      /*
  194.       * Draw the box.
  195.       */
  196.      DrawBox();
  197.      if (Freeze)
  198.       Frozen = window;
  199.      
  200.      /*
  201.       * We spin our wheels here looking for mouse movement or a change
  202.       * in the status of the buttons.
  203.       */
  204.      Snatched = TRUE;
  205.      while (TRUE) {
  206.       
  207.       /*
  208.        * Check to see if we have a change in mouse button status.
  209.        * This is how we get out of this "while" loop.
  210.        */
  211.       if (XPending(dpy) && !ProcessRequests(box, num_vectors) &&
  212.           GetButton(&button_event)) {
  213.            /*
  214.         * Process the pending events, this sequence is the only
  215.         * way out of the loop and the routine.
  216.         */
  217.            
  218.            if ((button_event.type != ButtonPress) && 
  219.            (button_event.type != ButtonRelease)) {
  220.             continue; /* spurious menu event... */
  221.            }
  222.            
  223.            /*
  224.         * If we froze the server, then erase the last lines drawn.
  225.         */
  226.            if (Freeze) {
  227.             DrawBox();
  228.             Frozen = (Window)0;
  229.             XUngrabServer(dpy);
  230.            }
  231.            
  232.            /*
  233.         * Save the mouse cursor location.
  234.         */
  235.            if (button_event.type == ButtonPress ||
  236.            button_event.type == ButtonRelease) {
  237.             mse_x = ((XButtonEvent *)&button_event)->x;
  238.             mse_y = ((XButtonEvent *)&button_event)->y;
  239.             break;
  240.            }
  241.       }
  242.       else {
  243.            /*
  244.         * Continue to track the mouse until we get a change
  245.         * in button status.
  246.         */
  247.            XQueryPointer(dpy, RootWindow(dpy, scr), 
  248.                  &root, &sub_win, &root_x, &root_y, &cur_x,
  249.                  &cur_y, &ptrmask);
  250.            
  251.            /*
  252.         * If the mouse has moved, then make sure the box follows it.
  253.         */
  254.            if ((cur_x != prev_x) || (cur_y != prev_y)) {
  255.             
  256.             /*
  257.              * If we've frozen the server, then erase the old box first!
  258.              */
  259.             if (Freeze)
  260.              DrawBox();
  261.             
  262.             /*
  263.              * Set the new box position.
  264.              */
  265.             ulx += cur_x - prev_x;
  266.             uly += cur_y - prev_y;
  267.             lrx += cur_x - prev_x;
  268.             lry += cur_y - prev_y;
  269.             
  270.             /*
  271.              * Calculate the vectors for the new box.
  272.              */
  273.             
  274.             if (Grid)
  275.              num_vectors = storegrid_func(box, ulx, uly, lrx,
  276.                              lry);
  277.             else
  278.              num_vectors = storebox_func(box, ulx, uly, lrx, lry);
  279.             
  280.             /*
  281.              * Draw the new box.
  282.              */
  283.             if (Freeze)
  284.              DrawBox();
  285.            }
  286.            
  287.            /*
  288.         * Save the old box position.
  289.         */
  290.            prev_x = cur_x;
  291.            prev_y = cur_y;
  292.            
  293.            /*
  294.         * If server is not frozen, then draw the "flicker" box.
  295.         */
  296.            if (!Freeze) {
  297.             DrawBox();
  298.             DrawBox();
  299.            }
  300.       }
  301.      }
  302.      Snatched = FALSE;
  303.      /*
  304.       * If the button is not a button release of the same button pressed,
  305.       * then abort the operation.
  306.       */
  307.      if ((button_event.type != ButtonRelease) ||
  308.      (((XButtonReleasedEvent *)&button_event)->button != button)) {
  309.       ResetCursor(button);
  310.       ungrab_pointer();
  311.       Leave(TRUE)
  312.      }
  313.      
  314.      /*
  315.       * If we are here we have committed to iconifying/deiconifying.
  316.       */
  317.      
  318.      /*
  319.       * Determine the coordinates of the icon or window;
  320.       * normalize the window or icon coordinates if the user so desires.
  321.       */
  322.      new_w = toInfo.width;
  323.      new_h = toInfo.height;
  324.      bdw = toInfo.border_width;
  325.      new_x = mse_x - (new_w >> 1) - bdw;
  326.      new_y = mse_y - (new_h >> 1) - bdw;
  327.      if ((NIcon && awi->state & ST_WINDOW) || (NWindow && awi->state & ST_ICON)) {
  328.       if (new_x < 0) new_x = 0;
  329.       if (new_y < 0) new_y = 0;
  330.       if ((new_x - 1 + new_w + (bdw << 1)) > ScreenWidth) {
  331.            new_x = ScreenWidth - new_w - (bdw << 1) + 1;
  332.       }
  333.       if ((new_y - 1 + new_h + (bdw << 1)) > ScreenHeight) {
  334.            new_y = ScreenHeight - new_h - (bdw << 1) + 1;
  335.       }
  336.      }
  337.      if (awi->state & ST_ICON) {
  338.       awi->state ^= ST_ICON;
  339.       awi->state |= (ST_WINDOW | ST_PLACED);
  340.       if (!awi->frame)
  341.            XRemoveFromSaveSet(dpy, awi->client);
  342.      }
  343.      else if (awi->state & ST_WINDOW) {
  344.       awi->state ^= ST_WINDOW;
  345.       awi->state |= ST_ICON;
  346.       XAddToSaveSet(dpy, awi->client);
  347.      }
  348.      else
  349.       fprintf(stderr, "NewIconify: Window state got trashed!\n");
  350.      
  351.      /*
  352.       * Move the window into place.
  353.       */
  354.      XMoveWindow(dpy, to, new_x, new_y);
  355.  
  356.      /*
  357.       * Map the icon window.
  358.       */
  359.      XMapRaised(dpy, to);
  360.      if (Zap) {
  361.       num_vectors = StoreZap(zap,
  362.                  fromInfo.x,
  363.                  fromInfo.y,
  364.                  fromInfo.x + fromInfo.width
  365.                  + (fromInfo.border_width << 1),
  366.                  fromInfo.y + fromInfo.height
  367.                  + (fromInfo.border_width << 1),
  368.                  ulx, uly, lrx, lry);
  369.       DrawZap();
  370.       DrawZap();
  371.      }
  372.      /*
  373.       * Unmap the event window.
  374.       */
  375.      XUnmapWindow(dpy, from);
  376.      XFlush(dpy);
  377.      ungrab_pointer();
  378.      Leave(TRUE)
  379. }
  380.