~ctwm/ctwm/trunk

304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1
/*
554.1.3 by Matthew Fuller
Reduce away license details in ctwm.c now that they're all in LICENSE.
2
 *       Copyright 1988 by Evans & Sutherland Computer Corporation,
3
 *                          Salt Lake City, Utah
4
 *  Portions Copyright 1989 by the Massachusetts Institute of Technology
5
 *                        Cambridge, Massachusetts
1 by Claude Lecommandeur
CTWM version 1.1
6
 *
7
 * $XConsortium: twm.c,v 1.124 91/05/08 11:01:54 dave Exp $
8
 *
9
 * twm - "Tom's Window Manager"
10
 *
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
11
 * 27-Oct-87 Thomas E. LaStrange        File created
1 by Claude Lecommandeur
CTWM version 1.1
12
 * 10-Oct-90 David M. Sternlicht        Storing saved colors on root
13
 *
554.1.3 by Matthew Fuller
Reduce away license details in ctwm.c now that they're all in LICENSE.
14
 * Copyright 1992 Claude Lecommandeur.
15
 *
1 by Claude Lecommandeur
CTWM version 1.1
16
 * Do the necessary modification to be integrated in ctwm.
17
 * Can no longer be used for the standard twm.
18
 *
19
 * 22-April-92 Claude Lecommandeur.
554.1.3 by Matthew Fuller
Reduce away license details in ctwm.c now that they're all in LICENSE.
20
 */
1 by Claude Lecommandeur
CTWM version 1.1
21
395.1.1 by Matthew Fuller
Move ctwm.h to always be included first.
22
#include "ctwm.h"
23
1 by Claude Lecommandeur
CTWM version 1.1
24
#include <stdio.h>
491.1.14 by Matthew Fuller
Remove incorrect pre-ANSI potential override prototypes for malloc()
25
#include <stdlib.h>
93 by Richard Levitte
- Convert all functions to use proper prototypes.
26
#include <unistd.h>
492.2.17 by Matthew Fuller
Cleanup some unneeded X headers and canoncalize ordering. In
27
#include <locale.h>
14 by Claude Lecommandeur
CTWM version 3.4
28
1 by Claude Lecommandeur
CTWM version 1.1
29
#include <fcntl.h>
371.2.4 by Matthew Fuller
Take out some preprocessor indenting that's vesitigial without #ifdef
30
#include <X11/Xatom.h>
492.2.15 by Matthew Fuller
Extract the shape.h include into just the .c files that need it.
31
#include <X11/extensions/shape.h>
340.1.1 by Matthew Fuller
Rearrange includes to be in what we'll call the Proper Order.
32
33
335.1.1 by Olaf 'Rhialto' Seibert
Automated Atoms, now for the ctwm core. Step 1: replacement of the many
34
#include "ctwm_atoms.h"
628 by Matthew Fuller
Reworking the building a little so main() becomes ctwm_main(), and we
35
#include "ctwm_main.h"
648.1.2 by Matthew Fuller
Minimal move of these takeover-related funcs to their own file to
36
#include "ctwm_takeover.h"
389.1.67 by Matthew Fuller
Bust the arg parsing and checking out into separate functions, and
37
#include "clargs.h"
1 by Claude Lecommandeur
CTWM version 1.1
38
#include "add_window.h"
39
#include "gc.h"
40
#include "parse.h"
41
#include "version.h"
518.1.28 by Matthew Fuller
Inagurate a colormaps.c by pulling the colormap functions out of
42
#include "colormaps.h"
1 by Claude Lecommandeur
CTWM version 1.1
43
#include "events.h"
44
#include "util.h"
481.1.2 by Matthew Fuller
Pull {Mask,Unmask}Screen() out into their own file, along with the
45
#include "mask_screen.h"
481.1.5 by Matthew Fuller
Pull the animation funcs/vars out into their own file.
46
#include "animate.h"
1 by Claude Lecommandeur
CTWM version 1.1
47
#include "screen.h"
14 by Claude Lecommandeur
CTWM version 3.4
48
#include "icons.h"
1 by Claude Lecommandeur
CTWM version 1.1
49
#include "iconmgr.h"
524.1.5 by Matthew Fuller
Pull list.h out of screen.h and #include it in the places that need
50
#include "list.h"
702.1.4 by Matthew Fuller
Conditionalize a bunch of the session bits.
51
#ifdef SESSION
207.1.10 by Richard Levitte
Clean out USE_SESSION, X11R6 and the remainders of I18N
52
#include "session.h"
702.1.4 by Matthew Fuller
Conditionalize a bunch of the session bits.
53
#endif
524.1.1 by Matthew Fuller
Pull occupation.h out of screen.h, and include it directly in the
54
#include "occupation.h"
240.1.3 by Rhialto
4 - Added the remaining OnTopPriority changes from Stefan Monnier
55
#include "otp.h"
93 by Richard Levitte
- Convert all functions to use proper prototypes.
56
#include "cursor.h"
700.1.7 by Matthew Fuller
Conditionalize away all the winbox stuff in the main function.
57
#ifdef WINBOX
93 by Richard Levitte
- Convert all functions to use proper prototypes.
58
#include "windowbox.h"
700.1.7 by Matthew Fuller
Conditionalize away all the winbox stuff in the main function.
59
#endif
692.1.6 by Matthew Fuller
Conditionalize including captive.h.
60
#ifdef CAPTIVE
503.1.44 by Matthew Fuller
Bust the bits related to Captive handling out of workmgr.c into their
61
#include "captive.h"
692.1.6 by Matthew Fuller
Conditionalize including captive.h.
62
#endif
614.1.11 by Maxime Soulé
Xrandr support can be disabled at compile time (ON by default)
63
#ifdef XRANDR
614.1.1 by Maxime Soulé
First step of xrandr integration
64
#include "xrandr.h"
614.1.67 by Matthew Fuller
Rearrange this logic so we try the non-RANDR variant even if we're
65
#endif
614.1.11 by Maxime Soulé
Xrandr support can be disabled at compile time (ON by default)
66
#include "r_area.h"
67
#include "r_area_list.h"
614.1.110 by Matthew Fuller
Fix non-XRANDR build; we now use the RLayout stuff explicitly here no
68
#include "r_layout.h"
647.1.7 by Matthew Fuller
Start splitting out signal handlers and their setup into their own
69
#include "signals.h"
524.1.3 by Matthew Fuller
Pull vscreen.h out of screen.h and #include it directly in the files
70
#include "vscreen.h"
538.1.3 by Matthew Fuller
Rename the decorations*.h to win_decorations*.h.
71
#include "win_decorations_init.h"
523.1.11 by Matthew Fuller
Inagurate win_ops.c by moving the focus functions from util.c into it.
72
#include "win_ops.h"
518.1.22 by Matthew Fuller
Break the funcs for handling WindowRegion stuff out of add_window.c
73
#include "win_regions.h"
523.1.3 by Matthew Fuller
Move GetGravityOffsets() into win_utils and give it a more descriptive
74
#include "win_utils.h"
510.1.9 by Matthew Fuller
Only stuff left in workmgr is the actual workspace manager stuff.
75
#include "workspace_manager.h"
136.1.9 by Richard Levitte
Include sound.h to declare sound functions properly.
76
#ifdef SOUNDS
77
#  include "sound.h"
78
#endif
340.1.1 by Matthew Fuller
Rearrange includes to be in what we'll call the Proper Order.
79
492.2.33 by Matthew Fuller
Do some more cleanup of headers including headers.
80
#include "gram.tab.h"
81
340.1.1 by Matthew Fuller
Rearrange includes to be in what we'll call the Proper Order.
82
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
83
XtAppContext appContext;        /* Xt application context */
84
Display *dpy;                   /* which display are we talking to */
85
Window ResizeWindow;            /* the window we are resizing */
1 by Claude Lecommandeur
CTWM version 1.1
86
648.1.11 by Matthew Fuller
Once upon a time, this single-use util func did a bunch of individiual
87
Atom XCTWMAtom[NUM_CTWM_XATOMS]; ///< Our various common atoms
88
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
89
int NumScreens;                 /* number of screens in ScreenList */
492.2.94 by Matthew Fuller
boolify these globals.
90
bool HasShape;                  /* server supports shape extension? */
1 by Claude Lecommandeur
CTWM version 1.1
91
int ShapeEventBase, ShapeErrorBase;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
92
ScreenInfo **ScreenList;        /* structures for each screen */
93
ScreenInfo *Scr = NULL;         /* the cur and prev screens */
94
int PreviousScreen;             /* last screen that we were on */
644.2.43 by Matthew Fuller
Move attempted takeover until after the config parsing, and
95
static bool cfgerrs = false;    ///< Whether there were config parsing errors
96
692.1.5 by Matthew Fuller
Add ifdef's around references to Screen and CLargs members that are
97
#ifdef CAPTIVE
641.1.1 by Matthew Fuller
Rename func to better match what it does.
98
static Window CreateCaptiveRootWindow(int x, int y,
99
                                      unsigned int width, unsigned int height);
692.1.5 by Matthew Fuller
Add ifdef's around references to Screen and CLargs members that are
100
#endif
641.1.31 by Matthew Fuller
Go ahead and pass the coordinates and dimensions of the screen into
101
ScreenInfo *InitScreenInfo(int scrnum, Window croot, int crootx, int crooty,
102
                           unsigned int crootw, unsigned int crooth);
518.1.1 by Matthew Fuller
This func is only used during startup in ctwm.c, so move it there and
103
static bool MappedNotOverride(Window w);
1 by Claude Lecommandeur
CTWM version 1.1
104
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
105
Cursor  UpperLeftCursor;
106
Cursor  TopRightCursor,
107
        TopLeftCursor,
108
        BottomRightCursor,
109
        BottomLeftCursor,
110
        LeftCursor,
111
        RightCursor,
112
        TopCursor,
113
        BottomCursor;
114
1 by Claude Lecommandeur
CTWM version 1.1
115
Cursor RightButt;
116
Cursor MiddleButt;
117
Cursor LeftButt;
118
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
119
XContext TwmContext;            /* context for twm windows */
120
XContext MenuContext;           /* context for all menu windows */
121
XContext ScreenContext;         /* context to get screen data */
122
XContext ColormapContext;       /* context for colormap operations */
1 by Claude Lecommandeur
CTWM version 1.1
123
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
124
XClassHint NoClass;             /* for applications with no class */
1 by Claude Lecommandeur
CTWM version 1.1
125
126
XGCValues Gcv;
127
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
128
char *Home;                     /* the HOME environment variable */
129
int HomeLen;                    /* length of Home */
130
492.2.94 by Matthew Fuller
boolify these globals.
131
bool HandlingEvents = false;    /* are we handling events yet? */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
132
502.1.18 by Matthew Fuller
Add comments about the usage of Junk vars, and collapse their
133
/*
134
 * Various junk vars for xlib calls.  Many calls have to get passed these
135
 * pointers to return values into, but in a lot of cases we don't care
136
 * about some/all of them, and since xlib blindly derefs and stores into
137
 * them, we can't just pass NULL for the ones we don't care about.  So we
138
 * make this set of globals to use as standin.  These should never be
139
 * used or read in our own code; use real vars for the values we DO use
140
 * from the calls.
141
 */
