source: trunk/third/mwm/WmWinList.c @ 9757

Revision 9757, 56.9 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r9756, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * (c) Copyright 1989, 1990, 1991, 1992, 1993 OPEN SOFTWARE FOUNDATION, INC.
3 * ALL RIGHTS RESERVED
4*/
5/*
6 * Motif Release 1.2.3
7*/
8#ifdef REV_INFO
9#ifndef lint
10static char rcsid[] = "$RCSfile: WmWinList.c,v $ $Revision: 1.1.1.1 $ $Date: 1997-03-25 09:12:27 $"
11#endif
12#endif
13/*
14 * (c) Copyright 1987, 1988, 1989, 1990 HEWLETT-PACKARD COMPANY */
15
16/*
17 * Included Files:
18 */
19
20#include "WmGlobal.h"
21
22#define MWM_NEED_NOENTER16
23#include "WmBitmap.h"
24
25
26/*
27 * include extern functions
28 */
29#include "WmWinList.h"
30#include "WmCEvent.h"
31#include "WmFunction.h"
32#include "WmKeyFocus.h"
33#include "WmResource.h"
34#include "WmWinInfo.h"
35
36
37
38
39/*
40 * Global Variables:
41 */
42
43
44/*************************************<->*************************************
45 *
46 *  AddClientToList (pWS, pCD, onTop)
47 *
48 *
49 *  Description:
50 *  -----------
51 *  This function adds a client window to the client window list.  If it is
52 *  a transient window then it is added to the transient window tree that
53 *  contains its transient leader.  The window stacking order is also
54 *  maintained for the cases where there is a system modal window active
55 *  or the window is a transient window.  If a system modal window is being
56 *  added then the system modal "input screen" window is setup.
57 *
58 *
59 *  Inputs:
60 *  ------
61 *  pCD = pointer to client data for the window to be added to the list
62 *
63 *  pWS = pointer to workspace data
64 *
65 *  onTop = if True then the window is displayed on top of the window
66 *      stack and is added to the beginning of the window list, otherwise
67 *      it is added to the end of the window list.
68 *
69 *
70 *  Outputs:
71 *  -------
72 *  pWS = (clientList, lastClient)
73 *
74 *************************************<->***********************************/
75
76#ifdef _NO_PROTO
77void AddClientToList (pWS, pCD, onTop)
78        ClientData *pCD;
79        WmWorkspaceData *pWS;
80        Boolean onTop;
81
82#else /* _NO_PROTO */
83void AddClientToList (WmWorkspaceData *pWS, ClientData *pCD, Boolean onTop)
84#endif /* _NO_PROTO */
85{
86    Boolean belowSystemModal = False;
87    XWindowChanges windowChanges;
88    WmScreenData *pSD = pWS->pSD;
89
90
91    if (pCD->inputMode == MWM_INPUT_SYSTEM_MODAL)
92    {
93        /*
94         * Set up the system modal input screen window just below the
95         * system modal window.
96         */
97
98        SetupSystemModalState (pCD);
99    }
100    else if (wmGD.systemModalActive &&
101             ((FindTransientTreeLeader (pCD))->inputMode !=
102              MWM_INPUT_SYSTEM_MODAL))
103    {
104        /*
105         * If a system modal window is active then place the window below
106         * the system modal input screen window if the window is not a
107         * descendant of the system modal window.
108         */
109
110        windowChanges.sibling = pSD->inputScreenWindow;
111        windowChanges.stack_mode = Below;
112        XConfigureWindow (DISPLAY, pCD->clientFrameWin,
113            CWSibling | CWStackMode, &windowChanges);
114        belowSystemModal = True;
115    }
116
117    if (pCD->transientLeader)
118    {
119        AddTransient (pWS, pCD);
120    }
121    else
122    {
123        pCD->clientEntry.type = NORMAL_STATE;
124        pCD->clientEntry.pCD = pCD;
125
126        if (belowSystemModal && wmGD.systemModalClient)
127        {
128            AddEntryToList (pWS, &pCD->clientEntry, False /*below*/,
129                            pSD->clientList);
130        }
131        else if (onTop)
132        {
133            AddEntryToList (pWS, &pCD->clientEntry, True /*on top*/, NULL);
134        }
135        else
136        {
137            AddEntryToList (pWS, &pCD->clientEntry, False /*on bottom*/, NULL);
138        }
139
140
141        if (!pCD->pIconBox && pCD->iconFrameWin)
142        {
143            /*
144             * Put the icon on the bottom of the stack.
145             */
146
147            if (pSD->lastClient->type == MINIMIZED_STATE)
148            {
149                windowChanges.sibling = pSD->lastClient->pCD->iconFrameWin;
150            }
151            else
152            {
153                windowChanges.sibling = pSD->lastClient->pCD->clientFrameWin;
154            }
155            windowChanges.stack_mode = Below;
156            XConfigureWindow (DISPLAY, pCD->iconFrameWin,
157                CWSibling | CWStackMode, &windowChanges);
158
159            pCD->iconEntry.type = MINIMIZED_STATE;
160            pCD->iconEntry.pCD = pCD;
161            pCD->iconEntry.nextSibling = NULL;
162            pCD->iconEntry.prevSibling = pSD->lastClient;
163            pSD->lastClient->nextSibling = &pCD->iconEntry;
164            pSD->lastClient = &pCD->iconEntry;
165        }
166    }
167
168} /* END OF FUNCTION AddClientToList */
169
170
171
172/*************************************<->*************************************
173 *
174 *  AddEntryToList (pWS, pEntry, onTop, pStackEntry)
175 *
176 *
177 *  Description:
178 *  -----------
179 *  This function adds a client list entry to the client window list.
180 *  This is usually done as part of the process of changing the ordering
181 *  of the window list.
182 *
183 *
184 *  Inputs:
185 *  ------
186 *  pWS  = pointer to workspace data
187 *  pEntry = pointer to a client list entry to be added to the client list
188 *
189 *  onTop = if True then the client list entry is added on top of the
190 *      specified client list stack entry (if the stack entry is not
191 *      specified then the entry is added to the front of the list);
192 *      otherwise the entry is added after the specified stacking entry
193 *      (or to the end of the list if the stacking entry is not specified).
194 *
195 *  pStackEntry = pointer to a client list entry to be used as a reference
196 *      in adding an entry to the client list.
197 *
198 *  Outputs:
199 *  -------
200 *  pWS = (clientList, lastClient)
201 *
202 *************************************<->***********************************/
203
204#ifdef _NO_PROTO
205void AddEntryToList (pWS, pEntry, onTop, pStackEntry)
206        WmWorkspaceData *pWS;
207        ClientListEntry *pEntry;
208        Boolean onTop;
209        ClientListEntry *pStackEntry;
210
211#else /* _NO_PROTO */
212void AddEntryToList (WmWorkspaceData *pWS, ClientListEntry *pEntry, Boolean onTop, ClientListEntry *pStackEntry)
213#endif /* _NO_PROTO */
214{
215    WmScreenData *pSD = pWS->pSD;
216
217    if (onTop)
218    {
219        if (pStackEntry)
220        {
221            if (pEntry != pStackEntry)
222            {
223                pEntry->nextSibling = pStackEntry;
224                pEntry->prevSibling = pStackEntry->prevSibling;
225                pStackEntry->prevSibling = pEntry;
226                if (pEntry->prevSibling)
227                {
228                    pEntry->prevSibling->nextSibling = pEntry;
229                }
230                else
231                {
232                    pSD->clientList = pEntry;
233                }
234            }
235        }
236        else
237        {
238            if (pSD->clientList != pEntry)
239            {
240                pEntry->nextSibling = pSD->clientList;
241                pEntry->prevSibling = NULL;
242                if (pSD->clientList)
243                {
244                    pSD->clientList->prevSibling = pEntry;
245                }
246                else
247                {
248                    pSD->lastClient = pEntry;
249                }
250                pSD->clientList = pEntry;
251            }
252        }
253    }
254    else
255    {
256        if (pStackEntry)
257        {
258            if (pEntry != pStackEntry)
259            {
260                pEntry->nextSibling = pStackEntry->nextSibling;
261                pEntry->prevSibling = pStackEntry;
262                pStackEntry->nextSibling = pEntry;
263                if (pEntry->nextSibling)
264                {
265                    pEntry->nextSibling->prevSibling = pEntry;
266                }
267                else
268                {
269                    pSD->lastClient = pEntry;
270                }
271            }
272        }
273        else
274        {
275            if (pSD->lastClient != pEntry)
276            {
277                pEntry->nextSibling = NULL;
278                pEntry->prevSibling = pSD->lastClient;
279                if (pSD->clientList)
280                {
281                    pSD->lastClient->nextSibling = pEntry;
282                }
283                else
284                {
285                    pSD->clientList = pEntry;
286                }
287                pSD->lastClient = pEntry;
288            }
289        }
290    }
291
292} /* END OF FUNCTION AddEntryToList */
293
294
295
296/*************************************<->*************************************
297 *
298 *  MoveEntryInList (pWS, pEntry, onTop, pStackEntry)
299 *
300 *
301 *  Description:
302 *  -----------
303 *  This function moves a client list entry in the client window list.
304 *
305 *
306 *  Inputs:
307 *  ------
308 *  pWS = pointer to workspace data
309 *
310 *  pEntry = pointer to a client list entry to be moved in the client list
311 *
312 *  onTop = if True then the client list entry is moved on top of the
313 *      specified client list stack entry (if the stack entry is not
314 *      specified then the entry is moved to the front of the list);
315 *      otherwise the entry is moved after the specified stacking entry
316 *      (or to the end of the list if the stacking entry is not specified).
317 *
318 *  pStackEntry = pointer to a client list entry to be used as a reference
319 *      in moving an entry in the client list.
320 *
321 *  Outputs:
322 *  -------
323 *  pWS = (clientList, lastClient)
324 *
325 *************************************<->***********************************/
326
327#ifdef _NO_PROTO
328void MoveEntryInList (pWS, pEntry, onTop, pStackEntry)
329        WmWorkspaceData *pWS;
330        ClientListEntry *pEntry;
331        Boolean onTop;
332        ClientListEntry *pStackEntry;
333
334#else /* _NO_PROTO */
335void MoveEntryInList (WmWorkspaceData *pWS, ClientListEntry *pEntry, Boolean onTop, ClientListEntry *pStackEntry)
336#endif /* _NO_PROTO */
337{
338    DeleteEntryFromList (pWS, pEntry);
339    AddEntryToList (pWS, pEntry, onTop, pStackEntry);
340
341} /* END OF FUNCTION MoveEntryInList */
342
343
344
345/*************************************<->*************************************
346 *
347 *  DeleteEntryFromList (pWS, pListEntry)
348 *
349 *
350 *  Description:
351 *  -----------
352 *  This function deletes a client list entry from the client window list.
353 *  This is usually done as part of the process of changing the ordering
354 *  of the window list.
355 *
356 *
357 *  Inputs:
358 *  ------
359 *  pWS = pointer to workspace data
360 *  listEntry = pointer to a client list entry
361 *
362 *  Outputs:
363 *  -------
364 *  pWS = (clientList, lastClient)
365 *
366 *************************************<->***********************************/
367
368#ifdef _NO_PROTO
369void DeleteEntryFromList (pWS, pListEntry)
370        WmWorkspaceData *pWS;
371        ClientListEntry *pListEntry;
372
373#else /* _NO_PROTO */
374void DeleteEntryFromList (WmWorkspaceData *pWS, ClientListEntry *pListEntry)
375#endif /* _NO_PROTO */
376{
377   
378    if (pListEntry->prevSibling)
379    {
380        pListEntry->prevSibling->nextSibling = pListEntry->nextSibling;
381    }
382    else
383    {
384        pWS->pSD->clientList = pListEntry->nextSibling;
385    }
386
387    if (pListEntry->nextSibling)
388    {
389        pListEntry->nextSibling->prevSibling = pListEntry->prevSibling;
390    }
391    else
392    {
393        pWS->pSD->lastClient = pListEntry->prevSibling;
394    }
395
396} /* END OF FUNCTION DeleteEntryFromList */
397
398
399
400/*************************************<->*************************************
401 *
402 *  DeleteClientFromList (pWS, pCD)
403 *
404 *
405 *  Description:
406 *  -----------
407 *  This function deletes a client from the client window list.  If this is
408 *  a transient window then it is deleted from its transient window tree.
409 *  If this is a system modal window then clean up the system modal state.
410 *
411 *
412 *  Inputs:
413 *  ------
414 *  pCD = pointer to client data for the window to be added to the list
415 *
416 *  Outputs:
417 *  -------
418 *  pWS = (clientList, lastClient)
419 *
420 *************************************<->***********************************/
421
422#ifdef _NO_PROTO
423void DeleteClientFromList (pWS, pCD)
424        WmWorkspaceData *pWS;
425        ClientData *pCD;
426
427#else /* _NO_PROTO */
428void DeleteClientFromList (WmWorkspaceData *pWS, ClientData *pCD)
429#endif /* _NO_PROTO */
430{
431    WmScreenData *pSD = pWS->pSD;
432
433    if (pCD->transientLeader)
434    {
435        DeleteTransient (pCD);
436    }
437    else
438    {
439        /*
440         * If this is a system modal window then clean up the system modal
441         * state.
442         */
443
444        if (pCD->inputMode == MWM_INPUT_SYSTEM_MODAL)
445        {
446            UndoSystemModalState ();
447        }
448
449        /*
450         * Remove the client and icon entries from the window list.
451         */
452
453        if (!pCD->pIconBox && pCD->iconFrameWin)
454        {
455            if (pCD->iconEntry.prevSibling)
456            {
457                pCD->iconEntry.prevSibling->nextSibling =
458                                                pCD->iconEntry.nextSibling;
459            }
460            else
461            {
462                pSD->clientList = pCD->iconEntry.nextSibling;
463            }
464            if (pCD->iconEntry.nextSibling)
465            {
466                pCD->iconEntry.nextSibling->prevSibling =
467                                                pCD->iconEntry.prevSibling;
468            }
469            else
470            {
471                pSD->lastClient = pCD->iconEntry.prevSibling;
472            }
473        }
474
475        if (pCD->clientEntry.prevSibling)
476        {
477            pCD->clientEntry.prevSibling->nextSibling =
478                                                pCD->clientEntry.nextSibling;
479        }
480        else
481        {
482            pSD->clientList = pCD->clientEntry.nextSibling;
483        }
484
485        if (pCD->clientEntry.nextSibling)
486        {
487            pCD->clientEntry.nextSibling->prevSibling =
488                                                pCD->clientEntry.prevSibling;
489        }
490        else
491        {
492            pSD->lastClient = pCD->clientEntry.prevSibling;
493        }
494    }
495
496} /* END OF FUNCTION DeleteClientFromList */
497
498
499
500/*************************************<->*************************************
501 *
502 *  AddTransient (pWS, pCD)
503 *
504 *
505 *  Description:
506 *  -----------
507 *  This function adds the transient window to the lead window's list of
508 *  transients.
509 *
510 *
511 *  Inputs:
512 *  ------
513 *  pWS = pointer to workspace data
514 *  pCD = pointer to client data of a transient window
515 *
516 *
517 *  Outputs:
518 *  -------
519 *  pCD->transientLeader = (transientChildren, modalCount)
520 *
521 *************************************<->***********************************/
522
523#ifdef _NO_PROTO
524void AddTransient (pWS, pCD)
525        WmWorkspaceData *pWS;
526        ClientData *pCD;
527
528#else /* _NO_PROTO */
529void AddTransient (WmWorkspaceData *pWS, ClientData *pCD)
530#endif /* _NO_PROTO */
531{
532    ClientData *pcdLeader = pCD->transientLeader;
533    ClientData *pcdTop = FindTransientTreeLeader (pCD);
534    Boolean restackTransients;
535    WmScreenData *pSD = pWS->pSD;
536
537
538    pCD->transientSiblings = pcdLeader->transientChildren;
539    pcdLeader->transientChildren = pCD;
540
541
542    /*
543     * Insure that the new transient window is on top of its siblings
544     * and that the transient window tree is on top of the window
545     * stack (this is the standard behavior for newly mapped and
546     * managed windows).  If there is a system modal window that the
547     * transient window is not associated with then don't raise the
548     * transient tree.
549     */
550
551    restackTransients = PutTransientOnTop (pcdLeader);
552
553
554    /*
555     * Handle application modal transient windows
556     */
557
558    if (pCD->inputMode == MWM_INPUT_PRIMARY_APPLICATION_MODAL)
559    {
560        /*
561         * If this is a primary application modal window then increment
562         * the modal count for transient leaders that are directly up
563         * the transient tree.
564         *
565         * (This is the old MWM_INPUT_APPLICATION_MODAL behavior.)
566         */
567        while (pcdLeader)
568        {
569            MarkModalTransient (pcdLeader, pCD);
570            pcdLeader = pcdLeader->transientLeader;
571        }
572    }
573    else if (pCD->inputMode == MWM_INPUT_FULL_APPLICATION_MODAL)
574    {
575        /*
576         * If this is a full application modal window then increment
577         * the modal count for the rest of the transient tree.
578         */
579
580        MarkModalSubtree (pcdTop, pCD);
581    }
582    else if (pcdTop->fullModalCount)
583    {
584        /*
585         * There is already a full application modal window in the tree
586         */
587        pcdLeader = pCD->transientLeader;
588        if ((pcdLeader->inputMode != MWM_INPUT_FULL_APPLICATION_MODAL) ||
589            (IS_APP_MODALIZED(pcdLeader)))
590        {
591            /*
592             * The immediate parent of this transient is not the
593             * current full application modal window.  Set the full
594             * modal count to the parent's so that they both become
595             * unmodalized at the same time. This allows a full
596             * app modal window to have active, non-modal transients.
597             */
598            pCD->fullModalCount = pcdLeader->fullModalCount;
599        }
600    }
601
602
603    /*
604     * Do the actual restacking in the X window stack if necessary.
605     */
606
607    if ((pSD->clientList != &pcdTop->clientEntry) && !wmGD.systemModalActive)
608    {
609        F_Raise (NULL, pCD, NULL);
610    }
611    else if (restackTransients)
612    {
613        RestackTransientsAtWindow (pCD);
614    }
615    else if (pCD != FindTransientOnTop (pcdTop))
616    {
617        StackTransientWindow (pCD);
618    }
619
620
621} /* END OF FUNCTION AddTransient */
622
623
624
625/*************************************<->*************************************
626 *
627 *  MarkModalSubtree (pcdTree, pcdAvoid)
628 *
629 *
630 *  Description:
631 *  -----------
632 *  This function marks the transient tree with pcdTree as its leader.
633 *  If pcdAvoid is in the tree, it is not marked.
634 *
635 *  Inputs:
636 *  ------
637 *  pcdTree     = pointer to client data of the tree to mark
638 *  pcdAvoid    = pointer to client data to not mark if in tree
639 *
640 *
641 *************************************<->***********************************/
642
643#ifdef _NO_PROTO
644void MarkModalSubtree (pcdTree, pcdAvoid)
645        ClientData *pcdTree, *pcdAvoid;
646
647#else /* _NO_PROTO */
648void MarkModalSubtree (ClientData *pcdTree, ClientData *pcdAvoid)
649#endif /* _NO_PROTO */
650{
651    /* Mark children, if any */
652
653    if (pcdTree->transientChildren)
654        MarkModalSubtree (pcdTree->transientChildren, pcdAvoid);
655
656    /* Mark this node */
657
658    if (pcdTree != pcdAvoid)
659    {
660        MarkModalTransient (pcdTree, pcdAvoid);
661    }
662
663    /* Mark siblings */
664
665    if (pcdTree->transientSiblings)
666        MarkModalSubtree (pcdTree->transientSiblings, pcdAvoid);
667
668}
669
670
671/*************************************<->*************************************
672 *
673 *  MarkModalTransient (pcdLeader, pCD)
674 *
675 *
676 *  Description:
677 *  -----------
678 *  This function marks a transient window for application modal processing.
679 *  Grabs are done to eat up pointer button events.
680 *
681 *  Inputs:
682 *  ------
683 *  pcdLeader = pointer to client data to mark
684 *  pCD = pointer to client data of new transient
685 *
686 *
687 *************************************<->***********************************/
688
689#ifdef _NO_PROTO
690void MarkModalTransient (pcdLeader, pCD)
691        ClientData *pcdLeader, *pCD;
692
693#else /* _NO_PROTO */
694void MarkModalTransient (ClientData *pcdLeader, ClientData *pCD)
695#endif /* _NO_PROTO */
696{
697    if (!IS_APP_MODALIZED(pcdLeader))
698    {
699        /*
700         * Eat pointer button events while application modal.
701         */
702        XGrabButton (DISPLAY, AnyButton, AnyModifier,
703            pcdLeader->clientBaseWin, True,
704            ButtonPressMask | ButtonMotionMask, GrabModeAsync,
705            GrabModeAsync, None, wmGD.workspaceCursor);
706    }
707
708    /* bump application modal count */
709    if (pCD->inputMode == MWM_INPUT_FULL_APPLICATION_MODAL)
710        pcdLeader->fullModalCount++;
711    else
712        pcdLeader->primaryModalCount++;
713}
714
715
716/*************************************<->*************************************
717 *
718 *  DeleteTransient (pCD)
719 *
720 *
721 *  Description:
722 *  -----------
723 *  This function deletes the transient window from the lead window's list
724 *  of transients
725 *
726 *  Much of the complication of this code arises from trying to handle
727 *  mixtures of both full- and primary-application modal transients.
728 *  It also tries to handle the case where a sequence of application
729 *  modal transients appear in different places in the transient tree
730 *  (i.e. not as descendents of a previously existing full app modal
731 *  transient).
732 *
733 *  Inputs:
734 *  ------
735 *  pCD = pointer to client data of transient.
736 *
737 *************************************<->***********************************/
738
739#ifdef _NO_PROTO
740void DeleteTransient (pCD)
741        ClientData *pCD;
742
743#else /* _NO_PROTO */
744void DeleteTransient (ClientData *pCD)
745#endif /* _NO_PROTO */
746{
747    ClientData *pcdLeader;
748    ClientData *pcdPrev;
749    int modalCount;
750
751
752    /*
753     * Handle primary application modality.
754     * Reset the modal window counts for the leader windows up through the
755     * transient window tree.
756     */
757
758    modalCount = pCD->primaryModalCount;
759    if (pCD->inputMode == MWM_INPUT_PRIMARY_APPLICATION_MODAL)
760    {
761        modalCount += 1;
762    }
763    if (modalCount)
764    {
765        pcdLeader = pCD->transientLeader;
766        while (pcdLeader)
767        {
768            if (modalCount)
769                UnMarkModalTransient (pcdLeader, modalCount, pCD);
770
771            pcdLeader = pcdLeader->transientLeader;
772        }
773    }
774
775    /*
776     * Handle full application modality.
777     * Undo application modal windows in a depth first manner.
778     */
779
780    pcdLeader = FindTransientTreeLeader (pCD);
781
782    if (pCD->transientChildren)
783    {
784        DeleteFullAppModalChildren (pcdLeader, pCD->transientChildren);
785    }
786    if (pCD->inputMode == MWM_INPUT_FULL_APPLICATION_MODAL)
787
788    {
789        /*
790         * If this is a full application modal window then decrement
791         * the modal count for the rest of the transient tree.
792         */
793
794        FixupFullAppModalCounts (pcdLeader, pCD);
795    }
796
797
798    /*
799     * Delete this transient from its parent's list of transient windows.
800     */
801
802    pcdPrev = pCD->transientLeader->transientChildren;
803    if(pcdPrev)
804    {
805        if (pcdPrev == pCD)
806        {
807            pCD->transientLeader->transientChildren = pCD->transientSiblings;
808        }
809        else
810        {
811            while (pcdPrev && (pcdPrev->transientSiblings != pCD))
812            {
813                pcdPrev = pcdPrev->transientSiblings;
814            }
815            if (pcdPrev)
816              pcdPrev->transientSiblings = pCD->transientSiblings;
817        }
818    }
819
820} /* END OF FUNCTION DeleteTransient */
821
822
823/*************************************<->*************************************
824 *
825 *  DeleteFullAppModalChildren (pcdLeader, pCD)
826 *
827 *
828 *  Description:
829 *  -----------
830 *  This function handles the clean-up of nested full application modal
831 *  windows. The deletion has to be handled carefully to keep a correct
832 *  fullModalCount on the transients that remain in the tree.
833 *
834 *  The algorithm is to traverse the transient children depth first and
835 *  fix up the tree's fullModalCount for each full application modal
836 *  window that's found.
837 *
838 *  Inputs:
839 *  ------
840 *  pcdLeader   = pointer to client data of transient tree root.
841 *  pCD         = pointer to client data of transient subtree to delete.
842 *
843 *************************************<->***********************************/
844
845#ifdef _NO_PROTO
846void DeleteFullAppModalChildren (pcdLeader, pCD)
847        ClientData *pcdLeader, *pCD;
848
849#else /* _NO_PROTO */
850void DeleteFullAppModalChildren (ClientData *pcdLeader, ClientData *pCD)
851#endif /* _NO_PROTO */
852{
853
854    /* recursively do children first */
855    if (pCD->transientChildren)
856        DeleteFullAppModalChildren (pcdLeader, pCD->transientChildren);
857
858    /* do fullAppModal fixup for this guy */
859    FixupFullAppModalCounts (pcdLeader, pCD);
860
861    /* do siblings of passed transient */
862    if (pCD->transientSiblings)
863        DeleteFullAppModalChildren (pcdLeader, pCD->transientSiblings);
864
865   
866} /* END OF FUNCTION DeleteFullAppModalChildren */
867
868
869/*************************************<->*************************************
870 *
871 *  FixupFullAppModalCounts (pcdLeader, pcdDelete)
872 *
873 *
874 *  Description:
875 *  -----------
876 *  This function traverses the entire transient tree (pointed to by
877 *  pcdLeader) and fixes up the fullModalCounts to reflect the removal
878 *  of pcdDelete.
879 *
880 *  The fix-up consists of decrementing the count
881 *  of the remaining full app modal windows in the tree iff the remaining
882 *  window's fullModalCount is greater than the fullModalCount of the
883 *  transient being deleted.
884 *
885 *  Inputs:
886 *  ------
887 *  pcdLeader   = pointer to client data for head of transient tree.
888 *  pcdDelet    = pointer to client data of transient being deleted.
889 *
890 *************************************<->***********************************/
891
892void
893#ifdef _NO_PROTO
894FixupFullAppModalCounts (pcdLeader, pcdDelete)
895ClientData *pcdLeader, *pcdDelete;
896#else /* _NO_PROTO */
897FixupFullAppModalCounts (ClientData *pcdLeader, ClientData *pcdDelete)
898#endif /* _NO_PROTO */
899
900{
901
902    /* fixup children */
903    if (pcdLeader->transientChildren)
904    {
905        FixupFullAppModalCounts (pcdLeader->transientChildren, pcdDelete);
906    }
907
908    /*
909     * fixup leader: decrement the count if it is greater than
910     * the transient being deleted.
911     *
912     */
913    if (pcdLeader->fullModalCount > pcdDelete->fullModalCount)
914    {
915        UnMarkModalTransient (pcdLeader, 1, pcdDelete);
916    }
917
918    /* fixup siblings */
919    if (pcdLeader->transientSiblings)
920    {
921        FixupFullAppModalCounts (pcdLeader->transientSiblings, pcdDelete);
922    }
923   
924} /* END OF FUNCTION FixupFullAppModalCounts */
925
926
927
928/*************************************<->*************************************
929 *
930 *  UnMarkModalTransient (pcdModee, modalCount, pcdModal)
931 *
932 *
933 *  Description:
934 *  -----------
935 *  This function unmarks a transient window for application modal processing.
936 *  Original grabs are restored.
937 *
938 *  Inputs:
939 *  ------
940 *  pcdModee   = pointer to client data for transient to unmark
941 *  pcdModal   = pointer to client data for modal transient
942 *  modalCount = amount to decrement the client's modal count by
943 *
944 *
945 *************************************<->***********************************/
946
947#ifdef _NO_PROTO
948void UnMarkModalTransient (pcdModee, modalCount, pcdModal)
949        ClientData *pcdModee, *pcdModal;
950        int modalCount;
951
952#else /* _NO_PROTO */
953void UnMarkModalTransient (ClientData *pcdModee, int modalCount, ClientData *pcdModal)
954#endif /* _NO_PROTO */
955{
956    /* decrement application modal count */
957    if (pcdModal->inputMode == MWM_INPUT_FULL_APPLICATION_MODAL)
958        pcdModee->fullModalCount -= modalCount;
959    else if (pcdModal->inputMode == MWM_INPUT_PRIMARY_APPLICATION_MODAL)
960        pcdModee->primaryModalCount -= modalCount;
961
962    /*
963     * Restore original button bindings/grabs if not modal anymore
964     */
965    if (!IS_APP_MODALIZED(pcdModee))
966    {
967        XUngrabButton (DISPLAY, AnyButton, AnyModifier,
968            pcdModee->clientBaseWin);
969
970        SetupCButtonBindings (pcdModee->clientBaseWin, BUTTON_SPECS(pcdModee));
971
972        if ((wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT) &&
973            (wmGD.keyboardFocus != pcdModee))
974        {
975            DoExplicitSelectGrab (pcdModee->clientBaseWin);
976        }
977    }
978}
979
980
981/*************************************<->*************************************
982 *
983 *  PutTransientOnTop (pcd)
984 *
985 *
986 *  Description:
987 *  -----------
988 *  This function changes the transient window list to insure that the
989 *  specified transient window is on top of its siblings and its parent
990 *  is on top of its siblings, etc.  The sibling list is ordered such
991 *  that the first window in the list is on top of second window in the
992 *  list, etc.
993 *
994 *
995 *  Inputs:
996 *  ------
997 *  pcd = pointer to client data of a transient window
998 *
999 *
1000 *  Outputs:
1001 *  -------
1002 *  pcdLeader = (transientSiblings)
1003 *
1004 *  RETURN = True if the transient tree needs to be restacked
1005 *
1006 *************************************<->***********************************/
1007
1008#ifdef _NO_PROTO
1009Boolean PutTransientOnTop (pcd)
1010        ClientData *pcd;
1011
1012#else /* _NO_PROTO */
1013Boolean PutTransientOnTop (ClientData *pcd)
1014#endif /* _NO_PROTO */
1015{
1016    ClientData *pcdLeader;
1017    ClientData *pcdPrev;
1018    Boolean restack = False;
1019
1020
1021    pcdLeader = pcd->transientLeader;
1022    if (pcdLeader != NULL)
1023    {
1024        pcdPrev = pcdLeader->transientChildren;
1025        if (pcdPrev != pcd)
1026        {
1027            while (pcdPrev->transientSiblings != pcd)
1028            {
1029                pcdPrev = pcdPrev->transientSiblings;
1030            }
1031            pcdPrev->transientSiblings = pcd->transientSiblings;
1032            pcd->transientSiblings = pcdLeader->transientChildren;
1033            pcdLeader->transientChildren = pcd;
1034            restack = True;
1035        }
1036
1037        if (PutTransientOnTop (pcdLeader))
1038        {
1039            restack = True;
1040        }
1041    }
1042
1043    return (restack);
1044
1045} /* END OF FUNCTION PutTransientOnTop */
1046
1047
1048
1049/*************************************<->*************************************
1050 *
1051 *  PutTransientBelowSiblings (pcd)
1052 *
1053 *
1054 *  Description:
1055 *  -----------
1056 *  This function changes the transient window list to insure that the
1057 *  specified transient window is below its sibling windows.
1058 *
1059 *
1060 *  Inputs:
1061 *  ------
1062 *  pcd = pointer to client data of a transient window
1063 *
1064 *
1065 *  Outputs:
1066 *  -------
1067 *  pcdLeader = (transientSiblings)
1068 *
1069 *  RETURN = True if restacking has been done in the transient window tree.
1070 *
1071 *************************************<->***********************************/
1072
1073#ifdef _NO_PROTO
1074Boolean PutTransientBelowSiblings (pcd)
1075        ClientData *pcd;
1076
1077#else /* _NO_PROTO */
1078Boolean PutTransientBelowSiblings (ClientData *pcd)
1079#endif /* _NO_PROTO */
1080{
1081    ClientData *pcdLeader;
1082    ClientData *pcdNext;
1083    Boolean restack = False;
1084
1085
1086    pcdLeader = pcd->transientLeader;
1087    if (pcdLeader)
1088    {
1089        if (pcd->transientSiblings || (pcdLeader->transientChildren != pcd))
1090        {
1091            restack = True;
1092            if (pcdLeader->transientChildren == pcd)
1093            {
1094                pcdLeader->transientChildren = pcd->transientSiblings;
1095            }
1096
1097            pcdNext = pcdLeader->transientChildren;
1098            while (pcdNext->transientSiblings)
1099            {
1100                if (pcdNext->transientSiblings == pcd)
1101                {
1102                    pcdNext->transientSiblings = pcd->transientSiblings;
1103                }
1104                else
1105                {
1106                    pcdNext = pcdNext->transientSiblings;
1107                }
1108            }
1109            pcdNext->transientSiblings = pcd;
1110        }
1111        pcd->transientSiblings = NULL;
1112    }
1113
1114    return (restack);
1115
1116} /* END OF FUNCTION PutTransientBelowSiblings */
1117
1118
1119
1120/*************************************<->*************************************
1121 *
1122 *  RestackTransients (pcd, doTop)
1123 *
1124 *
1125 *  Description:
1126 *  -----------
1127 *  This function restacks windows in a transient window tree.  Secondary
1128 *  (transient) windows are stacked on top of their associated primary
1129 *  windows and the first secondary window in the transientSiblings list
1130 *  is stacked on top of the second window in the list, etc.
1131 * 
1132 *
1133 *  Inputs:
1134 *  ------
1135 *  pcd = pointer to client data of a window in a transient tree
1136 *
1137 *  doTop = True, put transient on top before stacking
1138 *
1139 *************************************<->***********************************/
1140
1141#ifdef _NO_PROTO
1142void RestackTransients (pcd, doTop)
1143        ClientData *pcd;
1144        Boolean doTop;
1145
1146#else /* _NO_PROTO */
1147void RestackTransients (ClientData *pcd, Boolean doTop)
1148#endif /* _NO_PROTO */
1149{
1150    ClientData *pcdLeader;
1151    int count;
1152    static int size = 0;
1153    static Window *windows = NULL;
1154    Window *nextWindow;
1155
1156
1157    /*
1158     * Build a restacking list and do the restacking.
1159     */
1160
1161    pcdLeader = FindTransientTreeLeader (pcd);
1162    count = CountTransientChildren (pcdLeader);
1163
1164    if (count > size)
1165    {
1166        /*
1167         * Expand the (static) windows buffer that is used in restacking.
1168         */
1169
1170        if (!(windows =
1171                (Window *)WmMalloc ((char*)windows, (count + 5) * sizeof (Window))))
1172        {
1173            /* cannot get memory space */
1174            size = 0;
1175            return;
1176        }
1177        size = count + 5;
1178    }
1179
1180    nextWindow = MakeTransientWindowList (windows, pcdLeader);
1181    *nextWindow = pcdLeader->clientFrameWin;
1182
1183    if (doTop && (count > 1))
1184    {
1185        XWindowChanges windowChanges;
1186
1187        /*
1188         * Force the transient we want on top to the top first
1189         * before calling XRestackWindows to avoid spurious
1190         * exposures and unnecessary repainting.
1191         */
1192
1193        windowChanges.sibling = windows[1];
1194        windowChanges.stack_mode = Above;
1195        XConfigureWindow (DISPLAY, windows[0],
1196            CWSibling | CWStackMode, &windowChanges);
1197    }
1198
1199    XRestackWindows (DISPLAY, windows, count);
1200
1201
1202} /* END OF FUNCTION RestackTransients */
1203
1204
1205
1206/*************************************<->*************************************
1207 *
1208 *  RestackTransientsAtWindow (pcd)
1209 *
1210 *
1211 *  Description:
1212 *  -----------
1213 *  This function restacks windows in a transient window tree.  The
1214 *  "anchor point" in the stack for the transient window tree is the
1215 *  specified window.
1216 * 
1217 *
1218 *  Inputs:
1219 *  ------
1220 *  pcd = pointer to client data of a window in a transient tree
1221 *
1222 *************************************<->***********************************/
1223
1224#ifdef _NO_PROTO
1225void RestackTransientsAtWindow (pcd)
1226     ClientData *pcd;
1227
1228#else /* _NO_PROTO */
1229void RestackTransientsAtWindow (ClientData *pcd)
1230#endif /* _NO_PROTO */
1231{
1232    ClientData *pcdTop;
1233    XWindowChanges windowChanges;
1234
1235
1236    if ((pcdTop = FindTransientOnTop (pcd)) != pcd)
1237    {
1238        windowChanges.sibling = pcd->clientFrameWin;
1239        windowChanges.stack_mode = Above;
1240        XConfigureWindow (DISPLAY, pcdTop->clientFrameWin,
1241            CWSibling | CWStackMode, &windowChanges);
1242    }
1243
1244    RestackTransients (pcd, False);
1245
1246} /* END OF FUNCTION RestackTransientsAtWindow */
1247
1248
1249
1250/*************************************<->*************************************
1251 *
1252 *  FindTransientTreeLeader (pcd)
1253 *
1254 *
1255 *  Description:
1256 *  -----------
1257 *  This function identifies the leader of the transient tree that
1258 *  contains the specified client.
1259 * 
1260 *
1261 *  Inputs:
1262 *  ------
1263 *  pcd = pointer to client data of a window in a transient tree.
1264 *
1265 *  Outputs:
1266 *  -------
1267 *  RETURN = pointer to the client data for the transient tree leader.
1268 *
1269 *************************************<->***********************************/
1270
1271#ifdef _NO_PROTO
1272ClientData * FindTransientTreeLeader (pcd)
1273        ClientData *pcd;
1274#else /* _NO_PROTO */
1275ClientData * FindTransientTreeLeader (ClientData *pcd)
1276#endif /* _NO_PROTO */
1277
1278{
1279
1280    /*
1281     * Find the head of the transient window tree.
1282     */
1283
1284    while (pcd->transientLeader)
1285    {
1286        pcd = pcd->transientLeader;
1287    }
1288
1289    return (pcd);
1290
1291} /* END OF FUNCTION FindTransientTreeLeader */
1292
1293
1294
1295/*************************************<->*************************************
1296 *
1297 *  CountTransientChildren (pcd)
1298 *
1299 *
1300 *  Description:
1301 *  -----------
1302 *  This function returns a count of the number of children in the
1303 *  transient window tree headed by the specified client window.
1304 * 
1305 *
1306 *  Inputs:
1307 *  ------
1308 *  pcd = pointer to client data of a window in a transient tree
1309 *
1310 *  Outputs:
1311 *  -------
1312 *  RETURN = count of transient windows in the transient window tree
1313 *
1314 *************************************<->***********************************/
1315
1316#ifdef _NO_PROTO
1317int
1318CountTransientChildren (pcd)
1319ClientData *pcd;
1320#else /* _NO_PROTO */
1321int
1322CountTransientChildren (ClientData *pcd)
1323#endif /* _NO_PROTO */
1324
1325{
1326    ClientData *pcdNext;
1327    int count = 1;
1328
1329
1330    pcdNext = pcd->transientChildren;
1331    while (pcdNext)
1332    {
1333        if (pcdNext->transientChildren)
1334        {
1335            count += CountTransientChildren (pcdNext);
1336        }
1337        else
1338        {
1339            count++;
1340        }
1341        pcdNext = pcdNext->transientSiblings;
1342    }
1343
1344    return (count);
1345
1346} /* END OF FUNCTION CountTransientChildren */
1347
1348
1349
1350/*************************************<->*************************************
1351 *
1352 *  MakeTransientWindowList (windows, pcd)
1353 *
1354 *
1355 *  Description:
1356 *  -----------
1357 *  This function makes a transient window list of windows in the
1358 *  transient window tree headed by the specified client.  This list is
1359 *  to be passed to XRestackWindows.
1360 * 
1361 *
1362 *  Inputs:
1363 *  ------
1364 *  windows = pointer to the windows list to be filled out
1365 *
1366 *  pcd = pointer to client data of a window in a transient tree
1367 *
1368 *  Outputs:
1369 *  -------
1370 *  RETURN = pointer to the next entry in the windows list
1371 *
1372 *************************************<->***********************************/
1373
1374#ifdef _NO_PROTO
1375Window * MakeTransientWindowList (windows, pcd)
1376        Window *windows;
1377        ClientData *pcd;
1378#else /* _NO_PROTO */
1379Window * MakeTransientWindowList (Window *windows, ClientData *pcd)
1380#endif /* _NO_PROTO */
1381
1382{
1383    ClientData *pcdNext;
1384
1385
1386    pcdNext = pcd->transientChildren;
1387    while (pcdNext)
1388    {
1389        if (pcdNext->transientChildren)
1390        {
1391            windows = MakeTransientWindowList (windows, pcdNext);
1392        }
1393        *windows = pcdNext->clientFrameWin;
1394        windows++;
1395        pcdNext = pcdNext->transientSiblings;
1396    }
1397
1398    return (windows);
1399
1400
1401} /* END OF FUNCTION MakeTransientWindowList */
1402
1403
1404
1405/*************************************<->*************************************
1406 *
1407 *  FindTransientFocus (pcd)
1408 *
1409 *
1410 *  Description:
1411 *  -----------
1412 *  This function identifies a window in the transient tree that is headed
1413 *  by the specified client that can accept the keyboard input.  The
1414 *  effect of application modal windows is taken into account.
1415 * 
1416 *
1417 *  Inputs:
1418 *  ------
1419 *  pcd = pointer to client data of a window in a transient tree.
1420 *
1421 *  Outputs:
1422 *  -------
1423 *  RETURN = pointer to the client data for a window that can accept the
1424 *      keyboard input focus.
1425 *
1426 *************************************<->***********************************/
1427
1428#ifdef _NO_PROTO
1429ClientData * FindTransientFocus (pcd)
1430        ClientData *pcd;
1431#else /* _NO_PROTO */
1432ClientData * FindTransientFocus (ClientData *pcd)
1433#endif /* _NO_PROTO */
1434
1435{
1436
1437    ClientData *pcdFocus;
1438
1439    /*
1440     * Find a window that does not have an application modal subordinate.
1441     * First, search descendents
1442     */
1443
1444    pcdFocus = pcd;
1445    while (pcdFocus->transientChildren && IS_APP_MODALIZED(pcdFocus))
1446    {
1447        pcdFocus = pcdFocus->transientChildren;
1448    }
1449
1450    /*
1451     * If (search of descendents FAILS) then search siblings.
1452     */
1453   
1454    if (IS_APP_MODALIZED(pcdFocus))
1455    {
1456        ClientData *pcdSibling;
1457
1458        pcdFocus = pcd;
1459        while (pcdFocus && IS_APP_MODALIZED(pcdFocus))
1460        {
1461            pcdSibling = pcdFocus;
1462            while (pcdSibling->transientSiblings && IS_APP_MODALIZED(pcdFocus))
1463            {
1464                pcdSibling = pcdSibling->transientSiblings;
1465            }
1466            if (IS_APP_MODALIZED(pcdSibling))
1467            {
1468                pcdFocus = pcdFocus->transientChildren;
1469            }
1470            else
1471            {
1472                pcdFocus = pcdSibling;
1473                break;
1474            }
1475        }
1476    }
1477
1478    return (pcdFocus ? pcdFocus : wmGD.keyboardFocus);
1479
1480} /* END OF FUNCTION FindTransientFocus */
1481
1482
1483
1484/*************************************<->*************************************
1485 *
1486 *  FindTransientOnTop (pcd)
1487 *
1488 *
1489 *  Description:
1490 *  -----------
1491 *  This function identifies the top-most transient window in the
1492 *  transient window tree that contains the specified client.
1493 * 
1494 *
1495 *  Inputs:
1496 *  ------
1497 *  pcd = pointer to client data of a window in a transient tree.
1498 *
1499 *  Outputs:
1500 *  -------
1501 *  RETURN = pointer to the client data for the top-most transient window.
1502 *
1503 *************************************<->***********************************/
1504
1505#ifdef _NO_PROTO
1506ClientData * FindTransientOnTop (pcd)
1507        ClientData *pcd;
1508#else /* _NO_PROTO */
1509ClientData * FindTransientOnTop (ClientData *pcd)
1510#endif /* _NO_PROTO */
1511
1512{
1513
1514    /*
1515     * Find the head of the transient window tree.
1516     */
1517
1518    pcd = FindTransientTreeLeader (pcd);
1519
1520
1521    /*
1522     * Find the top-most transient window (the window in the transient tree
1523     * that is highest in the window stack).
1524     */
1525
1526    while (pcd->transientChildren)
1527    {
1528        pcd = pcd->transientChildren;
1529    }
1530
1531    return (pcd);
1532
1533} /* END OF FUNCTION FindTransientOnTop */
1534
1535
1536
1537/*************************************<->*************************************
1538 *
1539 *  StackWindow (pWS, pEntry, onTop, pStackEntry)
1540 *
1541 *
1542 *  Description:
1543 *  -----------
1544 *  This function stacks a window of a particular type (normal or icon)
1545 *  to the top or botton of the window stack on the screen.
1546 * 
1547 *
1548 *  Inputs:
1549 *  ------
1550 *  pWS = pointer to workspace data
1551 *
1552 *  pEntry = pointer to the client list entry for the window to be restacked.
1553 *
1554 *  onTop = if True then the window is to be restacked on top of the
1555 *      specified stack window (if the stack window is not specified then
1556 *      the entry is added to the top of the window stack)
1557 *      otherwise the window is stacked below the specified stack window
1558 *      (or at the bottom of the window stack if the stack window is not
1559 *      specified).
1560 *
1561 *  pStackEntry = pointer to a client list entry for a window in the window
1562 *      stack that is to be used as a reference in restacking.
1563 *
1564 *************************************<->***********************************/
1565
1566#ifdef _NO_PROTO
1567void StackWindow (pWS, pEntry, onTop, pStackEntry)
1568        WmWorkspaceData *pWS;
1569        ClientListEntry *pEntry;
1570        Boolean onTop;
1571        ClientListEntry *pStackEntry;
1572
1573#else /* _NO_PROTO */
1574void StackWindow (WmWorkspaceData *pWS, ClientListEntry *pEntry, Boolean onTop, ClientListEntry *pStackEntry)
1575#endif /* _NO_PROTO */
1576{
1577    Window stackWindow;
1578    Boolean stackTransientTreeWindows = False;
1579    Window activeIconWindow;
1580    Window window;
1581    XWindowChanges changes;
1582    WmScreenData *pSD = pWS->pSD;
1583
1584
1585    if (pStackEntry)
1586    {
1587        if (pStackEntry->type == MINIMIZED_STATE)
1588        {
1589            stackWindow = ICON_FRAME_WIN(pStackEntry->pCD);
1590        }
1591        else
1592        {
1593            stackWindow = pStackEntry->pCD->clientFrameWin;
1594        }
1595    }
1596    else
1597    {
1598        stackWindow = (Window)0;
1599    }
1600
1601    if (pEntry->type == MINIMIZED_STATE)
1602    {
1603        window = ICON_FRAME_WIN(pEntry->pCD);
1604    }
1605    else
1606    {
1607        /*
1608         * Restack the transient tree if appropriate.
1609         */
1610
1611        if (pEntry->pCD->transientLeader || pEntry->pCD->transientChildren)
1612        {
1613            stackTransientTreeWindows = True;
1614            window = (FindTransientOnTop (pEntry->pCD))->clientFrameWin;
1615        }
1616        else
1617        {
1618            window = pEntry->pCD->clientFrameWin;
1619        }
1620    }
1621
1622
1623    /*
1624     * The active icon text label must be restacked along with the associated
1625     * icon.
1626     */
1627
1628    if ((pEntry->type == MINIMIZED_STATE) &&
1629        (pEntry->pCD == wmGD.keyboardFocus) &&
1630        (ICON_DECORATION(pEntry->pCD) & ICON_ACTIVE_LABEL_PART) &&
1631        (ACTIVE_ICON_TEXT_WIN))
1632    {
1633        activeIconWindow = ACTIVE_ICON_TEXT_WIN;
1634    }
1635    else
1636    {
1637        activeIconWindow = (Window)0;
1638    }
1639
1640    if (onTop)
1641    {
1642        if ((stackWindow == 0) && (pSD->clientList))
1643        {
1644            if (pSD->clientList->type == MINIMIZED_STATE)
1645            {
1646                stackWindow = ICON_FRAME_WIN(pSD->clientList->pCD);
1647            }
1648            else
1649            {
1650                if (pSD->clientList->pCD->transientChildren)
1651                {
1652                    stackWindow =
1653                     (FindTransientOnTop(pSD->clientList->pCD))->clientFrameWin;
1654                }
1655                else
1656                {
1657                    stackWindow = pSD->clientList->pCD->clientFrameWin;
1658                }
1659            }
1660        }
1661
1662        if (activeIconWindow)
1663        {
1664            changes.sibling = stackWindow;
1665            changes.stack_mode = Above;
1666            XConfigureWindow (DISPLAY, activeIconWindow,
1667                (CWSibling | CWStackMode), &changes);
1668            changes.sibling = activeIconWindow;
1669            changes.stack_mode = Below;
1670            XConfigureWindow (DISPLAY, window, (CWSibling | CWStackMode),
1671                &changes);
1672        }
1673        else
1674        {
1675            changes.sibling = stackWindow;
1676            changes.stack_mode = Above;
1677            XConfigureWindow (DISPLAY, window, (CWSibling | CWStackMode),
1678                &changes);
1679            if (stackTransientTreeWindows)
1680            {
1681                RestackTransients (pEntry->pCD, False);
1682            }
1683        }
1684    }
1685    else
1686    {
1687        if (stackWindow == 0)
1688        {
1689            if (pSD->lastClient->type == MINIMIZED_STATE)
1690            {
1691                stackWindow = ICON_FRAME_WIN(pSD->lastClient->pCD);
1692            }
1693            else
1694            {
1695                stackWindow = pSD->lastClient->pCD->clientFrameWin;
1696            }
1697        }
1698
1699        if (activeIconWindow)
1700        {
1701            changes.sibling = stackWindow;
1702            changes.stack_mode = Below;
1703            XConfigureWindow (DISPLAY, activeIconWindow,
1704                              (CWSibling | CWStackMode), &changes);
1705            changes.sibling = activeIconWindow;
1706            changes.stack_mode = Below;
1707            XConfigureWindow (DISPLAY, window, (CWSibling | CWStackMode),
1708                              &changes);
1709        }
1710        else
1711        {
1712            changes.sibling = stackWindow;
1713            changes.stack_mode = Below;
1714            XConfigureWindow (DISPLAY, window, (CWSibling | CWStackMode),
1715                              &changes);
1716            if (stackTransientTreeWindows)
1717            {
1718                RestackTransients (pEntry->pCD, False);
1719            }
1720        }
1721    }
1722
1723} /* END OF FUNCTION StackWindow */
1724
1725
1726
1727/*************************************<->*************************************
1728 *
1729 *  StackTransientWindow (pcd)
1730 *
1731 *
1732 *  Description:
1733 *  -----------
1734 *  This function stacks a transient window within its transient window
1735 *  tree on the screen.  The transient window tree should indicate the
1736 *  intended stacking position.
1737 * 
1738 *
1739 *  Inputs:
1740 *  ------
1741 *  pcd = pointer to client data of a window in a transient tree
1742 *
1743 *************************************<->***********************************/
1744
1745#ifdef _NO_PROTO
1746void StackTransientWindow (pcd)
1747        ClientData *pcd;
1748
1749#else /* _NO_PROTO */
1750void StackTransientWindow (ClientData *pcd)
1751#endif /* _NO_PROTO */
1752{
1753    XWindowChanges changes;
1754    ClientData *pcdPrev;
1755
1756
1757    if (pcd->transientLeader->transientChildren == pcd)
1758    {
1759        if (pcd->transientSiblings)
1760        {
1761            changes.sibling = pcd->transientSiblings->clientFrameWin;
1762        }
1763        else
1764        {
1765            changes.sibling = pcd->transientLeader->clientFrameWin;
1766        }
1767        changes.stack_mode = Above;
1768    }
1769    else
1770    {
1771        pcdPrev = pcd->transientLeader;
1772        while (pcdPrev->transientSiblings != pcd)
1773        {
1774            pcdPrev = pcdPrev->transientSiblings;
1775        }
1776        changes.sibling = pcdPrev->clientFrameWin;
1777        changes.stack_mode = Below;
1778    }
1779
1780    XConfigureWindow (DISPLAY, pcd->clientFrameWin, (CWSibling | CWStackMode),
1781        &changes);
1782
1783
1784} /* END OF FUNCTION StackTransientWindow */
1785
1786
1787
1788/*************************************<->*************************************
1789 *
1790 *  CheckIfClientObscuring (pcdTop, pcd)
1791 *
1792 *
1793 *  Description:
1794 *  -----------
1795 *  This function determines whether a window or a transient window tree
1796 *  is obscuring (at least partially) a window or a transient window tree
1797 *  that is below it in the window stack.
1798 * 
1799 *
1800 *  Inputs:
1801 *  ------
1802 *  pcdTop = pointer to client data for a window (it may be the leader of
1803 *      a transient tree; this window is the higher in the window stack
1804 *      than the window it is be checked against.
1805 *
1806 *  pcd = pointer to client data for a window (it may be the leader of
1807 *      a transient tree.
1808 *
1809 *
1810 *  Outputs:
1811 *  -------
1812 *  RETURN = True if the top window(s) overlap the lower window(s)
1813 *
1814 *************************************<->***********************************/
1815
1816#ifdef _NO_PROTO
1817Boolean CheckIfClientObscuring (pcdTop, pcd)
1818        ClientData *pcdTop;
1819        ClientData *pcd;
1820
1821#else /* _NO_PROTO */
1822Boolean CheckIfClientObscuring (ClientData *pcdTop, ClientData *pcd)
1823#endif /* _NO_PROTO */
1824{
1825    Boolean obscuring = False;
1826    ClientData *pcdNext;
1827
1828
1829    /*
1830     * Check only if the top window is visible onscreen.
1831     */
1832
1833    if (pcdTop->transientChildren && (pcdTop->clientState != MINIMIZED_STATE))
1834    {
1835        pcdNext = pcdTop->transientChildren;
1836        while (pcdNext && !obscuring)
1837        {
1838            obscuring = CheckIfClientObscuring (pcdNext, pcd);
1839            pcdNext = pcdNext->transientSiblings;
1840        }
1841    }
1842
1843    if (!obscuring && pcd->transientChildren &&
1844        (pcd->clientState != MINIMIZED_STATE))
1845    {
1846        pcdNext = pcd->transientChildren;
1847        while (pcdNext && !obscuring)
1848        {
1849            obscuring = CheckIfClientObscuring (pcdTop, pcdNext);
1850            pcdNext = pcdNext->transientSiblings;
1851        }
1852    }
1853
1854    if (!obscuring)
1855    {
1856        obscuring = CheckIfObscuring (pcdTop, pcd);
1857    }
1858
1859    return (obscuring);
1860
1861} /* END OF FUNCTION CheckIfClientObscuring */
1862
1863
1864
1865/*************************************<->*************************************
1866 *
1867 *  CheckIfObscuring (pcdA, pcdB)
1868 *
1869 *
1870 *  Description:
1871 *  -----------
1872 *  This function determines whether a window (not a transient tree)
1873 *  is obscuring (at least partially) a window (not a transient tree)
1874 *  that is below it in the window stack.
1875 * 
1876 *
1877 *  Inputs:
1878 *  ------
1879 *  pcdA = pointer to client data for a window; this window is higher in
1880 *      the window stack than the window it is be checked against.
1881 *
1882 *  pcdB = pointer to client data for a window.
1883 *
1884 *
1885 *  Outputs:
1886 *  -------
1887 *  RETURN = True if the top window overlaps the lower window
1888 *
1889 *************************************<->***********************************/
1890
1891#ifdef _NO_PROTO
1892Boolean CheckIfObscuring (pcdA, pcdB)
1893        ClientData *pcdA;
1894        ClientData *pcdB;
1895
1896#else /* _NO_PROTO */
1897Boolean CheckIfObscuring (ClientData *pcdA, ClientData *pcdB)
1898#endif /* _NO_PROTO */
1899{
1900    Boolean obscuring = False;
1901    int aX1;
1902    int aX2;
1903    int aY1;
1904    int aY2;
1905    int bX1;
1906    int bX2;
1907    int bY1;
1908    int bY2;
1909
1910
1911    if (pcdA->clientState == NORMAL_STATE)
1912    {
1913        aX1 = pcdA->clientX - pcdA->clientOffset.x;
1914        aY1 = pcdA->clientY - pcdA->clientOffset.y;
1915        aX2 = aX1 + pcdA->clientWidth + (2 * pcdA->clientOffset.x) - 1;
1916        aY2 = aY1 + pcdA->clientHeight + pcdA->clientOffset.y +
1917              pcdA->clientOffset.x - 1;
1918    }
1919    else if (pcdA->clientState == MINIMIZED_STATE)
1920    {
1921        aX1 = ICON_X(pcdA);
1922        aY1 = ICON_Y(pcdA);
1923        aX2 = aX1 + ICON_WIDTH(pcdA) - 1;
1924        aY2 = aY1 + ICON_HEIGHT(pcdA) - 1;
1925    }
1926    else /* (pcdA->clientState == MAXIMIZED_STATE) */
1927    {
1928        aX1 = pcdA->maxX - pcdA->clientOffset.x;
1929        aY1 = pcdA->maxY - pcdA->clientOffset.y;
1930        aX2 = aX1 + pcdA->maxWidth + (2 * pcdA->clientOffset.x) - 1;
1931        aY2 = aY1 + pcdA->maxHeight + pcdA->clientOffset.y +
1932              pcdA->clientOffset.x - 1;
1933    }
1934
1935    if (pcdB->clientState == NORMAL_STATE)
1936    {
1937        bX1 = pcdB->clientX - pcdB->clientOffset.x;
1938        bY1 = pcdB->clientY - pcdB->clientOffset.y;
1939        bX2 = bX1 + pcdB->clientWidth + (2 * pcdB->clientOffset.x) - 1;
1940        bY2 = bY1 + pcdB->clientHeight + pcdB->clientOffset.y +
1941              pcdB->clientOffset.x - 1;
1942    }
1943    else if (pcdB->clientState == MINIMIZED_STATE)
1944    {
1945        bX1 = ICON_X(pcdB);
1946        bY1 = ICON_Y(pcdB);
1947        bX2 = bX1 + ICON_WIDTH(pcdB) - 1;
1948        bY2 = bY1 + ICON_HEIGHT(pcdB) - 1;
1949    }
1950    else /* (pcdB->clientState == MAXIMIZED_STATE) */
1951    {
1952        bX1 = pcdB->maxX - pcdB->clientOffset.x;
1953        bY1 = pcdB->maxY - pcdB->clientOffset.y;
1954        bX2 = bX1 + pcdB->maxWidth + (2 * pcdB->clientOffset.x) - 1;
1955        bY2 = bY1 + pcdB->maxHeight + pcdB->clientOffset.y +
1956              pcdB->clientOffset.x - 1;
1957    }
1958
1959    /*
1960     * Check if there is overlap in both dimensions.
1961     */
1962
1963    if (((aX1 >= bX1) && (aX1 <= bX2)) || ((aX2 >= bX1) && (aX2 <= bX2)) ||
1964        ((bX1 >= aX1) && (bX1 <= aX2)) || ((bX2 >= aX1) && (bX2 <= aX2)))
1965    {
1966        if (((aY1 >= bY1) && (aY1 <= bY2)) || ((aY2 >= bY1) && (aY2 <= bY2)) ||
1967            ((bY1 >= aY1) && (bY1 <= aY2)) || ((bY2 >= aY1) && (bY2 <= aY2)))
1968        {
1969            obscuring = True;
1970        }
1971    }
1972
1973    return (obscuring);
1974
1975
1976} /* END OF FUNCTION CheckIfObscuring */
1977
1978
1979
1980/*************************************<->*************************************
1981 *
1982 *  CheckIfClientObscuredByAny (pcd)
1983 *
1984 *
1985 *  Description:
1986 *  -----------
1987 *  This function determines whether a window or a transient window tree
1988 *  is obscured (at least partially) by any other window.
1989 * 
1990 *
1991 *  Inputs:
1992 *  ------
1993 *  pcd = pointer to client data for a window (it may be the leader of
1994 *      a transient tree.
1995 *
1996 *
1997 *  Outputs:
1998 *  -------
1999 *  RETURN = True if the window(s) are overlapped.
2000 *
2001 *************************************<->***********************************/
2002
2003#ifdef _NO_PROTO
2004Boolean CheckIfClientObscuredByAny (pcd)
2005        ClientData *pcd;
2006
2007#else /* _NO_PROTO */
2008Boolean CheckIfClientObscuredByAny (ClientData *pcd)
2009#endif /* _NO_PROTO */
2010{
2011    Boolean obscured = False;
2012    ClientListEntry *pListEntry;
2013
2014
2015    pListEntry = ACTIVE_PSD->clientList;
2016    while (pListEntry && !obscured)
2017    {
2018        if (pListEntry->pCD == pcd)
2019        {
2020            if (((pListEntry->type == MINIMIZED_STATE) &&
2021                 (pListEntry->pCD->clientState == MINIMIZED_STATE)) ||
2022                ((pListEntry->type != MINIMIZED_STATE) &&
2023                 (pListEntry->pCD->clientState != MINIMIZED_STATE)))
2024            {
2025                pListEntry = NULL;
2026            }
2027        }
2028        else if (((pListEntry->type == MINIMIZED_STATE) &&
2029                   (pListEntry->pCD->clientState == MINIMIZED_STATE)) ||
2030                 ((pListEntry->type != MINIMIZED_STATE) &&
2031                  (pListEntry->pCD->clientState != MINIMIZED_STATE)))
2032        {
2033            /*
2034             * The window for the entry is visible on screen.  See if it
2035             * obscures the indicated window.
2036             */
2037
2038            obscured = CheckIfClientObscuring (pListEntry->pCD, pcd);
2039        }
2040
2041        if (pListEntry)
2042        {
2043            pListEntry = pListEntry->nextSibling;
2044        }
2045    }
2046
2047    return (obscured);
2048
2049} /* END OF FUNCTION CheckIfClientObscuredByAny */
2050
2051
2052
2053/*************************************<->*************************************
2054 *
2055 *  CheckIfClientObscuringAny (pcd)
2056 *
2057 *
2058 *  Description:
2059 *  -----------
2060 *  This function determines whether a window or a transient window tree
2061 *  is obscuring another window.
2062 * 
2063 *
2064 *  Inputs:
2065 *  ------
2066 *  pcd = pointer to client data for a window (it may be the leader of
2067 *      a transient tree.
2068 *
2069 *
2070 *  Outputs:
2071 *  -------
2072 *  RETURN = True if the window(s) overlaps anther window.
2073 *
2074 *************************************<->***********************************/
2075
2076#ifdef _NO_PROTO
2077Boolean CheckIfClientObscuringAny (pcd)
2078ClientData *pcd;
2079
2080#else /* _NO_PROTO */
2081Boolean CheckIfClientObscuringAny (ClientData *pcd)
2082#endif /* _NO_PROTO */
2083{
2084    Boolean obscuring = False;
2085    ClientListEntry *pListEntry;
2086
2087
2088    pListEntry = (pcd->clientState == MINIMIZED_STATE) ?
2089                                        &pcd->iconEntry : &pcd->clientEntry;
2090    while (pListEntry && !obscuring)
2091    {
2092        if ((pListEntry->pCD != pcd) &&
2093            (((pListEntry->type == MINIMIZED_STATE) &&
2094              (pListEntry->pCD->clientState == MINIMIZED_STATE)) ||
2095             ((pListEntry->type != MINIMIZED_STATE) &&
2096              (pListEntry->pCD->clientState != MINIMIZED_STATE))))
2097        {
2098            obscuring = CheckIfClientObscuring (pcd, pListEntry->pCD);
2099        }
2100
2101        pListEntry = pListEntry->nextSibling;
2102    }
2103
2104    return (obscuring);
2105
2106} /* END OF FUNCTION CheckIfClientObscuringAny */
2107
2108
2109
2110/*************************************<->*************************************
2111 *
2112 *  SetupSystemModalState (pCD)
2113 *
2114 *
2115 *  Description:
2116 *  -----------
2117 *  This function prepares for mapping a system modal window.  An input
2118 *  screen window is mapped below the system modal window to prevent input
2119 *  to the windows not related to the system modal window.
2120 * 
2121 *
2122 *  Inputs:
2123 *  ------
2124 *  pCD = pointer to client data for the system modal window; if NULL the
2125 *      system modal window is a special window manager dialog box
2126 *
2127 *
2128 *  Outputs:
2129 *  -------
2130 *  wmGD = changes to system modal state data
2131 *
2132 *************************************<->***********************************/
2133
2134#ifdef _NO_PROTO
2135void SetupSystemModalState (pCD)
2136        ClientData *pCD;
2137
2138#else /* _NO_PROTO */
2139void SetupSystemModalState (ClientData *pCD)
2140#endif /* _NO_PROTO */
2141{
2142    XWindowChanges windowChanges;
2143    unsigned int   width, height;
2144    unsigned int   x_hot, y_hot;
2145    unsigned char *bits;
2146    unsigned char *mask_bits;
2147    WmScreenData *pSD;
2148    int scr;
2149
2150#ifdef LARGECURSORS
2151
2152    if (wmGD.useLargeCursors)
2153    {
2154        width = noenter32_width;
2155        height = noenter32_height;
2156        x_hot = noenter32_x_hot;
2157        y_hot = noenter32_y_hot;
2158        bits = noenter32_bits;
2159        mask_bits = noenter32m_bits;
2160    }
2161    else
2162
2163#endif /* LARGECURSORS */
2164
2165    {
2166        width = noenter16_width;
2167        height = noenter16_height;
2168        x_hot = noenter16_x_hot;
2169        y_hot = noenter16_y_hot;
2170        bits = noenter16_bits;
2171        mask_bits = noenter16m_bits;
2172    }
2173
2174    for (scr=0; scr<wmGD.numScreens; scr++)
2175    {
2176        pSD = &(wmGD.Screens[scr]);
2177       
2178        /*
2179         * Make the system modal input screen window if necessary.
2180         */
2181       
2182        if (pSD->managed && pSD->inputScreenWindow == 0)
2183        {
2184            XSetWindowAttributes windowAttributes;
2185            Pixmap               pixmap;
2186            Pixmap               maskPixmap;
2187            XColor               xcolors[2];
2188           
2189            windowAttributes.event_mask = ButtonPressMask;
2190            if (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_POINTER)
2191            {
2192                windowAttributes.event_mask |= EnterWindowMask;
2193            }
2194            windowAttributes.override_redirect = True;
2195           
2196            pixmap = XCreateBitmapFromData (DISPLAY, pSD->rootWindow,
2197                                            (char *)bits, width, height);
2198           
2199            maskPixmap = XCreateBitmapFromData (DISPLAY, pSD->rootWindow,
2200                                                (char *)mask_bits, width, height);
2201           
2202            xcolors[0].pixel = BlackPixel (DISPLAY, pSD->screen);
2203            xcolors[1].pixel = WhitePixel (DISPLAY, pSD->screen);
2204            XQueryColors (DISPLAY, DefaultColormap (DISPLAY, pSD->screen),
2205                          xcolors, 2);
2206            windowAttributes.cursor =
2207                XCreatePixmapCursor (DISPLAY, pixmap, maskPixmap,
2208                                     &(xcolors[0]), &(xcolors[1]),
2209                                     x_hot, y_hot);
2210            XFreePixmap (DISPLAY, pixmap);
2211            XFreePixmap (DISPLAY, maskPixmap);
2212           
2213            pSD->inputScreenWindow =
2214                XCreateWindow (DISPLAY, pSD->rootWindow, 0, 0,
2215                               DisplayWidth (DISPLAY, pSD->screen),
2216                               DisplayHeight (DISPLAY, pSD->screen),
2217                               0,
2218                               0,
2219                               InputOnly,
2220                               CopyFromParent,
2221                               CWEventMask | CWOverrideRedirect | CWCursor,
2222                               &windowAttributes);
2223        }
2224        if (pSD->managed && pSD != ACTIVE_PSD)
2225        {
2226            XMapRaised (DISPLAY, pSD->inputScreenWindow);
2227        }
2228    }
2229   
2230    if (pCD)
2231    {
2232        wmGD.systemModalWindow = pCD->clientFrameWin;
2233    }
2234    else
2235    {
2236        /*
2237         * ELSE: the system modal window is a special window manager dialog
2238         * box and wmGD.systemModalWindow is set prior to the call to
2239         * SetupSystemModalState.  Set the focus to the special window manager
2240         * dialog box.
2241         */
2242       
2243        SetKeyboardFocus (NULL, REFRESH_LAST_FOCUS);
2244        XSetInputFocus (DISPLAY, wmGD.systemModalWindow, RevertToPointerRoot,
2245                        CurrentTime);
2246    }
2247   
2248   
2249    /*
2250     * Map the system modal input screen window below the system modal
2251     * window.
2252     */
2253   
2254    windowChanges.sibling = wmGD.systemModalWindow;
2255    windowChanges.stack_mode = Below;
2256    XConfigureWindow (DISPLAY, ACTIVE_PSD->inputScreenWindow,
2257                      CWSibling | CWStackMode, &windowChanges);
2258   
2259    XMapWindow (DISPLAY, ACTIVE_PSD->inputScreenWindow);
2260   
2261   
2262    /*
2263     * Setup the system modal global data.
2264     */
2265   
2266    wmGD.systemModalActive = True;
2267    wmGD.systemModalClient = pCD;
2268   
2269   
2270} /* END OF FUNCTION SetupSystemModalState */
2271
2272
2273
2274/*************************************<->*************************************
2275 *
2276 *  UndoSystemModalState ()
2277 *
2278 *
2279 *  Description:
2280 *  -----------
2281 *  This function cleans up after a system modal window goes away.
2282 * 
2283 *
2284 *  Inputs:
2285 *  ------
2286 *  wmGD = (system modal state data)
2287 *
2288 *
2289 *  Outputs:
2290 *  -------
2291 *  wmGD = changes to system modal state data
2292 *
2293 *************************************<->***********************************/
2294
2295#ifdef _NO_PROTO
2296void UndoSystemModalState ()
2297
2298#else /* _NO_PROTO */
2299void UndoSystemModalState (void)
2300#endif /* _NO_PROTO */
2301{
2302    int scr;
2303   
2304    /*
2305     * Unmap the system modal input screen window.
2306     */
2307
2308    for (scr = 0; scr < wmGD.numScreens; scr++)
2309    {
2310        if(wmGD.Screens[scr].managed)
2311        {
2312            XUnmapWindow (DISPLAY, wmGD.Screens[scr].inputScreenWindow);
2313        }
2314    }
2315
2316    /*
2317     * Reset the focus if a window manager system modal dialog box was
2318     * being displayed.
2319     */
2320
2321    if (!wmGD.systemModalClient)
2322    {
2323        AutoResetKeyFocus (NULL, CurrentTime);
2324    }
2325
2326
2327    /*
2328     * Reset the system modal global data.
2329     */
2330
2331    wmGD.systemModalActive = False;
2332    wmGD.systemModalClient = NULL;
2333    wmGD.systemModalWindow = 0;
2334
2335} /* END OF FUNCTION UndoSystemModalState */
2336
2337
2338
2339/*************************************<->*************************************
2340 *
2341 *  FindClientNameMatch (pStartingEntry, toNext, clientName, types)
2342 *
2343 *
2344 *  Description:
2345 *  -----------
2346 *  This function searches for a client that has a particular name or class.
2347 *  A match will be indicated if the client with the name or class also
2348 *  is in a particular state.
2349 * 
2350 *
2351 *  Inputs:
2352 *  ------
2353 *  pEntry = pointer to the client list entry where the search is
2354 *      to begin.
2355 *
2356 *  toNext = if True then search client list from first to last; otherwise
2357 *      search the client list last to first.
2358 *
2359 *  clientName = string that indicates a client name or class.
2360 *
2361 *  type = types of objects (icon, window, ...) that are to be matched.
2362 *
2363 *
2364 *  Outputs:
2365 *  -------
2366 *  RETURN = pointer to client list entry for matched client.
2367 *
2368 *************************************<->***********************************/
2369#ifdef _NO_PROTO
2370ClientListEntry * FindClientNameMatch (pEntry, toNext, clientName, types)
2371        ClientListEntry *pEntry;
2372        Boolean toNext;
2373        String clientName;
2374        unsigned long types;
2375#else /* _NO_PROTO */
2376ClientListEntry * FindClientNameMatch (ClientListEntry *pEntry,
2377                                       Boolean toNext,
2378                                       String clientName,
2379                                       unsigned long types)
2380#endif /* _NO_PROTO */
2381
2382{
2383    Boolean foundMatch = False;
2384    Boolean checkEntry;
2385    ClientData *pCD;
2386
2387
2388    while (!foundMatch && pEntry)
2389    {
2390        checkEntry = False;
2391        pCD = pEntry->pCD;
2392        if (pEntry->type == MINIMIZED_STATE)
2393        {
2394            if ((pCD->clientState == MINIMIZED_STATE) &&
2395                (types & F_GROUP_ICON))
2396            {
2397                checkEntry = True;
2398            }
2399        }
2400        else
2401        {
2402            if ((pCD->clientState != MINIMIZED_STATE) &&
2403                (types & F_GROUP_WINDOW))
2404            {
2405                checkEntry = True;
2406            }
2407        }
2408
2409        if (checkEntry &&
2410            ((pCD->clientName && (strcmp (clientName,pCD->clientName) == 0)) ||
2411             (pCD->clientClass && (strcmp (clientName,pCD->clientClass) == 0))))
2412        {
2413            foundMatch = True;
2414        }
2415        else
2416        {
2417            pEntry = (toNext) ? pEntry->nextSibling : pEntry->prevSibling;
2418        }
2419    }
2420
2421    return (pEntry);
2422
2423} /* END OF FUNCTION FindClientNameMatch */
Note: See TracBrowser for help on using the repository browser.