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

Revision 9757, 29.8 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 OPEN SOFTWARE FOUNDATION, INC.
3 * ALL RIGHTS RESERVED
4*/
5/*
6 * Motif Release 1.2.1
7*/
8#ifdef REV_INFO
9#ifndef lint
10static char rcsid[] = "$RCSfile: WmWinState.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#include "WmICCC.h"
22#include "WmProtocol.h"
23
24#ifdef AUTOMATION
25#include <stdio.h>
26#include <math.h>
27#include <Xm/ScrollBarP.h>
28#endif /* AUTOMATION */
29
30/*
31 * include extern functions
32 */
33
34#include "WmCDecor.h"
35#include "WmFunction.h"
36#include "WmIDecor.h"
37#include "WmIPlace.h"
38#include "WmIconBox.h"
39#include "WmKeyFocus.h"
40#include "WmManage.h"
41#include "WmProperty.h"
42#include "WmWinInfo.h"
43#include "WmWinList.h"
44
45
46/*
47 * Function Declarations:
48 */
49
50#ifdef _NO_PROTO
51void    ConfigureNewState ();
52void    MapClientWindows ();
53void    SetClientState ();
54void    SetClientStateWithEventMask ();
55void    SetClientWMState ();
56void    SetupWindowState ();
57void    ShowIconForMinimizedClient ();
58static void UnmapClients ();
59static void SetupWindowStateWithEventMask ();
60#else /* _NO_PROTO */
61void SetClientState (ClientData *pCD, int newState, Time setTime);
62void SetClientStateWithEventMask (ClientData *pCD, int newState, Time setTime, unsigned int event_mask);
63void SetupWindowState (ClientData *pCD, int newState, Time setTime);
64void ConfigureNewState (ClientData *pcd);
65static void UnmapClients (ClientData *pCD, unsigned int event_mask);
66void SetClientWMState (ClientData *pCD, int wmState, int mwmState);
67void MapClientWindows (ClientData *pCD);
68void ShowIconForMinimizedClient (WmWorkspaceData *pWS, ClientData *pCD);
69static void SetupWindowStateWithEventMask (ClientData *pCD, int newState, Time setTime, unsigned int event_mask);
70#endif /* _NO_PROTO */
71
72#ifdef AUTOMATION
73#ifdef _NO_PROTO
74static void SetMwmIconInfo();
75static void FillIconBoxInfo();
76#else
77static void SetMwmIconInfo(ClientData *pcd);
78static void FillIconBoxInfo(ClientData *pcd,
79                            PropMwmFrameIconInfo *frame_icon_prop);
80#endif /* _NO_PROTO */
81#endif /* AUTOMATION */
82
83
84/*
85 * Global Variables:
86 */
87extern int firstTime;
88
89
90/******************************<->*************************************
91 *
92 *  SetClientState (pCD, newState, setTime)
93 *
94 *
95 *  Description:
96 *  -----------
97 *  This function is used to change the state of a client window (between
98 *  withdrawn, normal, minimized, maximized).
99 *
100 *
101 *  Inputs:
102 *  ------
103 *  pCD = This is a pointer to the window data for the window that
104 *        is to have its state changed. The fields that are used
105 *        are clientState, ...
106 *
107 *  newState = This is the state that the client window is to be changed to.
108 *
109 *  setTime = timestamp for state setting operations
110 *
111 *
112 *  Outputs:
113 *  -------
114 *  pCD.clientState = new client state
115 *
116 ******************************<->***********************************/
117
118#ifdef _NO_PROTO
119void SetClientState (pCD, newState, setTime)
120        ClientData *pCD;
121        int newState;
122        Time setTime;
123
124#else /* _NO_PROTO */
125void SetClientState (ClientData *pCD, int newState, Time setTime)
126#endif /* _NO_PROTO */
127{
128        SetClientStateWithEventMask(pCD, newState, setTime, (unsigned int)0);
129} /* END OF FUNCTION SetClientState */
130
131#ifdef _NO_PROTO
132void SetClientStateWithEventMask (pCD, newState, setTime, event_mask)
133        ClientData *pCD;
134        int newState;
135        Time setTime;
136        unsigned int event_mask;
137#else /* _NO_PROTO */
138void SetClientStateWithEventMask (ClientData *pCD, int newState, Time setTime, unsigned int event_mask)
139#endif /* _NO_PROTO */
140{
141    ClientData *pcdLeader;
142    int currentState;
143    WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
144
145    currentState = pCD->clientState;
146    if (currentState == newState)
147    {
148        /* no change in state */
149        return;
150    }
151
152
153    /*
154     * Undo the old state and setup the new state.  If this is a transient
155     * window then insure that it is put in a state that is compatible
156     * with its transient leader (e.g., it cannot be minimized separately).
157     */
158
159    pcdLeader = (pCD->transientLeader) ? FindTransientTreeLeader (pCD) : pCD;
160
161    if (pCD->transientLeader)
162    {
163        if ((pcdLeader->clientState == MINIMIZED_STATE) &&
164            (newState != WITHDRAWN_STATE))
165        {
166            newState = MINIMIZED_STATE;
167        }
168        else if ((newState == MINIMIZED_STATE) &&
169                 (pcdLeader->clientState != MINIMIZED_STATE))
170        {
171            if (currentState == WITHDRAWN_STATE)
172            {
173                newState = NORMAL_STATE;
174            }
175            else
176            {
177                newState = currentState;
178            }
179        }
180        if (newState == currentState)
181        {
182            return;
183        }
184    }
185
186    switch (newState)
187    {
188
189        case WITHDRAWN_STATE:
190        {
191            /*
192             * Free window manager resources (frame and icon).  The
193             * WM_STATE property is set in WithdrawWindow.
194             */
195
196            UnManageWindow (pCD);
197            break;
198        }
199
200        case NORMAL_STATE:
201        case MAXIMIZED_STATE:
202        {
203            SetupWindowStateWithEventMask (pCD, newState, setTime, event_mask);
204            break;
205        }
206
207        case MINIMIZED_STATE:
208        {
209            Boolean clientHasFocus;
210
211            /*
212             * Transient windows are minimized with the rest of the transient
213             * tree, including the transient leader.
214             */
215
216            if ((pCD->clientState == NORMAL_STATE) ||
217                (pCD->clientState == MAXIMIZED_STATE))
218            {
219                if ((wmGD.keyboardFocus == pCD) ||
220                    (pCD->transientChildren && wmGD.keyboardFocus &&
221                     (pCD == FindTransientTreeLeader (wmGD.keyboardFocus))))
222                {
223                    clientHasFocus = True;
224                }
225                else
226                {
227                    clientHasFocus = False;
228                }
229
230                if (clientHasFocus ||
231                  ((wmGD.nextKeyboardFocus == pCD) ||
232                   (pCD->transientChildren && wmGD.keyboardFocus &&
233                    (pCD == FindTransientTreeLeader (wmGD.nextKeyboardFocus)))))
234                {
235                    /*
236                     * Give up the keyboard focus when minimized (including
237                     * the case in which an associated transient window has
238                     * the focus).  Immediately remove the focus indication
239                     * from the window being minimized.
240                     */
241
242                    if (wmGD.autoKeyFocus &&
243                        (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT))
244                    {
245                        AutoResetKeyFocus (pcdLeader, setTime);
246                    }
247                    else
248                    {
249                        Do_Focus_Key (NULL, setTime,
250                                ALWAYS_SET_FOCUS | WORKSPACE_IF_NULL);
251                    }
252
253                    if (clientHasFocus)
254                    {
255                        SetKeyboardFocus (NULL, 0);
256                    }
257                }
258
259                /* unmap main client and all transients */
260                UnmapClients (pCD, event_mask);
261            }
262
263            /*
264             * Display the icon for the minimized client.
265             */
266
267            if (ICON_FRAME_WIN(pCD))
268            {
269                ShowIconForMinimizedClient (pSD->pActiveWS, pCD);
270            }
271
272            SetClientWMState (pCD, IconicState, MINIMIZED_STATE);
273
274            if ((pSD->useIconBox) && P_ICON_BOX(pCD))
275            {
276                if ((pCD->clientFlags & ICON_BOX) && ACTIVE_ICON_TEXT_WIN)
277                {
278                    /*
279                     * Hide active icon text window and reparent it to
280                     * root
281                     */
282                    HideActiveIconText((WmScreenData *)NULL);
283                    pSD->activeLabelParent = ACTIVE_ROOT;
284                    XReparentWindow(DISPLAY, ACTIVE_ICON_TEXT_WIN ,
285                                ACTIVE_ROOT, 0, 0 );
286                }
287                if (ICON_FRAME_WIN(pCD))
288                {
289                    /*
290                     * force icon appearance in icon box to change
291                     */
292                    IconExposureProc (pCD, True);
293                }
294            }
295            break;
296        }
297
298    }
299#ifdef AUTOMATION
300        SetMwmIconInfo(pCD);
301#endif
302
303} /* END OF FUNCTION SetClientStateWithEventMask */
304
305
306
307/*************************************<->*************************************
308 *
309 *  SetupWindowStateWithEventMask (pCD, newState, setTime, event_mask)
310 *
311 *
312 *  Description:
313 *  -----------
314 *  This function is used to setup a client window in the Normal or Maximized
315 *  state.
316 *
317 *
318 *  Inputs:
319 *  ------
320 *  pCD = This is a pointer to the window data for the window that
321 *        is to have its state changed.
322 *
323 *  newState = This is the state that the client window is to be changed to.
324 *
325 *  setTime = timestamp for state setting operations
326 *
327 *  event_mask = what to grab to prevent stray events going somewhere
328 *
329 *  Outputs:
330 *  -------
331 *  pCD.clientState = new client state
332 *
333 *************************************<->***********************************/
334
335#ifdef _NO_PROTO
336static void SetupWindowStateWithEventMask (pCD, newState, setTime, event_mask)
337        ClientData *pCD;
338        int newState;
339        Time setTime;
340        unsigned int event_mask;
341#else /* _NO_PROTO */
342static void SetupWindowStateWithEventMask (ClientData *pCD, int newState,
343        Time setTime, unsigned int event_mask)
344#endif /* _NO_PROTO */
345{
346    int currentState;
347    WmWorkspaceData *pWS = PSD_FOR_CLIENT(pCD)->pActiveWS;
348    WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
349
350    currentState = pCD->clientState;
351
352    /*
353     * A transient window is not restored or maximized if the transient leader
354     * is minimized.
355     */
356
357    if (newState == NORMAL_STATE)
358    {
359        if (pCD->maxConfig == True)
360        {
361            /*
362             * The configuration function uses maxConfig to determine
363             * what the current configuration is (and then resets
364             * maxConfig) and uses the state paramenter to determine
365             * what the new configuration is.
366             */
367
368            ConfigureNewState (pCD);
369        }
370    }
371    else /* MAXIMIZED_STATE */
372    {
373        if (pCD->maxConfig == False)
374        {
375            ConfigureNewState (pCD);
376        }
377    }
378
379    if (currentState == MINIMIZED_STATE)
380    {
381        Boolean clearIconFocus;
382
383        /*
384         * give up keyboard focus
385         */
386
387        if ((wmGD.keyboardFocus == pCD) ||
388            (wmGD.nextKeyboardFocus == pCD))
389        {
390            Do_Focus_Key (NULL, setTime, ALWAYS_SET_FOCUS | WORKSPACE_IF_NULL);
391        }
392
393        if (wmGD.keyboardFocus == pCD)
394        {
395            clearIconFocus = True;
396        }
397        else
398        {
399            clearIconFocus = False;
400        }
401
402        /*
403         * The wm icon frame window and the client icon window
404         * (if it is being used) are mapped and the client window and
405         * client frame are unmapped.
406         */
407
408        if (ICON_FRAME_WIN(pCD))
409        {
410            if (pSD->useIconBox && P_ICON_BOX(pCD) &&
411                !(pCD->clientFlags & ICON_BOX))
412            {
413                ShowClientIconState(pCD, newState);
414            }
415            else
416            {
417                Boolean doGrab = False;
418                if (event_mask)
419                doGrab = (Success == XGrabPointer
420                        (DISPLAY, DefaultRootWindow(DISPLAY),
421                        False, event_mask, GrabModeAsync, GrabModeAsync,
422                        None, None, CurrentTime));
423                XUnmapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
424                if (pCD->iconWindow)
425                {
426                    XUnmapWindow (DISPLAY, pCD->iconWindow);
427                }
428                if (event_mask && doGrab)
429                {
430                        XEvent event;
431                        XMaskEvent(DISPLAY, event_mask, &event);
432                        XUngrabPointer(DISPLAY,CurrentTime);
433                }
434                if ((wmGD.iconAutoPlace) && (ICON_PLACE(pCD) != NO_ICON_PLACE))
435                {
436                    pWS->IPData.placeList[ICON_PLACE(pCD)].pCD =
437                        NULL;
438                }
439            }
440
441            if (clearIconFocus)
442            {
443                ClearFocusIndication (pCD, False /*no refresh*/);
444                wmGD.keyboardFocus = NULL;
445            }
446        }
447    }
448    if ((currentState != NORMAL_STATE) && (currentState != MAXIMIZED_STATE))
449    {
450        /*
451         * Note that maximized state is considered a NormalState in
452         * the ICCC.  SetClientWMState also sets the state in the
453         * client data.
454         */
455
456        if (currentState == MINIMIZED_STATE)
457        {
458            /*
459             * Raise the window(s) when they are deiconified.
460             */
461
462            pCD->clientState = newState;
463            F_Raise (NULL, pCD, NULL);
464        }
465
466        if ( (!(pCD->clientFlags & ICON_BOX)) ||
467             ((pCD->clientFlags & ICON_BOX) && (!(firstTime))) )
468        {
469            MapClientWindows (pCD);
470        }
471
472
473        /*
474         * Set the WM_STATE property of the window and any associated
475         * transients, along with the clientState value.  The call
476         * is made with an indication of NORMAL_STATE to insure
477         * that transient window clientState values are setup
478         * correctly.  The top-level window clientState is set later.
479         */
480
481        SetClientWMState (pCD, NormalState, NORMAL_STATE);
482    }
483    pCD->clientState = newState;
484
485    if ((wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT) &&
486        (currentState == MINIMIZED_STATE) && wmGD.deiconifyKeyFocus)
487    {
488        ClientData *pcdFocus;
489
490        pcdFocus = FindTransientFocus (pCD);
491        if (pcdFocus)
492        {
493            Do_Focus_Key (pcdFocus, setTime, ALWAYS_SET_FOCUS);
494        }
495    }
496
497    if ( pSD->useIconBox &&  P_ICON_BOX(pCD) &&
498         (!(pCD->clientFlags & ICON_BOX)) && (ICON_FRAME_WIN(pCD)))
499    {
500        /*
501         * force icon appearance in icon box to change
502         */
503
504        IconExposureProc (pCD, True);
505    }
506
507} /* END OF FUNCTION SetupWindowStateWithEventMask */
508
509
510
511
512/*************************************<->*************************************
513 *
514 *  ConfigureNewState (pcd)
515 *
516 *
517 *  Description:
518 *  -----------
519 *  Configure the window to a new state
520 *
521 *
522 *  Inputs:
523 *  ------
524 *  pcd         - pointer to client data
525 *
526 *  Outputs:
527 *  -------
528 *
529 *
530 *  Comments:
531 *  --------
532 *  o This is only good for going between NORMAL and MAXIMIZED state.
533 *
534 *************************************<->***********************************/
535
536#ifdef _NO_PROTO
537void ConfigureNewState (pcd)
538        ClientData *pcd;
539
540#else /* _NO_PROTO */
541void ConfigureNewState (ClientData *pcd)
542#endif /* _NO_PROTO */
543{
544    if (pcd->maxConfig)
545    {
546        pcd->maxConfig = FALSE;
547        RegenerateClientFrame(pcd);
548        XResizeWindow (DISPLAY, pcd->client,
549                           (unsigned int) pcd->clientWidth,
550                           (unsigned int) pcd->clientHeight);
551    }
552    else
553    {
554        XResizeWindow (DISPLAY, pcd->client,
555                           (unsigned int) pcd->maxWidth,
556                           (unsigned int) pcd->maxHeight);
557        pcd->maxConfig = TRUE;
558        RegenerateClientFrame(pcd);
559    }
560    SendConfigureNotify (pcd);
561
562    /*
563     * Force repaint if size doesn't change to update frame appearance.
564     */
565
566    if ((pcd->clientWidth == pcd->maxWidth) &&
567        (pcd->clientHeight == pcd->maxHeight))
568    {
569        FrameExposureProc (pcd);
570    }
571
572} /* END OF FUNCTION ConfigureNewState */
573
574
575
576/*************************************<->*************************************
577 *
578 *  UnmapClients (pCD, event_mask)
579 *
580 *
581 *  Description:
582 *  -----------
583 *  Unmap the window(s).  The indicated client may be the head of a transient
584 *  tree - if it is unmap all windows in the transient tree.
585 *
586 *
587 *  Inputs:
588 *  ------
589 *  pCD = pointer to client data of window(s) to be unmapped
590 *  event_mask = what to grab to prevent stray events going somewhere. Our
591 *      passive grab has just been activated -- but it is dropped when the
592 *      window is unmapped and the ButtonRelease event can go to the window
593 *      now exposed. Avoid this by grabbing the ButtonRelease before the unmap
594 *      and swallowing it.
595 *      Also done for icon being unmapped.
596 *
597 *************************************<->***********************************/
598
599#ifdef _NO_PROTO
600static void UnmapClients (pCD, event_mask)
601        ClientData *pCD;
602        unsigned int event_mask;
603#else /* _NO_PROTO */
604static void UnmapClients (ClientData *pCD, unsigned int event_mask)
605#endif /* _NO_PROTO */
606{
607    ClientData *pNext;
608    Boolean doGrab = False;
609
610    pNext = pCD->transientChildren;
611    while (pNext)
612    {
613        /* unmap all children first */
614        if (pNext->transientChildren)
615            UnmapClients (pNext, (unsigned int) 0);
616
617        /* then unmap all siblings at this level */
618        XUnmapWindow (DISPLAY, pNext->clientFrameWin);
619        XUnmapWindow (DISPLAY, pNext->client);
620        pNext->wmUnmapCount++;
621        pNext = pNext->transientSiblings;
622    }
623
624    if (event_mask)
625        doGrab = (Success == XGrabPointer (DISPLAY, DefaultRootWindow(DISPLAY),
626                False, event_mask, GrabModeAsync, GrabModeAsync,
627                None, None, CurrentTime));
628    /* unmap this primary window */
629    XUnmapWindow (DISPLAY, pCD->clientFrameWin);
630    XUnmapWindow (DISPLAY, pCD->client);
631    if (event_mask && doGrab)
632        {
633        XEvent event;
634        XMaskEvent(DISPLAY, event_mask, &event);
635        XUngrabPointer(DISPLAY,CurrentTime);
636        }
637    pCD->wmUnmapCount++;
638
639} /* END OF FUNCTION UnmapClients */
640
641
642
643/*************************************<->*************************************
644 *
645 *  SetClientWMState (pCD, wmState, mwmState)
646 *
647 *
648 *  Description:
649 *  -----------
650 *  Set a new window manage state for a client window or a tree of transient
651 *  client windows.
652 *
653 *  Inputs:
654 *  ------
655 *  pCD = pointer to  client data
656 *
657 *  wmState = new state for WM_STATE property
658 *
659 *  mwmState = mwm client state
660 *
661 *************************************<->***********************************/
662
663#ifdef _NO_PROTO
664void SetClientWMState (pCD, wmState, mwmState)
665        ClientData *pCD;
666        int wmState;
667        int mwmState;
668
669#else /* _NO_PROTO */
670void SetClientWMState (ClientData *pCD, int wmState, int mwmState)
671#endif /* _NO_PROTO */
672{
673    ClientData *pNext;
674
675    pNext = pCD->transientChildren;
676    while (pNext)
677    {
678        if (pNext->transientChildren)
679        {
680            SetClientWMState (pNext, wmState, mwmState);
681        }
682
683        SetWMState (pNext->client, wmState, ICON_FRAME_WIN(pNext));
684        if (pNext->maxConfig && mwmState == NORMAL_STATE)
685        {
686            pNext->clientState = MAXIMIZED_STATE;
687        }
688        else
689        {
690            pNext->clientState = mwmState;
691        }
692        pNext = pNext->transientSiblings;
693    }
694
695    SetWMState (pCD->client, wmState, ICON_FRAME_WIN(pCD));
696    pCD->clientState = mwmState;
697
698} /* END OF FUNCTION SetClientWMState */
699
700
701
702/*************************************<->*************************************
703 *
704 *  MapClientWindows (pCD)
705 *
706 *
707 *  Description:
708 *  -----------
709 *  Maps the window.  If this is a transient tree then all the windows in
710 *  the transient tree are mapped.
711 *
712 *
713 *  Inputs:
714 *  ------
715 *  pCD = pointer to  client data
716 *
717 *************************************<->***********************************/
718
719#ifdef _NO_PROTO
720void MapClientWindows (pCD)
721        ClientData *pCD;
722
723#else /* _NO_PROTO */
724void MapClientWindows (ClientData *pCD)
725#endif /* _NO_PROTO */
726{
727    ClientData *pNext;
728
729
730    pNext = pCD->transientChildren;
731    while (pNext)
732    {
733        /* map all transient children first */
734        if (pNext->transientChildren)
735        {
736            MapClientWindows (pNext);
737        }
738
739        /* then map all siblings at this level */
740        XMapWindow (DISPLAY, pNext->client);
741        XMapWindow (DISPLAY, pNext->clientFrameWin);
742
743        pNext = pNext->transientSiblings;
744    }
745
746    /* map the primary window */
747    XMapWindow (DISPLAY, pCD->client);
748    XMapWindow (DISPLAY, pCD->clientFrameWin);
749
750} /* END OF FUNCTION MapClientWindows */
751
752
753
754/*************************************<->*************************************
755 *
756 *  ShowIconForMinimizedClient (pWS, pCD)
757 *
758 *
759 *  Description:
760 *  -----------
761 *  This function shows the icon for the specified client.  If the icon
762 *  is in an icon box then the "minimized" icon is displayed.  If the icon
763 *  is on the root window it is mapped.
764 *
765 *
766 *  Inputs:
767 *  ------
768 *  pWS = pointer to workspace data
769 *  pCD = pointer to  client data
770 *
771 *************************************<->***********************************/
772
773#ifdef _NO_PROTO
774void ShowIconForMinimizedClient (pWS, pCD)
775        WmWorkspaceData *pWS;
776        ClientData *pCD;
777       
778#else /* _NO_PROTO */
779void ShowIconForMinimizedClient (WmWorkspaceData *pWS, ClientData *pCD)
780#endif /* _NO_PROTO */
781{
782    WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
783
784    /*
785     * Handle auto-placement for root icons (icons not in an icon
786     * box).
787     */
788    if (wmGD.iconAutoPlace && !P_ICON_BOX(pCD))
789    {
790        if ((ICON_PLACE(pCD) == NO_ICON_PLACE) ||
791            ((pWS->IPData.placeList[ICON_PLACE(pCD)].pCD) &&
792             (pWS->IPData.placeList[ICON_PLACE(pCD)].pCD != pCD)))
793        {
794            /*
795             * Icon place not defined or occupied by another client,
796             * find a free place to put the icon.
797             */
798
799            if ((ICON_PLACE(pCD) = GetNextIconPlace (&pWS->IPData))
800                == NO_ICON_PLACE)
801            {
802                ICON_PLACE(pCD) =
803                    CvtIconPositionToPlace (&pWS->IPData,
804                                                         pCD->clientX,
805                                                         pCD->clientY);
806            }
807            CvtIconPlaceToPosition (&pWS->IPData, ICON_PLACE(pCD),
808                                    &ICON_X(pCD), &ICON_Y(pCD));
809
810            XMoveWindow (DISPLAY, ICON_FRAME_WIN(pCD),
811                ICON_X(pCD), ICON_Y(pCD));
812
813        }
814
815        pWS->IPData.placeList[ICON_PLACE(pCD)].pCD = pCD;
816    }
817
818    if (pCD->iconWindow)
819    {
820        XMapWindow (DISPLAY, pCD->iconWindow);
821    }
822
823    if ((pSD->useIconBox) && P_ICON_BOX(pCD))
824    {
825        ShowClientIconState (pCD, MINIMIZED_STATE );
826    }
827    else
828    {
829        XWindowChanges windowChanges;
830
831        /*
832         * Map the icon on the screen at the appropriate place in the
833         * window stack.
834         */
835
836        if (wmGD.lowerOnIconify)
837        {
838            if ((&pCD->iconEntry != pSD->lastClient) &&
839                (pSD->lastClient))
840            {
841                if (pSD->lastClient->type == MINIMIZED_STATE)
842                {
843                    windowChanges.sibling =
844                        ICON_FRAME_WIN(pSD->lastClient->pCD);
845                }
846                else
847                {
848                    windowChanges.sibling =
849                        pSD->lastClient->pCD->clientFrameWin;
850                }
851                windowChanges.stack_mode = Below;
852                XConfigureWindow (DISPLAY, ICON_FRAME_WIN(pCD),
853                                  (CWSibling | CWStackMode), &windowChanges);
854                MoveEntryInList (pWS, &pCD->iconEntry,
855                    False /*on bottom*/, NULL);
856            }
857        }
858        else
859        {
860            windowChanges.sibling = pCD->clientFrameWin;
861            windowChanges.stack_mode = Below;
862            XConfigureWindow (DISPLAY, ICON_FRAME_WIN(pCD),
863                              (CWSibling | CWStackMode), &windowChanges);
864            MoveEntryInList (pWS, &pCD->iconEntry, False /*below*/,
865                             &pCD->clientEntry);
866        }
867
868        XMapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
869    }
870
871} /* END OF FUNCTION ShowIconForMinimizedClient */
872
873
874#ifdef AUTOMATION
875#ifdef _NO_PROTO
876static void SetMwmIconInfo (pcd)
877ClientData *pcd;
878
879#else
880static void SetMwmIconInfo (ClientData *pcd)
881#endif /* _NO_PROTO */
882{
883
884    PropMwmFrameIconInfo    frame_icon_prop;
885    char                    *ret_data;
886    Atom                    frame_icon_atom, new_type;
887    int                     new_format;
888    unsigned long           new_nitems, new_bytes_after;
889
890
891    frame_icon_atom = XmInternAtom(DISPLAY, "_MOTIF_WM_FRAME_ICON_INFO", False);
892    XGetWindowProperty(DISPLAY, pcd->client, frame_icon_atom, 0L,
893                       PROP_MWM_FRAME_ICON_INFO_ELEMENTS, False,
894                       AnyPropertyType, &new_type, &new_format,
895                       &new_nitems, &new_bytes_after,
896                       (unsigned char **)&ret_data);
897        if (ret_data != NULL)
898        bcopy((char *)ret_data, (char *)&frame_icon_prop, new_nitems);
899        /* Swap bytes if necessary */
900        AutoSwapBytes(&frame_icon_prop);
901
902    frame_icon_prop.iconInfo.clientState = pcd->clientState;
903    frame_icon_prop.iconInfo.useIconBox = pcd->pSD->useIconBox;
904    frame_icon_prop.iconInfo.X = pcd->iconX;
905    frame_icon_prop.iconInfo.Y = pcd->iconY;
906    frame_icon_prop.iconInfo.Width = pcd->pSD->iconWidth;
907    frame_icon_prop.iconInfo.Height = pcd->pSD->iconHeight;
908    frame_icon_prop.iconInfo.iconFrameWin = pcd->iconFrameWin;
909
910    if (pcd->pSD->useIconBox == True)
911        FillIconBoxInfo(pcd, &frame_icon_prop);
912
913    frame_icon_prop.byte_order = AutoByteOrderChar;
914    XChangeProperty(DISPLAY, pcd->client, wmGD.xa_MWM_FRAME_ICON_INFO,
915                    wmGD.xa_MWM_FRAME_ICON_INFO, 8, PropModeReplace,
916                    (unsigned char *)&frame_icon_prop,
917                    PROP_MWM_FRAME_ICON_INFO_ELEMENTS);
918    XSync(DISPLAY, False);
919
920    if (ret_data != NULL)
921                XFree((char *)ret_data);
922
923} /* SetMwmIconInfo */
924
925
926#ifdef _NO_PROTO
927static void FillIconBoxInfo(pcd, frame_icon_prop)
928ClientData           *pcd;
929PropMwmFrameIconInfo *frame_icon_prop;
930
931#else
932static void FillIconBoxInfo(ClientData *pcd,
933                            PropMwmFrameIconInfo *frame_icon_prop)
934#endif /* _NO_PROTO */
935{
936    Widget              shellWidget;
937    IconBoxData         *icon_box;
938    XmScrollBarWidget   hScrollBar, vScrollBar;
939    int                 hslider_area_width, vslider_area_height;
940    int                 num_visible_cols, num_visible_rows;
941    int                 visible_first_col, visible_last_col, visible_first_row,
942                        visible_last_row, current_icon_col, current_icon_row;
943    int                 pointerX, pointerY;
944    int                 vert_slider_inc, horiz_slider_inc;
945    int                 vert_inc_needed, horiz_inc_needed;
946    int                 iPlaceW, iPlaceH, maxval, minval;
947    int                 iconX, iconY;
948        int                 sliderX, sliderY, slider_area_x, slider_area_y;
949    int                 lastRow, lastCol;
950
951    icon_box = pcd->pIconBox;
952    if (icon_box == NULL) {
953        return;
954    }
955
956    hScrollBar = (XmScrollBarWidget)icon_box->hScrollBar;
957    vScrollBar = (XmScrollBarWidget)icon_box->vScrollBar;
958    shellWidget = icon_box->shellWidget;
959
960    lastCol = icon_box->lastCol;
961    lastRow = icon_box->lastRow;
962    iPlaceW = icon_box->IPD.iPlaceW;
963    iPlaceH = icon_box->IPD.iPlaceH;
964    iconX = pcd->iconX;
965    iconY = pcd->iconY;
966
967    /* Compute pointerX and horiz_inc_needed */
968    minval = hScrollBar->scrollBar.minimum;
969    maxval = hScrollBar->scrollBar.maximum;
970    hslider_area_width = hScrollBar->scrollBar.slider_area_width;
971    horiz_slider_inc = (iPlaceW * hslider_area_width) / (maxval - minval);
972    sliderX = hScrollBar->scrollBar.slider_x;
973    slider_area_x = hScrollBar->scrollBar.slider_area_x;
974    visible_first_col = round_quotient((sliderX - slider_area_x),
975                                       horiz_slider_inc);
976    num_visible_cols = round_quotient((hslider_area_width * (lastCol + 1)),
977                                      (maxval - minval));
978    visible_last_col = visible_first_col + num_visible_cols - 1;
979    current_icon_col = iconX / iPlaceW;
980
981    if ((visible_first_col == 0 && visible_last_col == lastCol) ||
982        (current_icon_col >= visible_first_col &&
983         current_icon_col <= visible_last_col)) {
984       
985        horiz_inc_needed = 0;
986        if (num_visible_cols > 1)
987            pointerX = slider_area_x + (current_icon_col * iPlaceW) +
988                       (iPlaceW / 2);
989        else
990            pointerX = slider_area_x + (iPlaceW / 2);
991
992    }
993    else if (current_icon_col < visible_first_col) {
994
995        horiz_inc_needed = current_icon_col - visible_first_col;
996        pointerX = slider_area_x + (iPlaceW / 2);
997
998    }
999    else if (current_icon_col > visible_last_col) {
1000
1001        horiz_inc_needed = current_icon_col - visible_last_col;
1002        pointerX = slider_area_x +
1003                   ((visible_last_col - visible_first_col) * iPlaceW) +
1004                   (iPlaceW / 2);
1005
1006    }
1007
1008    /* Now compute pointerY and vert_inc_needed */
1009    minval = vScrollBar->scrollBar.minimum;
1010    maxval = vScrollBar->scrollBar.maximum;
1011    vslider_area_height = vScrollBar->scrollBar.slider_area_height;
1012    vert_slider_inc = (iPlaceH * vslider_area_height) / (maxval - minval);
1013    sliderY = vScrollBar->scrollBar.slider_y;
1014    slider_area_y = vScrollBar->scrollBar.slider_area_y;
1015    visible_first_row = round_quotient((sliderY - slider_area_y),
1016                                       vert_slider_inc);
1017    num_visible_rows = round_quotient((vslider_area_height * (lastRow + 1)),
1018                                      (maxval - minval));
1019    visible_last_row = visible_first_row + num_visible_rows - 1;
1020    current_icon_row = iconY / iPlaceH;
1021
1022    if ((visible_first_row == 0 && visible_last_row == lastRow) ||
1023        (current_icon_row >= visible_first_row &&
1024         current_icon_row <= visible_last_row)) {
1025       
1026        vert_inc_needed = 0;
1027        if (num_visible_rows > 1)
1028            pointerY = slider_area_y + (current_icon_row * iPlaceH) +
1029                       (iPlaceH / 2);
1030        else
1031            pointerY = slider_area_y + (iPlaceH / 2);
1032
1033    }
1034    else if (current_icon_row < visible_first_row) {
1035
1036        vert_inc_needed = current_icon_row - visible_first_row;
1037        pointerY = slider_area_y + (iPlaceH / 2);
1038
1039    }
1040    else if (current_icon_row > visible_last_row) {
1041
1042        vert_inc_needed = current_icon_row - visible_last_row;
1043        pointerY = slider_area_y +
1044                   ((visible_last_row - visible_first_row) * iPlaceH) +
1045                   (iPlaceH / 2);
1046
1047    }
1048
1049    /* Now fill icon box info into property */
1050    frame_icon_prop->iconBoxInfo.iconboxX = shellWidget->core.x;
1051    frame_icon_prop->iconBoxInfo.iconboxY = shellWidget->core.y;
1052    frame_icon_prop->iconBoxInfo.iconboxWidth = shellWidget->core.width;
1053    frame_icon_prop->iconBoxInfo.iconboxHeight = shellWidget->core.height;
1054    frame_icon_prop->iconBoxInfo.pointerX = pointerX;
1055    frame_icon_prop->iconBoxInfo.pointerY = pointerY;
1056    frame_icon_prop->iconBoxInfo.horiz_inc_needed = horiz_inc_needed;
1057    frame_icon_prop->iconBoxInfo.vert_inc_needed = vert_inc_needed;
1058    frame_icon_prop->iconBoxInfo.iconShellWin = XtWindow(shellWidget);
1059    frame_icon_prop->iconBoxInfo.left_arrowX = hScrollBar->core.x +
1060                                      hScrollBar->scrollBar.arrow1_x +
1061                                      (hScrollBar->scrollBar.arrow_width / 2);
1062    frame_icon_prop->iconBoxInfo.left_arrowY = hScrollBar->core.y +
1063                                      hScrollBar->scrollBar.arrow1_y +
1064                                      (hScrollBar->scrollBar.arrow_height / 2);
1065    frame_icon_prop->iconBoxInfo.right_arrowX = hScrollBar->core.x +
1066                                      hScrollBar->scrollBar.arrow2_x +
1067                                      (hScrollBar->scrollBar.arrow_width / 2);
1068    frame_icon_prop->iconBoxInfo.right_arrowY = hScrollBar->core.y +
1069                                      hScrollBar->scrollBar.arrow2_y +
1070                                      (hScrollBar->scrollBar.arrow_height / 2);
1071    frame_icon_prop->iconBoxInfo.top_arrowX = vScrollBar->core.x +
1072                                      vScrollBar->scrollBar.arrow1_x +
1073                                      (vScrollBar->scrollBar.arrow_width / 2);
1074    frame_icon_prop->iconBoxInfo.top_arrowY = vScrollBar->core.y +
1075                                      vScrollBar->scrollBar.arrow1_y +
1076                                      (vScrollBar->scrollBar.arrow_height / 2);
1077    frame_icon_prop->iconBoxInfo.bottom_arrowX = vScrollBar->core.x +
1078                                      vScrollBar->scrollBar.arrow2_x +
1079                                      (vScrollBar->scrollBar.arrow_width / 2);
1080    frame_icon_prop->iconBoxInfo.bottom_arrowY = vScrollBar->core.y +
1081                                      vScrollBar->scrollBar.arrow2_y +
1082                                      (vScrollBar->scrollBar.arrow_height / 2);
1083
1084    frame_icon_prop->iconBoxInfo.iconFrameWin = XtWindow(icon_box->frameWidget);
1085    frame_icon_prop->iconBoxInfo.iconScrollWin =
1086                                           XtWindow(icon_box->scrolledWidget);
1087    frame_icon_prop->iconBoxInfo.hScrollWin = XtWindow(hScrollBar);
1088    frame_icon_prop->iconBoxInfo.vScrollWin = XtWindow(vScrollBar);
1089
1090}
1091
1092round_quotient(num, denom)
1093int    num;
1094int    denom;
1095{
1096    double    act_quotient;
1097    int        quotient;
1098
1099    if (denom <= 0) {
1100        fprintf(stderr, "Fatal Error: Divide by 0 in SetMwmIconInfo\n");
1101        exit(0);
1102    }
1103    act_quotient = (double)num / (double)denom;
1104    quotient = act_quotient;
1105
1106    quotient = ((act_quotient - quotient) > 0.5) ? (quotient + 1) :
1107               quotient;
1108
1109    return(quotient);
1110}
1111
1112#endif /* AUTOMATION */
Note: See TracBrowser for help on using the repository browser.