~profzoom/ubuntu/quantal/wmaker/bug-1079925

« back to all changes in this revision

Viewing changes to src/shutdown.c

  • Committer: Bazaar Package Importer
  • Author(s): Marcelo E. Magallon
  • Date: 2004-11-10 14:05:30 UTC
  • Revision ID: james.westby@ubuntu.com-20041110140530-qpd66b5lm38x7apk
Tags: upstream-0.91.0
ImportĀ upstreamĀ versionĀ 0.91.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Window Maker window manager
 
3
 *
 
4
 *  Copyright (c) 1997-2003 Alfredo K. Kojima
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; either version 2 of the License, or
 
9
 *  (at your option) any later version.
 
10
 *
 
11
 *  This program is distributed in the hope that it will be useful,
 
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *  GNU General Public License for more details.
 
15
 *
 
16
 *  You should have received a copy of the GNU General Public License
 
17
 *  along with this program; if not, write to the Free Software
 
18
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
 
19
 *  USA.
 
20
 */
 
21
 
 
22
#include "wconfig.h"
 
23
 
 
24
#include <stdlib.h>
 
25
#include <signal.h>
 
26
#include <unistd.h>
 
27
 
 
28
#include <X11/Xlib.h>
 
29
#include <X11/Xutil.h>
 
30
#include <X11/Intrinsic.h>
 
31
 
 
32
#include "WindowMaker.h"
 
33
#include "window.h"
 
34
#include "client.h"
 
35
#include "funcs.h"
 
36
#include "properties.h"
 
37
#include "session.h"
 
38
#include "winspector.h"
 
39
#include "wmspec.h"
 
40
 
 
41
extern Atom _XA_WM_DELETE_WINDOW;
 
42
extern Time LastTimestamp;
 
43
extern int wScreenCount;
 
44
 
 
45
 
 
46
static void wipeDesktop(WScreen *scr);
 
47
 
 
48
 
 
49
/*
 
50
 *----------------------------------------------------------------------
 
51
 * Shutdown-
 
52
 *      Exits the window manager cleanly. If mode is WSLogoutMode,
 
53
 * the whole X session will be closed, by killing all clients if
 
54
 * no session manager is running or by asking a shutdown to
 
55
 * it if its present.
 
56
 *
 
57
 *----------------------------------------------------------------------
 
58
 */
 
59
void
 
60
Shutdown(WShutdownMode mode)
 
61
{
 
62
    int i;
 
63
 
 
64
    switch (mode) {
 
65
    case WSLogoutMode:
 
66
#ifdef XSMP_ENABLED
 
67
        wSessionRequestShutdown();
 
68
        break;
 
69
#else
 
70
        /* fall through */
 
71
#endif
 
72
    case WSKillMode:
 
73
    case WSExitMode:
 
74
        /* if there is no session manager, send SAVE_YOURSELF to
 
75
         * the clients */
 
76
#if 0
 
77
#ifdef XSMP_ENABLED
 
78
        if (!wSessionIsManaged())
 
79
#endif
 
80
            for (i = 0; i < wScreenCount; i++) {
 
81
                WScreen *scr;
 
82
 
 
83
                scr = wScreenWithNumber(i);
 
84
                if (scr) {
 
85
                    wSessionSendSaveYourself(scr);
 
86
                }
 
87
            }
 
88
#endif
 
89
        for (i = 0; i < wScreenCount; i++) {
 
90
            WScreen *scr;
 
91
 
 
92
            scr = wScreenWithNumber(i);
 
93
            if (scr) {
 
94
                if (scr->helper_pid)
 
95
                    kill(scr->helper_pid, SIGKILL);
 
96
 
 
97
                /* if the session is not being managed, save restart info */
 
98
#ifdef XSMP_ENABLED
 
99
                if (!wSessionIsManaged())
 
100
#endif
 
101
                    wSessionSaveClients(scr);
 
102
 
 
103
                wScreenSaveState(scr);
 
104
 
 
105
                if (mode == WSKillMode)
 
106
                    wipeDesktop(scr);
 
107
                else
 
108
                    RestoreDesktop(scr);
 
109
            }
 
110
        }
 
111
        ExecExitScript();
 
112
        Exit(0);
 
113
        break;
 
114
 
 
115
    case WSRestartPreparationMode:
 
116
        for (i=0; i<wScreenCount; i++) {
 
117
            WScreen *scr;
 
118
 
 
119
            scr = wScreenWithNumber(i);
 
120
            if (scr) {
 
121
                if (scr->helper_pid)
 
122
                    kill(scr->helper_pid, SIGKILL);
 
123
                wScreenSaveState(scr);
 
124
                RestoreDesktop(scr);
 
125
            }
 
126
        }
 
127
        break;
 
128
    }
 
129
}
 
