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