CTWM
Loading...
Searching...
No Matches
/usr/src/RPM/BUILD/ctwm-4.1.0/ctwm_shutdown.c
Go to the documentation of this file.
1/*
2 * Shutdown (/restart) bits
3 */
4
5#include "ctwm.h"
6
7#include <stdlib.h>
8#include <stdio.h>
9#include <unistd.h>
10
11#include "animate.h"
12#ifdef CAPTIVE
13#include "captive.h"
14#endif
15#include "colormaps.h"
16#include "ctwm_atoms.h"
17#include "ctwm_shutdown.h"
18#include "screen.h"
19#ifdef SESSION
20#include "session.h"
21#endif
22#ifdef SOUNDS
23# include "sound.h"
24#endif
25#include "otp.h"
26#include "win_ops.h"
27#include "win_utils.h"
28
29
30static void RestoreForShutdown(Time mytime);
31
32
33/**
34 * Put a window back where it should be if we don't (any longer) control
35 * it and reparent it back up to the root. This leaves it where it was
36 * before we started (well, adjusted by any moves we've made to it
37 * since), and placed so that if we restart and take it back over, it'll
38 * wind up right where it is now, so restarting doesn't shift windows all
39 * over the place.
40 */
41void
43{
44 int gravx, gravy;
45 int newx, newy;
46
47 // Things adjusting by the border have to move our border size, but
48 // subtract away from that the old border we're restoring.
49 const int borders = tmp->frame_bw + tmp->frame_bw3D - tmp->old_bw;
50
51 // If this window is "unmapped" by moving it way offscreen, and is in
52 // that state, move it back onto the window.
53 if(tmp->UnmapByMovingFarAway && !visible(tmp)) {
54 XMoveWindow(dpy, tmp->frame, tmp->frame_x, tmp->frame_y);
55 }
56
57 // If it's squeezed, unsqueeze it.
58 if(tmp->squeezed) {
59 Squeeze(tmp);
60 }
61
62 // This is apparently our standard "is this window still around?"
63 // idiom.
65 &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth) == 0) {
66 // Well, give up...
67 return;
68 }
69
70 // Get gravity bits to know how to move stuff around when we take
71 // away the decorations.
73
74 // We want to move the window to where it should be "outside" of our
75 // frame. This varies depending on the window gravity detail, and we
76 // have to account for that, since on re-startup we'll be doing it to
77 // resposition it after we re-wrap it.
78 //
79 // e.g., in simple "NorthWest" gravity, we just made the frame start
80 // where the window did, and shifted the app window right (by the
81 // border width) and down (by the border width + titlebar). However,
82 // "SouthEast" gravity means the bottom right of the frame is where
83 // the windows' was, and the window itself shifted left/up by the
84 // border. Compare e.g. an xterm with -geometry "+0+0" with one
85 // using "-0-0" as an easy trick to make windows with different
86 // geoms.
87 newx = tmp->frame_x;
88 newy = tmp->frame_y;
89
90
91 // So, first consider the north/south gravity. If gravity is North,
92 // we put the top of the frame where the window was and shifted
93 // everything inside down, so the top of the frame now is where the
94 // window should be put. With South-y gravity, the window should
95 // wind up at the bottom of the frame, which means we need to shift
96 // it down by the titlebar height, plus twice the border width. But
97 // if the vertical gravity is neutral, then the window needs to wind
98 // up staying right where it is, because we built the frame around it
99 // without moving it.
100 //
101 // Previous code here (and code elsewhere) expressed this calculation
102 // by the rather confusing idiom ((gravy + 1) * border_width), which
103 // gives the right answer, but is confusing as hell...
104 if(gravy < 0) {
105 // North; where the frame starts (already set)
106 }
107 else if(gravy > 0) {
108 // South; shift down title + 2*border
109 newy += tmp->title_height + 2 * borders;
110 }
111 else {
112 // Neutral; down by the titlebar + border.
113 newy += tmp->title_height + borders;
114 }
115
116
117 // Now east/west. West means align with the frame start, east means
118 // align with the frame right edge, neutral means where it already
119 // is.
120 if(gravx < 0) {
121 // West; it's already correct
122 }
123 else if(gravx > 0) {
124 // East; shift over by 2*border
125 newx += 2 * borders;
126 }
127 else {
128 // Neutral; over by the left border
129 newx += borders;
130 }
131
132
133#ifdef WINBOX
134 // If it's in a WindowBox, reparent the frame back up to our real root
135 if(tmp->winbox && tmp->winbox->twmwin && tmp->frame) {
136 int xbox, ybox;
137 unsigned int j_bw;
138
139 // XXX This isn't right, right? This will give coords relative
140 // to the window box, but we're using them relative to the real
141 // screen root?
142 if(XGetGeometry(dpy, tmp->frame, &JunkRoot, &xbox, &ybox,
145 }
146 }
147#endif
148
149
150 // Restore the original window border if there were one
151 if(tmp->old_bw) {
152 XSetWindowBorderWidth(dpy, tmp->w, tmp->old_bw);
153 }
154
155 // Reparent and move back to where it otter be
156 XReparentWindow(dpy, tmp->w, Scr->Root, newx, newy);
157
158 // If it came with a pre-made icon window, hide it
159 if(tmp->wmhints->flags & IconWindowHint) {
160 XUnmapWindow(dpy, tmp->wmhints->icon_window);
161 }
162
163 // Done
164 return;
165}
166
167
168/**
169 * Restore some window positions/etc in preparation for going away.
170 */
171static void
173{
174 ScreenInfo *savedScr = Scr; // We need Scr flipped around...
175
177
178 for(int scrnum = 0; scrnum < NumScreens; scrnum++) {
179 if((Scr = ScreenList[scrnum]) == NULL) {
180 continue;
181 }
182
183 // Force reinstalling any colormaps
184 InstallColormaps(0, &Scr->RootColormaps);
185
186 // Pull all the windows out of their frames and reposition them
187 // where the frame was, with approprate adjustments for gravity.
188 // This will preserve their positions when we restart, or put
189 // them back where they were before we started. Do it from the
190 // bottom up of our stacking order to preserve the stacking.
191 for(TwmWindow *tw = OtpBottomWin() ; tw != NULL
192 ; tw = OtpNextWinUp(tw)) {
193 if(tw->isiconmgr || tw->iswspmgr || tw->isoccupy) {
194 // Don't bother with internals...
195 continue;
196 }
198 }
199 }
200
202
203 // Restore
204 Scr = savedScr;
205
206 // Focus away from any windows
208}
209
210
211/**
212 * Cleanup and exit ctwm
213 */
214void
216{
217
218#ifdef SOUNDS
219 // Denounce ourselves
221#endif
222
223 // Restore windows/colormaps for our absence.
225
226#ifdef EWMH
227 // Clean up EWMH properties
229#endif
230
231 // Clean up our list of workspaces
233
234#ifdef CAPTIVE
235 // Shut down captive stuff
236 if(CLarg.is_captive) {
237 RemoveFromCaptiveList(Scr->captivename);
238 }
239#endif
240
241 // Close up shop
243 exit(0);
244}
245
246
247/**
248 * exec() ourself to restart.
249 */
250void
252{
253 // Don't try to do any further animating
255 XSync(dpy, 0);
256
257 // Replace all the windows/colormaps as if we were going away. 'cuz
258 // we are.
260 XSync(dpy, 0);
261
262#ifdef SESSION
263 // Shut down session management connection cleanly.
265#endif
266
267 // Re-run ourself
268 fprintf(stderr, "%s: restarting: %s\n", ProgramName, *Argv);
269 execvp(*Argv, Argv);
270
271 // Uh oh, we shouldn't get here...
272 fprintf(stderr, "%s: unable to restart: %s\n", ProgramName, *Argv);
273
274 // We should probably un-RestoreForShutdown() etc. If that exec
275 // fails, we're in a really weird state...
276 XBell(dpy, 0);
277}
static int PlaceX
Definition add_window.c:82
void StopAnimation(void)
Definition animate.c:117
void RemoveFromCaptiveList(const char *cptname)
Definition captive.c:425
ctwm_cl_args CLarg
Definition clargs.c:27
bool InstallColormaps(int type, Colormaps *cmaps)
Definition colormaps.c:51
int JunkY
Definition ctwm.h:358
char * ProgramName
Definition ctwm_main.c:146
unsigned int JunkBW
Definition ctwm.h:359
unsigned int JunkWidth
Definition ctwm_main.c:144
Window JunkRoot
Definition ctwm_main.c:142
int JunkX
Definition ctwm_main.c:143
Display * dpy
Definition ctwm_main.c:84
char ** Argv
Definition ctwm_main.c:149
unsigned int JunkHeight
Definition ctwm.h:359
unsigned int JunkDepth
Definition ctwm.h:359
int NumScreens
How many Screens are on our display.
Definition ctwm_main.c:89
#define Scr
ScreenInfo ** ScreenList
List of ScreenInfo structs for each Screen.
Definition ctwm_main.c:92
void DoShutdown(void)
Cleanup and exit ctwm.
void RestoreWinConfig(TwmWindow *tmp)
Put a window back where it should be if we don't (any longer) control it and reparent it back up to t...
static void RestoreForShutdown(Time mytime)
Restore some window positions/etc in preparation for going away.
void DoRestart(Time t)
exec() ourself to restart.
void EwmhTerminate(void)
Definition ewmh.c:528
TwmWindow * OtpNextWinUp(TwmWindow *twm_win)
Definition otp.c:1458
TwmWindow * OtpBottomWin(void)
Definition otp.c:1437
int ReparentWindow(Display *display, TwmWindow *twm_win, WinType wintype, Window parent, int x, int y)
Definition otp.c:1378
@ WinWin
Definition otp.h:14
void shutdown_session(void)
Definition session.c:1174
void play_exit_sound(void)
Definition sound.c:258
Info and control for each X Screen we control.
Definition screen.h:96
Info and control for every X Window we take over.
void Squeeze(TwmWindow *tmp_win)
Definition win_ops.c:223
void SetFocus(TwmWindow *tmp_win, Time tim)
Definition win_ops.c:128
bool visible(const TwmWindow *tmp_win)
Definition win_utils.c:341
void GetGravityOffsets(TwmWindow *tmp, int *xp, int *yp)
Definition win_utils.c:149