dtwm: Change to ANSI function definitions
[oweals/cde.git] / cde / programs / dtwm / WmIPlace.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* 
24  * (c) Copyright 1989, 1990, 1991, 1992 OPEN SOFTWARE FOUNDATION, INC. 
25  * ALL RIGHTS RESERVED 
26 */ 
27 /* 
28  * Motif Release 1.2.1
29 */
30 /*
31  * (c) Copyright 1987, 1988, 1989, 1990 HEWLETT-PACKARD COMPANY */
32
33 /*
34  * Included Files:
35  */
36
37 #include "WmGlobal.h"
38
39 /*
40  * include extern functions
41  */
42
43 #include "WmError.h"
44 #include "WmIDecor.h"
45 #include "WmIconBox.h"
46 #include "WmWinConf.h"
47 #include "WmWrkspace.h"
48
49
50 /*
51  * Function Declarations:
52  */
53 #include "WmIPlace.h"
54
55
56 /*
57  * Global Variables:
58  */
59 extern Dimension clipWidth;
60 extern Dimension clipHeight;
61 extern Position clipX;
62 extern Position clipY;
63 \f
64 /*************************************<->*************************************
65  *
66  *  InitIconPlacement ()
67  *
68  *
69  *  Description:
70  *  -----------
71  *  This function intializes icon placement information.
72  *
73  *
74  *  Inputs:
75  *  ------
76  *  pWS = pointer to workspace data
77  *
78  * 
79  *  Outputs:
80  *  -------
81  *  IconPlacmementData
82  *
83  *************************************<->***********************************/
84
85 void InitIconPlacement (WmWorkspaceData *pWS)
86 {
87     Boolean useMargin;
88     int sW;
89     int sH;
90     int iSpaceX;
91     int iSpaceY;
92     int placementW;
93     int placementH;
94     int extraXSpace;
95     int extraYSpace;
96     int xMargin;
97     int yMargin;
98     int extraPX;
99     int extraPY;
100     int i;
101
102
103     xMargin = yMargin = extraPX = extraPY = 0;
104
105     sW = DisplayWidth (DISPLAY, pWS->pSD->screen);
106     sH = DisplayHeight (DISPLAY, pWS->pSD->screen);
107     useMargin = (pWS->pSD->iconPlacementMargin >= 0);
108     pWS->IPData.iconPlacement = pWS->pSD->iconPlacement;
109
110     if (useMargin)
111     {
112         pWS->IPData.placementCols =
113             (sW - (2 * pWS->pSD->iconPlacementMargin)) / pWS->pSD->iconWidth;
114         pWS->IPData.placementRows =
115             (sH - (2 * pWS->pSD->iconPlacementMargin)) / pWS->pSD->iconHeight;
116     }
117     else
118     {
119         pWS->IPData.placementCols = sW / pWS->pSD->iconWidth;
120         pWS->IPData.placementRows = sH / pWS->pSD->iconHeight;
121     }
122
123     if (pWS->IPData.iconPlacement & ICON_PLACE_TIGHT)
124     {
125         iSpaceX = 0;
126         iSpaceY = 0;
127         xMargin = 2;
128         yMargin = 2;
129     }
130     else
131     {
132         do
133         {
134             if (useMargin)
135             {
136                 iSpaceX = 
137                     (sW - (2 * pWS->pSD->iconPlacementMargin) -
138                           (pWS->IPData.placementCols * pWS->pSD->iconWidth)) /
139                               (pWS->IPData.placementCols - 1);
140             }
141             else
142             {
143                 iSpaceX = 
144                     (sW - (pWS->IPData.placementCols * pWS->pSD->iconWidth)) /
145                                pWS->IPData.placementCols;
146             }
147             if (iSpaceX < MINIMUM_ICON_SPACING)
148             {
149                 pWS->IPData.placementCols--;
150             }
151         }
152         while (iSpaceX < MINIMUM_ICON_SPACING);
153
154         do
155         {
156             if (useMargin)
157             {
158                 iSpaceY = (sH - (2 * pWS->pSD->iconPlacementMargin) -
159                        (pWS->IPData.placementRows * pWS->pSD->iconHeight)) /
160                                   (pWS->IPData.placementRows - 1);
161             }
162             else
163             {
164                 iSpaceY = 
165                     (sH - (pWS->IPData.placementRows * pWS->pSD->iconHeight)) /
166                                             pWS->IPData.placementRows;
167             }
168             if (iSpaceY < MINIMUM_ICON_SPACING)
169             {
170                 pWS->IPData.placementRows--;
171             }
172         }
173         while (iSpaceY < MINIMUM_ICON_SPACING);
174     }
175
176     pWS->IPData.iPlaceW = pWS->pSD->iconWidth + iSpaceX;
177     pWS->IPData.iPlaceH = pWS->pSD->iconHeight + iSpaceY;
178
179     placementW = pWS->IPData.placementCols * pWS->IPData.iPlaceW;
180     placementH = pWS->IPData.placementRows * pWS->IPData.iPlaceH;
181
182     pWS->IPData.placeIconX = 
183         ((pWS->IPData.iPlaceW - pWS->pSD->iconWidth) + 1) / 2;
184     pWS->IPData.placeIconY = 
185         ((pWS->IPData.iPlaceH - pWS->pSD->iconHeight) + 1) / 2;
186
187     /*
188      * Special case margin handling for TIGHT icon placement
189      */
190     if (pWS->IPData.iconPlacement & ICON_PLACE_TIGHT)
191     {
192         if (useMargin)
193         {
194             xMargin = pWS->pSD->iconPlacementMargin;
195             yMargin = pWS->pSD->iconPlacementMargin;
196         }
197
198         extraXSpace = 0;
199         extraYSpace = 0;
200
201         if ((pWS->IPData.iconPlacement & ICON_PLACE_RIGHT_PRIMARY) ||
202            (pWS->IPData.iconPlacement & ICON_PLACE_RIGHT_SECONDARY))
203             xMargin = sW - placementW - xMargin;
204
205         if ((pWS->IPData.iconPlacement & ICON_PLACE_BOTTOM_PRIMARY) ||
206            (pWS->IPData.iconPlacement & ICON_PLACE_BOTTOM_SECONDARY))
207             yMargin = sH - placementH - yMargin;
208     }
209     else
210     {
211         if (useMargin)
212         {
213             xMargin = pWS->pSD->iconPlacementMargin - pWS->IPData.placeIconX;
214             extraXSpace = sW - (2 * pWS->pSD->iconPlacementMargin) -
215                           (placementW - iSpaceX);
216             extraPX = (pWS->IPData.iconPlacement & ICON_PLACE_RIGHT_PRIMARY) ?
217                                 1 : (pWS->IPData.placementCols - extraXSpace);
218
219             yMargin = pWS->pSD->iconPlacementMargin - pWS->IPData.placeIconY;
220             extraYSpace = sH - (2 * pWS->pSD->iconPlacementMargin) -
221                           (placementH - iSpaceY);
222             extraPY = (pWS->IPData.iconPlacement & ICON_PLACE_BOTTOM_PRIMARY) ?
223                                 1 : (pWS->IPData.placementRows - extraYSpace);
224         }
225         else
226         {
227             xMargin = (sW - placementW + 
228                 ((pWS->IPData.iPlaceW - pWS->pSD->iconWidth) & 1)) / 2;
229             extraXSpace = 0;
230             yMargin = (sH - placementH + 
231                 ((pWS->IPData.iPlaceH - pWS->pSD->iconHeight) & 1))/ 2;
232             extraYSpace = 0;
233
234             if (pWS->IPData.iconPlacement & ICON_PLACE_RIGHT_PRIMARY)
235             {
236                 xMargin = sW - placementW - xMargin;
237                 pWS->IPData.placeIconX = pWS->IPData.iPlaceW - 
238                                          pWS->pSD->iconWidth - 
239                                          pWS->IPData.placeIconX;
240             }
241             if (pWS->IPData.iconPlacement & ICON_PLACE_BOTTOM_PRIMARY)
242             {
243                 yMargin = sH - placementH - yMargin;
244                 pWS->IPData.placeIconY = pWS->IPData.iPlaceH - 
245                                          pWS->pSD->iconHeight - 
246                                          pWS->IPData.placeIconY;
247             }
248         }
249     }
250
251     /*
252      * Setup array of grid row positions and grid column positions:
253      */
254
255     if ((pWS->IPData.placementRowY =
256             (int *)XtMalloc ((pWS->IPData.placementRows+2) * sizeof (int)))
257         == NULL)
258     {
259         Warning (((char *)GETMESSAGE(34, 1, "Insufficient memory for icon placement")));
260         wmGD.iconAutoPlace = False;
261         return;
262     }
263     else if ((pWS->IPData.placementColX =
264                 (int *)XtMalloc ((pWS->IPData.placementCols+2) * sizeof (int)))
265              == NULL)
266     {
267         XtFree ((char *)pWS->IPData.placementRowY);
268         Warning (((char *)GETMESSAGE(34, 2, "Insufficient memory for icon placement")));
269         wmGD.iconAutoPlace = False;
270         return;
271     }
272
273     pWS->IPData.placementRowY[0] = yMargin;
274     for (i = 1; i <= pWS->IPData.placementRows; i++)
275     {
276         pWS->IPData.placementRowY[i] = pWS->IPData.placementRowY[i - 1] + 
277             pWS->IPData.iPlaceH;
278         if ((extraYSpace > 0) && (i >= extraPY))
279         {
280             (pWS->IPData.placementRowY[i])++;
281             extraYSpace--;
282         }
283     }
284
285     pWS->IPData.placementColX[0] = xMargin;
286     for (i = 1; i <= pWS->IPData.placementCols; i++)
287     {
288         pWS->IPData.placementColX[i] = pWS->IPData.placementColX[i - 1] + 
289             pWS->IPData.iPlaceW;
290         if ((extraXSpace > 0) && (i >= extraPX))
291         {
292             (pWS->IPData.placementColX[i])++;
293             extraXSpace--;
294         }
295     }
296
297
298     /*
299      * Setup an array of icon places.
300      */
301
302     pWS->IPData.totalPlaces = 
303         pWS->IPData.placementRows * pWS->IPData.placementCols;
304
305     if ((pWS->IPData.placeList =
306           (IconInfo *)XtMalloc (pWS->IPData.totalPlaces * sizeof (IconInfo)))
307         == NULL)
308     {
309         Warning (((char *)GETMESSAGE(34, 3, "Insufficient memory for icon placement")));
310         XtFree ((char *)pWS->IPData.placementRowY);
311         XtFree ((char *)pWS->IPData.placementColX);
312         wmGD.iconAutoPlace = False;
313         return;
314     }
315
316     memset ((char *)pWS->IPData.placeList, 0, 
317         pWS->IPData.totalPlaces * sizeof (IconInfo));
318
319     pWS->IPData.onRootWindow = True;
320
321
322 } /* END OF FUNCTION InitIconPlacement */
323
324
325 \f
326 /*************************************<->*************************************
327  *
328  *  GetNextIconPlace (pIPD)
329  *
330  *
331  *  Description:
332  *  -----------
333  *  This function identifies and returns the next free icon grid place.
334  *
335  * 
336  *  Outputs:
337  *  -------
338  *  Return = next free place (index)
339  *
340  *************************************<->***********************************/
341
342 int GetNextIconPlace (IconPlacementData *pIPD)
343 {
344     int i;
345
346
347     for (i = 0; i < pIPD->totalPlaces; i++)
348     {
349         if (pIPD->placeList[i].pCD == (ClientData *)NULL)
350         {
351             return (i);
352         }
353     }
354
355     /*
356      * All places are filled!  Find an alternative place.
357      */
358
359     return (NO_ICON_PLACE);
360
361 } /* END OF FUNCTION GetNextIconPlace */
362
363
364 \f
365 /*************************************<->*************************************
366  *
367  *  CvtIconPlaceToPosition (pIPD, place, pX, pY)
368  *
369  *
370  *  Description:
371  *  -----------
372  *  This function converts an icon place (index) into an icon position.
373  *
374  *
375  *  Inputs:
376  *  ------
377  *  pIPD = ptr to icon placement data
378  *
379  *  place = place to be converted
380  *
381  *  wmGD = (iconPlacement ...)
382  *
383  * 
384  *  Outputs:
385  *  -------
386  *  pX = pointer to icon place X location
387  *
388  *  pY = pointer to icon place Y location
389  * 
390  *************************************<->***********************************/
391
392 void CvtIconPlaceToPosition (IconPlacementData *pIPD, int place, int *pX, int *pY)
393 {
394     int row;
395     int col;
396
397
398     if (pIPD->iconPlacement &
399         (ICON_PLACE_LEFT_PRIMARY | ICON_PLACE_RIGHT_PRIMARY))
400     {
401         col = place % pIPD->placementCols;
402         row = place / pIPD->placementCols;
403     }
404     else
405     {
406         col = place / pIPD->placementRows;
407         row = place % pIPD->placementRows;
408     }
409
410     if (pIPD->iconPlacement &
411         (ICON_PLACE_RIGHT_PRIMARY | ICON_PLACE_RIGHT_SECONDARY))
412     {
413         col = pIPD->placementCols - col - 1;
414     }
415     if (pIPD->iconPlacement &
416              (ICON_PLACE_BOTTOM_PRIMARY | ICON_PLACE_BOTTOM_SECONDARY))
417     {
418         row = pIPD->placementRows - row - 1;
419     }
420
421     if (pIPD->onRootWindow)
422     {
423         *pX = pIPD->placementColX[col] + pIPD->placeIconX;
424         *pY = pIPD->placementRowY[row] + pIPD->placeIconY;
425     }
426     else 
427     {
428         *pX = col * pIPD->iPlaceW;
429         *pY = row * pIPD->iPlaceH;
430     }
431
432 } /* END OF FUNCTION CvtIconPlaceToPosition */
433
434
435 \f
436 /*************************************<->*************************************
437  *
438  *  FindIconPlace (pCD, pIPD, x, y)
439  *
440  *
441  *  Description:
442  *  -----------
443  *  This function is used to find a free icon place in the proximity of the
444  *  specified position.
445  *
446  *
447  *  Inputs:
448  *  ------
449  *  pIPD = ptr to icon placement data
450  *
451  *  x = desired x location of icon place
452  *
453  *  y = desired y location of icon place
454  *
455  * 
456  *  Outputs:
457  *  -------
458  *  Return = icon place (index)
459  *
460  *
461  *  Comments:
462  *  --------
463  *  Look first for a free icon place at the position passed in.  If that place
464  *  is taken then look at positions that are +- one half the icon width/height
465  *  from the postion passed in.  If those positions are taken look at
466  *  positions that are +- one half icon placement width/height from the
467  *  position passed in.
468  * 
469  *************************************<->***********************************/
470
471 int FindIconPlace (ClientData *pCD, IconPlacementData *pIPD, int x, int y)
472 {
473     int place;
474     int i;
475     int j;
476     int diffX;
477     int diffY;
478     int altX;
479     int altY;
480     int amt;
481
482
483     place = CvtIconPositionToPlace (pIPD, x, y);
484
485     if (place < pIPD->totalPlaces)
486     {
487         if (pIPD->placeList[place].pCD == (ClientData *)NULL)
488         {
489         return (place);
490         }
491     }
492     else
493     {
494         if (pIPD->iconPlacement & ICON_PLACE_LEFT_PRIMARY)
495         {
496             amt = pIPD->placementCols;              /* add a new row */
497         }
498         else
499         {
500             amt = pIPD->placementRows;              /* add a new column */
501         }
502
503         if (!ExtendIconList (P_ICON_BOX(pCD), amt))
504         {
505             Warning (((char *)GETMESSAGE(34, 4, "Insufficient memory to create icon box data")));
506             return (NO_ICON_PLACE);            
507         }
508     }
509     /*
510      * The place for the passed in position is in use, look at places for
511      * alternative positions.
512      */
513
514     for (i = 0; i < 2; i++)
515     {
516         switch (i)
517         {
518             case 0:
519             {
520                 diffX = ICON_WIDTH(pCD) / 2;
521                 diffY = ICON_HEIGHT(pCD) / 2;
522                 break;
523             }
524
525             case 1:
526             {
527                 diffX = pIPD->iPlaceW / 2;
528                 diffY = pIPD->iPlaceH / 2;
529                 break;
530             }
531         }
532
533
534         for (j = 0; j < 4; j++)
535         {
536             switch (j)
537             {
538                 case 0:
539                 {
540                     if (pIPD->iconPlacement & ICON_PLACE_LEFT_PRIMARY)
541                     {
542                         altX = x - diffX;
543                         altY = y;
544                     }
545                     else if (pIPD->iconPlacement & ICON_PLACE_RIGHT_PRIMARY)
546                     {
547                         altX = x + diffX;
548                         altY = y;
549                     }
550                     else if (pIPD->iconPlacement & ICON_PLACE_TOP_PRIMARY)
551                     {
552                         altX = x;
553                         altY = y - diffY;
554                     }
555                     else
556                     {
557                         altX = x;
558                         altY = y + diffY;
559                     }
560                     break;
561                 }
562
563                 case 1:
564                 {
565                     if (pIPD->iconPlacement & ICON_PLACE_LEFT_PRIMARY)
566                     {
567                         altX = x + diffX;
568                         altY = y;
569                     }
570                     else if (pIPD->iconPlacement & ICON_PLACE_RIGHT_PRIMARY)
571                     {
572                         altX = x - diffX;
573                         altY = y;
574                     }
575                     else if (pIPD->iconPlacement & ICON_PLACE_TOP_PRIMARY)
576                     {
577                         altX = x;
578                         altY = y + diffY;
579                     }
580                     else
581                     {
582                         altX = x;
583                         altY = y - diffY;
584                     }
585                     break;
586                 }
587
588                 case 2:
589                 {
590                     if (pIPD->iconPlacement & ICON_PLACE_LEFT_SECONDARY)
591                     {
592                         altX = x - diffX;
593                         altY = y;
594                     }
595                     else if (pIPD->iconPlacement & ICON_PLACE_RIGHT_SECONDARY)
596                     {
597                         altX = x + diffX;
598                         altY = y;
599                     }
600                     else if (pIPD->iconPlacement & ICON_PLACE_TOP_SECONDARY)
601                     {
602                         altX = x;
603                         altY = y + diffY;
604                     }
605                     else
606                     {
607                         altX = x;
608                         altY = y - diffY;
609                     }
610                     break;
611                 }
612
613                 case 3:
614                 {
615                     if (pIPD->iconPlacement & ICON_PLACE_LEFT_SECONDARY)
616                     {
617                         altX = x + diffX;
618                         altY = y;
619                     }
620                     else if (pIPD->iconPlacement & ICON_PLACE_RIGHT_SECONDARY)
621                     {
622                         altX = x - diffX;
623                         altY = y;
624                     }
625                     else if (pIPD->iconPlacement & ICON_PLACE_TOP_SECONDARY)
626                     {
627                         altX = x;
628                         altY = y - diffY;
629                     }
630                     else
631                     {
632                         altX = x;
633                         altY = y + diffY;
634                     }
635                     break;
636                 }
637             }
638
639             if (P_ICON_BOX(pCD))
640             {
641                 GetClipDimensions(pCD, False);
642                 if (altX < clipX) 
643                 {
644                     return (NO_ICON_PLACE);
645                 }
646                 if (altY < clipY) 
647                 {
648                     return (NO_ICON_PLACE);
649                 }
650                 if (((int)altX) > ((int)clipX + 
651                         (int)clipWidth - ((int)ICON_WIDTH(pCD)))) 
652                 {
653                     return (NO_ICON_PLACE);
654                 }
655                 if (((int)altY) > ((int)clipY + 
656                         (int)clipHeight - ((int)ICON_HEIGHT(pCD))))
657                 {
658                     return (NO_ICON_PLACE);
659                 }
660             }
661
662             place = CvtIconPositionToPlace (pIPD, altX, altY);
663             if ((pIPD->placeList[place].pCD) == NULL)
664             {
665                 return (place);
666             }
667
668         }
669     }
670
671     /*
672      * Couldn't find an unoccupied place in the proximity of the passed-in
673      * position.
674      */
675
676     return (NO_ICON_PLACE);
677
678
679 } /* END OF FUNCTION FindIconPlace */
680
681
682 \f
683 /*************************************<->*************************************
684  *
685  *  CvtIconPostionToPlace (pIPD, x, y)
686  *
687  *
688  *  Description:
689  *  -----------
690  *  This function converts an icon position to an icon place.
691  *
692  *
693  *  Inputs:
694  *  ------
695  *  pIPD = ptr to icon placement data
696  *
697  *  x,y = location to be converted into an icon place
698  *
699  * 
700  *  Outputs:
701  *  -------
702  *  Return = icon place (index)
703  *
704  *************************************<->***********************************/
705
706 int CvtIconPositionToPlace (IconPlacementData *pIPD, int x, int y)
707 {
708     int row;
709     int col;
710
711
712     if (pIPD->onRootWindow)
713     {
714         /*
715          * Scan through the root window row/column arrays and find the 
716          * placement position.
717          */
718
719         for (row = 1; row < pIPD->placementRows; row++)
720         {
721             if (y < pIPD->placementRowY[row])
722             {
723                 break;
724             }
725         }
726         row--;
727
728         for (col = 1; col < pIPD->placementCols; col++)
729         {
730             if (x < pIPD->placementColX[col])
731             {
732                 break;
733             }
734         }
735         col--;
736
737
738         if (pIPD->iconPlacement &
739             (ICON_PLACE_RIGHT_PRIMARY | ICON_PLACE_RIGHT_SECONDARY))
740         {
741             col = pIPD->placementCols - col - 1;
742         }
743         if (pIPD->iconPlacement &
744             (ICON_PLACE_BOTTOM_PRIMARY | ICON_PLACE_BOTTOM_SECONDARY))
745         {
746             row = pIPD->placementRows - row - 1;
747         }
748     }
749     else
750     {
751         /* 
752          * convert icon box coords
753          */
754         col = x / pIPD->iPlaceW;
755         row = y / pIPD->iPlaceH;
756     }
757
758
759     if (pIPD->iconPlacement &
760         (ICON_PLACE_LEFT_PRIMARY | ICON_PLACE_RIGHT_PRIMARY))
761     {
762         return ((row * pIPD->placementCols) + col);
763     }
764     else
765     {
766         return ((col * pIPD->placementRows) + row);
767     }
768     
769
770 } /* END OF FUNCTION CvtIconPositionToPlace */
771
772
773
774
775 \f
776 /*************************************<->*************************************
777  *
778  *  PackRootIcons ()
779  *
780  *
781  *  Description:
782  *  -----------
783  *  This function packs the icons on the root window
784  *
785  *
786  *  Inputs:
787  *  ------
788  * 
789  *  Outputs:
790  *  -------
791  *
792  *  Comments:
793  *  ---------
794  *
795  *************************************<->***********************************/
796
797 void PackRootIcons (void)
798 {
799     int iOld, iNew;
800     ClientData *pCD;
801     ClientData *pCD_active;
802     int hasActiveText = 1;
803     WsClientData *pWsc;
804
805     /* 
806      * find context of the activeIconTextWin to get pCD and then 
807      * if it is the same as this client, hide it.
808      */
809
810     if (XFindContext (DISPLAY, ACTIVE_PSD->activeIconTextWin,
811                         wmGD.windowContextType, (caddr_t *)&pCD_active))
812     {
813         hasActiveText = 0;
814     }
815
816     /* 
817      *  Traverse the list and pack them together
818      */
819
820     if (wmGD.iconAutoPlace)
821     {
822         for (iOld = iNew = 0; iOld < ACTIVE_WS->IPData.totalPlaces; 
823             iOld++, iNew++)
824         {
825             if (ACTIVE_WS->IPData.placeList[iOld].pCD == NULL)
826             {
827                 /* advance to next non-null entry */
828                 while (++iOld < ACTIVE_WS->IPData.totalPlaces && 
829                        !ACTIVE_WS->IPData.placeList[iOld].pCD)
830                     ;
831             }
832
833             if (iOld < ACTIVE_WS->IPData.totalPlaces && iOld != iNew)
834             {
835                 /* move the icon from its old place to the new place */
836
837                 MoveIconInfo (&ACTIVE_WS->IPData, iOld, iNew);
838
839                 pCD = ACTIVE_WS->IPData.placeList[iNew].pCD;
840                 pWsc = GetWsClientData (ACTIVE_WS, pCD);
841                 pWsc->iconPlace = iNew;
842                 CvtIconPlaceToPosition (&ACTIVE_WS->IPData, 
843                     pWsc->iconPlace, &pWsc->iconX, &pWsc->iconY);
844
845                 if (hasActiveText && (pCD == pCD_active))
846                 {
847                     /* hide activeIconTextWin first */
848                     HideActiveIconText ((WmScreenData *)NULL);
849                     XMoveWindow (DISPLAY, pWsc->iconFrameWin, pWsc->iconX, 
850                              pWsc->iconY);
851                     ShowActiveIconText (pCD);
852                 }
853                 else
854                 {
855                     XMoveWindow (DISPLAY, pWsc->iconFrameWin, pWsc->iconX, 
856                              pWsc->iconY);
857                 }
858             }
859         }
860     }
861 } /* END OF FUNCTION PackRootIcons */
862
863
864 \f
865 /*************************************<->*************************************
866  *
867  *  MoveIconInfo (pIPD, p1, p2)
868  *
869  *
870  *  Description:
871  *  -----------
872  *  Move icon info from place 1 to place 2 in the placement list.
873  *
874  *
875  *  Inputs:
876  *  ------
877  *  pIPD        - ptr to icon placement data
878  *  p1          - placement index 1 (source)
879  *  p2          - placement index 2 (destination)
880  * 
881  *  Outputs:
882  *  -------
883  *
884  *  Comments:
885  *  --------
886  * 
887  *************************************<->***********************************/
888
889 void MoveIconInfo (IconPlacementData *pIPD, int p1, int p2)
890 {
891     WsClientData *pWsc;
892
893     /* only move if destination is empty */
894     if (pIPD->placeList[p2].pCD == NULL)
895     {
896         pIPD->placeList[p2].pCD = pIPD->placeList[p1].pCD;
897         pIPD->placeList[p2].theWidget = pIPD->placeList[p1].theWidget;
898
899         pWsc = GetWsClientData (pIPD->placeList[p2].pCD->pSD->pActiveWS,
900                                 pIPD->placeList[p2].pCD);
901         pWsc->iconPlace = p2;
902
903         pIPD->placeList[p1].pCD =  NULL;
904         pIPD->placeList[p1].theWidget = NULL;
905     }
906 }
907
908 /****************************   eof    ***************************/