142
Window JunkRoot, JunkChild;
143
int JunkX, JunkY;
1 by Claude Lecommandeur
CTWM version 1.1
144
unsigned int JunkWidth, JunkHeight, JunkBW, JunkDepth, JunkMask;
145
146
char *ProgramName;
647.1.5 by Matthew Fuller
Adjust the SIGHUP signal handler to be async-signal-safe.
147
size_t ProgramNameLen;
1 by Claude Lecommandeur
CTWM version 1.1
148
int Argc;
149
char **Argv;
150
573.1.1 by Matthew Fuller
Flip over a bunch of defaults.
151
bool RestartPreviousState = true;      /* try to restart in previous state */
1 by Claude Lecommandeur
CTWM version 1.1
152
648.1.12 by Matthew Fuller
Adjust comment on ctwm_main().
153
656.1.3 by Matthew Fuller
Instead of using --cfgchk to bypass actually dealing with an X server,
154
/// Magic flag for tests.  Nothing else should touch this!
155
bool ctwm_test = false;
156
656.1.1 by Matthew Fuller
Provide a callback for tests to hook into, to let them grub around in
157
/// Magic callback for tests.  This will trigger right after config file
158
/// parsing if it's set, and then exit.  Nothing else should ever touch
159
/// this!
160
int (*ctwm_test_postparse)(void) = NULL;
161
162
648.1.12 by Matthew Fuller
Adjust comment on ctwm_main().
163
164
165
/**
166
 * Start up ctwm.  This is effectively main(), just wrapped for various
167
 * unimportant reasons.
1 by Claude Lecommandeur
CTWM version 1.1
168
 */
