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

Revision 9757, 28.4 KB checked in by ghudson, 27 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: WmManage.c,v $ $Revision: 1.1.1.1 $ $Date: 1997-03-25 09:12:22 $"
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/*
23 * include extern functions
24 */
25#include "WmCDecor.h"
26#include "WmCEvent.h"
27#include "WmColormap.h"
28#include "WmError.h"
29#include "WmEvent.h"
30#include "WmFunction.h"
31#include "WmGraphics.h"
32#include "WmIDecor.h"
33#include "WmIconBox.h"
34#include "WmImage.h"
35#include "WmKeyFocus.h"
36#include "WmMenu.h"
37#include "WmProperty.h"
38#include "WmProtocol.h"
39#include "WmWinInfo.h"
40#include "WmWinList.h"
41#include "WmWinState.h"
42
43
44
45/*
46 * Function Declarations:
47 */
48
49#ifdef _NO_PROTO
50void    AdoptIntialClients ();
51void    FreeClientFrame ();
52void    FreeCustomMenuSpec ();
53void    FreeIcon ();
54void    ManageWindow ();
55void    ReManageDialog ();
56void    ResetWithdrawnFocii ();
57void    UnManageWindow ();
58void    WithdrawDialog ();
59void    WithdrawTransientChildren ();
60void    WithdrawWindow ();
61#else /* _NO_PROTO */
62void AdoptInitialClients (WmScreenData *pSD);
63void ManageWindow (WmScreenData *pSD, Window clientWindow, long manageFlags);
64void UnManageWindow (ClientData *pCD);
65void WithdrawTransientChildren (ClientData *pCD);
66void WithdrawWindow (ClientData *pCD);
67void ResetWithdrawnFocii (ClientData *pCD);
68void FreeClientFrame (ClientData *pCD);
69void FreeIcon (ClientData *pCD);
70void WithdrawDialog (Widget dialogboxW);
71void ReManageDialog (WmScreenData *pSD, Widget dialogboxW);
72#endif /* _NO_PROTO */
73
74
75/*
76 * Global Variables:
77 */
78
79
80
81/*************************************<->*************************************
82 *
83 *  AdoptInitialClients (pSD)
84 *
85 *  Inputs:
86 *  -------
87 *  pSD = pointer to screen data
88 *
89 *
90 *  Description:
91 *  -----------
92 *  This function is called to find client windows that were mapped prior to
93 *  starting (or restarting) the window manager.  These windows are included
94 *  in the set of windows managed by the window manager.
95 *
96 *************************************<->***********************************/
97
98#ifdef _NO_PROTO
99void AdoptInitialClients (pSD)
100
101    WmScreenData *pSD;
102#else /* _NO_PROTO */
103void AdoptInitialClients (WmScreenData *pSD)
104#endif /* _NO_PROTO */
105{
106    Window  root;
107    Window  parent;
108    Window *clients;
109    unsigned int     nclients;
110    ClientData *pcd;
111    PropWMState *wmStateProp;
112    Boolean manageOnRestart;
113    int i,j;
114    long manageFlags;
115
116
117    /*
118     * Look for mapped top-level windows and start managing them:
119     */
120
121    if (XQueryTree (DISPLAY, pSD->rootWindow, &root, &parent, &clients,
122            &nclients))
123    {
124        /*
125         * Filter out icon windows so they don't get managed as a client
126         * window.  Icon windows will be process in SetupClientIconWindow().
127         */
128        XWMHints *tmphint;
129
130        for (i = 0; i < nclients; i++) {
131            if (clients[i]) {
132                if ((tmphint = XGetWMHints (DISPLAY, clients[i])) != NULL) {
133                    if (tmphint->flags & IconWindowHint) {
134                        for (j = 0; j < nclients; j++) {
135                            if (clients[j] == tmphint->icon_window) {
136                                clients[j] = None;
137                                break;
138                            }
139                        }
140                    }
141                    XFree ((char *) tmphint);
142                }
143            }
144        }
145
146        for (i = 0; i < nclients; i++)
147        {
148            /* determine if the client window should be managed by wm */
149            if ((clients[i] == XtWindow (pSD->screenTopLevelW)) ||
150                (clients[i] == XtWindow (pSD->pActiveWS->workspaceTopLevelW)) ||
151                (clients[i] == pSD->activeIconTextWin))
152            {
153                /* don't manage ancillary window manager windows */
154                continue;
155            }
156            if (!XFindContext (DISPLAY, clients[i], wmGD.windowContextType,
157                (caddr_t *)&pcd))
158            {
159                /* don't manage a window we've already established a
160                   context for (e.g. icon windows) */
161                continue;
162            }
163            if (!WmGetWindowAttributes (clients[i]))
164            {
165                /* can't access the window; ignore it */
166                continue;
167            }
168            /* window attributes are put into the global cache */
169
170            /*
171             * Get the window WM_STATE property value to determine the
172             * initial window state if the wm is being restarted.
173             */
174
175            manageFlags = MANAGEW_WM_STARTUP;
176            manageOnRestart = True;
177
178            if (wmGD.wmRestarted)
179            {
180                manageFlags |= MANAGEW_WM_RESTART;
181                if ((wmStateProp = GetWMState (clients[i])) != NULL)
182                {
183                    if (wmStateProp->state == IconicState)
184                    {
185                        manageFlags |= MANAGEW_WM_RESTART_ICON;
186                    }
187                    else if (wmStateProp->state != NormalState)
188                    {
189                        manageOnRestart = False;
190                    }
191                    XFree ((char *)wmStateProp);
192                }
193                else
194                {
195                    manageOnRestart = False;
196                }
197            }
198
199            /*
200             * Don't manage any override_redirect windows (mapped or not).
201             * Manage an unmapped window if it has a WM_STATE property
202             *   and it is not Withdrawn.
203             * Manage any window that is mapped.
204             */
205
206            if ((wmGD.windowAttributes.override_redirect != True) &&
207                ((wmGD.wmRestarted && manageOnRestart) ||
208                 (wmGD.windowAttributes.map_state != IsUnmapped)))
209            {
210                ManageWindow (pSD, clients[i], manageFlags);
211            }
212        }
213
214        if (nclients)
215        {
216            XFree ((char *)clients);
217        }
218    }
219
220
221} /* END OF FUNCTION AdoptInitialClients */
222
223
224
225/*************************************<->*************************************
226 *
227 *  ManageWindow (pSD, clientWindow, manageFlags)
228 *
229 *
230 *  Description:
231 *  -----------
232 *  This is the highlevel function that is used to include a window in
233 *  the set of windows that are managed by the window manager.  The window
234 *  gets reparented and decorated, gets an icon, is setup for window
235 *  management event handling, etc.  Client windows that are controlled
236 *  by the window manager (e.g., the icon box) are also managed with
237 *  this function.
238 *
239 *
240 *  Inputs:
241 *  ------
242 *  clientWindow = window of the client that we should manage
243 *
244 *  manageFlags = additional control information
245 *
246 *
247 *  Outputs:
248 *  -------
249 *  pCD = initialized client data
250 *
251 *************************************<->***********************************/
252
253#ifdef _NO_PROTO
254void
255ManageWindow (pSD, clientWindow, manageFlags)
256    WmScreenData *pSD;
257    Window clientWindow;
258    long manageFlags;
259
260#else /* _NO_PROTO */
261void
262ManageWindow (WmScreenData *pSD, Window clientWindow, long manageFlags)
263#endif /* _NO_PROTO */
264{
265    ClientData *pCD;
266    int initialState;
267    int i;
268    Boolean sendConfigNotify;
269
270    /*
271     * Get client information including window attributes and window
272     * property values.  Use this information to determine how the window
273     * is to be managed.
274     */
275
276    if (!(pCD = GetClientInfo (pSD, clientWindow, manageFlags)))
277    {
278        /* error getting client info; do not manage the client window */
279        return;
280    }
281
282
283    if (manageFlags & MANAGEW_WM_RESTART)
284    {
285        if (manageFlags & MANAGEW_WM_RESTART_ICON)
286        {
287            pCD->clientState = MINIMIZED_STATE;
288        }
289        else
290        {
291            pCD->clientState = NORMAL_STATE;
292        }
293    }
294
295
296    /*
297     * Setup the initial placement of the client window.  Do interactive
298     * placement if configured.
299     */
300
301    sendConfigNotify = InitClientPlacement (pCD, manageFlags);
302
303
304    /*
305     * Make a window frame for the client window and reparent the client
306     * window.
307     */
308
309    if (!FrameWindow (pCD))
310    {
311        /*
312         * Error in framing the window; clean up the wm resources made
313         * up to this point for the client window. Do not manage the
314         * client window.
315         */
316
317        UnManageWindow (pCD);
318        return;
319    }
320
321    /*
322     * Send config notify if the client's been moved/resized
323     */
324    if (sendConfigNotify)
325    {
326        SendConfigureNotify (pCD);
327    }
328
329    /*
330     * Send client offset message if:
331     *
332     *   1. The client is interested.
333     *   2. The position we report to the user is not the client's real
334     *      position.
335     *   3. There is a client offset to report.
336     */
337    if ((pCD->protocolFlags & PROTOCOL_MWM_OFFSET) &&
338        (wmGD.positionIsFrame) &&
339        ((pCD->clientOffset.x != 0) ||
340         (pCD->clientOffset.y != 0)))
341    {
342        SendClientOffsetMessage (pCD);
343    }
344
345    /*
346     * Make an icon for the client window if it is not a valid transient
347     * window.
348     */
349
350    if ((pCD->clientFunctions & MWM_FUNC_MINIMIZE) &&
351        (pCD->transientLeader == NULL) &&
352          !MakeIcon (pCD->pSD->pActiveWS, pCD))
353    {
354        /*
355         * Error in making an icon for the client window; clean up the wm
356         * resources; do not manage the client window.
357         */
358
359        UnManageWindow (pCD);
360        return;
361    }
362
363
364    /*
365     * Register window contexts to facilitate event handling:
366     */
367
368    XSaveContext (DISPLAY, pCD->clientFrameWin, wmGD.windowContextType,
369        (caddr_t)pCD);
370
371    XSaveContext (DISPLAY, pCD->clientBaseWin, wmGD.windowContextType,
372        (caddr_t)pCD);
373
374    if (DECOUPLE_TITLE_APPEARANCE(pCD) && pCD->clientTitleWin)
375    {
376        /*
377         * handle exposures on title bar if it has its own appearance
378         */
379        XSaveContext (DISPLAY, pCD->clientTitleWin, wmGD.windowContextType,
380            (caddr_t)pCD);
381    }
382    if (pCD->iconFrameWin)
383    {
384        XSaveContext (DISPLAY, pCD->iconFrameWin, wmGD.windowContextType,
385            (caddr_t)pCD);
386    }
387
388    if (pCD->clientCmapCount > 0)
389    {
390        for (i = 0; i < pCD->clientCmapCount; i++)
391        {
392            if (pCD->cmapWindows[i] != pCD->client)
393            {
394                XSaveContext (DISPLAY, pCD->cmapWindows[i],
395                    wmGD.windowContextType, (caddr_t)pCD);
396            }
397        }
398    }
399
400    pCD->clientFlags |= CLIENT_CONTEXT_SAVED;
401
402
403    /*
404     * Setup button binding handling for actions that apply to the client
405     * window.
406     */
407
408    if (BUTTON_SPECS(pCD))
409    {
410        SetupCButtonBindings (pCD->clientBaseWin, BUTTON_SPECS(pCD));
411    }
412
413    if (pCD->iconWindow && pCD->iconFrameWin)
414    {
415        XGrabButton (DISPLAY, AnyButton, AnyModifier, pCD->iconFrameWin, True,
416            ButtonPressMask | ButtonReleaseMask | ButtonMotionMask,
417            GrabModeAsync, GrabModeAsync, None, wmGD.workspaceCursor);
418    }
419
420
421    /*
422     * Setup key binding handling for system menu accelerators.
423     */
424
425    if (pCD->systemMenuSpec &&
426        (pCD->systemMenuSpec->accelKeySpecs))
427    {
428        SetupKeyBindings (pCD->systemMenuSpec->accelKeySpecs,
429                          pCD->clientFrameWin, GrabModeSync, F_CONTEXT_ALL);
430        if (!pCD->pIconBox && pCD->iconFrameWin)
431        {
432            SetupKeyBindings (pCD->systemMenuSpec->accelKeySpecs,
433                              pCD->iconFrameWin, GrabModeSync, F_CONTEXT_ALL);
434        }
435    }
436
437    if (!pCD->pIconBox && pCD->iconFrameWin)
438    {
439        static int iconKeySpec = 1;
440        static int iconAccelSpec = 1;
441
442        if ((iconKeySpec != 0) && KEY_SPECS(pCD))
443        {
444            iconKeySpec = SetupKeyBindings (KEY_SPECS(pCD), pCD->iconFrameWin,
445                                GrabModeSync, F_CONTEXT_ICON);
446        }
447
448        if ((iconAccelSpec != 0) && ACCELERATOR_MENU_COUNT(pCD))
449        {
450            int n;
451
452            iconAccelSpec = 0;
453            for (n= 0; n < pSD->acceleratorMenuCount; n++)
454            {
455                iconAccelSpec += SetupKeyBindings (
456                            ACCELERATOR_MENU_SPECS(pCD)[n]->accelKeySpecs,
457                            pCD->iconFrameWin, GrabModeSync,
458                            F_CONTEXT_ICON);
459            }
460        }
461    }
462
463
464    /*
465     * Setup keyboard focus handling if policy is "explicit".
466     */
467
468    if (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT)
469    {
470        DoExplicitSelectGrab (pCD->clientBaseWin);
471    }
472
473
474    /*
475     * Make sure the client window has been reparented ...
476     */
477
478    if (!(manageFlags & MANAGEW_WM_CLIENTS))
479    {
480        XSync (DISPLAY, False);
481
482        if (pCD->clientFlags & CLIENT_DESTROYED)
483        {
484            UnManageWindow (pCD);
485            return;
486        }
487    }
488
489
490    /*
491     * Setup the initial display state for the client window:
492     */
493
494    initialState = pCD->clientState;
495    pCD->clientState = WITHDRAWN_STATE;
496    pCD->clientFlags &= ~WM_INITIALIZATION;
497
498    AddClientToList (pSD->pActiveWS, pCD, True /*on top*/);
499    SetClientState (pCD, initialState, CurrentTime);
500
501    /*
502     * Set the keyboard input focus to the newly managed window if appropriate:
503     * - focus is automatically set only if the focus policy is explicit
504     * - if there is a system modal window active then set the focus only
505     *   if the new window is in the system modal heirarchy
506     * - focus is automatically set if startupKeyFocus is selected or
507     *   the new window is a system modal window or the current focus window
508     *   has the new window as an application modal subordinate
509     * - don't automatically set the focus if the window is minimized or
510     *   is a window that generally doesn't take input
511     */
512
513    if ((wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT) &&
514        ((pCD->inputMode == MWM_INPUT_SYSTEM_MODAL) ||
515         ((!wmGD.systemModalActive ||
516           (wmGD.systemModalClient == FindTransientTreeLeader (pCD))) &&
517          (wmGD.startupKeyFocus ||
518           (wmGD.keyboardFocus && (IS_APP_MODALIZED(wmGD.keyboardFocus)))) &&
519          !(manageFlags &
520            (MANAGEW_WM_STARTUP | MANAGEW_WM_RESTART | MANAGEW_WM_CLIENTS)) &&
521          (pCD->clientState != MINIMIZED_STATE) &&
522          (pCD->inputFocusModel ||
523           (pCD->protocolFlags & PROTOCOL_WM_TAKE_FOCUS)))))
524    {
525        Do_Focus_Key (pCD, CurrentTime , ALWAYS_SET_FOCUS);
526    }
527    else if ((pCD->inputMode == MWM_INPUT_SYSTEM_MODAL) ||
528             (wmGD.keyboardFocus && IS_APP_MODALIZED(wmGD.keyboardFocus)))
529    {
530        Do_Focus_Key ((ClientData *)NULL, CurrentTime , ALWAYS_SET_FOCUS);
531    }
532
533
534} /* END OF FUNCTION ManageWindow */
535
536
537
538/*************************************<->*************************************
539 *
540 *  UnManageWindow (pCD)
541 *
542 *
543 *  Description:
544 *  -----------
545 *  This function removes a top-level client window and it's transients
546 *  from the set of windows that is managed by the window manager. 
547 *
548 *
549 *  Inputs:
550 *  ------
551 *  pCD         - pointer to client data of window to unmanage
552 *
553 *************************************<->***********************************/
554
555#ifdef _NO_PROTO
556void UnManageWindow (pCD)
557    ClientData *pCD;
558
559#else /* _NO_PROTO */
560void UnManageWindow (ClientData *pCD)
561#endif /* _NO_PROTO */
562{
563    /*
564     * If this is a transient window, then delete it from the leader's
565     * list of transients.
566     */
567
568    if (pCD->transientLeader)
569    {
570        DeleteTransient (pCD);
571    }
572
573
574    /*
575     * Withdraw all the transient children of this window.
576     */
577
578    if (pCD->transientChildren != NULL)
579    {
580        WithdrawTransientChildren (pCD);
581    }
582
583
584    /*
585     * Withdraw this window
586     */
587
588    WithdrawWindow (pCD);
589
590} /* END OF FUNCTION UnManageWindow */
591
592
593
594/*************************************<->*************************************
595 *
596 *  WithdrawTransientChildren (pCD)
597 *
598 *
599 *  Description:
600 *  -----------
601 *  This function withdraws all transient children of the specified window.
602 *
603 *
604 *  Inputs:
605 *  ------
606 *  pCD = pointer to client data of the leader of the transient tree.
607 *
608 *************************************<->***********************************/
609
610#ifdef _NO_PROTO
611void WithdrawTransientChildren (pCD)
612    ClientData *pCD;
613
614#else /* _NO_PROTO */
615void WithdrawTransientChildren (ClientData *pCD)
616#endif /* _NO_PROTO */
617{
618    ClientData *pcdNext;
619    ClientData *pcdThis;
620
621
622    pcdNext = pCD->transientChildren;
623    while (pcdNext)
624    {
625        if (pcdNext->transientChildren)
626        {
627            WithdrawTransientChildren (pcdNext);
628        }
629        pcdThis = pcdNext;
630        pcdNext = pcdThis->transientSiblings;
631        WithdrawWindow (pcdThis);
632    }
633
634} /* END OF FUNCTION WithdrawTransientChildren */
635
636
637
638/*************************************<->*************************************
639 *
640 *  WithdrawWindow (pCD)
641 *
642 *
643 *  Description:
644 *  -----------
645 *  This function removes a top-level client window from the set of windows
646 *  that is managed by the window manager.  All window manager resources
647 *  associtated with the client window are freed up (possibly cached for
648 *  reuse).  Any custom system menu is destroyed.
649 *
650 *
651 *  Inputs:
652 *  ------
653 *  pCD         - pointer to client data of window to withdraw
654 *
655 *************************************<->***********************************/
656
657#ifdef _NO_PROTO
658void WithdrawWindow (pCD)
659    ClientData *pCD;
660
661#else /* _NO_PROTO */
662void WithdrawWindow (ClientData *pCD)
663#endif /* _NO_PROTO */
664{
665    int x;
666    int y;
667    int i;
668    XWindowChanges xwc;
669
670
671    /*
672     * Put the client window into a withdrawn state:
673     *
674     * - remove the icon/client window from the screen
675     * - make sure the input focus no longer is associted with the window
676     * - free the icon placement (if necessary)
677     */
678
679    if (!(pCD->clientFlags & WM_INITIALIZATION))
680    {
681        if (!pCD->transientLeader)
682        {
683            DeleteClientFromList (pCD->pSD->pActiveWS, pCD);
684        }
685        ResetWithdrawnFocii (pCD);
686        if (pCD->clientState & MINIMIZED_STATE)
687        {
688            if (wmGD.iconAutoPlace && (!(P_ICON_BOX(pCD))))
689            {
690                if (ICON_PLACE(pCD) != NO_ICON_PLACE)
691                {
692                pCD->pSD->pActiveWS->IPData.placeList[ICON_PLACE(pCD)].pCD
693                    = NULL;
694                }
695            }
696            if (ICON_FRAME_WIN(pCD))
697            {
698                XUnmapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
699            }
700            XFlush (DISPLAY);
701        }
702        else if ((pCD->clientState == NORMAL_STATE) ||
703                 (pCD->clientState == MAXIMIZED_STATE))
704        {
705            XUnmapWindow (DISPLAY, pCD->clientFrameWin);
706            XFlush (DISPLAY);
707        }
708    }
709
710    /*
711     * Check to see if the window is being unmanaged because the window
712     * was destroyed.
713     */
714
715    if (!(pCD->clientFlags & CLIENT_DESTROYED))
716    {
717        XEvent eventReturn;
718
719        if (XCheckTypedWindowEvent (DISPLAY, pCD->clientBaseWin, DestroyNotify,
720                &eventReturn))
721        {
722            pCD->clientFlags |= CLIENT_DESTROYED;
723        }
724    }
725
726
727    /*
728     * Reparent the client window back to root if the window has been
729     * reparented by the window manager.  Remove the window from the
730     * window managers save-set if necessary.
731     */
732
733    if ((pCD->clientFlags & CLIENT_REPARENTED) &&
734        !(pCD->clientFlags & CLIENT_DESTROYED))
735    {
736        SetWMState (pCD->client, WithdrawnSTATE, ICON_FRAME_WIN(pCD));
737
738        if (pCD->maxConfig)
739        {
740            x = pCD->maxX;
741            y = pCD->maxY;
742        }
743        else
744        {
745            int xoff, yoff;
746           
747            if(wmGD.positionIsFrame)
748            {
749              CalculateGravityOffset (pCD, &xoff, &yoff);
750              x = pCD->clientX - xoff;
751              y = pCD->clientY - yoff;
752            }
753            else
754              {
755            x = pCD->clientX;
756            y = pCD->clientY;
757            }
758        }
759
760        XUnmapWindow (DISPLAY, pCD->client);
761        XReparentWindow (DISPLAY, pCD->client, ROOT_FOR_CLIENT(pCD), x, y);
762
763        /* give the window back it's X border */
764        xwc.border_width = pCD->xBorderWidth;
765        XConfigureWindow(DISPLAY, pCD->client, CWBorderWidth, &xwc);
766
767        if (pCD->iconWindow && (pCD->clientFlags & ICON_REPARENTED))
768        {
769            XUnmapWindow (DISPLAY, pCD->iconWindow);
770            XReparentWindow (DISPLAY, pCD->iconWindow, ROOT_FOR_CLIENT(pCD),
771                             ICON_X(pCD), ICON_Y(pCD));
772        }
773    }
774
775
776    if ((pCD->clientFlags & CLIENT_IN_SAVE_SET) &&
777        !(pCD->clientFlags & CLIENT_DESTROYED))
778    {
779        XRemoveFromSaveSet (DISPLAY, pCD->client);
780
781        if (pCD->iconWindow && (pCD->clientFlags & ICON_IN_SAVE_SET))
782        {
783            XRemoveFromSaveSet (DISPLAY, pCD->iconWindow);
784        }
785    }
786
787    /*
788     * Free a custom system menu if one was created.
789     */
790
791    FreeCustomMenuSpec (pCD->systemMenuSpec);
792
793    /*
794     * Free the client window frame:
795     */
796
797    if (pCD->clientFrameWin)
798    {
799        FreeClientFrame (pCD);
800    }
801
802
803    /*
804     * Free the icon associated with the client window:
805     */
806
807    if ((pCD->iconFlags & ICON_HINTS_PIXMAP) && pCD->iconPixmap)
808    {
809        XFreePixmap (DISPLAY, pCD->iconPixmap);
810    }
811
812    if (ICON_FRAME_WIN(pCD))
813    {
814        FreeIcon (pCD);
815    }
816
817
818    /*
819     * Free up the client protocol list:
820     */
821
822    if (pCD->clientProtocols)
823    {
824        XtFree ((char *)pCD->clientProtocols);
825    }
826
827
828    /*
829     * Free up the mwm messages list:
830     */
831
832    if (pCD->mwmMessages)
833    {
834        XtFree ((char *)pCD->mwmMessages);
835    }
836
837
838    /*
839     * Delete client window manager timers:
840     */
841
842    DeleteClientWmTimers (pCD);
843
844
845    /*
846     * Free up window context associations.  The context for the client
847     * window is always set if there is a client data structure.
848     */
849
850    XDeleteContext (DISPLAY, pCD->client, wmGD.windowContextType);
851    if (pCD->clientFlags & CLIENT_CONTEXT_SAVED)
852    {
853        XDeleteContext (DISPLAY, pCD->clientFrameWin, wmGD.windowContextType);
854        XDeleteContext (DISPLAY, pCD->clientBaseWin, wmGD.windowContextType);
855        if (DECOUPLE_TITLE_APPEARANCE(pCD))
856        {
857            XDeleteContext (DISPLAY, pCD->clientTitleWin,
858                wmGD.windowContextType);
859        }
860        if (ICON_FRAME_WIN(pCD))
861        {
862            XDeleteContext (DISPLAY, pCD->iconFrameWin,
863                             wmGD.windowContextType);
864        }
865    }
866
867
868    /*
869     * Free up window manager resources:
870     */
871
872    if (!(pCD->clientFlags & CLIENT_WM_CLIENTS))
873    {
874        if (pCD->clientName)
875        {
876            XFree ((char *) (pCD->clientName));
877        }
878        if (pCD->clientClass)
879        {
880            XFree ((char *) (pCD->clientClass));
881        }
882    }
883
884    if ((pCD->clientFlags & CLIENT_HINTS_TITLE) && pCD->clientTitle)
885    {
886        XmStringFree (pCD->clientTitle);
887    }
888
889    if ((pCD->iconFlags & ICON_HINTS_TITLE) && pCD->iconTitle)
890    {
891        XmStringFree (pCD->iconTitle);
892    }
893
894    if (pCD->clientCmapCount > 0)
895    {
896        for (i = 0; i < pCD->clientCmapCount; i++)
897        {
898            if (pCD->cmapWindows[i] != pCD->client)
899            {
900                XDeleteContext (DISPLAY, pCD->cmapWindows[i],
901                    wmGD.windowContextType);
902            }
903        }
904        XtFree ((char *) (pCD->cmapWindows));
905        XtFree ((char *) (pCD->clientCmapList));
906#ifndef OLD_COLORMAP /* colormap */
907        XtFree ((char  *) (pCD->clientCmapFlags));
908#endif
909    }
910
911
912    /*
913     * Clean up references to this data before we free it.
914     */
915    if (wmGD.menuClient == pCD) {
916        wmGD.menuClient = NULL;
917    }
918
919    if (wmGD.gadgetClient == pCD) {
920        wmGD.gadgetClient = NULL;
921        wmGD.gadgetDepressed = 0;
922    }
923
924    if (wmGD.clickData.pCD == pCD) {
925        wmGD.clickData.pCD = NULL;
926    }
927
928    if (wmGD.nextKeyboardFocus == pCD)
929        wmGD.nextKeyboardFocus = NULL;
930    if (wmGD.keyboardFocus == pCD)
931        wmGD.keyboardFocus = NULL;
932
933/*
934 * Fix for 5325 - Delete reference by dirty stack
935 */
936    ClearDirtyStackEntry(pCD);
937
938    XtFree ((char *)pCD);
939
940
941} /* END OF FUNCTION WithdrawWindow */
942
943
944
945/*************************************<->*************************************
946 *
947 *  ResetWitdrawnFocii (pCD)
948 *
949 *
950 *  Description:
951 *  -----------
952 *  This function resets the various types of focus if they are set to a
953 *  window being withdrawn.
954 * 
955 *
956 *
957 *  Inputs:
958 *  ------
959 *  pCD         - pointer to client data
960 *
961 *  Outputs:
962 *  -------
963 *
964 *  Comments:
965 *  --------
966 *
967 *************************************<->***********************************/
968
969#ifdef _NO_PROTO
970void ResetWithdrawnFocii (pCD)
971    ClientData *pCD;
972
973#else /* _NO_PROTO */
974void ResetWithdrawnFocii (ClientData *pCD)
975#endif /* _NO_PROTO */
976{
977    if (wmGD.keyboardFocus == pCD)
978    {
979        if (wmGD.autoKeyFocus &&
980            (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT))
981        {
982            /* local hack: if we've already received a map for a new
983            ** focus window, be sure to use wmGD.nextKeyboardFocus; otherwise
984            ** AutoResetKeyFocus chooses an essentially arbitrary window to
985            ** set focus to.
986            */
987            if (wmGD.nextKeyboardFocus == pCD)
988                    AutoResetKeyFocus (pCD, CurrentTime);
989            else
990                Do_Focus_Key ((ClientData *)wmGD.nextKeyboardFocus, CurrentTime,
991                    ALWAYS_SET_FOCUS);
992        }
993        else
994        {
995            /*
996             * Set the focus to the default state if the focus is not in
997             * the process of being set (i.e. a FocusIn event will be
998             * comming along shortly.
999             */
1000
1001            if (wmGD.nextKeyboardFocus == wmGD.keyboardFocus)
1002            {
1003                Do_Focus_Key ((ClientData *)NULL, CurrentTime,
1004                    ALWAYS_SET_FOCUS);
1005            }
1006        }
1007        SetKeyboardFocus ((ClientData *)NULL, 0);
1008    }
1009
1010    if ((pCD->inputMode == MWM_INPUT_PRIMARY_APPLICATION_MODAL) &&
1011        (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_POINTER) &&
1012        (wmGD.keyboardFocus == NULL) &&
1013        (wmGD.nextKeyboardFocus == NULL))
1014    {
1015        RepairFocus ();
1016    }
1017
1018    if (wmGD.nextKeyboardFocus == pCD)
1019    {
1020        wmGD.nextKeyboardFocus = NULL;
1021    }
1022
1023    if (ACTIVE_PSD->colormapFocus == pCD)
1024    {
1025        SetColormapFocus (ACTIVE_PSD, (ClientData *)NULL);
1026    }
1027
1028} /* END OF FUNCTION ResetWithdrawnFocii */
1029
1030
1031
1032/*************************************<->*************************************
1033 *
1034 *  FreeClientFrame (pCD)
1035 *
1036 *
1037 *  Description:
1038 *  -----------
1039 *  This function frees up frame windows and associated resources.
1040 *
1041 *
1042 *  Inputs:
1043 *  ------
1044 *  pCD         - pointer to client data
1045 *
1046 *************************************<->***********************************/
1047
1048#ifdef _NO_PROTO
1049void FreeClientFrame (pCD)
1050    ClientData *pCD;
1051
1052#else /* _NO_PROTO */
1053void FreeClientFrame (ClientData *pCD)
1054#endif /* _NO_PROTO */
1055{
1056    if (pCD->pclientTopShadows) {
1057        FreeRList (pCD->pclientTopShadows);
1058        pCD->pclientTopShadows = NULL;
1059    }
1060    if (pCD->pclientBottomShadows) {
1061        FreeRList (pCD->pclientBottomShadows);
1062        pCD->pclientBottomShadows = NULL;
1063    }
1064    if (pCD->pclientTitleTopShadows) {
1065        FreeRList (pCD->pclientTitleTopShadows);
1066        pCD->pclientTitleTopShadows = NULL;
1067    }
1068    if (pCD->pclientTitleBottomShadows) {
1069        FreeRList (pCD->pclientTitleBottomShadows);
1070        pCD->pclientTitleBottomShadows = NULL;
1071    }
1072    if (pCD->pclientMatteTopShadows) {
1073        FreeRList (pCD->pclientMatteTopShadows);
1074        pCD->pclientMatteTopShadows = NULL;
1075    }
1076    if (pCD->pclientMatteBottomShadows) {
1077        FreeRList (pCD->pclientMatteBottomShadows);
1078        pCD->pclientMatteBottomShadows = NULL;
1079    }
1080    if (pCD->pTitleGadgets) {
1081        XtFree ((char *)pCD->pTitleGadgets);
1082        pCD->pTitleGadgets = NULL;
1083        pCD->cTitleGadgets = 0;
1084    }
1085    if (pCD->pResizeGadgets) {
1086        XtFree ((char *)pCD->pResizeGadgets);
1087        pCD->pResizeGadgets = NULL;
1088    }
1089
1090    /* destroy frame window & all children */
1091    XDestroyWindow (DISPLAY, pCD->clientFrameWin);
1092
1093} /* END OF FUNCTION FreeClientFrame */
1094
1095
1096
1097/*************************************<->*************************************
1098 *
1099 *  FreeIcon (pCD)
1100 *
1101 *
1102 *  Description:
1103 *  -----------
1104 *  This function frees up icon windows and associated resources.
1105 *
1106 *
1107 *  Inputs:
1108 *  ------
1109 *  pCD         - pointer to client data
1110 *
1111 *************************************<->***********************************/
1112
1113#ifdef _NO_PROTO
1114void FreeIcon (pCD)
1115    ClientData *pCD;
1116
1117#else /* _NO_PROTO */
1118void FreeIcon (ClientData *pCD)
1119#endif /* _NO_PROTO */
1120{
1121
1122    if (pCD->piconTopShadows) {
1123        FreeRList (pCD->piconTopShadows);
1124        pCD->piconTopShadows = NULL;
1125    }
1126    if (pCD->piconBottomShadows) {
1127        FreeRList (pCD->piconBottomShadows);
1128        pCD->piconBottomShadows = NULL;
1129    }
1130
1131    /*
1132     * destroy frame window & all children
1133     */
1134
1135    if (pCD->pSD->useIconBox && P_ICON_BOX(pCD))
1136    {
1137        DeleteIconFromBox (pCD->pSD->pActiveWS->pIconBox, pCD);
1138    }
1139    else
1140    {
1141        XDestroyWindow (DISPLAY, pCD->iconFrameWin);
1142    }
1143
1144} /* END OF FUNCTION FreeIcon */
1145
1146
1147
1148
1149/*************************************<->*************************************
1150 *
1151 *  WithdrawDialog (dialogboxW)
1152 *
1153 *
1154 *  Description:
1155 *  -----------
1156 *  This function removes a DialogBox widget "client" from the set of windows
1157 *  that are managed by the window manager.
1158 *
1159 *
1160 *  Inputs:
1161 *  ------
1162 *  dialogboxW = DialogBox widget to withdraw.
1163 *
1164 *  Comments:
1165 *  --------
1166 *  Does not maintain the WM_STATE property on the dialog "client".
1167 *
1168 *************************************<->***********************************/
1169
1170#ifdef _NO_PROTO
1171void WithdrawDialog (dialogboxW)
1172
1173    Widget   dialogboxW;
1174
1175#else /* _NO_PROTO */
1176void WithdrawDialog (Widget dialogboxW)
1177#endif /* _NO_PROTO */
1178{
1179    ClientData *pCD;
1180
1181    /*
1182     * Get the dialog shell window client data.
1183     */
1184
1185    XFindContext (DISPLAY, XtWindow (XtParent (dialogboxW)),
1186                  wmGD.windowContextType, (caddr_t *)&pCD);
1187
1188    XtUnmanageChild (dialogboxW);
1189    DeleteClientFromList (ACTIVE_WS, pCD);
1190    ResetWithdrawnFocii (pCD);
1191    XUnmapWindow (DISPLAY, pCD->clientFrameWin);
1192
1193} /* END OF FUNCTION WithdrawDialog */
1194
1195
1196
1197/*************************************<->*************************************
1198 *
1199 *  ReManageDialog (pSD, dialogboxW)
1200 *
1201 *
1202 *  Description:
1203 *  -----------
1204 *  This function remanages a DialogBox "client" that was unmanaged via
1205 *  WithdrawDialog ().
1206 *
1207 *
1208 *  Inputs:
1209 *  ------
1210 *  pSD = pointer to screen data
1211 *  dialogboxW = DialogBox widget to remanage.
1212 *
1213 *
1214 *  Outputs:
1215 *  -------
1216 *  Does not maintain the WM_STATE property on the dialog "client".
1217 *
1218 *************************************<->***********************************/
1219
1220#ifdef _NO_PROTO
1221void ReManageDialog (pSD, dialogboxW)
1222
1223    WmScreenData *pSD;
1224    Widget   dialogboxW;
1225
1226#else /* _NO_PROTO */
1227void ReManageDialog (WmScreenData *pSD, Widget dialogboxW)
1228#endif /* _NO_PROTO */
1229{
1230    ClientData *pCD;
1231
1232    /*
1233     * Get the dialog shell window client data.
1234     */
1235
1236    XFindContext (DISPLAY, XtWindow (XtParent (dialogboxW)),
1237                  wmGD.windowContextType, (caddr_t *)&pCD);
1238
1239    /*
1240     * The order is important here:
1241     */
1242
1243
1244    if (pSD->clientList)
1245    {
1246      StackWindow (pSD->pActiveWS, &pCD->clientEntry,
1247                    TRUE, (ClientListEntry *) NULL);
1248    }
1249    AddClientToList (pSD->pActiveWS, pCD, True /*on top*/);
1250    XMapWindow (DISPLAY, pCD->clientFrameWin);
1251    XtManageChild (dialogboxW);
1252
1253    if ((wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT))
1254    {
1255        Do_Focus_Key (pCD, CurrentTime , ALWAYS_SET_FOCUS);
1256    }
1257
1258
1259} /* END OF FUNCTION ReManageDialog */
1260
Note: See TracBrowser for help on using the repository browser.