130
 
 
131
 
 
132
static void
 
133
restoreWindows(WMBag *bag, WMBagIterator iter)
 
134
{
 
135
    WCoreWindow *next;
 
136
    WCoreWindow *core;
 
137
    WWindow *wwin;
 
138
 
 
139
 
 
140
    if (iter == NULL) {
 
141
        core = WMBagFirst(bag, &iter);
 
142
    } else {
 
143
        core = WMBagNext(bag, &iter);
 
144
    }
 
145
 
 
146
    if (core == NULL)
 
147
        return;
 
148
 
 
149
    restoreWindows(bag, iter);
 
150
 
 
151
    /* go to the end of the list */
 
152
    while (core->stacking->under)
 
153
        core = core->stacking->under;
 
154
 
 
155
    while (core) {
 
156
        next = core->stacking->above;
 
157
 
 
158
        if (core->descriptor.parent_type==WCLASS_WINDOW) {
 
159
            Window window;
 
160
 
 
161
            wwin = core->descriptor.parent;
 
162
            window = wwin->client_win;
 
163
            wUnmanageWindow(wwin, !wwin->flags.internal_window, False);
 
164
            XMapWindow(dpy, window);
 
165
        }
 
166
        core = next;
 
167
    }
 
168
}
 
169
 
 
170
 
 
171
/*
 
172
 *----------------------------------------------------------------------
 
173
 * RestoreDesktop--
 
174
 *      Puts the desktop in a usable state when exiting.
 
175
 *
 
176
 * Side effects:
 
177
 *      All frame windows are removed and windows are reparented
 
178
 * back to root. Windows that are outside the screen are
 
179
 * brought to a viable place.
 
180
 *
 
181
 *----------------------------------------------------------------------
 
182
 */
 
183
void
 
184
RestoreDesktop(WScreen *scr)
 
185
{
 
186
    if (scr->helper_pid > 0) {
 
187
        kill(scr->helper_pid, SIGTERM);
 
188
        scr->helper_pid = 0;
 
189
    }
 
190
 
 
191
    XGrabServer(dpy);
 
192
    wDestroyInspectorPanels();
 
193
 
 
194
    /* reparent windows back to the root window, keeping the stacking order */
 
195
    restoreWindows(scr->stacking_list, NULL);
 
196
 
 
197
    XUngrabServer(dpy);
 
198
    XSetInputFocus(dpy, PointerRoot, RevertToParent, CurrentTime);
 
199
    wColormapInstallForWindow(scr, NULL);
 
200
    PropCleanUp(scr->root_win);
 
201
    wNETWMCleanup(scr);
 
202
    XSync(dpy, 0);
 
203
}
 
204
 
 
205
 
 
206
/*
 
207
 *----------------------------------------------------------------------
 
208
 * wipeDesktop--
 
209
 *      Kills all windows in a screen. Send DeleteWindow to all windows
 
210
 * that support it and KillClient on all windows that don't.
 
211
 *
 
212
 * Side effects:
 
213
 *      All managed windows are closed.
 
214
 *
 
215
 * TODO: change to XQueryTree()
 
216
 *----------------------------------------------------------------------
 
217
 */
 
218
static void
 
219
wipeDesktop(WScreen *scr)
 
220
{
 
221
    WWindow *wwin;
 
222
 
 
223
    wwin = scr->focused_window;
 
224
    while (wwin) {
 
225
        if (wwin->protocols.DELETE_WINDOW)
 
226
            wClientSendProtocol(wwin, _XA_WM_DELETE_WINDOW, LastTimestamp);
 
227
        else
 
228
            wClientKill(wwin);
 
229
        wwin = wwin->prev;
 
230
    }
 
231
    XSync(dpy, False);
 
232
}
 
233