628 by Matthew Fuller
Reworking the building a little so main() becomes ctwm_main(), and we
169
int
170
ctwm_main(int argc, char *argv[])
1 by Claude Lecommandeur
CTWM version 1.1
171
{
641.1.2 by Matthew Fuller
Move a bunch of vars to inner scope, set default values in the only
172
	int numManaged, firstscrn, lastscrn;
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
173
	bool FirstScreen;
644.2.6 by Matthew Fuller
takeover actually doesn't even vary by screen, it's a global, so pull
174
	bool takeover = true;
644.2.46 by Matthew Fuller
Add the last few checks so that --cfgchk will now run and do its best
175
	bool nodpyok = false;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
176
544.1.2 by Matthew Fuller
GCC some remaining (void) return casts.
177
	setlocale(LC_ALL, "");
13 by Claude Lecommandeur
CTWM version 3.3.1
178
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
179
	ProgramName = argv[0];
647.1.5 by Matthew Fuller
Adjust the SIGHUP signal handler to be async-signal-safe.
180
	ProgramNameLen = strlen(ProgramName);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
181
	Argc = argc;
182
	Argv = argv;
1 by Claude Lecommandeur
CTWM version 1.1
183
389.1.25 by Matthew Fuller
Tweak whitespace and comments to make the sectional nature more
184
185
	/*
488 by Matthew Fuller
Add a func to check the order of the entries in our keyword lookup
186
	 * Run consistency check.  This is mostly to keep devs from
187
	 * accidental screwups; if a user ever sees anything from this,
188
	 * something went very very wrong.
189
	 */
190
	chk_keytable_order();
191
192
	/*
389.1.67 by Matthew Fuller
Bust the arg parsing and checking out into separate functions, and
193
	 * Parse-out command line args, and check the results.
194
	 */
195
	clargs_parse(argc, argv);
196
	clargs_check();
197
	/* If we get this far, it was all good */
389.1.65 by Matthew Fuller
Add some simple sanity checking, to avoid mutually incompatible arg
198
644.2.6 by Matthew Fuller
takeover actually doesn't even vary by screen, it's a global, so pull
199
	/* Some clargs mean we're not actually trying to take over the screen */
692.1.5 by Matthew Fuller
Add ifdef's around references to Screen and CLargs members that are
200
	if(CLarg.cfgchk) {
201
		takeover = false;
202
	}
203
#ifdef CAPTIVE
204
	if(CLarg.is_captive) {
205
		takeover = false;
206
	}
207
#endif
644.2.6 by Matthew Fuller
takeover actually doesn't even vary by screen, it's a global, so pull
208
644.2.46 by Matthew Fuller
Add the last few checks so that --cfgchk will now run and do its best
209
	/* And some mean we actually don't care if we lack an X server */
210
	if(CLarg.cfgchk) {
211
		nodpyok = true;
212
	}
213
656.1.3 by Matthew Fuller
Instead of using --cfgchk to bypass actually dealing with an X server,
214
	/* Support for tests: be ready to fake everything */
215
	if(ctwm_test) {
216
		takeover = false;
217
		nodpyok  = true;
218
	}
219
389.1.65 by Matthew Fuller
Add some simple sanity checking, to avoid mutually incompatible arg
220
647.1.6 by Matthew Fuller
Just use signal(3) directly, don't bother trying to allow
221
	/*
222
	 * Hook up signal handlers
223
	 */
647.1.7 by Matthew Fuller
Start splitting out signal handlers and their setup into their own
224
	setup_signal_handlers();
647.1.4 by Matthew Fuller
GC fossils of attempted SIGCHLD handling that weren't built. Default
225
1 by Claude Lecommandeur
CTWM version 1.1
226
641.1.8 by Matthew Fuller
Add various narrative comments through the startup process (outside of
227
	// Various bits of code care about $HOME
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
228
	Home = getenv("HOME");
390 by Matthew Fuller
Rerun 'make indent' after VMS reorbit, which cleans up a few nits.
229
	if(Home == NULL) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
230
		Home = "./";
390 by Matthew Fuller
Rerun 'make indent' after VMS reorbit, which cleans up a few nits.
231
	}
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
232
	HomeLen = strlen(Home);
233
641.1.8 by Matthew Fuller
Add various narrative comments through the startup process (outside of
234
235
	// XXX This is only used in AddWindow(), and is probably bogus to
236
	// have globally....
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
237
	NoClass.res_name = NoName;
238
	NoClass.res_class = NoName;
239
641.1.6 by Matthew Fuller
Wrap a scope and comment around this "set up X connection" stuff.
240
241
	/*
242
	 * Initialize our X connection and state bits.
243
	 */
244
	{
245
		int zero = 0; // Fakey
246
247
		XtToolkitInitialize();
248
		appContext = XtCreateApplicationContext();
249
656.1.9 by Matthew Fuller
Conditionalize even trying OpenDisplay, so we don't even bother on
250
		// Tests don't talk to a real X server.
251
		// XXX This needs revisiting if we ever get one that _does_.
252
		// We'll have to add another flag...
253
		if(!ctwm_test) {
254
			// Connect
255
			dpy = XtOpenDisplay(appContext, CLarg.display_name, "twm", "twm",
256
			                    NULL, 0, &zero, NULL);
257
		}
656.1.8 by Matthew Fuller
Add some comments.
258
259
		// Failed?  Usually a problem, but somethings we allow faking...
656.1.7 by Matthew Fuller
Do this open and var assignment outside the if(); it's way more
260
		if(!dpy && !nodpyok) {
641.1.6 by Matthew Fuller
Wrap a scope and comment around this "set up X connection" stuff.
261
			fprintf(stderr, "%s:  unable to open display \"%s\"\n",
262
			        ProgramName, XDisplayName(CLarg.display_name));
263
			exit(1);
264
		}
265
644.2.46 by Matthew Fuller
Add the last few checks so that --cfgchk will now run and do its best
266
		if(dpy && fcntl(ConnectionNumber(dpy), F_SETFD, FD_CLOEXEC) == -1) {
641.1.6 by Matthew Fuller
Wrap a scope and comment around this "set up X connection" stuff.
267
			fprintf(stderr,
268
			        "%s:  unable to mark display connection as close-on-exec\n",
269
			        ProgramName);
270
			exit(1);
271
		}
644.2.46 by Matthew Fuller
Add the last few checks so that --cfgchk will now run and do its best
272
656.1.9 by Matthew Fuller
Conditionalize even trying OpenDisplay, so we don't even bother on
273
		if(!dpy && !ctwm_test) {
274
			// At least warn, except for tests
644.2.46 by Matthew Fuller
Add the last few checks so that --cfgchk will now run and do its best
275
			fprintf(stderr, "%s: Can't connect to X server, proceeding anyway...\n",
648.1.7 by Matthew Fuller
make indent
276
			        ProgramName);
644.2.46 by Matthew Fuller
Add the last few checks so that --cfgchk will now run and do its best
277
		}
641.1.6 by Matthew Fuller
Wrap a scope and comment around this "set up X connection" stuff.
278
	}
279
280
702.1.4 by Matthew Fuller
Conditionalize a bunch of the session bits.
281
#ifdef SESSION
641.1.8 by Matthew Fuller
Add various narrative comments through the startup process (outside of
282
	// Load session stuff
389.1.50 by Matthew Fuller
Convert --restore arg to CLarg.
283
	if(CLarg.restore_filename) {
284
		ReadWinConfigFile(CLarg.restore_filename);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
285
	}
702.1.4 by Matthew Fuller
Conditionalize a bunch of the session bits.
286
#endif
641.1.8 by Matthew Fuller
Add various narrative comments through the startup process (outside of
287
644.2.46 by Matthew Fuller
Add the last few checks so that --cfgchk will now run and do its best
288
289
	if(dpy) {
290
		// Load up info about X extensions
291
		HasShape = XShapeQueryExtension(dpy, &ShapeEventBase, &ShapeErrorBase);
292
293
		// Allocate contexts/atoms/etc we use
294
		TwmContext = XUniqueContext();
295
		MenuContext = XUniqueContext();
296
		ScreenContext = XUniqueContext();
297
		ColormapContext = XUniqueContext();
298
		InitWorkSpaceManagerContext();
299
648.1.11 by Matthew Fuller
Once upon a time, this single-use util func did a bunch of individiual
300
		// Load up our standard set of atoms
301
		XInternAtoms(dpy, XCTWMAtomNames, NUM_CTWM_XATOMS, False, XCTWMAtom);
644.2.46 by Matthew Fuller
Add the last few checks so that --cfgchk will now run and do its best
302
303
		NumScreens = ScreenCount(dpy);
304
		PreviousScreen = DefaultScreen(dpy);
305
	}
306
	else {
307
		NumScreens = 1;
308
		PreviousScreen = 0;
309
	}
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
310
641.1.15 by Matthew Fuller
Move setting these cursors out of the per-Screen loop totally.
311
	// Allocate/define common cursors
312
	NewFontCursor(&TopLeftCursor, "top_left_corner");
313
	NewFontCursor(&TopRightCursor, "top_right_corner");
314
	NewFontCursor(&BottomLeftCursor, "bottom_left_corner");
315
	NewFontCursor(&BottomRightCursor, "bottom_right_corner");
316
	NewFontCursor(&LeftCursor, "left_side");
317
	NewFontCursor(&RightCursor, "right_side");
318
	NewFontCursor(&TopCursor, "top_side");
319
	NewFontCursor(&BottomCursor, "bottom_side");
320
321
	NewFontCursor(&UpperLeftCursor, "top_left_corner");
322
	NewFontCursor(&RightButt, "rightbutton");
323
	NewFontCursor(&LeftButt, "leftbutton");
324
	NewFontCursor(&MiddleButt, "middlebutton");
325
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
326
641.1.8 by Matthew Fuller
Add various narrative comments through the startup process (outside of
327
	// Prep up the per-screen global info
389.1.34 by Matthew Fuller
Convert MultiScreen into CLarg.
328
	if(CLarg.MultiScreen) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
329
		firstscrn = 0;
330
		lastscrn = NumScreens - 1;
9 by Claude Lecommandeur
CTWM version 3.1
331
	}
644.2.46 by Matthew Fuller
Add the last few checks so that --cfgchk will now run and do its best
332
	else if(!dpy) {
333
		firstscrn = lastscrn = 0;
334
	}
9 by Claude Lecommandeur
CTWM version 3.1
335
	else {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
336
		firstscrn = lastscrn = DefaultScreen(dpy);
337
	}
338
641.1.8 by Matthew Fuller
Add various narrative comments through the startup process (outside of
339
	// For simplicity, pre-allocate NumScreens ScreenInfo struct pointers
491.1.8 by Matthew Fuller
Stop casting return values of [mc]alloc(). void * has existed for 27
340
	ScreenList = calloc(NumScreens, sizeof(ScreenInfo *));
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
341
	if(ScreenList == NULL) {
342
		fprintf(stderr, "%s: Unable to allocate memory for screen list, exiting.\n",
343
		        ProgramName);
344
		exit(1);
345
	}
641.1.8 by Matthew Fuller
Add various narrative comments through the startup process (outside of
346
347
348
	// Do a little early initialization
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
349
#ifdef EWMH
644.2.46 by Matthew Fuller
Add the last few checks so that --cfgchk will now run and do its best
350
	if(dpy) {
351
		EwmhInit();
352
	}
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
353
#endif /* EWMH */
463.1.8 by Matthew Fuller
Now we have to move the sound_init() up higher, so it's ready before
354
#ifdef SOUNDS
641.1.50 by Matthew Fuller
Drop a comment to remind me that this has to happen before config
355
	// Needs init'ing before we get to config parsing
463.1.8 by Matthew Fuller
Now we have to move the sound_init() up higher, so it's ready before
356
	sound_init();
357
#endif
641.1.49 by Matthew Fuller
This is just setting up data structures as well. Might as well move
358
	InitEvents();
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
359
644.2.46 by Matthew Fuller
Add the last few checks so that --cfgchk will now run and do its best
360
361
641.1.8 by Matthew Fuller
Add various narrative comments through the startup process (outside of
362
	// Start looping over the screens
363
	numManaged = 0;
364
	FirstScreen = true;
641.1.2 by Matthew Fuller
Move a bunch of vars to inner scope, set default values in the only
365
	for(int scrnum = firstscrn ; scrnum <= lastscrn; scrnum++) {
641.1.3 by Matthew Fuller
Wrap a scope around and comment the block where we iterate over the
366
		Window croot;
641.1.2 by Matthew Fuller
Move a bunch of vars to inner scope, set default values in the only
367
		int crootx, crooty;
368
		unsigned int crootw, crooth;
369
		bool screenmasked;
370
		char *welcomefile;
371
644.2.34 by Matthew Fuller
Add a little sectionalizing whitespace.
372
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
373
		/*
374
		 * First, setup the root window for the screen.
375
		 */
692.1.5 by Matthew Fuller
Add ifdef's around references to Screen and CLargs members that are
376
		if(0) {
377
			// Dummy
378
		}
379
#ifdef CAPTIVE
380
		else if(CLarg.is_captive) {
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
381
			// Captive ctwm.  We make a fake root.
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
382
			XWindowAttributes wa;
389.1.48 by Matthew Fuller
Move --window's optional argument value into CLarg.
383
			if(CLarg.capwin && XGetWindowAttributes(dpy, CLarg.capwin, &wa)) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
384
				Window junk;
389.1.48 by Matthew Fuller
Move --window's optional argument value into CLarg.
385
				croot  = CLarg.capwin;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
386
				crootw = wa.width;
387
				crooth = wa.height;
389.1.64 by Matthew Fuller
Rerun indent.
388
				XTranslateCoordinates(dpy, CLarg.capwin, wa.root, 0, 0, &crootx, &crooty,
389
				                      &junk);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
390
			}
391
			else {
641.1.51 by Matthew Fuller
Tweak up some comments, including some extra verbiage about why
392
				// Fake up default size.  Probably ideally should be
641.1.2 by Matthew Fuller
Move a bunch of vars to inner scope, set default values in the only
393
				// configurable, but even more ideally we wouldn't have
394
				// captive...
395
				crootx = crooty = 100;
396
				crootw = 1280;
397
				crooth = 768;
641.1.1 by Matthew Fuller
Rename func to better match what it does.
398
				croot = CreateCaptiveRootWindow(crootx, crooty, crootw, crooth);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
399
			}
400
		}
692.1.5 by Matthew Fuller
Add ifdef's around references to Screen and CLargs members that are
401
#endif
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
402
		else {
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
403
			// Normal; get the real display's root.
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
404
			crootx = 0;
405
			crooty = 0;
644.2.27 by Matthew Fuller
Few more dpy conditionals.
406
407
			if(dpy) {
408
				croot  = RootWindow(dpy, scrnum);
409
				crootw = DisplayWidth(dpy, scrnum);
410
				crooth = DisplayHeight(dpy, scrnum);
411
			}
412
			else {
413
				croot = None;
414
				crootw = 1280;
415
				crooth = 768;
416
			}
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
417
		}
418
641.1.30 by Matthew Fuller
Comment
419
644.2.34 by Matthew Fuller
Add a little sectionalizing whitespace.
420
641.1.30 by Matthew Fuller
Comment
421
		/*
422
		 * Create ScreenInfo for this Screen, and populate various
423
		 * default/initial config.
424
		 */
641.1.31 by Matthew Fuller
Go ahead and pass the coordinates and dimensions of the screen into
425
		Scr = ScreenList[scrnum] = InitScreenInfo(scrnum, croot,
426
		                           crootx, crooty, crootw, crooth);
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
427
		if(Scr == NULL) {
428
			fprintf(stderr,
429
			        "%s: unable to allocate memory for ScreenInfo structure"
430
			        " for screen %d.\n",
431
			        ProgramName, scrnum);
432
			continue;
433
		}
434
641.1.37 by Matthew Fuller
Move this back out of the function; it's the only thing that relies
435
		// Other misc adjustments to default config.
436
		Scr->ShowWelcomeWindow = CLarg.ShowWelcomeWindow;
437
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
438
644.2.34 by Matthew Fuller
Add a little sectionalizing whitespace.
439
644.2.16 by Matthew Fuller
Move getting the layout together up to early stuff, right after we get
440
		/*
441
		 * Figure out the layout of our various monitors if RANDR is
442
		 * around and can tell us.
443
		 */
444
#ifdef XRANDR
644.2.27 by Matthew Fuller
Few more dpy conditionals.
445
		if(dpy) {
446
			Scr->Layout = XrandrNewLayout(dpy, Scr->XineramaRoot);
447
		}
644.2.16 by Matthew Fuller
Move getting the layout together up to early stuff, right after we get
448
#endif
449
		if(Scr->Layout == NULL) {
450
			// No RANDR, so as far as we know, the layout is just one
451
			// monitor with our full size.
452
			RArea *fs;
453
			RAreaList *fsl;
454
455
			fs = RAreaNewStatic(Scr->rootx, Scr->rooty, Scr->rootw, Scr->rooth);
456
			fsl = RAreaListNew(1, fs, NULL);
457
			Scr->Layout = RLayoutNew(fsl);
458
		}
459
#ifdef DEBUG
460
		fprintf(stderr, "Layout: ");
461
		RLayoutPrint(Scr->Layout);
462
#endif
463
		if(RLayoutNumMonitors(Scr->Layout) < 1) {
464
			fprintf(stderr, "Error: No monitors found on screen %d!\n", scrnum);
465
			continue;
466
		}
467
468
644.2.17 by Matthew Fuller
The OTP init stuff is just memory, so we can move that into the Init
469
614.1.122 by Matthew Fuller
Move the layout building a little earlier, before we bump numManaged.
470
		// Now we can stash some info about the screen
644.2.24 by Matthew Fuller
Setup "I have no display" defaults for these values too.
471
		if(dpy) {
472
			Scr->d_depth = DefaultDepth(dpy, scrnum);
473
			Scr->d_visual = DefaultVisual(dpy, scrnum);
474
			Scr->RealRoot = RootWindow(dpy, scrnum);
475
			{
476
				// Stash these for m4
477
				Screen *tscr = ScreenOfDisplay(dpy, scrnum);
478
				Scr->mm_w = tscr->mwidth;
479
				Scr->mm_h = tscr->mheight;
480
			}
481
		}
482
		else {
483
			// Standin; fake the values we need in m4 parsing
484
			Scr->d_visual = calloc(1, sizeof(Visual));
485
			Scr->d_visual->bits_per_rgb = 8;
486
			Scr->d_visual->class = TrueColor;
644.2.23 by Matthew Fuller
Make m4_defs() work fine without a display connection. Several values
487
		}
488
614.1.122 by Matthew Fuller
Move the layout building a little earlier, before we bump numManaged.
489
490
		// Now that we have d_depth...
491
		Scr->XORvalue = (((unsigned long) 1) << Scr->d_depth) - 1;
492
692.1.5 by Matthew Fuller
Add ifdef's around references to Screen and CLargs members that are
493
#ifdef CAPTIVE
644.2.33 by Matthew Fuller
Few more explicit comments on things that need to preceed config
494
		// Init captive bits.  We stick this name into m4 props, so do it
495
		// before config processing.
389.1.46 by Matthew Fuller
Convert the 'captive' flag to is_captive and move it into CLarg.
496
		if(CLarg.is_captive) {
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
497
			Scr->CaptiveRoot = croot;
389.1.61 by Matthew Fuller
Now that captivename is only used in ctwm.c, and then only as an
498
			Scr->captivename = AddToCaptiveList(CLarg.captivename);
389.1.60 by Matthew Fuller
Switch AddToCaptiveList() over to taking the captivename as an
499
			if(Scr->captivename) {
505.1.5 by Matthew Fuller
Convert other XSetStandardProperties()/XSetWM*() sequences into
500
				XmbSetWMProperties(dpy, croot,
505.1.6 by Matthew Fuller
make indent
501
				                   Scr->captivename, Scr->captivename,
502
				                   NULL, 0, NULL, NULL, NULL);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
503
			}
504
		}
692.1.5 by Matthew Fuller
Add ifdef's around references to Screen and CLargs members that are
505
#endif
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
506
507
644.2.33 by Matthew Fuller
Few more explicit comments on things that need to preceed config
508
		// Init some colormap bits.  We need this before we get into the
509
		// config parsing, since various things in there poke into
510
		// colormaps.
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
511
		{
512
			// 1 on the root
513
			Scr->RootColormaps.number_cwins = 1;
514
			Scr->RootColormaps.cwins = malloc(sizeof(ColormapWindow *));
515
			Scr->RootColormaps.cwins[0] = CreateColormapWindow(Scr->Root, true,
641.1.19 by Matthew Fuller
make indent
516
			                              false);
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
517
			Scr->RootColormaps.cwins[0]->visibility = VisibilityPartiallyObscured;
518
519
			// Initialize storage for all maps the Screen can hold
520
			Scr->cmapInfo.cmaps = NULL;
644.2.32 by Matthew Fuller
Do necessary dpy conditionalization in the colormap stuff used in
521
			if(dpy) {
522
				Scr->cmapInfo.maxCmaps = MaxCmapsOfScreen(ScreenOfDisplay(dpy,
523
				                         Scr->screen));
524
			}
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
525
			Scr->cmapInfo.root_pushes = 0;
526
			InstallColormaps(0, &Scr->RootColormaps);
527
528
			// Setup which we're using
529
			Scr->StdCmapInfo.head = Scr->StdCmapInfo.tail
641.1.19 by Matthew Fuller
make indent
530
			                        = Scr->StdCmapInfo.mru = NULL;
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
531
			Scr->StdCmapInfo.mruindex = 0;
644.2.32 by Matthew Fuller
Do necessary dpy conditionalization in the colormap stuff used in
532
			if(dpy) {
533
				LocateStandardColormaps();
534
			}
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
535
		}
536
537
538
		// Are we monochrome?  Or do we care this millennium?
644.2.25 by Matthew Fuller
Add another default, and conditionalize a few more things on dpy.
539
		if(CLarg.Monochrome || (dpy && DisplayCells(dpy, scrnum) < 3)) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
540
			Scr->Monochrome = MONOCHROME;
541
		}
542
		else {
543
			Scr->Monochrome = COLOR;
544
		}
545
641.1.38 by Matthew Fuller
Minor comment/whitespace/non-functional tweaks.
546
547
		// With the colormap/monochrome bits set, we can setup our
548
		// default color bits.
322.1.8 by Matthew Fuller
Assign straight to the vars we want these in.
549
		GetColor(Scr->Monochrome, &(Scr->Black), "black");
550
		GetColor(Scr->Monochrome, &(Scr->White), "white");
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
551
641.1.22 by Matthew Fuller
Change InitVariables() to do a little more of the early
552
		Scr->MenuShadowColor = Scr->Black;
553
		Scr->IconBorderColor = Scr->Black;
554
		Scr->IconManagerHighlight = Scr->Black;
555
556
#define SETFB(fld) Scr->fld.fore = Scr->Black; Scr->fld.back = Scr->White;
557
		SETFB(DefaultC)
558
		SETFB(BorderColorC)
559
		SETFB(BorderTileC)
560
		SETFB(TitleC)
561
		SETFB(MenuC)
562
		SETFB(MenuTitleC)
563
		SETFB(IconC)
564
		SETFB(IconManagerC)
641.1.41 by Matthew Fuller
Extract the constant bits of WSM setup out of the WSM-specific init
565
		SETFB(workSpaceMgr.windowcp)
566
		SETFB(workSpaceMgr.curColors)
567
		SETFB(workSpaceMgr.defColors)
641.1.22 by Matthew Fuller
Change InitVariables() to do a little more of the early
568
#undef SETFB
569
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
570
571
		// The first time around, we focus onto the root [of the first
641.1.15 by Matthew Fuller
Move setting these cursors out of the per-Screen loop totally.
572
		// Screen].  Maybe we should revisit this...
644.2.26 by Matthew Fuller
I still think this should probably happen later or not at all, but
573
		if(dpy && FirstScreen) {
641.1.17 by Matthew Fuller
Leave a comment about an interesting open question.
574
			// XXX This func also involves a lot of stuff that isn't
575
			// setup yet, and probably only works by accident.  Maybe we
576
			// should just manually extract out the couple bits we
577
			// actually want to run?
497.1.17 by Matthew Fuller
Don't cast NULL to particular pointer types.
578
			SetFocus(NULL, CurrentTime);
641.1.38 by Matthew Fuller
Minor comment/whitespace/non-functional tweaks.
579
			FirstScreen = false;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
580
		}
581
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
582
		// Create default icon manager memory bits (in the first
583
		// workspace)
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
584
		AllocateIconManager("TWM", "Icons", "", 1);
585
586
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
587
		/*
588
		 * Mask over the screen with our welcome window stuff if we were
589
		 * asked to on the command line/environment; too early to get
590
		 * info from config file about it.
591
		 */
604.1.1 by Matthew Fuller
This var is used as a bool, so make it one.
592
		screenmasked = false;
644.2.38 by Matthew Fuller
Don't mask the screen if we're not taking it over, that's just dumb.
593
		if(dpy && takeover && Scr->ShowWelcomeWindow
644.2.25 by Matthew Fuller
Add another default, and conditionalize a few more things on dpy.
594
		                && (welcomefile = getenv("CTWM_WELCOME_FILE"))) {
604.1.1 by Matthew Fuller
This var is used as a bool, so make it one.
595
			screenmasked = true;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
596
			MaskScreen(welcomefile);
597
		}
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
598
599
644.2.34 by Matthew Fuller
Add a little sectionalizing whitespace.
600
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
601
		/*
641.1.51 by Matthew Fuller
Tweak up some comments, including some extra verbiage about why
602
		 * Load up config file
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
603
		 */
644.2.43 by Matthew Fuller
Move attempted takeover until after the config parsing, and
604
		{
605
			bool ok = LoadTwmrc(CLarg.InitFile);
606
607
			// cfgchk just displays whether there are errors, then moves
608
			// on.
609
			if(CLarg.cfgchk) {
610
				if(ok) {
611
					fprintf(stderr, "%d: No errors found\n", scrnum);
612
				}
613
				else {
614
					fprintf(stderr, "%d: Errors found\n", scrnum);
615
					cfgerrs = true;
616
				}
644.2.50 by Matthew Fuller
Extract out of the conditional, since it's not conditional.
617
				continue;
644.2.43 by Matthew Fuller
Move attempted takeover until after the config parsing, and
618
			}
619
620
			// In non-config-check mode, we historically proceed even if
621
			// there were errors, so keep doing that...
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
622
		}
644.2.43 by Matthew Fuller
Move attempted takeover until after the config parsing, and
623
624
656.1.1 by Matthew Fuller
Provide a callback for tests to hook into, to let them grub around in
625
		// For testing, it's useful to do all that initial setup up
626
		// through parsing, and then inspect Scr and the like.
627
		// Long-term, IWBNI we had a better way to do all the necessary
628
		// initialization and then call the parse ourselves at that
629
		// level.  But for now, provide a callback func that can pass
630
		// control back to the test code, then just exits.
631
		if(ctwm_test_postparse != NULL) {
632
			exit(ctwm_test_postparse());
633
		}
634
635
644.2.43 by Matthew Fuller
Move attempted takeover until after the config parsing, and
636
637
		/*
638
		 * Since we've loaded the config, go ahead and take over the
639
		 * screen.
640
		 */
641
		if(takeover) {
642
			if(takeover_screen(Scr) != true) {
643
				// Well, move on to the next one, maybe we'll get it...
644
				if(screenmasked) {
645
					UnmaskScreen();
646
				}
647
				continue;
648
			}
649
650
			// Well, we got this one
651
			numManaged++;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
652
		}
653
652.1.9 by Matthew Fuller
Move the config-conditional splashscreen setup over to right after the
654
		// If the config wants us to show the splash screen and we
655
		// haven't already, do it now.
656
		if(Scr->ShowWelcomeWindow && !screenmasked) {
657
			MaskScreen(NULL);
658
		}
659
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
660
644.2.18 by Matthew Fuller
Better distinguish the largely set-internal-stuff block from the
661
662
		/*
663
		 * Do various setup based on the results from the config file.
664
		 */
665
666
		// Few simple var defaults
667
		if(Scr->ClickToFocus) {
668
			Scr->FocusRoot  = false;
669
			Scr->TitleFocus = false;
670
		}
671
672
		if(Scr->use3Dborders) {
673
			Scr->ClientBorderWidth = false;
674
		}
675
676
677
		// Now that we know what Border's there may be, create our
678
		// BorderedLayout.
614.1.2 by Maxime Soulé
Menus are now clipped using layout
679
		Scr->BorderedLayout = RLayoutCopyCropped(Scr->Layout,
680
		                      Scr->BorderLeft, Scr->BorderRight,
681
		                      Scr->BorderTop, Scr->BorderBottom);
682
		if(Scr->BorderedLayout == NULL) {
683
			Scr->BorderedLayout = Scr->Layout;        // nothing to crop
684
		}
685
		else if(Scr->BorderedLayout->monitors->len == 0) {
686
			fprintf(stderr,
687
			        "Borders too large! correct BorderLeft, BorderRight, BorderTop and/or BorderBottom parameters\n");
688
			exit(1);
614.1.1 by Maxime Soulé
First step of xrandr integration
689
		}
614.1.17 by Maxime Soulé
Remove some debugs, use stderr for remaining ones only if DEBUG set
690
#ifdef DEBUG
691
		fprintf(stderr, "Bordered: ");
614.1.11 by Maxime Soulé
Xrandr support can be disabled at compile time (ON by default)
692
		RLayoutPrint(Scr->BorderedLayout);
614.1.17 by Maxime Soulé
Remove some debugs, use stderr for remaining ones only if DEBUG set
693
#endif
614.1.1 by Maxime Soulé
First step of xrandr integration
694
614.3.5 by Matthew Fuller
Merge up significant rework of per-screen loop and resolve a bunch of conflicts.
695
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
696
		/*
697
		 * Setup stuff relating to VirtualScreens.  If something to do
698
		 * with it is set in the config, this all implements stuff needed
699
		 * for that.  If not, InitVirtualScreens() creates a single one
700
		 * mirroring our real root.
701
		 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
702
		InitVirtualScreens(Scr);
696.1.15 by Matthew Fuller
Move EWMH vscreen-related bits behind the define.
703
#ifdef VSCREEN
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
704
#ifdef EWMH
705
		EwmhInitVirtualRoots(Scr);
706
#endif /* EWMH */
696.1.15 by Matthew Fuller
Move EWMH vscreen-related bits behind the define.
707
#endif // vscreen
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
708
652.1.20 by Matthew Fuller
Expand comment to note a new thing here.
709
		// Setup WSM[s] (per-vscreen).  This also sets up the about the
710
		// workspaces for each vscreen and which is currently displayed.
652.1.10 by Matthew Fuller
Make ConfigureWorkSpaceManager() take its ScreenInfo directly rather
711
		ConfigureWorkSpaceManager(Scr);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
712
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
713
714
		/*
715
		 * Various decoration default overrides for 3d/2d.  Values that
641.1.14 by Matthew Fuller
Macroize setting these defaults, and expand the comment a little to
716
		 * [presumtively] look "nice" on 75/100dpi displays.  -100 is a
717
		 * sentinel value we set before the config file parsing; since
718
		 * these defaults differ for 3d vs not, we can't just set them as
719
		 * default before the parse.
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
720
		 */
641.1.14 by Matthew Fuller
Macroize setting these defaults, and expand the comment a little to
721
#define SETDEF(fld, num) if(Scr->fld == -100) { Scr->fld = num; }
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
722
		if(Scr->use3Dtitles) {
641.1.14 by Matthew Fuller
Macroize setting these defaults, and expand the comment a little to
723
			SETDEF(FramePadding,  0);
724
			SETDEF(TitlePadding,  0);
725
			SETDEF(ButtonIndent,  0);
726
			SETDEF(TBInfo.border, 0);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
727
		}
728
		else {
641.1.14 by Matthew Fuller
Macroize setting these defaults, and expand the comment a little to
729
			SETDEF(FramePadding,  2);
730
			SETDEF(TitlePadding,  8);
731
			SETDEF(ButtonIndent,  1);
732
			SETDEF(TBInfo.border, 1);
641.1.12 by Matthew Fuller
Move these to their own block for symmetry.
733
		}
641.1.14 by Matthew Fuller
Macroize setting these defaults, and expand the comment a little to
734
#undef SETDEF
641.1.12 by Matthew Fuller
Move these to their own block for symmetry.
735
736
		// These values are meaningless in !3d cases, so always zero them
737
		// out.
738
		if(! Scr->use3Dtitles) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
739
			Scr->TitleShadowDepth       = 0;
740
			Scr->TitleButtonShadowDepth = 0;
741
		}
742
		if(! Scr->use3Dborders) {
743
			Scr->BorderShadowDepth = 0;
744
		}
745
		if(! Scr->use3Dmenus) {
746
			Scr->MenuShadowDepth = 0;
747
		}
748
		if(! Scr->use3Diconmanagers) {
749
			Scr->IconManagerShadowDepth = 0;
750
		}
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
751
		if(! Scr->use3Dborders) {
752
			Scr->ThreeDBorderWidth = 0;
753
		}
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
754
641.1.48 by Matthew Fuller
Unify this GetShadeColors() with the earlier ones.
755
		// Setup colors stuff
641.1.47 by Matthew Fuller
Extract out common condition.
756
		if(!Scr->BeNiceToColormap) {
641.1.48 by Matthew Fuller
Unify this GetShadeColors() with the earlier ones.
757
			// Default pair
758
			GetShadeColors(&Scr->DefaultC);
759
760
			// Various conditionally 3d bits
641.1.47 by Matthew Fuller
Extract out common condition.
761
			if(Scr->use3Dtitles) {
762
				GetShadeColors(&Scr->TitleC);
763
			}
764
			if(Scr->use3Dmenus) {
765
				GetShadeColors(&Scr->MenuC);
766
			}
767
			if(Scr->use3Dmenus) {
768
				GetShadeColors(&Scr->MenuTitleC);
769
			}
770
			if(Scr->use3Dborders) {
771
				GetShadeColors(&Scr->BorderColorC);
772
			}
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
773
		}
774
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
775
		// Defaults for IconRegion bits that aren't set.
641.1.2 by Matthew Fuller
Move a bunch of vars to inner scope, set default values in the only
776
		for(IconRegion *ir = Scr->FirstRegion; ir; ir = ir->next) {
496.1.16 by Matthew Fuller
Convert TitleJustification elements to their own enum type, and fixup
777
			if(ir->TitleJustification == TJ_UNDEF) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
778
				ir->TitleJustification = Scr->IconJustification;
779
			}
496.1.17 by Matthew Fuller
Convert IconRegion Justification to its own enum type too. This is
780
			if(ir->Justification == IRJ_UNDEF) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
781
				ir->Justification = Scr->IconRegionJustification;
782
			}
496.1.14 by Matthew Fuller
Create an enum for the IconRegion Alignement (misspelling preserved
783
			if(ir->Alignement == IRA_UNDEF) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
784
				ir->Alignement = Scr->IconRegionAlignement;
785
			}
786
		}
787
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
788
		// Put the results of SaveColor{} into _MIT_PRIORITY_COLORS.
789
		assign_var_savecolor();
790
641.1.20 by Matthew Fuller
Instead of setting all these cursors at the start, then possibly
791
		// Setup cursor values that weren't give in the config
792
#define DEFCURSOR(name, val) if(!Scr->name) NewFontCursor(&Scr->name, val)
793
		DEFCURSOR(FrameCursor,   "top_left_arrow");
794
		DEFCURSOR(TitleCursor,   "top_left_arrow");
795
		DEFCURSOR(IconCursor,    "top_left_arrow");
796
		DEFCURSOR(IconMgrCursor, "top_left_arrow");
797
		DEFCURSOR(MoveCursor,    "fleur");
798
		DEFCURSOR(ResizeCursor,  "fleur");
799
		DEFCURSOR(MenuCursor,    "sb_left_arrow");
800
		DEFCURSOR(ButtonCursor,  "hand2");
801
		DEFCURSOR(WaitCursor,    "watch");
802
		DEFCURSOR(SelectCursor,  "dot");
803
		DEFCURSOR(DestroyCursor, "pirate");
804
		DEFCURSOR(AlterCursor,   "question_arrow");
805
#undef DEFCURSOR
806
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
807
		// Load up fonts for the screen.
808
		//
809
		// XXX HaveFonts is kinda stupid, however it gets useful in one
810
		// place: when loading button bindings, we make some sort of
811
		// "menu" for things (x-ref GotButton()), and the menu gen code
812
		// needs to load font stuff, so if that happened in the config
813
		// process, we would have already run CreateFonts().  Of course,
814
		// that's a order-dependent bit of the config file parsing too;
815
		// if you define the fonts too late, they wouldn't have been set
816
		// by then, and we won't [re]try them now...    arg.
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
817
		if(!Scr->HaveFonts) {
641.1.33 by Matthew Fuller
Pass Scr into CreateFonts() rather than it just going straight to the
818
			CreateFonts(Scr);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
819
		}
820
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
821
		// Adjust settings for titlebar.  Must follow CreateFonts() call
822
		// so we know these bits are populated
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
823
		Scr->TitleBarFont.y += Scr->FramePadding;
824
		Scr->TitleHeight = Scr->TitleBarFont.height + Scr->FramePadding * 2;
825
		if(Scr->use3Dtitles) {
826
			Scr->TitleHeight += 2 * Scr->TitleShadowDepth;
827
		}
828
		/* make title height be odd so buttons look nice and centered */
829
		if(!(Scr->TitleHeight & 1)) {
830
			Scr->TitleHeight++;
831
		}
832
644.2.18 by Matthew Fuller
Better distinguish the largely set-internal-stuff block from the
833
834
835
		/*
836
		 * Now we can start making various things.
837
		 */
838
644.2.28 by Matthew Fuller
Move saving this context down to the end. I'm pretty sure we never
839
		// Stash up a ref to our Scr on the root, so we can find the
840
		// right Scr for events etc.
841
		XSaveContext(dpy, Scr->Root, ScreenContext, (XPointer) Scr);
842
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
843
		// Setup GC's for drawing, so we can start making stuff we have
844
		// to actually draw.  Could move earlier, has to preceed a lot of
845
		// following.
846
		CreateGCs();
847
848
		// Create and draw the menus we config'd
849
		MakeMenus();
850
851
		// Load up the images for titlebar buttons
641.1.10 by Matthew Fuller
Adjust a few more comments.
852
		InitTitlebarButtons();
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
853
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
854
		// Allocate controls for WindowRegion's.  Has to follow
855
		// workspaces setup, but doesn't talk to X.
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
856
		CreateWindowRegions();
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
857
858
		// Copy the icon managers over to workspaces past the first as
859
		// necessary.  AllocateIconManager() and the config parsing
860
		// already made them on the first WS.
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
861
		AllocateOtherIconManagers();
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
862
863
		// Create the windows for our icon managers now that all our
864
		// tracking for it is setup.
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
865
		CreateIconManagers();
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
866
867
		// Create the WSM window (per-vscreen) and stash info on the root
868
		// about our WS's.
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
869
		CreateWorkSpaceManager();
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
870
871
		// Create the f.occupy window
510.1.21 by Matthew Fuller
Disentangle a little by creating the occupy window from the top level
872
		CreateOccupyWindow();
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
873
874
		// Setup TwmWorkspaces menu.  Needs workspaces setup, as well as
875
		// menus made.
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
876
		MakeWorkspacesMenu();
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
877
700.1.7 by Matthew Fuller
Conditionalize away all the winbox stuff in the main function.
878
#ifdef WINBOX
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
879
		// setup WindowBox's
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
880
		createWindowBoxes();
700.1.7 by Matthew Fuller
Conditionalize away all the winbox stuff in the main function.
881
#endif
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
882
641.1.40 by Matthew Fuller
Don't initialize Xrm stuff inside WSM setup stuff; just do it inline.
883
		// Initialize Xrm stuff; things with setting occupation etc use
884
		// Xrm bits.
885
		XrmInitialize();
886
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
887
#ifdef EWMH
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
888
		// Set EWMH-related properties on various root-ish windows, for
889
		// other programs to read to find out how we view the world.
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
890
		EwmhInitScreenLate(Scr);
891
#endif /* EWMH */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
892
641.1.3 by Matthew Fuller
Wrap a scope around and comment the block where we iterate over the
893
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
894
		/*
641.1.3 by Matthew Fuller
Wrap a scope around and comment the block where we iterate over the
895
		 * Look up and handle all the windows on the screen.
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
896
		 */
641.1.3 by Matthew Fuller
Wrap a scope around and comment the block where we iterate over the
897
		{
898
			Window parent, *children;
899
			unsigned int nchildren;
900
901
			XQueryTree(dpy, Scr->Root, &croot, &parent, &children, &nchildren);
902
903
			/* Weed out icon windows */
904
			for(int i = 0; i < nchildren; i++) {
905
				if(children[i]) {
906
					XWMHints *wmhintsp = XGetWMHints(dpy, children[i]);
907
908
					if(wmhintsp) {
909
						if(wmhintsp->flags & IconWindowHint) {
910
							for(int j = 0; j < nchildren; j++) {
911
								if(children[j] == wmhintsp->icon_window) {
912
									children[j] = None;
913
									break;
914
								}
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
915
							}
916
						}
641.1.3 by Matthew Fuller
Wrap a scope around and comment the block where we iterate over the
917
						XFree(wmhintsp);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
918
					}
641.1.3 by Matthew Fuller
Wrap a scope around and comment the block where we iterate over the
919
				}
920
			}
921
922
			/*
923
			 * Map all of the non-override windows.  This winds down
924
			 * into AddWindow() and friends through SimulateMapRequest(),
925
			 * so this is where we actually adopt the windows on the
926
			 * screen.
927
			 */
928
			for(int i = 0; i < nchildren; i++) {
929
				if(children[i] && MappedNotOverride(children[i])) {
930
					XUnmapWindow(dpy, children[i]);
931
					SimulateMapRequest(children[i]);
932
				}
933
			}
641.1.10 by Matthew Fuller
Adjust a few more comments.
934
935
			/*
936
			 * At this point, we've adopted all the windows currently on
937
			 * the screen (aside from those we're intentionally not).
938
			 * Note that this happens _before_ the various other windows
939
			 * we create below, which is why they don't wind up getting
940
			 * TwmWindow's tied to them or show up in icon managers, etc.
941
			 * We'd need to actually make it _explicit_ that those
942
			 * windows aren't tracked by us if we changed that order...
943
			 */
641.1.3 by Matthew Fuller
Wrap a scope around and comment the block where we iterate over the
944
		}
945
946
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
947
		// Show the WSM window if we should
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
948
		if(Scr->ShowWorkspaceManager && Scr->workSpaceManagerActive) {
949
			VirtualScreen *vs;
950
			if(Scr->WindowMask) {
951
				XRaiseWindow(dpy, Scr->WindowMask);
952
			}
953
			for(vs = Scr->vScreenList; vs != NULL; vs = vs->next) {
954
				SetMapStateProp(vs->wsw->twm_win, NormalState);
955
				XMapWindow(dpy, vs->wsw->twm_win->frame);
956
				if(vs->wsw->twm_win->StartSqueezed) {
957
					Squeeze(vs->wsw->twm_win);
958
				}
959
				else {
960
					XMapWindow(dpy, vs->wsw->w);
961
				}
492.2.75 by Matthew Fuller
Convert a bunch of boolean flags in the TwmWindow structure
962
				vs->wsw->twm_win->mapped = true;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
963
			}
964
		}
965
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
966
641.1.5 by Matthew Fuller
Wrap a scope around setting up the InfoWindow too. Move the X
967
		/*
968
		 * Setup the Info window, used for f.identify and f.version.
969
		 */
970
		{
971
			unsigned long valuemask;
972
			XSetWindowAttributes attributes;
973
974
			attributes.border_pixel = Scr->DefaultC.fore;
975
			attributes.background_pixel = Scr->DefaultC.back;
976
			attributes.event_mask = (ExposureMask | ButtonPressMask |
977
			                         KeyPressMask | ButtonReleaseMask);
978
			NewFontCursor(&attributes.cursor, "hand2");
979
			valuemask = (CWBorderPixel | CWBackPixel | CWEventMask | CWCursor);
980
			Scr->InfoWindow.win =
981
			        XCreateWindow(dpy, Scr->Root, 0, 0,
982
			                      5, 5,
983
			                      0, 0,
984
			                      CopyFromParent, CopyFromParent,
985
			                      valuemask, &attributes);
986
		}
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
987
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
988
641.1.4 by Matthew Fuller
Move setting up text sizeing bits for the SizeWindow into the scope
989
		/*
990
		 * Setup the Size/Position window for showing during resize/move
991
		 * operations.
992
		 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
993
		{
614.1.101 by Matthew Fuller
Drop a comment about why we're doing what we're doing here, and why we
994
			// Stick the SizeWindow at the top left of the first monitor
995
			// we found on this Screen.  That _may_ not be (0,0) (imagine
996
			// a shorter left and taller right monitor, with their bottom
997
			// edges lined up instead of top), so we have to look up what
998
			// that coordinate is.  If we're CenterFeedbackWindow'ing,
999
			// the window will have to move between monitors depending on
1000
			// where the window we're moving is (starts), but
1001
			// MoveResizeSizeWindow() will handle that.  If not, it
1002
			// always stays in the top-left of the first display.
614.1.20 by Maxime Soulé
If CenterFeedbackWindow, feedback window centered in first monitor
1003
			RArea area = RLayoutGetAreaIndex(Scr->Layout, 0);
641.1.4 by Matthew Fuller
Move setting up text sizeing bits for the SizeWindow into the scope
1004
			XRectangle ink_rect;
1005
			XRectangle logical_rect;
641.1.5 by Matthew Fuller
Wrap a scope around setting up the InfoWindow too. Move the X
1006
			unsigned long valuemask;
1007
			XSetWindowAttributes attributes;
641.1.4 by Matthew Fuller
Move setting up text sizeing bits for the SizeWindow into the scope
1008
1009
			XmbTextExtents(Scr->SizeFont.font_set,
1010
			               " 8888 x 8888 ", 13,
1011
			               &ink_rect, &logical_rect);
1012
			Scr->SizeStringWidth = logical_rect.width;
1013
			valuemask = (CWBorderPixel | CWBackPixel | CWBitGravity);
1014
			attributes.bit_gravity = NorthWestGravity;
1015
614.1.121 by Matthew Fuller
Restore SaveUnder for the SizeWindow. It makes as much sense as it
1016
			if(Scr->SaveUnder) {
1017
				attributes.save_under = True;
1018
				valuemask |= CWSaveUnder;
1019
			}
1020
614.1.28 by Maxime Soulé
If CenterFeedbackWindow, feedback window centered in current monitor
1021
			Scr->SizeWindow = XCreateWindow(dpy, Scr->Root,
1022
			                                area.x, area.y,
505.1.19 by Matthew Fuller
Remove casts from XCreateWindow() calls. Some of these were probably
1023
			                                Scr->SizeStringWidth,
1024
			                                (Scr->SizeFont.height +
507.1.2 by Matthew Fuller
make indent
1025
			                                 SIZE_VINDENT * 2),
505.1.19 by Matthew Fuller
Remove casts from XCreateWindow() calls. Some of these were probably
1026
			                                0, 0,
1027
			                                CopyFromParent,
1028
			                                CopyFromParent,
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1029
			                                valuemask, &attributes);
1030
		}
641.1.10 by Matthew Fuller
Adjust a few more comments.
1031
1032
		// Create util window used in animation
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1033
		Scr->ShapeWindow = XCreateSimpleWindow(dpy, Scr->Root, 0, 0,
1034
		                                       Scr->rootw, Scr->rooth, 0, 0, 0);
1035
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
1036
1037
		// Clear out the splash screen if we had one
389.1.51 by Matthew Fuller
Stick a ShowWelcomeWindow member in the ScreenInfo struct, set that
1038
		if(Scr->ShowWelcomeWindow) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1039
			UnmaskScreen();
1040
		}
1041
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
1042
		// Done setting up this Screen.  x-ref XXX's about whether this
1043
		// element is worth anything...
492.2.104 by Matthew Fuller
Massive rewrite of various struct Screen config params that are
1044
		Scr->FirstTime = false;
641.1.9 by Matthew Fuller
Do a bunch more commenting and a few minor moves of the loop for
1045
	} // for each screen on display
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1046
641.1.8 by Matthew Fuller
Add various narrative comments through the startup process (outside of
1047
644.2.44 by Matthew Fuller
Better to exit explicitly; should always be the same, but...
1048
	// If we're just checking the config, there's nothing more to do.
1049
	if(CLarg.cfgchk) {
1050
		exit(cfgerrs);
1051
	}
1052
1053
641.1.8 by Matthew Fuller
Add various narrative comments through the startup process (outside of
1054
	// We're not much of a window manager if we didn't get stuff to
1055
	// manage...
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1056
	if(numManaged == 0) {
389.1.34 by Matthew Fuller
Convert MultiScreen into CLarg.
1057
		if(CLarg.MultiScreen && NumScreens > 0)
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1058
			fprintf(stderr, "%s:  unable to find any unmanaged screens\n",
1059
			        ProgramName);
1060
		exit(1);
1061
	}
641.1.8 by Matthew Fuller
Add various narrative comments through the startup process (outside of
1062
702.1.4 by Matthew Fuller
Conditionalize a bunch of the session bits.
1063
#ifdef SESSION
641.1.8 by Matthew Fuller
Add various narrative comments through the startup process (outside of
1064
	// Hook up session
522.1.1 by Matthew Fuller
Eliminate most (void) casts; they don't really add anything, and just
1065
	ConnectToSessionManager(CLarg.client_id);
702.1.4 by Matthew Fuller
Conditionalize a bunch of the session bits.
1066
#endif
641.1.8 by Matthew Fuller
Add various narrative comments through the startup process (outside of
1067
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1068
#ifdef SOUNDS
641.1.8 by Matthew Fuller
Add various narrative comments through the startup process (outside of
1069
	// Announce ourselves
463.1.6 by Matthew Fuller
Export and load the list in the main func too. Remove the code in
1070
	sound_load_list();
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1071
	play_startup_sound();
1072
#endif
1073
641.1.8 by Matthew Fuller
Add various narrative comments through the startup process (outside of
1074
	// Hard-reset this flag.
1075
	// XXX This doesn't seem right?
492.2.48 by Matthew Fuller
Some more Bool->bool conversions.
1076
	RestartPreviousState = true;
641.1.8 by Matthew Fuller
Add various narrative comments through the startup process (outside of
1077
652.1.4 by Matthew Fuller
Don't need to set this var before we set animation vars, so move it
1078
	// Set vars to enable animation bits
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1079
	StartAnimation();
641.1.8 by Matthew Fuller
Add various narrative comments through the startup process (outside of
1080
1081
	// Main loop.
652.1.4 by Matthew Fuller
Don't need to set this var before we set animation vars, so move it
1082
	HandlingEvents = true;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1083
	HandleEvents();
641.1.8 by Matthew Fuller
Add various narrative comments through the startup process (outside of
1084
1085
	// Should never get here...
322.1.25 by Matthew Fuller
HandleEvents() never returns, so mark it with __attribute__ to hint to
1086
	fprintf(stderr, "Shouldn't return from HandleEvents()!\n");
1087
	exit(1);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1088
}
1089
389.1.10 by Matthew Fuller
Move the usage message off into a usage() function. Still as
1090
644.2.39 by Matthew Fuller
Do a little mostly cosmetic whitespace/comment/etc through the
1091
641.1.35 by Matthew Fuller
doxygen-ify the documentation for this func, so we can emphasize that
1092
/**
1093
 * Initialize ScreenInfo for a Screen.  This allocates the struct,
1094
 * assigns in the info we pass it about the screen and dimensions, and
1095
 * then puts in our various default/fallback/sentinel/etc values to
1096
 * prepare it for later use.
1097
 *
1098
 * It is intentional that this doesn't do any of the initialization that
1099
 * involves calling out to X functions; it operates as a pure function.
1100
 * This makes it easier to use it to fake up a ScreenInfo for something
1101
 * that isn't actually an X Screen, for testing etc.
1102
 *
1103
 * \param scrnum The Screen number (e.g, :0.0 -> 0)
1104
 * \param croot  The X Window for the Screen's root window
1105
 * \param crootx Root X coordinate
1106
 * \param crooty Root Y coordinate
1107
 * \param crootw Root width
1108
 * \param crooth Root height
1109
 * \return Allocated and populated ScreenInfo
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1110
 */
641.1.23 by Matthew Fuller
Change InitVariables() so it actually does the allocation of the
1111
ScreenInfo *
641.1.31 by Matthew Fuller
Go ahead and pass the coordinates and dimensions of the screen into
1112
InitScreenInfo(int scrnum, Window croot, int crootx, int crooty,
1113
               unsigned int crootw, unsigned int crooth)
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1114
{
641.1.23 by Matthew Fuller
Change InitVariables() so it actually does the allocation of the
1115
	ScreenInfo *scr;
1116
	scr = calloc(1, sizeof(ScreenInfo));
1117
	if(scr == NULL) {
1118
		return NULL;
1119
	}
641.1.25 by Matthew Fuller
Adjust this comment and move it to where it's most useful now.
1120
	// Because of calloc(), it's already all 0 bytes, which are NULL and
1121
	// false and 0 and similar.  Some following initializations are
1122
	// nugatory because of that, but are left for clarity.
641.1.23 by Matthew Fuller
Change InitVariables() so it actually does the allocation of the
1123
641.1.42 by Matthew Fuller
Add a guardrail in here to more quickly catch when I accidentally let
1124
	// Poison the global Scr to protect against typos
1125
#define Scr StupidProgrammer
1126
1127
641.1.31 by Matthew Fuller
Go ahead and pass the coordinates and dimensions of the screen into
1128
	// Basic pieces about the X screen we're talking about, and some
1129
	// derived dimension-related bits.
641.1.23 by Matthew Fuller
Change InitVariables() so it actually does the allocation of the
1130
	scr->screen = scrnum;
1131
	scr->XineramaRoot = scr->Root = croot;
692.1.5 by Matthew Fuller
Add ifdef's around references to Screen and CLargs members that are
1132
	scr->rootx = crootx;
1133
	scr->rooty = crooty;
1134
	scr->rootw = crootw;
1135
	scr->rooth = crooth;
1136
1137
#ifdef CAPTIVE
1138
	scr->crootx = crootx;
1139
	scr->crooty = crooty;
1140
	scr->crootw = crootw;
1141
	scr->crooth = crooth;
1142
#endif
641.1.31 by Matthew Fuller
Go ahead and pass the coordinates and dimensions of the screen into
1143
1144
	// Don't allow icon titles wider than the screen
1145
	scr->MaxIconTitleWidth = scr->rootw;
1146
641.1.52 by Matthew Fuller
Doc why these calculations are how they are, adjust them slightly to
1147
	// Attempt to come up with a sane default for the max sizes.  Start
1148
	// by limiting so that a window with its left/top on the right/bottom
1149
	// edge of the screen can't extend further than X can address (signed
1150
	// 16-bit).  However, when your screen size starts approaching that
1151
	// limit, reducing the max window sizes too much gets stupid too, so
1152
	// set an arbitrary floor on how low this will take it.
1153
	// MaxWindowSize in the config will override whatever's here anyway.
1154
	scr->MaxWindowWidth  = 32767 - (scr->rootx + scr->rootw);
1155
	scr->MaxWindowHeight = 32767 - (scr->rooty + scr->rooth);
641.1.53 by Matthew Fuller
make indent
1156
	if(scr->MaxWindowWidth < 4096) {
641.1.52 by Matthew Fuller
Doc why these calculations are how they are, adjust them slightly to
1157
		scr->MaxWindowWidth = 4096;
641.1.53 by Matthew Fuller
make indent
1158
	}
1159
	if(scr->MaxWindowHeight < 4096) {
641.1.52 by Matthew Fuller
Doc why these calculations are how they are, adjust them slightly to
1160
		scr->MaxWindowHeight = 4096;
641.1.53 by Matthew Fuller
make indent
1161
	}
641.1.31 by Matthew Fuller
Go ahead and pass the coordinates and dimensions of the screen into
1162
641.1.23 by Matthew Fuller
Change InitVariables() so it actually does the allocation of the
1163
641.1.26 by Matthew Fuller
Do a little further commenting/adjustment and move one declaration out
1164
	// Flags used in the code to keep track of where in various processes
1165
	// (especially startup) we are.
1166
	scr->HaveFonts = false;
1167
641.1.36 by Matthew Fuller
Move a few other simple initializations into the Initialize func,
1168
	// Flag which basically means "initial screen setup time".
1169
	// XXX Not clear to what extent this should even exist; a lot of
1170
	// uses are fairly bogus.
1171
	scr->FirstTime = true;
1172
641.1.26 by Matthew Fuller
Do a little further commenting/adjustment and move one declaration out
1173
	// Sentinel values for defaulting config values
641.1.23 by Matthew Fuller
Change InitVariables() so it actually does the allocation of the
1174
	scr->FramePadding = -100;
1175
	scr->TitlePadding = -100;
1176
	scr->ButtonIndent = -100;
1177
	scr->TBInfo.border = -100;
641.1.13 by Matthew Fuller
Move setting this sentinel value to alongside the other 3 msmts using
1178
641.1.26 by Matthew Fuller
Do a little further commenting/adjustment and move one declaration out
1179
	// Default values for all sorts of config params
641.1.23 by Matthew Fuller
Change InitVariables() so it actually does the allocation of the
1180
	scr->SizeStringOffset = 0;
1181
	scr->ThreeDBorderWidth = 6;
1182
	scr->BorderWidth = BW;
1183
	scr->IconBorderWidth = BW;
1184
	scr->NumAutoRaises = 0;
1185
	scr->NumAutoLowers = 0;
1186
	scr->TransientOnTop = 30;
1187
	scr->NoDefaults = false;
1188
	scr->UsePPosition = PPOS_OFF;
1189
	scr->UseSunkTitlePixmap = false;
1190
	scr->FocusRoot = true;
1191
	scr->WarpCursor = false;
1192
	scr->ForceIcon = false;
1193
	scr->NoGrabServer = true;
1194
	scr->NoRaiseMove = false;
1195
	scr->NoRaiseResize = false;
1196
	scr->NoRaiseDeicon = false;
1197
	scr->RaiseOnWarp = true;
1198
	scr->DontMoveOff = false;
1199
	scr->DoZoom = false;
1200
	scr->TitleFocus = true;
1201
	scr->IconManagerFocus = true;
1202
	scr->StayUpMenus = false;
1203
	scr->WarpToDefaultMenuEntry = false;
1204
	scr->ClickToFocus = false;
1205
	scr->SloppyFocus = false;
1206
	scr->SaveWorkspaceFocus = false;
1207
	scr->NoIconTitlebar = false;
1208
	scr->NoTitlebar = false;
1209
	scr->DecorateTransients = true;
1210
	scr->IconifyByUnmapping = false;
1211
	scr->ShowIconManager = false;
1212
	scr->ShowWorkspaceManager = false;
1213
	scr->WMgrButtonShadowDepth = 2;
1214
	scr->WMgrVertButtonIndent  = 5;
1215
	scr->WMgrHorizButtonIndent = 5;
1216
	scr->BorderShadowDepth = 2;
1217
	scr->TitleShadowDepth = 2;
1218
	scr->TitleButtonShadowDepth = 2;
1219
	scr->MenuShadowDepth = 2;
1220
	scr->IconManagerShadowDepth = 2;
1221
	scr->AutoOccupy = false;
1222
	scr->TransientHasOccupation = false;
1223
	scr->DontPaintRootWindow = false;
1224
	scr->IconManagerDontShow = false;
1225
	scr->BackingStore = false;
1226
	scr->SaveUnder = true;
1227
	scr->RandomPlacement = RP_ALL;
1228
	scr->RandomDisplacementX = 30;
1229
	scr->RandomDisplacementY = 30;
1230
	scr->DoOpaqueMove = true;
1231
	scr->OpaqueMove = false;
1232
	scr->OpaqueMoveThreshold = 200;
1233
	scr->OpaqueResize = false;
1234
	scr->DoOpaqueResize = true;
1235
	scr->OpaqueResizeThreshold = 1000;
1236
	scr->Highlight = true;
1237
	scr->StackMode = true;
1238
	scr->TitleHighlight = true;
641.1.26 by Matthew Fuller
Do a little further commenting/adjustment and move one declaration out
1239
	scr->MoveDelta = 1;
641.1.23 by Matthew Fuller
Change InitVariables() so it actually does the allocation of the
1240
	scr->MoveOffResistance = -1;
1241
	scr->MovePackResistance = 20;
1242
	scr->ZoomCount = 8;
1243
	scr->SortIconMgr = true;
1244
	scr->Shadow = true;
1245
	scr->InterpolateMenuColors = false;
1246
	scr->NoIconManagers = false;
1247
	scr->ClientBorderWidth = false;
1248
	scr->SqueezeTitle = false;
1249
	scr->FirstTime = true;
1250
	scr->CaseSensitive = true;
1251
	scr->WarpUnmapped = false;
1252
	scr->WindowRingAll = false;
1253
	scr->WarpRingAnyWhere = true;
1254
	scr->ShortAllWindowsMenus = false;
1255
	scr->use3Diconmanagers = false;
1256
	scr->use3Dmenus = false;
1257
	scr->use3Dtitles = false;
1258
	scr->use3Dborders = false;
1259
	scr->use3Dwmap = false;
1260
	scr->SunkFocusWindowTitle = false;
1261
	scr->ClearShadowContrast = 50;
1262
	scr->DarkShadowContrast  = 40;
1263
	scr->BeNiceToColormap = false;
1264
	scr->BorderCursors = false;
1265
	scr->IconJustification = TJ_CENTER;
1266
	scr->IconRegionJustification = IRJ_CENTER;
1267
	scr->IconRegionAlignement = IRA_CENTER;
1268
	scr->TitleJustification = TJ_LEFT;
1269
	scr->IconifyStyle = ICONIFY_NORMAL;
1270
	scr->ReallyMoveInWorkspaceManager = false;
1271
	scr->ShowWinWhenMovingInWmgr = false;
1272
	scr->ReverseCurrentWorkspace = false;
1273
	scr->DontWarpCursorInWMap = false;
1274
	scr->XMoveGrid = 1;
1275
	scr->YMoveGrid = 1;
1276
	scr->CenterFeedbackWindow = false;
1277
	scr->ShrinkIconTitles = false;
1278
	scr->AutoRaiseIcons = false;
641.1.26 by Matthew Fuller
Do a little further commenting/adjustment and move one declaration out
1279
	scr->AutoFocusToTransients = false;
641.1.23 by Matthew Fuller
Change InitVariables() so it actually does the allocation of the
1280
	scr->OpenWindowTimeout = 0;
1281
	scr->RaiseWhenAutoUnSqueeze = false;
1282
	scr->RaiseOnClick = false;
1283
	scr->RaiseOnClickButton = 1;
1284
	scr->IgnoreModifier = 0;
1285
	scr->IgnoreCaseInMenuSelection = false;
1286
	scr->PackNewWindows = false;
1287
	scr->AlwaysSqueezeToGravity = false;
1288
	scr->NoWarpToMenuTitle = false;
1289
	scr->DontToggleWorkspaceManagerState = false;
1290
	scr->NameDecorations = true;
1291
	scr->ForceFocus = false;
1292
	scr->BorderTop    = 0;
1293
	scr->BorderBottom = 0;
1294
	scr->BorderLeft   = 0;
1295
	scr->BorderRight  = 0;
641.1.36 by Matthew Fuller
Move a few other simple initializations into the Initialize func,
1296
	scr->PixmapDirectory   = PIXMAP_DIRECTORY;
641.1.26 by Matthew Fuller
Do a little further commenting/adjustment and move one declaration out
1297
#ifdef EWMH
1298
	scr->PreferredIconWidth = 48;
1299
	scr->PreferredIconHeight = 48;
644.2.1 by Matthew Fuller
Move some other ewmh-related ScreenInfo definitions into the
1300
1301
	scr->ewmh_CLIENT_LIST_used = 0;
1302
	scr->ewmh_CLIENT_LIST_size = 16;
1303
	scr->ewmh_CLIENT_LIST = calloc(scr->ewmh_CLIENT_LIST_size,
1304
	                               sizeof(scr->ewmh_CLIENT_LIST[0]));
1305
	if(scr->ewmh_CLIENT_LIST == NULL) {
1306
		free(scr);
1307
		return NULL;
1308
	}
641.1.26 by Matthew Fuller
Do a little further commenting/adjustment and move one declaration out
1309
#endif
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1310
644.2.17 by Matthew Fuller
The OTP init stuff is just memory, so we can move that into the Init
1311
	// OTP structure bits
1312
	OtpScrInitData(scr);
1313
641.1.32 by Matthew Fuller
Macro-ize setting/loading these fonts.
1314
641.1.41 by Matthew Fuller
Extract the constant bits of WSM setup out of the WSM-specific init
1315
	// WorkSpaceManager stuff
1316
	scr->workSpaceMgr.initialstate  = WMS_map;
1317
	scr->workSpaceMgr.buttonStyle   = STYLE_NORMAL;
641.1.43 by Matthew Fuller
Actually, the rest of these are static too. I thought they were here
1318
	scr->workSpaceMgr.vspace        = scr->WMgrVertButtonIndent;
1319
	scr->workSpaceMgr.hspace        = scr->WMgrHorizButtonIndent;
641.1.41 by Matthew Fuller
Extract the constant bits of WSM setup out of the WSM-specific init
1320
1321
	scr->workSpaceMgr.occupyWindow = calloc(1, sizeof(OccupyWindow));
641.1.43 by Matthew Fuller
Actually, the rest of these are static too. I thought they were here
1322
	scr->workSpaceMgr.occupyWindow->vspace    = scr->WMgrVertButtonIndent;
1323
	scr->workSpaceMgr.occupyWindow->hspace    = scr->WMgrHorizButtonIndent;
641.1.41 by Matthew Fuller
Extract the constant bits of WSM setup out of the WSM-specific init
1324
	scr->workSpaceMgr.occupyWindow->name      = "Occupy Window";
1325
	scr->workSpaceMgr.occupyWindow->icon_name = "Occupy Window Icon";
1326
1327
	scr->workSpaceMgr.name      = "WorkSpaceManager";
1328
	scr->workSpaceMgr.icon_name = "WorkSpaceManager Icon";
1329
1330
641.1.32 by Matthew Fuller
Macro-ize setting/loading these fonts.
1331
	// Setup default fonts in case the config file doesn't
1332
#define DEFAULT_NICE_FONT "-*-helvetica-bold-r-normal-*-*-120-*"
1333
#define DEFAULT_FAST_FONT "-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-*"
1334
#define SETFONT(fld, var) (scr->fld##Font.basename = DEFAULT_##var##_FONT)
1335
1336
	SETFONT(TitleBar,    NICE);
1337
	SETFONT(Menu,        NICE);
1338
	SETFONT(Icon,        NICE);
1339
	SETFONT(Size,        FAST);
1340
	SETFONT(IconManager, NICE);
1341
	SETFONT(Default,     FAST);
641.1.41 by Matthew Fuller
Extract the constant bits of WSM setup out of the WSM-specific init
1342
	scr->workSpaceMgr.windowFont.basename =
1343
	        "-adobe-courier-medium-r-normal--10-100-75-75-m-60-iso8859-1";
641.1.32 by Matthew Fuller
Macro-ize setting/loading these fonts.
1344
1345
#undef SETFONT
1346
#undef DEFAULT_FAST_FONT
1347
#undef DEFAULT_NICE_FONT
641.1.23 by Matthew Fuller
Change InitVariables() so it actually does the allocation of the
1348
644.2.24 by Matthew Fuller
Setup "I have no display" defaults for these values too.
1349
1350
	// Set some fallback values that we set from the X server, for
1351
	// special cases where we may not actually be talking to one.
1352
	scr->d_depth = 24;
1353
	scr->RealRoot = croot;
1354
	scr->mm_w = 406; // 16 in
1355
	scr->mm_h = 229; // 9 in
644.2.25 by Matthew Fuller
Add another default, and conditionalize a few more things on dpy.
1356
	scr->Monochrome = COLOR;
644.2.24 by Matthew Fuller
Setup "I have no display" defaults for these values too.
1357
641.1.42 by Matthew Fuller
Add a guardrail in here to more quickly catch when I accidentally let
1358
	// Cleanup poisoning
1359
#undef Scr
641.1.23 by Matthew Fuller
Change InitVariables() so it actually does the allocation of the
1360
	return scr;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1361
}
1362
1363
644.2.39 by Matthew Fuller
Do a little mostly cosmetic whitespace/comment/etc through the
1364
1365
692.1.5 by Matthew Fuller
Add ifdef's around references to Screen and CLargs members that are
1366
#ifdef CAPTIVE
644.2.39 by Matthew Fuller
Do a little mostly cosmetic whitespace/comment/etc through the
1367
/**
1368
 * Create a new window to use for a captive ctwm.
1369
 */
641.1.1 by Matthew Fuller
Rename func to better match what it does.
1370
static Window
1371
CreateCaptiveRootWindow(int x, int y,
1372
                        unsigned int width, unsigned int height)
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1373
{
1374
	int         scrnum;
1375
	Window      ret;
1376
	XWMHints    wmhints;
1377
1378
	scrnum = DefaultScreen(dpy);
1379
	ret = XCreateSimpleWindow(dpy, RootWindow(dpy, scrnum),
1380
	                          x, y, width, height, 2, WhitePixel(dpy, scrnum),
1381
	                          BlackPixel(dpy, scrnum));
1382
	wmhints.initial_state = NormalState;
1383
	wmhints.input         = True;
1384
	wmhints.flags         = InputHint | StateHint;
1385
505.1.5 by Matthew Fuller
Convert other XSetStandardProperties()/XSetWM*() sequences into
1386
	XmbSetWMProperties(dpy, ret, "Captive ctwm", NULL, NULL, 0, NULL,
505.1.6 by Matthew Fuller
make indent
1387
	                   &wmhints, NULL);
335.1.11 by Olaf 'Rhialto' Seibert
Missed another XInternAtom(). Also, set 1 XA_WINDOW, not 4.
1388
	XChangeProperty(dpy, ret, XA_WM_CTWM_ROOT, XA_WINDOW, 32,
1389
	                PropModeReplace, (unsigned char *) &ret, 1);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1390
	XSelectInput(dpy, ret, StructureNotifyMask);
1391
	XMapWindow(dpy, ret);
1392
	return (ret);
1393
}
692.1.5 by Matthew Fuller
Add ifdef's around references to Screen and CLargs members that are
1394
#endif
518.1.1 by Matthew Fuller
This func is only used during startup in ctwm.c, so move it there and
1395
1396
644.2.39 by Matthew Fuller
Do a little mostly cosmetic whitespace/comment/etc through the
1397
1398
/**
518.1.1 by Matthew Fuller
This func is only used during startup in ctwm.c, so move it there and
1399
 * Return true if a window is not set to override_redirect ("Hey!  WM!
1400
 * Leave those wins alone!"), and isn't unmapped.  Used during startup to
1401
 * fake mapping for wins that should be up.
1402
 */
1403
static bool
1404
MappedNotOverride(Window w)
1405
{
1406
	XWindowAttributes wa;
1407
1408
	XGetWindowAttributes(dpy, w, &wa);
1409
	return ((wa.map_state != IsUnmapped) && (wa.override_redirect != True));
1410
}