home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume3 / awm2 / part06 / Neaten.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-20  |  14.5 KB  |  537 lines

  1.  
  2.  
  3.  
  4. #ifndef lint
  5. static char *rcsid_Neaten_c = "$Header: /usr/graph2/X11.3/contrib/windowmgrs/awm/RCS/Neaten.c,v 1.2 89/02/07 21:23:05 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.  * MODIFICATION HISTORY
  31.  *
  32.  * 002 -- Jordan Hubbard, Ardent Computer.
  33.  *  Changes to work with awm, specifically reparented windows.
  34.  */
  35.  
  36. #include "awm.h"
  37.      
  38. #ifdef NEATEN
  39.      
  40. #include "X11/Xutil.h"
  41. #include "X11/cursorfont.h"
  42. #include "neaten.ext.h"
  43.  
  44. static void GetIconHints();
  45. static void GetName();
  46. extern Boolean IsIcon();
  47. extern int neaten_debug_level;
  48.  
  49. #define TOP_LEVEL (awi->frame ? awi->frame : awi->client)
  50.  
  51. /*ARGSUSED*/
  52. Boolean Neaten(window, mask, button, x, y)
  53. Window window;                          /* Event window. */
  54. int mask;                               /* Button/key mask. */
  55. int button;                               /* Button event detail. */
  56. int x, y;                               /* Event mouse position. */
  57. {
  58.      Window junk_window;
  59.      Window w;
  60.      Window icon_window;
  61.      Window stacktop;
  62.      Window *children;
  63.      XWindowAttributes attrs;
  64.      XSizeHints hints;
  65.      XWindowChanges  wc;
  66.      Status rstatus;
  67.      char name[50];
  68.      int junk;
  69.      int root_x, root_y;
  70.      int root_width, root_height;
  71.      int icon_x, icon_y;
  72.      int icon_width, icon_height;
  73.      int icon_border;
  74.      int window_x, window_y;
  75.      int window_width, window_height;
  76.      int rval;
  77.      int ix;
  78.      int iconic;
  79.      int tiled;
  80.      int adjustment;
  81.      int priority;
  82.      int priority_increment;
  83.      unsigned int nchildren;
  84.      unsigned int mapped_children = 0;
  85.      unsigned int opened_children = 0;
  86.      unsigned int  wcmask;
  87.      Placement primary;
  88.      Placement secondary;
  89.      Boolean is_iconic;
  90.      Cursor rtlcursor;
  91.      XFontStruct *font;
  92.      GC gc;
  93.      AwmInfoPtr awi;
  94.  
  95.      Entry("Neaten")
  96.  
  97.      font = (XFontStruct *) XLoadQueryFont(dpy, "cursor");
  98.      gc = DefaultGC(dpy, scr);
  99.      XSetFont(dpy, gc, font->fid);
  100.      
  101.      rtlcursor = XCreateFontCursor(dpy, XC_rtl_logo);
  102.      
  103.      XGrabPointer(dpy, RootWindow(dpy, scr), FALSE, (unsigned int) 0,
  104.           GrabModeAsync, GrabModeAsync,
  105.           (Window) None, rtlcursor, CurrentTime);
  106.      
  107.      if (AbsMinWidth == 0)
  108.       AbsMinWidth = DEFAULT_ABS_MIN;
  109.      if (AbsMinHeight == 0)
  110.       AbsMinHeight = DEFAULT_ABS_MIN;
  111.      
  112.      XGetGeometry(dpy, RootWindow(dpy, scr), &junk_window,
  113.           &root_x, &root_y,
  114.           &root_width, &root_height,
  115.           &junk, &junk);
  116.      
  117.      Neaten_Initialize(root_width+SEPARATION,
  118.                root_height+SEPARATION,
  119.                AbsMinWidth, AbsMinHeight);
  120.      
  121.      if (strcmp(PrimaryIconPlacement, "Closest") == 0)
  122.       primary = Place_Closest;
  123.      else if (strcmp(PrimaryIconPlacement, "Top") == 0)
  124.       primary = Place_Top;
  125.      else if (strcmp(PrimaryIconPlacement, "Bottom") == 0)
  126.       primary = Place_Bottom;
  127.      else if (strcmp(PrimaryIconPlacement, "Left") == 0)
  128.       primary = Place_Left;
  129.      else if (strcmp(PrimaryIconPlacement, "Right") == 0)
  130.       primary = Place_Right;
  131.      else
  132.       primary = Place_Top;
  133.      
  134.      if (strcmp(SecondaryIconPlacement, "Closest") == 0)
  135.       secondary = Place_Closest;
  136.      else if (strcmp(SecondaryIconPlacement, "Top") == 0)
  137.       secondary = Place_Top;
  138.      else if (strcmp(SecondaryIconPlacement, "Bottom") == 0)
  139.       secondary = Place_Bottom;
  140.      else if (strcmp(SecondaryIconPlacement, "Left") == 0)
  141.       secondary = Place_Left;
  142.      else if (strcmp(SecondaryIconPlacement, "Right") == 0)
  143.       secondary = Place_Right;
  144.      else if (strcmp(SecondaryIconPlacement, "Center") == 0)
  145.       secondary = Place_Center;
  146.      else
  147.       secondary = Place_Left;
  148.      
  149.      Neaten_Icon_Placement(primary, secondary);
  150.      
  151.      if (XQueryTree(dpy, RootWindow(dpy, scr), &junk_window,
  152.             &junk_window, &children, &nchildren))
  153.      {
  154.       for (ix = 0; ix < nchildren; ix++)
  155.       {
  156.            XGetWindowAttributes(dpy, children[ix], &attrs);        
  157.            
  158.            if ((attrs.map_state != IsUnmapped) &&
  159.            (attrs.override_redirect == False) &&
  160.            (awi = GetAwmInfo(children[ix])))
  161.            {
  162.             w = children[ix];
  163.             if (w != TOP_LEVEL && w != awi->icon)
  164.              continue;
  165.             mapped_children++;
  166.             
  167.             is_iconic = IsIcon(w, (Window *) NULL);
  168.             
  169.             if (is_iconic == TRUE)
  170.             {
  171.              window_x = window_y =
  172.                   window_width = window_height = 0;
  173.              icon_x = attrs.x;
  174.              icon_y = attrs.y;
  175.              icon_width = attrs.width;
  176.              icon_height = attrs.height;
  177.              
  178.              adjustment = SEPARATION;
  179.              icon_width += adjustment;
  180.              icon_height += adjustment;
  181.             }
  182.             else
  183.             {
  184.              window_x = attrs.x;
  185.              window_y = attrs.y;
  186.              window_width = attrs.width;
  187.              window_height = attrs.height;
  188.              
  189.              window_x -= attrs.border_width;
  190.              window_y -= attrs.border_width;
  191.              
  192.              adjustment = (2 * attrs.border_width) + SEPARATION;
  193.              window_width += adjustment;
  194.              window_height += adjustment;
  195.              
  196.              GetIconHints(w, &icon_x, &icon_y,
  197.                       &icon_width, &icon_height, &icon_border);
  198.              
  199.              icon_x -= icon_border;
  200.              icon_y -= icon_border;
  201.              icon_width += (2 * icon_border) + SEPARATION;
  202.              icon_height += (2 * icon_border) + SEPARATION;
  203.              
  204.              opened_children++;
  205.              stacktop = TOP_LEVEL;
  206.             }
  207.             
  208.             GetName(w, name);
  209.             if(neaten_debug_level)
  210.             {
  211.              printf("%s\ticonic = %s\n",
  212.                 name, (is_iconic ? "TRUE" : "FALSE"));
  213.              printf("\ticon: x = %d y = %d width = %d height = %d\n",
  214.                 icon_x, icon_y, icon_width, icon_height);
  215.              if (is_iconic != TRUE)
  216.                   printf("\twindow: x = %d y = %d width = %d height = %d\n",
  217.                      window_x, window_y, window_width,
  218.                      window_height);
  219.             }
  220.             
  221.             Neaten_Identify((int) w, is_iconic,
  222.                     NEATEN_TRUE, NEATEN_FALSE,
  223.                     window_x, window_y,
  224.                     window_width, window_height,
  225.                     NEATEN_TRUE, NEATEN_FALSE,
  226.                     icon_x, icon_y,
  227.                     icon_width, icon_height,
  228.                     (unsigned long) adjustment);
  229.             
  230.             rstatus = XGetNormalHints(dpy, w, &hints);
  231.             if (rstatus != (Status) 0 && is_iconic != TRUE)
  232.             {
  233.              if (hints.flags & PMinSize)
  234.              {
  235.                   rval = Neaten_Set_Min((int) w,
  236.                             hints.min_width+adjustment,
  237.                             hints.min_height+adjustment);
  238.                   if(neaten_debug_level)
  239.                    printf("\tmin: width = %d height = %d status = %s\n",
  240.                       hints.min_width, hints.min_height,
  241.                       (rval ? "SUCCESS" : "FAILURE"));
  242.              }
  243.              if (hints.flags & PMaxSize) 
  244.              {
  245.                   rval = Neaten_Set_Max((int) w,
  246.                             hints.max_width+adjustment,
  247.                             hints.max_height+adjustment);
  248.                   if(neaten_debug_level)
  249.                    printf("\tmax: width = %d height = %d status = %s\n",
  250.                       hints.max_width, hints.max_height,
  251.                       (rval ? "SUCCESS" : "FAILURE"));            
  252.              }
  253.              if (hints.flags & (USSize | PSize))
  254.              {
  255.                   rval = Neaten_Set_Desired((int) w,
  256.                             hints.width+adjustment,
  257.                             hints.height+adjustment);
  258.                   if(neaten_debug_level)
  259.                    printf("\tdes: width = %d height = %d status = %s\n",
  260.                       hints.width, hints.height,
  261.                       (rval ? "SUCCESS" : "FAILURE"));            
  262.              }
  263.              
  264.              /* if no max hints are given, set the max to the
  265.                 max of the desired and current size 
  266.                 */
  267.              if (!(hints.flags & PMaxSize))
  268.              {
  269.                   int desired_width = hints.width+adjustment;
  270.                   int desired_height = hints.height+adjustment;
  271.                   
  272.                   window_width = ((window_width > desired_width)
  273.                           ? window_width :
  274.                           desired_width);
  275.                   window_height = ((window_height > desired_height) 
  276.                            ? window_height :
  277.                            desired_height);
  278.                   rval = Neaten_Set_Max((int) w,
  279.                             window_width,
  280.                             window_height);
  281.                   if(neaten_debug_level)
  282.                    printf("\tmax: width = %d height = %d status = %s\n",
  283.                       window_width-adjustment, window_height-adjustment,
  284.                       (rval ? "SUCCESS" : "FAILURE"));
  285.              }
  286.             }
  287.            }
  288.       }
  289.       
  290.       if (UsePriorities == TRUE)
  291.       {
  292.            priority = MIN_PRIORITY;
  293.            if (opened_children > 1)
  294.             priority_increment = (MAX_PRIORITY - MIN_PRIORITY) /
  295.              (opened_children - 1);
  296.            for (ix = 0; ix < nchildren; ix++)
  297.            {
  298.             w = children[ix];
  299.             awi = GetAwmInfo(w);
  300.             if (!awi)
  301.              continue;
  302.             if (w != TOP_LEVEL && w != awi->icon)
  303.              continue;
  304.             is_iconic = IsIcon(w, (Window *) NULL);
  305.             
  306.             if (is_iconic != TRUE)
  307.             {
  308.              XGetWindowAttributes(dpy, w, &attrs);        
  309.              if ((attrs.map_state != IsUnmapped) &&
  310.                  (attrs.override_redirect == False))
  311.              {
  312.                   Neaten_Set_Priorities((int) w, priority, priority);
  313.                   if (neaten_debug_level)
  314.                   {
  315.                    GetName(w, name);
  316.                    printf("%s: priority = %d\n", name, priority);
  317.                   }
  318.                   priority += priority_increment;
  319.              }
  320.             }
  321.            }
  322.       }
  323.       
  324.       if (FixTopOfStack == TRUE)
  325.       {
  326.            Neaten_Set_Options((int) stacktop, NEATEN_FALSE, NEATEN_TRUE);
  327.            if (neaten_debug_level)
  328.            {
  329.             GetName(stacktop, name);
  330.             printf("stacktop = %s\n", name);
  331.            }
  332.       }
  333.       
  334.       if(neaten_debug_level)
  335.            printf("mapped children = %d\topened_children = %d\n",
  336.               mapped_children, opened_children);
  337.       
  338.       Neaten_Desktop((RetainSize == FALSE), (KeepOpen == FALSE), Fill);
  339.       
  340.       for (ix = 0; ix < nchildren; ix++)
  341.       {
  342.            w = children[ix];
  343.            awi = GetAwmInfo(w);
  344.            if (!awi)
  345.             continue;
  346.            if (w != TOP_LEVEL && w != awi->icon)
  347.             continue;
  348.            if (Neaten_Get_Geometry((int) w, &iconic, &tiled,
  349.                        &window_x, &window_y,
  350.                        &window_width, &window_height,
  351.                        (unsigned long) &adjustment) == 0)
  352.             continue;
  353.            GetName(w, name);
  354.            if(neaten_debug_level)
  355.            {
  356.             printf("%s iconic = %s  tiled = %s\n", name,
  357.                (iconic ? "TRUE" : "FALSE"),
  358.                (tiled ? "TRUE" : "FALSE"));
  359.             printf("   x = %d, y = %d, width = %d, height = %d\n",
  360.                window_x, window_y, window_width, window_height);
  361.            }
  362.            
  363.            wc.x = window_x;
  364.            wc.y = window_y;
  365.            wc.width = window_width;
  366.            wc.height = window_height;
  367.            wcmask = CWX | CWY | CWWidth | CWHeight;
  368.            
  369.            if (iconic == NEATEN_TRUE)
  370.            {
  371.             is_iconic = IsIcon(w, &icon_window);
  372.             if (is_iconic == TRUE)
  373.             {
  374.              wc.width -= adjustment;
  375.              wc.height -= adjustment;
  376.              
  377.              XConfigureWindow(dpy, w, wcmask, &wc);
  378.              if(tiled != NEATEN_TRUE)
  379.                   XRaiseWindow(dpy, w);
  380.             }
  381.             else
  382.             {
  383.              /* have to go to the server to get the info, this
  384.                 could have been avoided if the the variable
  385.                 adjustment was a pointer to a structure that
  386.                 contained the information for the icon and the
  387.                 information for the window.  However, I chose
  388.                 not to mess with all that memory management
  389.                 */
  390.              GetIconHints(w, &icon_x, &icon_y,
  391.                       &icon_width, &icon_height, &icon_border);
  392.              
  393.              wc.x -= icon_border;
  394.              wc.y -= icon_border;
  395.              wc.width -= (2 * icon_border) + SEPARATION;
  396.              wc.height -= (2 * icon_border) + SEPARATION;
  397.              
  398.              XAddToSaveSet(dpy, w);
  399.              XUnmapWindow(dpy, TOP_LEVEL);
  400.              XConfigureWindow(icon_window, wcmask, &wc);
  401.              XMapWindow(dpy, icon_window);
  402.              if (tiled != NEATEN_TRUE)
  403.                   XRaiseWindow(dpy, icon_window);
  404.             }
  405.            }
  406.            else
  407.            {
  408.             wc.width -= adjustment;
  409.             wc.height -= adjustment;
  410.             adjustment -= SEPARATION;
  411.             wc.x += adjustment/2;
  412.             wc.y += adjustment/2;
  413.             /* I think this will be the outer win */
  414.             ConfigureWindow(w, wcmask, &wc);
  415.             if(tiled != NEATEN_TRUE)
  416.              XRaiseWindow(dpy, TOP_LEVEL);
  417.            }
  418.       }
  419.       
  420.       if (FixTopOfStack == TRUE)
  421.            XRaiseWindow(dpy, stacktop);
  422.       
  423.       XFree(children);
  424.      }
  425.      
  426.      XBell(dpy, VOLUME_PERCENTAGE(Volume));
  427.      XUngrabPointer(dpy, CurrentTime);
  428.      Leave(FALSE)
  429. }
  430.  
  431. static void
  432.      GetIconHints(window, x, y, width, height, border)
  433. Window window;
  434. int *x, *y, *width, *height, *border;
  435. {
  436.      Window root;
  437.      XWMHints *wmhints;
  438.      XWindowAttributes attrs;
  439.      int junk;
  440.      
  441.      *border = *x = *y = 0;
  442.      /*
  443.       * Process window manager hints.
  444.       */ 
  445.      if (wmhints = XGetWMHints(dpy, window)) 
  446.      {
  447.       if (wmhints->flags&IconWindowHint)
  448.       {
  449.            XGetWindowAttributes(dpy, wmhints->icon_window, &attrs);
  450.            *x = attrs.x;
  451.            *y = attrs.y;
  452.            *width = attrs.width;
  453.            *height = attrs.height;
  454.            *border = attrs.border_width;
  455.       }
  456.       else if (wmhints->flags&IconPixmapHint) 
  457.       {
  458.            XGetWindowAttributes(dpy, wmhints->icon_pixmap, &attrs);
  459.            *width = attrs.width;
  460.            *height = attrs.height;
  461.       }
  462.       else
  463.       {
  464.            GetDefaultSize(window, width, height);
  465.       }
  466.      }
  467.      else
  468.      {
  469.       GetDefaultSize(window, width, height);
  470.      }
  471.      
  472.      /*
  473.       * Fix up sizes by padding.
  474.       */ 
  475.      if (!wmhints || !(wmhints->flags&(IconPixmapHint|IconWindowHint))) {
  476.       *width += (HIconPad << 1);
  477.       *height += (VIconPad << 1);
  478.      }
  479.      
  480.      if (wmhints && (wmhints->flags&IconPositionHint)) {
  481.       *x = wmhints->icon_x;
  482.       *y = wmhints->icon_y;
  483.      }
  484. }
  485.  
  486. static void
  487.      GetName(w, name)
  488. Window w;
  489. char *name;
  490. {
  491.      Status rstatus;
  492.      char *s = (char *) NULL;
  493.      
  494.      
  495.      rstatus = XFetchName(dpy, w, &s);
  496.      
  497.      if (rstatus != (Status) 0 && s != (char *) NULL)
  498.      {
  499.       strcpy(name, s);
  500.       XFree(s);
  501.      }
  502.      else
  503.      {
  504.       strcpy(name, "UNKNOWN");
  505.      }
  506. }
  507.  
  508. void NeatenDebug(window, left, top, width, height, adjustment)
  509. int window;
  510. int left, top;
  511. int width, height;
  512. unsigned long adjustment;
  513. {
  514.      Window w = (Window) window;
  515.      
  516.      left += (int) ((float)adjustment/2.0);
  517.      top += (int) ((float)adjustment/2.0);
  518.      
  519.      width -= adjustment;
  520.      height -= adjustment;
  521.      
  522.      XMoveResizeWindow(dpy, w, left, top, width, height);
  523.      XFlush(dpy);
  524. }
  525. #else /* NEATEN not installed */
  526. /*ARGSUSED*/
  527. Boolean Neaten(window, mask, button, x, y)
  528. Window window;                          /* Event window. */
  529. int mask;                               /* Button/key mask. */
  530. int button;                               /* Button event detail. */
  531. int x, y;                               /* Event mouse position. */
  532. {
  533.      fprintf(stderr, "awm: Warning: Neaten package not installed in ");
  534.      fprintf(stderr, "this version of of awm.\n");
  535. }
  536. #endif NEATEN
  537.