home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / clients / twm / iconmgr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-21  |  18.4 KB  |  770 lines

  1. /*
  2.  * Copyright 1989 Massachusetts Institute of Technology
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software and its
  5.  * documentation for any purpose and without fee is hereby granted, provided
  6.  * that the above copyright notice appear in all copies and that both that
  7.  * copyright notice and this permission notice appear in supporting
  8.  * documentation, and that the name of M.I.T. not be used in advertising
  9.  * or publicity pertaining to distribution of the software without specific,
  10.  * written prior permission.  M.I.T. makes no representations about the
  11.  * suitability of this software for any purpose.  It is provided "as is"
  12.  * without express or implied warranty.
  13.  *
  14.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  15.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  16.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  17.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  18.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
  19.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  20.  */
  21.  
  22. /***********************************************************************
  23.  *
  24.  * $XConsortium: iconmgr.c,v 1.48 91/09/10 15:27:07 dave Exp $
  25.  *
  26.  * Icon Manager routines
  27.  *
  28.  * 09-Mar-89 Tom LaStrange        File Created
  29.  *
  30.  ***********************************************************************/
  31.  
  32. #include <stdio.h>
  33. #include "twm.h"
  34. #include "util.h"
  35. #include "parse.h"
  36. #include "screen.h"
  37. #include "resize.h"
  38. #include "add_window.h"
  39. #include "siconify.bm"
  40. #include <X11/Xos.h>
  41. #include <X11/Xmu/CharSet.h>
  42. #ifdef macII
  43. int strcmp(); /* missing from string.h in AUX 2.0 */
  44. #endif
  45.  
  46. int iconmgr_textx = siconify_width+11;
  47. WList *Active = NULL;
  48. WList *DownIconManager = NULL;
  49. int iconifybox_width = siconify_width;
  50. int iconifybox_height = siconify_height;
  51.  
  52. /***********************************************************************
  53.  *
  54.  *  Procedure:
  55.  *    CreateIconManagers - creat all the icon manager windows
  56.  *        for this screen.
  57.  *
  58.  *  Returned Value:
  59.  *    none
  60.  *
  61.  *  Inputs:
  62.  *    none
  63.  *
  64.  ***********************************************************************
  65.  */
  66.  
  67. void CreateIconManagers()
  68. {
  69.     IconMgr *p;
  70.     int mask;
  71.     char str[100];
  72.     char str1[100];
  73.     Pixel background;
  74.     char *icon_name;
  75.  
  76.     if (Scr->NoIconManagers)
  77.     return;
  78.  
  79.     if (Scr->siconifyPm == None)
  80.     {
  81.     Scr->siconifyPm = XCreatePixmapFromBitmapData(dpy, Scr->Root,
  82.         (char *)siconify_bits, siconify_width, siconify_height, 1, 0, 1);
  83.     }
  84.  
  85.     for (p = &Scr->iconmgr; p != NULL; p = p->next)
  86.     {
  87.     mask = XParseGeometry(p->geometry, &JunkX, &JunkY,
  88.                   (unsigned int *) &p->width, (unsigned int *)&p->height);
  89.  
  90.     if (mask & XNegative)
  91.         JunkX = Scr->MyDisplayWidth - p->width - 
  92.           (2 * Scr->BorderWidth) + JunkX;
  93.  
  94.     if (mask & YNegative)
  95.         JunkY = Scr->MyDisplayHeight - p->height -
  96.           (2 * Scr->BorderWidth) + JunkY;
  97.  
  98.     background = Scr->IconManagerC.back;
  99.     GetColorFromList(Scr->IconManagerBL, p->name, (XClassHint *)NULL,
  100.              &background);
  101.  
  102.     p->w = XCreateSimpleWindow(dpy, Scr->Root,
  103.         JunkX, JunkY, p->width, p->height, 1,
  104.         Scr->Black, background);
  105.  
  106.     sprintf(str, "%s Icon Manager", p->name);
  107.     sprintf(str1, "%s Icons", p->name);
  108.     if (p->icon_name)
  109.         icon_name = p->icon_name;
  110.     else
  111.         icon_name = str1;
  112.  
  113.     XSetStandardProperties(dpy, p->w, str, icon_name, None, NULL, 0, NULL);
  114.  
  115.     p->twm_win = AddWindow(p->w, TRUE, p);
  116.     SetMapStateProp (p->twm_win, WithdrawnState);
  117.     }
  118.     for (p = &Scr->iconmgr; p != NULL; p = p->next)
  119.     {
  120.     GrabButtons(p->twm_win);
  121.     GrabKeys(p->twm_win);
  122.     }
  123. }
  124.  
  125. /***********************************************************************
  126.  *
  127.  *  Procedure:
  128.  *    AllocateIconManager - allocate a new icon manager
  129.  *
  130.  *  Inputs:
  131.  *    name    - the name of this icon manager
  132.  *    icon_name - the name of the associated icon
  133.  *    geom    - a geometry string to eventually parse
  134.  *    columns    - the number of columns this icon manager has
  135.  *
  136.  ***********************************************************************
  137.  */
  138.  
  139. IconMgr *AllocateIconManager(name, icon_name, geom, columns)
  140.     char *name;
  141.     char *geom;
  142.     char *icon_name;
  143.     int columns;
  144. {
  145.     IconMgr *p;
  146.  
  147. #ifdef DEBUG_ICONMGR
  148.     fprintf(stderr, "AllocateIconManager\n");
  149.     fprintf(stderr, "  name=\"%s\" icon_name=\"%s\", geom=\"%s\", col=%d\n",
  150.     name, icon_name, geom, columns);
  151. #endif
  152.  
  153.     if (Scr->NoIconManagers)
  154.     return NULL;
  155.  
  156.     p = (IconMgr *)malloc(sizeof(IconMgr));
  157.     p->name = name;
  158.     p->icon_name = icon_name;
  159.     p->geometry = geom;
  160.     p->columns = columns;
  161.     p->first = NULL;
  162.     p->last = NULL;
  163.     p->active = NULL;
  164.     p->scr = Scr;
  165.     p->count = 0;
  166.     p->x = 0;
  167.     p->y = 0;
  168.     p->width = 150;
  169.     p->height = 10;
  170.  
  171.     Scr->iconmgr.lasti->next = p;
  172.     p->prev = Scr->iconmgr.lasti;
  173.     Scr->iconmgr.lasti = p;
  174.     p->next = NULL;
  175.  
  176.     return(p);
  177. }
  178.  
  179. /***********************************************************************
  180.  *
  181.  *  Procedure:
  182.  *    MoveIconManager - move the pointer around in an icon manager
  183.  *
  184.  *  Inputs:
  185.  *    dir    - one of the following:
  186.  *            F_FORWICONMGR    - forward in the window list
  187.  *            F_BACKICONMGR    - backward in the window list
  188.  *            F_UPICONMGR    - up one row
  189.  *            F_DOWNICONMGR    - down one row
  190.  *            F_LEFTICONMGR    - left one column
  191.  *            F_RIGHTICONMGR    - right one column
  192.  *
  193.  *  Special Considerations:
  194.  *    none
  195.  *
  196.  ***********************************************************************
  197.  */
  198.  
  199. void MoveIconManager(dir)
  200.     int dir;
  201. {
  202.     IconMgr *ip;
  203.     WList *tmp = NULL;
  204.     int cur_row, cur_col, new_row, new_col;
  205.     int row_inc, col_inc;
  206.     int got_it;
  207.  
  208.     if (!Active) return;
  209.  
  210.     cur_row = Active->row;
  211.     cur_col = Active->col;
  212.     ip = Active->iconmgr;
  213.  
  214.     row_inc = 0;
  215.     col_inc = 0;
  216.     got_it = FALSE;
  217.  
  218.     switch (dir)
  219.     {
  220.     case F_FORWICONMGR:
  221.         if ((tmp = Active->next) == NULL)
  222.         tmp = ip->first;
  223.         got_it = TRUE;
  224.         break;
  225.  
  226.     case F_BACKICONMGR:
  227.         if ((tmp = Active->prev) == NULL)
  228.         tmp = ip->last;
  229.         got_it = TRUE;
  230.         break;
  231.  
  232.     case F_UPICONMGR:
  233.         row_inc = -1;
  234.         break;
  235.  
  236.     case F_DOWNICONMGR:
  237.         row_inc = 1;
  238.         break;
  239.  
  240.     case F_LEFTICONMGR:
  241.         col_inc = -1;
  242.         break;
  243.  
  244.     case F_RIGHTICONMGR:
  245.         col_inc = 1;
  246.         break;
  247.     }
  248.  
  249.     /* If got_it is FALSE ast this point then we got a left, right,
  250.      * up, or down, command.  We will enter this loop until we find
  251.      * a window to warp to.
  252.      */
  253.     new_row = cur_row;
  254.     new_col = cur_col;
  255.  
  256.     while (!got_it)
  257.     {
  258.     new_row += row_inc;
  259.     new_col += col_inc;
  260.     if (new_row < 0)
  261.         new_row = ip->cur_rows - 1;
  262.     if (new_col < 0)
  263.         new_col = ip->cur_columns - 1;
  264.     if (new_row >= ip->cur_rows)
  265.         new_row = 0;
  266.     if (new_col >= ip->cur_columns)
  267.         new_col = 0;
  268.         
  269.     /* Now let's go through the list to see if there is an entry with this
  270.      * new position
  271.      */
  272.     for (tmp = ip->first; tmp != NULL; tmp = tmp->next)
  273.     {
  274.         if (tmp->row == new_row && tmp->col == new_col)
  275.         {
  276.         got_it = TRUE;
  277.         break;
  278.         }
  279.     }
  280.     }
  281.  
  282.     if (!got_it)
  283.     {
  284.     fprintf (stderr, 
  285.          "%s:  unable to find window (%d, %d) in icon manager\n", 
  286.          ProgramName, new_row, new_col);
  287.     return;
  288.     }
  289.  
  290.     if (tmp == NULL)
  291.       return;
  292.  
  293.     /* raise the frame so the icon manager is visible */
  294.     if (ip->twm_win->mapped) {
  295.     XRaiseWindow(dpy, ip->twm_win->frame);
  296.     XWarpPointer(dpy, None, tmp->icon, 0,0,0,0, 5, 5);
  297.     } else {
  298.     if (tmp->twm->title_height) {
  299.         int tbx = Scr->TBInfo.titlex;
  300.         int x = tmp->twm->highlightx;
  301.         XWarpPointer (dpy, None, tmp->twm->title_w, 0, 0, 0, 0,
  302.               tbx + (x - tbx) / 2,
  303.               Scr->TitleHeight / 4);
  304.     } else {
  305.         XWarpPointer (dpy, None, tmp->twm->w, 0, 0, 0, 0, 5, 5);
  306.     }
  307.     }
  308. }
  309.  
  310. /***********************************************************************
  311.  *
  312.  *  Procedure:
  313.  *    JumpIconManager - jump from one icon manager to another,
  314.  *        possibly even on another screen
  315.  *
  316.  *  Inputs:
  317.  *    dir    - one of the following:
  318.  *            F_NEXTICONMGR    - go to the next icon manager 
  319.  *            F_PREVICONMGR    - go to the previous one
  320.  *
  321.  ***********************************************************************
  322.  */
  323.  
  324. void JumpIconManager(dir)
  325.     register int dir;
  326. {
  327.     IconMgr *ip, *tmp_ip = NULL;
  328.     int got_it = FALSE;
  329.     ScreenInfo *sp;
  330.     int screen;
  331.  
  332.     if (!Active) return;
  333.  
  334.  
  335. #define ITER(i) (dir == F_NEXTICONMGR ? (i)->next : (i)->prev)
  336. #define IPOFSP(sp) (dir == F_NEXTICONMGR ? &(sp->iconmgr) : sp->iconmgr.lasti)
  337. #define TEST(ip) if ((ip)->count != 0 && (ip)->twm_win->mapped) \
  338.          { got_it = TRUE; break; }
  339.  
  340.     ip = Active->iconmgr;
  341.     for (tmp_ip = ITER(ip); tmp_ip; tmp_ip = ITER(tmp_ip)) {
  342.     TEST (tmp_ip);
  343.     }
  344.  
  345.     if (!got_it) {
  346.     int origscreen = ip->scr->screen;
  347.     int inc = (dir == F_NEXTICONMGR ? 1 : -1);
  348.  
  349.     for (screen = origscreen + inc; ; screen += inc) {
  350.         if (screen >= NumScreens)
  351.           screen = 0;
  352.         else if (screen < 0)
  353.           screen = NumScreens - 1;
  354.  
  355.         sp = ScreenList[screen];
  356.         if (sp) {
  357.         for (tmp_ip = IPOFSP (sp); tmp_ip; tmp_ip = ITER(tmp_ip)) {
  358.             TEST (tmp_ip);
  359.         }
  360.         }
  361.         if (got_it || screen == origscreen) break;
  362.     }
  363.     }
  364.  
  365. #undef ITER
  366. #undef IPOFSP
  367. #undef TEST
  368.  
  369.     if (!got_it) {
  370.     XBell (dpy, 0);
  371.     return;
  372.     }
  373.  
  374.     /* raise the frame so it is visible */
  375.     XRaiseWindow(dpy, tmp_ip->twm_win->frame);
  376.     if (tmp_ip->active)
  377.     XWarpPointer(dpy, None, tmp_ip->active->icon, 0,0,0,0, 5, 5);
  378.     else
  379.     XWarpPointer(dpy, None, tmp_ip->w, 0,0,0,0, 5, 5);
  380. }
  381.  
  382. /***********************************************************************
  383.  *
  384.  *  Procedure:
  385.  *    AddIconManager - add a window to an icon manager
  386.  *
  387.  *  Inputs:
  388.  *    tmp_win    - the TwmWindow structure
  389.  *
  390.  ***********************************************************************
  391.  */
  392.  
  393. WList *AddIconManager(tmp_win)
  394.     TwmWindow *tmp_win;
  395. {
  396.     WList *tmp;
  397.     int h;
  398.     unsigned long valuemask;        /* mask for create windows */
  399.     XSetWindowAttributes attributes;    /* attributes for create windows */
  400.     IconMgr *ip;
  401.  
  402.     tmp_win->list = NULL;
  403.  
  404.     if (tmp_win->iconmgr || tmp_win->transient || Scr->NoIconManagers)
  405.     return NULL;
  406.  
  407.     if (LookInList(Scr->IconMgrNoShow, tmp_win->full_name, &tmp_win->class))
  408.     return NULL;
  409.     if (Scr->IconManagerDontShow &&
  410.     !LookInList(Scr->IconMgrShow, tmp_win->full_name, &tmp_win->class))
  411.     return NULL;
  412.     if ((ip = (IconMgr *)LookInList(Scr->IconMgrs, tmp_win->full_name,
  413.         &tmp_win->class)) == NULL)
  414.     ip = &Scr->iconmgr;
  415.  
  416.     tmp = (WList *) malloc(sizeof(WList));
  417.     tmp->iconmgr = ip;
  418.     tmp->next = NULL;
  419.     tmp->active = FALSE;
  420.     tmp->down = FALSE;
  421.  
  422.     InsertInIconManager(ip, tmp, tmp_win);
  423.  
  424.     tmp->twm = tmp_win;
  425.  
  426.     tmp->fore = Scr->IconManagerC.fore;
  427.     tmp->back = Scr->IconManagerC.back;
  428.     tmp->highlight = Scr->IconManagerHighlight;
  429.  
  430.     GetColorFromList(Scr->IconManagerFL, tmp_win->full_name, &tmp_win->class,
  431.     &tmp->fore);
  432.     GetColorFromList(Scr->IconManagerBL, tmp_win->full_name, &tmp_win->class,
  433.     &tmp->back);
  434.     GetColorFromList(Scr->IconManagerHighlightL, tmp_win->full_name,
  435.     &tmp_win->class, &tmp->highlight);
  436.  
  437.     h = Scr->IconManagerFont.height + 10;
  438.     if (h < (siconify_height + 4))
  439.     h = siconify_height + 4;
  440.  
  441.     ip->height = h * ip->count;
  442.     tmp->me = ip->count;
  443.     tmp->x = -1;
  444.     tmp->y = -1;
  445.     
  446.     valuemask = (CWBackPixel | CWBorderPixel | CWEventMask | CWCursor);
  447.     attributes.background_pixel = tmp->back;
  448.     attributes.border_pixel = tmp->back;
  449.     attributes.event_mask = (KeyPressMask | ButtonPressMask |
  450.                  ButtonReleaseMask | ExposureMask |
  451.                  EnterWindowMask | LeaveWindowMask);
  452.     attributes.cursor = Scr->IconMgrCursor;
  453.     tmp->w = XCreateWindow (dpy, ip->w, 0, 0, (unsigned int) 1, 
  454.                 (unsigned int) h, (unsigned int) 0, 
  455.                 CopyFromParent, (unsigned int) CopyFromParent,
  456.                 (Visual *) CopyFromParent, valuemask, &attributes);
  457.  
  458.  
  459.     valuemask = (CWBackPixel | CWBorderPixel | CWEventMask | CWCursor);
  460.     attributes.background_pixel = tmp->back;
  461.     attributes.border_pixel = Scr->Black;
  462.     attributes.event_mask = (ButtonReleaseMask| ButtonPressMask |
  463.                  ExposureMask);
  464.     attributes.cursor = Scr->ButtonCursor;
  465.     tmp->icon = XCreateWindow (dpy, tmp->w, 5, (int) (h - siconify_height)/2,
  466.                    (unsigned int) siconify_width,
  467.                    (unsigned int) siconify_height,
  468.                    (unsigned int) 0, CopyFromParent,
  469.                    (unsigned int) CopyFromParent,
  470.                    (Visual *) CopyFromParent,
  471.                    valuemask, &attributes);
  472.  
  473.     ip->count += 1;
  474.     PackIconManager(ip);
  475.     XMapWindow(dpy, tmp->w);
  476.  
  477.     XSaveContext(dpy, tmp->w, IconManagerContext, (caddr_t) tmp);
  478.     XSaveContext(dpy, tmp->w, TwmContext, (caddr_t) tmp_win);
  479.     XSaveContext(dpy, tmp->w, ScreenContext, (caddr_t) Scr);
  480.     XSaveContext(dpy, tmp->icon, TwmContext, (caddr_t) tmp_win);
  481.     XSaveContext(dpy, tmp->icon, ScreenContext, (caddr_t) Scr);
  482.     tmp_win->list = tmp;
  483.  
  484.     if (!ip->twm_win->icon)
  485.     {
  486.     XMapWindow(dpy, ip->w);
  487.     XMapWindow(dpy, ip->twm_win->frame);
  488.     }
  489.  
  490.     return (tmp);
  491. }
  492.  
  493. /***********************************************************************
  494.  *
  495.  *  Procedure:
  496.  *    InsertInIconManager - put an allocated entry into an icon 
  497.  *        manager
  498.  *
  499.  *  Inputs:
  500.  *    ip    - the icon manager pointer
  501.  *    tmp    - the entry to insert
  502.  *
  503.  ***********************************************************************
  504.  */
  505.  
  506. void InsertInIconManager(ip, tmp, tmp_win)
  507.     IconMgr *ip;
  508.     WList *tmp;
  509.     TwmWindow *tmp_win;
  510. {
  511.     WList *tmp1;
  512.     int added;
  513.     int (*compar)() = (Scr->CaseSensitive ? strcmp : XmuCompareISOLatin1);
  514.  
  515.     added = FALSE;
  516.     if (ip->first == NULL)
  517.     {
  518.     ip->first = tmp;
  519.     tmp->prev = NULL;
  520.     ip->last = tmp;
  521.     added = TRUE;
  522.     }
  523.     else if (Scr->SortIconMgr)
  524.     {
  525.     for (tmp1 = ip->first; tmp1 != NULL; tmp1 = tmp1->next)
  526.     {
  527.         if ((*compar)(tmp_win->icon_name, tmp1->twm->icon_name) < 0)
  528.         {
  529.         tmp->next = tmp1;
  530.         tmp->prev = tmp1->prev;
  531.         tmp1->prev = tmp;
  532.         if (tmp->prev == NULL)
  533.             ip->first = tmp;
  534.         else
  535.             tmp->prev->next = tmp;
  536.         added = TRUE;
  537.         break;
  538.         }
  539.     }
  540.     }
  541.  
  542.     if (!added)
  543.     {
  544.     ip->last->next = tmp;
  545.     tmp->prev = ip->last;
  546.     ip->last = tmp;
  547.     }
  548. }
  549.  
  550. void RemoveFromIconManager(ip, tmp)
  551.     IconMgr *ip;
  552.     WList *tmp;
  553. {
  554.     if (tmp->prev == NULL)
  555.     ip->first = tmp->next;
  556.     else
  557.     tmp->prev->next = tmp->next;
  558.  
  559.     if (tmp->next == NULL)
  560.     ip->last = tmp->prev;
  561.     else
  562.     tmp->next->prev = tmp->prev;
  563. }
  564.  
  565. /***********************************************************************
  566.  *
  567.  *  Procedure:
  568.  *    RemoveIconManager - remove a window from the icon manager
  569.  *
  570.  *  Inputs:
  571.  *    tmp_win    - the TwmWindow structure
  572.  *
  573.  ***********************************************************************
  574.  */
  575.  
  576. void RemoveIconManager(tmp_win)
  577.     TwmWindow *tmp_win;
  578. {
  579.     IconMgr *ip;
  580.     WList *tmp;
  581.  
  582.     if (tmp_win->list == NULL)
  583.     return;
  584.  
  585.     tmp = tmp_win->list;
  586.     tmp_win->list = NULL;
  587.     ip = tmp->iconmgr;
  588.  
  589.     RemoveFromIconManager(ip, tmp);
  590.     
  591.     XDeleteContext(dpy, tmp->icon, TwmContext);
  592.     XDeleteContext(dpy, tmp->icon, ScreenContext);
  593.     XDestroyWindow(dpy, tmp->icon);
  594.     XDeleteContext(dpy, tmp->w, IconManagerContext);
  595.     XDeleteContext(dpy, tmp->w, TwmContext);
  596.     XDeleteContext(dpy, tmp->w, ScreenContext);
  597.     XDestroyWindow(dpy, tmp->w);
  598.     ip->count -= 1;
  599.     free((char *) tmp);
  600.  
  601.     PackIconManager(ip);
  602.  
  603.     if (ip->count == 0)
  604.     {
  605.     XUnmapWindow(dpy, ip->twm_win->frame);
  606.     }
  607.  
  608. }
  609.  
  610. void ActiveIconManager(active)
  611.     WList *active;
  612. {
  613.     active->active = TRUE;
  614.     Active = active;
  615.     Active->iconmgr->active = active;
  616.     DrawIconManagerBorder(active);
  617. }
  618.  
  619. void NotActiveIconManager(active)
  620.     WList *active;
  621. {
  622.     active->active = FALSE;
  623.     DrawIconManagerBorder(active);
  624. }
  625.  
  626. void DrawIconManagerBorder(tmp)
  627.     WList *tmp;
  628. {
  629.     {
  630.     XSetForeground(dpy, Scr->NormalGC, tmp->fore);
  631.         XDrawRectangle(dpy, tmp->w, Scr->NormalGC, 2, 2,
  632.         tmp->width-5, tmp->height-5);
  633.  
  634.     if (tmp->active && Scr->Highlight)
  635.         XSetForeground(dpy, Scr->NormalGC, tmp->highlight);
  636.     else
  637.         XSetForeground(dpy, Scr->NormalGC, tmp->back);
  638.  
  639.     XDrawRectangle(dpy, tmp->w, Scr->NormalGC, 0, 0,
  640.         tmp->width-1, tmp->height-1);
  641.     XDrawRectangle(dpy, tmp->w, Scr->NormalGC, 1, 1,
  642.         tmp->width-3, tmp->height-3);
  643.     }
  644. }
  645.  
  646. /***********************************************************************
  647.  *
  648.  *  Procedure:
  649.  *    SortIconManager - sort the dude
  650.  *
  651.  *  Inputs:
  652.  *    ip    - a pointer to the icon manager struture
  653.  *
  654.  ***********************************************************************
  655.  */
  656.  
  657. void SortIconManager(ip)
  658.     IconMgr *ip;
  659. {
  660.     WList *tmp1, *tmp2;
  661.     int done;
  662.     int (*compar)() = (Scr->CaseSensitive ? strcmp : XmuCompareISOLatin1);
  663.  
  664.     if (ip == NULL)
  665.     ip = Active->iconmgr;
  666.  
  667.     done = FALSE;
  668.     do
  669.     {
  670.     for (tmp1 = ip->first; tmp1 != NULL; tmp1 = tmp1->next)
  671.     {
  672.         if ((tmp2 = tmp1->next) == NULL)
  673.         {
  674.         done = TRUE;
  675.         break;
  676.         }
  677.         if ((*compar)(tmp1->twm->icon_name, tmp2->twm->icon_name) > 0)
  678.         {
  679.         /* take it out and put it back in */
  680.         RemoveFromIconManager(ip, tmp2);
  681.         InsertInIconManager(ip, tmp2, tmp2->twm);
  682.         break;
  683.         }
  684.     }
  685.     }
  686.     while (!done);
  687.     PackIconManager(ip);
  688. }
  689.  
  690. /***********************************************************************
  691.  *
  692.  *  Procedure:
  693.  *    PackIconManager - pack the icon manager windows following
  694.  *        an addition or deletion
  695.  *
  696.  *  Inputs:
  697.  *    ip    - a pointer to the icon manager struture
  698.  *
  699.  ***********************************************************************
  700.  */
  701.  
  702. void PackIconManager(ip)
  703.     IconMgr *ip;
  704. {
  705.     int newwidth, i, row, col, maxcol,  colinc, rowinc, wheight, wwidth;
  706.     int new_x, new_y;
  707.     int savewidth;
  708.     WList *tmp;
  709.  
  710.     wheight = Scr->IconManagerFont.height + 10;
  711.     if (wheight < (siconify_height + 4))
  712.     wheight = siconify_height + 4;
  713.  
  714.     wwidth = ip->width / ip->columns;
  715.  
  716.     rowinc = wheight;
  717.     colinc = wwidth;
  718.  
  719.     row = 0;
  720.     col = ip->columns;
  721.     maxcol = 0;
  722.     for (i = 0, tmp = ip->first; tmp != NULL; i++, tmp = tmp->next)
  723.     {
  724.     tmp->me = i;
  725.     if (++col >= ip->columns)
  726.     {
  727.         col = 0;
  728.         row += 1;
  729.     }
  730.     if (col > maxcol)
  731.         maxcol = col;
  732.  
  733.     new_x = col * colinc;
  734.     new_y = (row-1) * rowinc;
  735.  
  736.     /* if the position or size has not changed, don't touch it */
  737.     if (tmp->x != new_x || tmp->y != new_y ||
  738.         tmp->width != wwidth || tmp->height != wheight)
  739.     {
  740.         XMoveResizeWindow(dpy, tmp->w, new_x, new_y, wwidth, wheight);
  741.  
  742.         tmp->row = row-1;
  743.         tmp->col = col;
  744.         tmp->x = new_x;
  745.         tmp->y = new_y;
  746.         tmp->width = wwidth;
  747.         tmp->height = wheight;
  748.     }
  749.     }
  750.     maxcol += 1;
  751.  
  752.     ip->cur_rows = row;
  753.     ip->cur_columns = maxcol;
  754.     ip->height = row * rowinc;
  755.     if (ip->height == 0)
  756.         ip->height = rowinc;
  757.     newwidth = maxcol * colinc;
  758.     if (newwidth == 0)
  759.     newwidth = colinc;
  760.  
  761.     XResizeWindow(dpy, ip->w, newwidth, ip->height);
  762.  
  763.     savewidth = ip->width;
  764.     if (ip->twm_win)
  765.       SetupWindow (ip->twm_win,
  766.            ip->twm_win->frame_x, ip->twm_win->frame_y,
  767.            newwidth, ip->height + ip->twm_win->title_height, -1);
  768.     ip->width = savewidth;
  769. }
  770.