home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume15 / twm / part02 / resize.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-06-12  |  10.3 KB  |  384 lines

  1. /*****************************************************************************/
  2. /**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
  3. /**                          Salt Lake City, Utah                           **/
  4. /**                                                                         **/
  5. /**                           All Rights Reserved                           **/
  6. /**                                                                         **/
  7. /**    Permission to use, copy, modify, and distribute this software and    **/
  8. /**    its documentation  for  any  purpose  and  without  fee is hereby    **/
  9. /**    granted, provided that the above copyright notice appear  in  all    **/
  10. /**    copies and that both  that  copyright  notice  and  this  permis-    **/
  11. /**    sion  notice appear in supporting  documentation,  and  that  the    **/
  12. /**    name  of Evans & Sutherland  not be used in advertising or publi-    **/
  13. /**    city pertaining to distribution  of the software without  specif-    **/
  14. /**    ic, written prior permission.                                        **/
  15. /**                                                                         **/
  16. /**    EVANS  & SUTHERLAND  DISCLAIMS  ALL  WARRANTIES  WITH  REGARD  TO    **/
  17. /**    THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILI-    **/
  18. /**    TY AND FITNESS, IN NO EVENT SHALL EVANS &  SUTHERLAND  BE  LIABLE    **/
  19. /**    FOR  ANY  SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY  DAM-    **/
  20. /**    AGES  WHATSOEVER RESULTING FROM  LOSS OF USE,  DATA  OR  PROFITS,    **/
  21. /**    WHETHER   IN  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS    **/
  22. /**    ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE  OR PER-    **/
  23. /**    FORMANCE OF THIS SOFTWARE.                                           **/
  24. /*****************************************************************************/
  25.  
  26. /***********************************************************************
  27.  *
  28.  * $Header: resize.c,v 1.6 88/04/15 07:09:35 tlastran Exp $
  29.  *
  30.  * window resizing borrowed from the "wm" window manager
  31.  *
  32.  * 11-Dec-87 Thomas E. LaStrange        File created
  33.  *
  34.  ***********************************************************************/
  35.  
  36. #ifndef lint
  37. static char RCSinfo[]=
  38. "$Header: resize.c,v 1.6 88/04/15 07:09:35 tlastran Exp $";
  39. #endif
  40.  
  41. #include <stdio.h>
  42. #include "twm.h"
  43. #include "util.h"
  44. #include "resize.h"
  45. #include "resize.bm"
  46. #include "focus.bm"
  47.  
  48. #define MINHEIGHT 32
  49. #define MINWIDTH 60
  50.  
  51. static int dragx;    /* all these variables are used */
  52. static int dragy;    /* in resize operations */
  53. static int dragWidth;
  54. static int dragHeight;
  55.  
  56. static int origx;
  57. static int origy;
  58. static int origWidth;
  59. static int origHeight;
  60.  
  61. static int clampTop;
  62. static int clampBottom;
  63. static int clampLeft;
  64. static int clampRight;
  65.  
  66. /***********************************************************************
  67.  *
  68.  *  Procedure:
  69.  *    StartResize - begin a window resize operation
  70.  *
  71.  *  Inputs:
  72.  *    ev    - the event structure (button press)
  73.  *    tmp_win    - the TwmWindow pointer
  74.  *
  75.  ***********************************************************************
  76.  */
  77.  
  78. void
  79. StartResize(ev, tmp_win)
  80. XEvent ev;
  81. TwmWindow *tmp_win;
  82. {
  83.     Window      junkRoot;
  84.     int         junkbw, junkDepth;
  85.  
  86.     XMapRaised(dpy, SizeWindow);
  87.     ResizeWindow = tmp_win->frame;
  88.     XGrabServer(dpy);
  89.     XGrabPointer(dpy, ev.xbutton.root, True,
  90.     ButtonReleaseMask | PointerMotionMask,
  91.     GrabModeAsync, GrabModeSync,
  92.     Root, MoveCursor, CurrentTime);
  93.  
  94.     XGetGeometry(dpy, (Drawable) tmp_win->frame, &junkRoot,
  95.     &dragx, &dragy, &dragWidth, &dragHeight, &junkbw,
  96.          &junkDepth);
  97.     dragx += BorderWidth;
  98.     dragy += BorderWidth;
  99.     origx = dragx;
  100.     origy = dragy;
  101.     origWidth = dragWidth;
  102.     origHeight = dragHeight;
  103.     clampTop = clampBottom = clampLeft = clampRight = 0;
  104.  
  105.     DisplaySize(tmp_win, origWidth, origHeight);
  106. }
  107.  
  108. /***********************************************************************
  109.  *
  110.  *  Procedure:
  111.  *    DoResize - move the rubberband around.  This is called for
  112.  *           each motion event when we are resizing 
  113.  *
  114.  *  Inputs:
  115.  *    ev    - the event structure for the motion event
  116.  *    tmp_win    - the current twm window
  117.  *
  118.  ***********************************************************************
  119.  */
  120.  
  121. void
  122. DoResize(ev, tmp_win)
  123. XEvent ev;
  124. TwmWindow *tmp_win;
  125. {
  126.     int action;
  127.  
  128.     action = 0;
  129.  
  130.     if (clampTop) {
  131.     int         delta = ev.xmotion.y_root - dragy;
  132.     if (dragHeight - delta < MINHEIGHT) {
  133.         delta = dragHeight - MINHEIGHT;
  134.         clampTop = 0;
  135.     }
  136.     dragy += delta;
  137.     dragHeight -= delta;
  138.     action = 1;
  139.     }
  140.     else if (ev.xmotion.y_root <= dragy/* ||
  141.          ev.xmotion.y_root == findRootInfo(root)->rooty*/) {
  142.     dragy = ev.xmotion.y_root;
  143.     dragHeight = origy + origHeight -
  144.         ev.xmotion.y_root;
  145.     clampBottom = 0;
  146.     clampTop = 1;
  147.     action = 1;
  148.     }
  149.     if (clampLeft) {
  150.     int         delta = ev.xmotion.x_root - dragx;
  151.     if (dragWidth - delta < MINWIDTH) {
  152.         delta = dragWidth - MINWIDTH;
  153.         clampLeft = 0;
  154.     }
  155.     dragx += delta;
  156.     dragWidth -= delta;
  157.     action = 1;
  158.     }
  159.     else if (ev.xmotion.x_root <= dragx/* ||
  160.          ev.xmotion.x_root == findRootInfo(root)->rootx*/) {
  161.     dragx = ev.xmotion.x_root;
  162.     dragWidth = origx + origWidth -
  163.         ev.xmotion.x_root;
  164.     clampRight = 0;
  165.     clampLeft = 1;
  166.     action = 1;
  167.     }
  168.     if (clampBottom) {
  169.     int         delta = ev.xmotion.y_root - dragy - dragHeight;
  170.     if (dragHeight + delta < MINHEIGHT) {
  171.         delta = MINHEIGHT - dragHeight;
  172.         clampBottom = 0;
  173.     }
  174.     dragHeight += delta;
  175.     action = 1;
  176.     }
  177.     else if (ev.xmotion.y_root >= dragy + dragHeight - 1/* ||
  178.        ev.xmotion.y_root == findRootInfo(root)->rooty
  179.        + findRootInfo(root)->rootheight - 1*/) {
  180.     dragy = origy;
  181.     dragHeight = 1 + ev.xmotion.y_root - dragy;
  182.     clampTop = 0;
  183.     clampBottom = 1;
  184.     action = 1;
  185.     }
  186.     if (clampRight) {
  187.     int         delta = ev.xmotion.x_root - dragx - dragWidth;
  188.     if (dragWidth + delta < MINWIDTH) {
  189.         delta = MINWIDTH - dragWidth;
  190.         clampRight = 0;
  191.     }
  192.     dragWidth += delta;
  193.     action = 1;
  194.     }
  195.     else if (ev.xmotion.x_root >= dragx + dragWidth - 1/* ||
  196.          ev.xmotion.x_root == findRootInfo(root)->rootx +
  197.          findRootInfo(root)->rootwidth - 1*/) {
  198.     dragx = origx;
  199.     dragWidth = 1 + ev.xmotion.x_root - origx;
  200.     clampLeft = 0;
  201.     clampRight = 1;
  202.     action = 1;
  203.     }
  204.     if (action) {
  205.     MoveOutline(Root,
  206.             dragx - BorderWidth,
  207.             dragy - BorderWidth,
  208.             dragWidth + 2 * BorderWidth,
  209.             dragHeight + 2 * BorderWidth);
  210.     }
  211.  
  212.     DisplaySize(tmp_win, dragWidth, dragHeight);
  213. }
  214.  
  215. /***********************************************************************
  216.  *
  217.  *  Procedure:
  218.  *    DisplaySize - display the size in the dimensions window
  219.  *
  220.  *  Inputs:
  221.  *    tmp_win - the current twm window 
  222.  *    width    - the width of the rubber band
  223.  *    height    - the height of the rubber band
  224.  *
  225.  ***********************************************************************
  226.  */
  227.  
  228. void
  229. DisplaySize(tmp_win, width, height)
  230. TwmWindow *tmp_win;
  231. int width;
  232. int height;
  233. {
  234.     char str[100];
  235.     int dwidth;
  236.     int dheight;
  237.  
  238.     dwidth = width;
  239.     dheight = height - tmp_win->title_height;
  240.  
  241.     if (tmp_win->hints.flags&PMinSize && tmp_win->hints.flags & PResizeInc)
  242.     {
  243.     dwidth -= tmp_win->hints.min_width;
  244.     dheight -= tmp_win->hints.min_height;
  245.     }
  246.  
  247.     if (tmp_win->hints.flags & PResizeInc)
  248.     {
  249.     dwidth /= tmp_win->hints.width_inc;
  250.     dheight /= tmp_win->hints.height_inc;
  251.     }
  252.  
  253.     sprintf(str, "%d x %d", dwidth, dheight);
  254.  
  255.     width = XTextWidth(SizeFont, str, strlen(str)) + 20,
  256.     strcat(str, "        ");
  257.     XResizeWindow(dpy, SizeWindow, width, SizeFontHeight + 4);
  258.     XRaiseWindow(dpy, SizeWindow);
  259.     XDrawImageString(dpy, SizeWindow, SizeNormalGC,
  260.     10, 2 + SizeFont->ascent, str, strlen(str));
  261. }
  262.  
  263. /***********************************************************************
  264.  *
  265.  *  Procedure:
  266.  *    EndResize - finish the resize operation
  267.  *
  268.  ***********************************************************************
  269.  */
  270.  
  271. void
  272. EndResize()
  273. {
  274.     TwmWindow *tmp_win;
  275.  
  276.     XUnmapWindow(dpy, SizeWindow);
  277.     MoveOutline(Root, 0, 0, 0, 0);
  278.  
  279.     XFindContext(dpy, ResizeWindow, TwmContext, &tmp_win);
  280.  
  281.     dragHeight = dragHeight - tmp_win->title_height;
  282.  
  283.     if (tmp_win->hints.flags&PMinSize && tmp_win->hints.flags & PResizeInc)
  284.     {
  285.     dragWidth -= tmp_win->hints.min_width;
  286.     dragHeight -= tmp_win->hints.min_height;
  287.     }
  288.  
  289.     if (tmp_win->hints.flags & PResizeInc)
  290.     {
  291.     dragWidth /= tmp_win->hints.width_inc;
  292.     dragHeight /= tmp_win->hints.height_inc;
  293.  
  294.     dragWidth *= tmp_win->hints.width_inc;
  295.     dragHeight *= tmp_win->hints.height_inc;
  296.     }
  297.  
  298.     if (tmp_win->hints.flags&PMinSize && tmp_win->hints.flags & PResizeInc)
  299.     {
  300.     dragWidth += tmp_win->hints.min_width;
  301.     dragHeight += tmp_win->hints.min_height;
  302.     }
  303.  
  304.     dragHeight = dragHeight + tmp_win->title_height;
  305.  
  306.     SetupWindow(tmp_win,
  307.     dragx - BorderWidth,
  308.     dragy - BorderWidth,
  309.     dragWidth, dragHeight);
  310.  
  311.     XRaiseWindow(dpy, ResizeWindow);
  312.     ResizeWindow = NULL;
  313. }
  314.  
  315. /***********************************************************************
  316.  *
  317.  *  Procedure:
  318.  *    SetupWindow - set window sizes, this was called from either
  319.  *        AddWindow, EndResize, or HandleConfigureNotify.
  320.  *
  321.  *  Inputs:
  322.  *    tmp_win    - the TwmWindow pointer
  323.  *    x    - the x coordinate of the frame window
  324.  *    y    - the y coordinate of the frame window
  325.  *    w    - the width of the frame window
  326.  *    h    - the height of the frame window
  327.  *
  328.  ***********************************************************************
  329.  */
  330.  
  331. void
  332. SetupWindow(tmp_win, x, y, w, h)
  333. TwmWindow *tmp_win;
  334. int x, y, w, h;
  335. {
  336.     XWindowChanges xwc;
  337.     unsigned int   xwcm;
  338.     int width;
  339.  
  340.     tmp_win->frame_x = x;
  341.     tmp_win->frame_y = y;
  342.  
  343.     xwcm = CWX | CWY | CWWidth | CWHeight;
  344.  
  345.     xwc.x = x;
  346.     xwc.y = y;
  347.     xwc.width = w;
  348.     xwc.height = h;
  349.     XConfigureWindow(dpy, tmp_win->frame, xwcm, &xwc);
  350.  
  351.     xwcm = CWWidth;
  352.     XConfigureWindow(dpy, tmp_win->title_w, xwcm, &xwc);
  353.  
  354.     xwcm |= CWX | CWY | CWHeight;
  355.     xwc.x = 0;
  356.     xwc.y = tmp_win->title_height;
  357.     xwc.height = h - tmp_win->title_height;
  358.     XConfigureWindow(dpy, tmp_win->w, xwcm, &xwc);
  359.  
  360.     xwcm = CWX;
  361.     xwc.x = w - resize_width - 1;
  362.     XConfigureWindow(dpy, tmp_win->resize_w, xwcm, &xwc);
  363.  
  364.     xwc.x = w - resize_width - focus_width - 3;
  365.     XConfigureWindow(dpy, tmp_win->focus_w, xwcm, &xwc);
  366.  
  367.     width = w - TitleBarX - focus_width - resize_width - 5 -
  368.     tmp_win->name_width - 10;
  369.  
  370.     if (width <= 0)
  371.     {
  372.     xwc.x = 3000;
  373.     xwc.width = 1;
  374.     }
  375.     else
  376.     {
  377.     xwc.x = TitleBarX + tmp_win->name_width + 6;
  378.     xwc.width = width;
  379.     }
  380.  
  381.     xwcm = CWX | CWWidth;
  382.     XConfigureWindow(dpy, tmp_win->hilite_w, xwcm, &xwc);
  383. }
  384.