~ctwm/ctwm/trunk

304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1
/*
554.1.10 by Matthew Fuller
Pull out the simple cases of long-form twm+Claude copyright/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
6
 *
7
 * Copyright 1992 Claude Lecommandeur.
11 by Claude Lecommandeur
CTWM version 3.2p1
8
 */
1 by Claude Lecommandeur
CTWM version 1.1
9
10
/***********************************************************************
11
 *
12
 * $XConsortium: util.c,v 1.47 91/07/14 13:40:37 rws Exp $
13
 *
14
 * utility routines for twm
15
 *
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
16
 * 28-Oct-87 Thomas E. LaStrange        File created
1 by Claude Lecommandeur
CTWM version 1.1
17
 *
18
 * Do the necessary modification to be integrated in ctwm.
19
 * Can no longer be used for the standard twm.
20
 *
21
 * 22-April-92 Claude Lecommandeur.
22
 *
55 by Richard Levitte
Include Björns DontMoveOff change.
23
 * Changed behavior of DontMoveOff/MoveOffResistance to allow
24
 * moving a window off screen less than #MoveOffResistance pixels.
25
 * New code will no longer "snap" windows to #MoveOffResistance
26
 * pixels off screen and instead movements will just be stopped and
27
 * then resume once movement of #MoveOffResistance have been attempted.
28
 *
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
29
 * 15-December-02 Bjorn Knutsson
1 by Claude Lecommandeur
CTWM version 1.1
30
 *
31
 ***********************************************************************/
32
395.1.1 by Matthew Fuller
Move ctwm.h to always be included first.
33
#include "ctwm.h"
34
11 by Claude Lecommandeur
CTWM version 3.2p1
35
#include <stdio.h>
491.1.14 by Matthew Fuller
Remove incorrect pre-ANSI potential override prototypes for malloc()
36
#include <stdlib.h>
324.1.9 by Matthew Fuller
Kill off the list of the XmuCompare's.
37
#include <string.h>
38
#include <strings.h>
282 by Matthew Fuller
Go ahead and pull in inttypes.h for these uint's, with a comment about
39
9 by Claude Lecommandeur
CTWM version 3.1
40
#include <signal.h>
41
#include <sys/time.h>
42
481.1.5 by Matthew Fuller
Pull the animation funcs/vars out into their own file.
43
#include "animate.h"
340.1.1 by Matthew Fuller
Rearrange includes to be in what we'll call the Proper Order.
44
#include "add_window.h"
539.1.8 by Matthew Fuller
Sort includes.
45
#include "cursor.h"
46
#include "drawing.h"
340.1.1 by Matthew Fuller
Rearrange includes to be in what we'll call the Proper Order.
47
#include "gram.tab.h"
518.1.24 by Matthew Fuller
iconmgr.h isn't needed for add_window.h. Pull it out and add it to
48
#include "iconmgr.h"
340.1.1 by Matthew Fuller
Rearrange includes to be in what we'll call the Proper Order.
49
#include "icons.h"
479.1.2 by Matthew Fuller
Break out XPM functions into image_xpm. Start laying a little
50
#include "image.h"
539.1.8 by Matthew Fuller
Sort includes.
51
#include "screen.h"
52
#include "util.h"
53
#include "vscreen.h"
538.1.3 by Matthew Fuller
Rename the decorations*.h to win_decorations*.h.
54
#include "win_decorations.h"
538.1.5 by Matthew Fuller
And rename over resize.h.
55
#include "win_resize.h"
21 by Richard Levitte
This constitutes all the changes Claude had done since version 3.6.
56
6 by Claude Lecommandeur
CTWM version 2.2
57
521.1.54 by Matthew Fuller
tracefile is used broadly across the code for debug output. Move it
58
/* Handle for debug tracing */
59
FILE *tracefile = NULL;
60
61
480.1.7 by Matthew Fuller
Drop a comment for a function that needs some reworking, or perhaps it
62
/*
63
 * Rewrite this, possibly in terms of replace_substr().  Alternately, the
497.1.3 by Matthew Fuller
Tpyo in comment.
64
 * places it's being used might be better served by being preprocessed
480.1.7 by Matthew Fuller
Drop a comment for a function that needs some reworking, or perhaps it
65
 * into arrays anyway.
66
 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
67
char *ExpandFilePath(char *path)
14 by Claude Lecommandeur
CTWM version 3.4
68
{
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
69
	char *ret, *colon, *p;
70
	int  len;
71
72
	len = 0;
73
	p   = path;
74
	while((colon = strchr(p, ':'))) {
75
		len += colon - p + 1;
76
		if(*p == '~') {
77
			len += HomeLen - 1;
78
		}
79
		p = colon + 1;
80
	}
81
	if(*p == '~') {
82
		len += HomeLen - 1;
83
	}
84
	len += strlen(p);
491.1.8 by Matthew Fuller
Stop casting return values of [mc]alloc(). void * has existed for 27
85
	ret = malloc(len + 1);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
86
	*ret = 0;
87
88
	p   = path;
89
	while((colon = strchr(p, ':'))) {
90
		*colon = '\0';
91
		if(*p == '~') {
92
			strcat(ret, Home);
93
			strcat(ret, p + 1);
94
		}
95
		else {
96
			strcat(ret, p);
97
		}
98
		*colon = ':';
99
		strcat(ret, ":");
100
		p = colon + 1;
101
	}
102
	if(*p == '~') {
103
		strcat(ret, Home);
104
		strcat(ret, p + 1);
105
	}
106
	else {
107
		strcat(ret, p);
108
	}
109
	return ret;
14 by Claude Lecommandeur
CTWM version 3.4
110
}
111
1 by Claude Lecommandeur
CTWM version 1.1
112
/***********************************************************************
113
 *
114
 *  Procedure:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
115
 *      ExpandFilename - expand the tilde character to HOME
116
 *              if it is the first character of the filename
1 by Claude Lecommandeur
CTWM version 1.1
117
 *
118
 *  Returned Value:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
119
 *      a pointer to the new name
1 by Claude Lecommandeur
CTWM version 1.1
120
 *
121
 *  Inputs:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
122
 *      name    - the filename to expand
1 by Claude Lecommandeur
CTWM version 1.1
123
 *
124
 ***********************************************************************
480.1.8 by Matthew Fuller
Adjust ExpandFilename so that it _always_ returns a newly allocated
125
 *
126
 * Currently only used in one place in image_bitmap.c.  I've left this
127
 * here instead of moving it into images at the moment on the assumption
128
 * that there might be other places in the codebase where it's useful.
1 by Claude Lecommandeur
CTWM version 1.1
129
 */
480.1.8 by Matthew Fuller
Adjust ExpandFilename so that it _always_ returns a newly allocated
130
char *
131
ExpandFilename(const char *name)
1 by Claude Lecommandeur
CTWM version 1.1
132
{
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
133
	char *newname;
1 by Claude Lecommandeur
CTWM version 1.1
134
480.1.8 by Matthew Fuller
Adjust ExpandFilename so that it _always_ returns a newly allocated
135
	/* If it doesn't start with ~/ then it's not our concern */
136
	if(name[0] != '~' || name[1] != '/') {
137
		return strdup(name);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
138
	}
1 by Claude Lecommandeur
CTWM version 1.1
139
480.1.8 by Matthew Fuller
Adjust ExpandFilename so that it _always_ returns a newly allocated
140
	asprintf(&newname, "%s/%s", Home, &name[1]);
1 by Claude Lecommandeur
CTWM version 1.1
141
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
142
	return newname;
1 by Claude Lecommandeur
CTWM version 1.1
143
}
144
9 by Claude Lecommandeur
CTWM version 3.1
145
648.1.8 by Matthew Fuller
Some whitespace/commenting of util.c funcs.
146
147
/*
148
 * Some color utils
149
 */
150
/**
151
 * Get info from the server about a given color.
152
 */
508 by Matthew Fuller
const-ify GetColor().
153
void
154
GetColor(int kind, Pixel *what, const char *name)
1 by Claude Lecommandeur
CTWM version 1.1
155
{
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
156
	XColor color;
157
	Colormap cmap = Scr->RootColormaps.cwins[0]->colormap->c;
1 by Claude Lecommandeur
CTWM version 1.1
158
644.2.19 by Matthew Fuller
Add conditions in a few places that get called a lot during config
159
	// If we have no valid X connection (generally means a --cfgchk or
160
	// similar run; wont' happen in normal operations), just stub out.
161
	if(dpy == NULL) {
162
		*what = 0;
163
		return;
164
	}
165
1 by Claude Lecommandeur
CTWM version 1.1
166
#ifndef TOM
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
167
	if(!Scr->FirstTime) {
168
		return;
169
	}
1 by Claude Lecommandeur
CTWM version 1.1
170
#endif
171
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
172
	if(Scr->Monochrome != kind) {
173
		return;
174
	}
175
176
	if(! XParseColor(dpy, cmap, name, &color)) {
177
		fprintf(stderr, "%s:  invalid color name \"%s\"\n", ProgramName, name);
178
		return;
179
	}
180
	if(! XAllocColor(dpy, cmap, &color)) {
181
		/* if we could not allocate the color, let's see if this is a
182
		 * standard colormap
183
		 */
184
		XStandardColormap *stdcmap = NULL;
185
186
		if(! XParseColor(dpy, cmap, name, &color)) {
187
			fprintf(stderr, "%s:  invalid color name \"%s\"\n", ProgramName, name);
188
			return;
189
		}
190
191
		/*
192
		 * look through the list of standard colormaps (check cache first)
193
		 */
194
		if(Scr->StdCmapInfo.mru && Scr->StdCmapInfo.mru->maps &&
195
		                (Scr->StdCmapInfo.mru->maps[Scr->StdCmapInfo.mruindex].colormap ==
196
		                 cmap)) {
197
			stdcmap = &(Scr->StdCmapInfo.mru->maps[Scr->StdCmapInfo.mruindex]);
198
		}
199
		else {
200
			StdCmap *sc;
201
202
			for(sc = Scr->StdCmapInfo.head; sc; sc = sc->next) {
203
				int i;
204
205
				for(i = 0; i < sc->nmaps; i++) {
206
					if(sc->maps[i].colormap == cmap) {
207
						Scr->StdCmapInfo.mru = sc;
208
						Scr->StdCmapInfo.mruindex = i;
209
						stdcmap = &(sc->maps[i]);
210
						goto gotit;
211
					}
212
				}
213
			}
214
		}
215
216
gotit:
217
		if(stdcmap) {
218
			color.pixel = (stdcmap->base_pixel +
219
			               ((Pixel)(((float)color.red / 65535.0) *
220
			                        stdcmap->red_max + 0.5) *
221
			                stdcmap->red_mult) +
222
			               ((Pixel)(((float)color.green / 65535.0) *
223
			                        stdcmap->green_max + 0.5) *
224
			                stdcmap->green_mult) +
225
			               ((Pixel)(((float)color.blue  / 65535.0) *
226
			                        stdcmap->blue_max + 0.5) *
227
			                stdcmap->blue_mult));
228
		}
229
		else {
230
			fprintf(stderr, "%s:  unable to allocate color \"%s\"\n",
231
			        ProgramName, name);
232
			return;
233
		}
234
	}
235
236
	*what = color.pixel;
237
	return;
238
}
239
648.1.8 by Matthew Fuller
Some whitespace/commenting of util.c funcs.
240
241
/**
242
 * Try and create a 'shaded' version of a color for prettier UI.
243
 */
644.2.19 by Matthew Fuller
Add conditions in a few places that get called a lot during config
244
void
245
GetShadeColors(ColorPair *cp)
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
246
{
247
	XColor      xcol;
248
	Colormap    cmap = Scr->RootColormaps.cwins[0]->colormap->c;
492.2.105 by Matthew Fuller
Switch some temp vars holding Scr->FirstTime over to bool.
249
	bool        save;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
250
	float       clearfactor;
251
	float       darkfactor;
252
	char        clearcol [32], darkcol [32];
253
644.2.19 by Matthew Fuller
Add conditions in a few places that get called a lot during config
254
	// If we have no valid X connection (generally means a --cfgchk or
255
	// similar run; wont' happen in normal operations), just stub out.
256
	if(dpy == NULL) {
257
		cp->shadc = 0;
258
		cp->shadd = 0;
259
		return;
260
	}
261
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
262
	clearfactor = (float) Scr->ClearShadowContrast / 100.0;
263
	darkfactor  = (100.0 - (float) Scr->DarkShadowContrast)  / 100.0;
264
	xcol.pixel = cp->back;
265
	XQueryColor(dpy, cmap, &xcol);
266
267
	sprintf(clearcol, "#%04x%04x%04x",
268
	        xcol.red   + (unsigned short)((65535 -   xcol.red) * clearfactor),
269
	        xcol.green + (unsigned short)((65535 - xcol.green) * clearfactor),
270
	        xcol.blue  + (unsigned short)((65535 -  xcol.blue) * clearfactor));
271
	sprintf(darkcol,  "#%04x%04x%04x",
272
	        (unsigned short)(xcol.red   * darkfactor),
273
	        (unsigned short)(xcol.green * darkfactor),
274
	        (unsigned short)(xcol.blue  * darkfactor));
275
276
	save = Scr->FirstTime;
492.2.104 by Matthew Fuller
Massive rewrite of various struct Screen config params that are
277
	Scr->FirstTime = true;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
278
	GetColor(Scr->Monochrome, &cp->shadc, clearcol);
279
	GetColor(Scr->Monochrome, &cp->shadd,  darkcol);
280
	Scr->FirstTime = save;
281
}
282
648.1.8 by Matthew Fuller
Some whitespace/commenting of util.c funcs.
283
284
285
/*
286
 * Various font utils
287
 */
288
/**
289
 * Try adjusting a font's height.  Used in drawing the icon manager.
290
 */
492.2.2 by Matthew Fuller
Convert various exported util.c funcs to C99 bool from X Bool. This
291
bool
292
UpdateFont(MyFont *font, int height)
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
293
{
294
	int prev = font->avg_height;
295
	font->avg_fheight = (font->avg_fheight * font->avg_count + height)
296
	                    / (font->avg_count + 1);
297
	font->avg_count++;
298
	/* Arbitrary limit.  */
299
	if(font->avg_count >= 256) {
300
		font->avg_count = 256;
301
	}
302
	font->avg_height = (int)(font->avg_fheight + 0.5);
303
	/* fprintf (stderr, "Updating avg with %d(%d) + %d -> %d(%f)\n",
304
	 *       prev, font->avg_count, height,
305
	 *       font->avg_height, font->avg_fheight); */
306
	return (prev != font->avg_height);
240.1.2 by Rhialto
3 - Selected a number of cleanups from Stefan Monnier
307
}
308
648.1.8 by Matthew Fuller
Some whitespace/commenting of util.c funcs.
309
310
/**
648.1.10 by Matthew Fuller
GetFont() is only used by CreateFonts(), so we can static-ize it now.
311
 * Load up fontsets from the X server.  Only used by CreateFonts() below.
648.1.8 by Matthew Fuller
Some whitespace/commenting of util.c funcs.
312
 */
648.1.10 by Matthew Fuller
GetFont() is only used by CreateFonts(), so we can static-ize it now.
313
static void
648.1.8 by Matthew Fuller
Some whitespace/commenting of util.c funcs.
314
GetFont(MyFont *font)
1 by Claude Lecommandeur
CTWM version 1.1
315
{
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
316
	char *deffontname = "fixed,*";
317
	char **missing_charset_list_return;
318
	int missing_charset_count_return;
319
	char *def_string_return;
320
	XFontSetExtents *font_extents;
321
	XFontStruct **xfonts;
322
	char **font_names;
434 by Matthew Fuller
Eliminate register qualifiers. The judgements of even very smart
323
	int i;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
324
	int ascent;
325
	int descent;
326
	int fnum;
327
	char *basename2;
328
644.2.22 by Matthew Fuller
Add escape hatch in GetFont() to squeak out early if we lack a display
329
	// In special cases where we have no dpy, I don't think we're going
330
	// to need details here, so just leave things untouched.  We may need
331
	// to stub in some magic values; deal with that when we run into the
332
	// case.
333
	if(dpy == NULL) {
334
		return;
335
	}
336
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
337
	if(font->font_set != NULL) {
338
		XFreeFontSet(dpy, font->font_set);
339
	}
340
491.1.1 by Matthew Fuller
Replace some malloc(strlen()+x);sprintf() constructs with asprintf().
341
	asprintf(&basename2, "%s,*", font->basename);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
342
	if((font->font_set = XCreateFontSet(dpy, basename2,
343
	                                    &missing_charset_list_return,
344
	                                    &missing_charset_count_return,
345
	                                    &def_string_return)) == NULL) {
346
		fprintf(stderr, "Failed to get fontset %s\n", basename2);
347
		if(Scr->DefaultFont.basename) {
348
			deffontname = Scr->DefaultFont.basename;
349
		}
350
		if((font->font_set = XCreateFontSet(dpy, deffontname,
351
		                                    &missing_charset_list_return,
352
		                                    &missing_charset_count_return,
353
		                                    &def_string_return)) == NULL) {
354
			fprintf(stderr, "%s:  unable to open fonts \"%s\" or \"%s\"\n",
355
			        ProgramName, font->basename, deffontname);
356
			exit(1);
357
		}
358
	}
491.1.1 by Matthew Fuller
Replace some malloc(strlen()+x);sprintf() constructs with asprintf().
359
	free(basename2);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
360
	font_extents = XExtentsOfFontSet(font->font_set);
361
362
	fnum = XFontsOfFontSet(font->font_set, &xfonts, &font_names);
363
	for(i = 0, ascent = 0, descent = 0; i < fnum; i++) {
364
		ascent = MaxSize(ascent, (*xfonts)->ascent);
365
		descent = MaxSize(descent, (*xfonts)->descent);
366
		xfonts++;
367
	}
368
369
	font->height = font_extents->max_logical_extent.height;
370
	font->y = ascent;
371
	font->ascent = ascent;
372
	font->descent = descent;
373
	font->avg_height = 0;
374
	font->avg_fheight = 0.0;
375
	font->avg_count = 0;
376
}
377
378
648.1.9 by Matthew Fuller
Move CreateFonts() over to util.c alongside the other related font
379
/**
380
 * Load up our various defined fonts
381
 */
382
void
383
CreateFonts(ScreenInfo *scr)
384
{
385
#define LOADFONT(fld) (GetFont(&scr->fld##Font))
386
	LOADFONT(TitleBar);
387
	LOADFONT(Menu);
388
	LOADFONT(Icon);
389
	LOADFONT(Size);
390
	LOADFONT(IconManager);
391
	LOADFONT(Default);
392
	LOADFONT(workSpaceMgr.window);
393
#undef LOADFONT
394
395
	scr->HaveFonts = true;
396
}
397
398
648.1.8 by Matthew Fuller
Some whitespace/commenting of util.c funcs.
399
520.1.1 by Matthew Fuller
These functions appear to have been unused for several years at least,
400
#if 0
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
401
static void move_to_head(TwmWindow *t)
402
{
403
	if(t == NULL) {
404
		return;
405
	}
406
	if(Scr->FirstWindow == t) {
407
		return;
408
	}
409
410
	/* Unlink t from current position */
411
	if(t->prev) {
412
		t->prev->next = t->next;
413
	}
414
	if(t->next) {
415
		t->next->prev = t->prev;
416
	}
417
418
	/* Re-link t at head */
419
	t->next = Scr->FirstWindow;
420
	if(Scr->FirstWindow != NULL) {
421
		Scr->FirstWindow->prev = t;
422
	}
423
	t->prev = NULL;
424
	Scr->FirstWindow = t;
20 by Claude Lecommandeur
CTWM version 3.6
425
}
240.1.1 by Rhialto
Add an option (default off) to map and unmap workspaces in the "best"
426
427
/*
428
 * Moves window 't' after window 'after'.
429
 *
430
 * If 'after' == NULL, puts it at the head.
431
 * If 't' == NULL, does nothing.
432
 * If the 't' is already after 'after', does nothing.
433
 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
434
435
void move_to_after(TwmWindow *t, TwmWindow *after)
240.1.1 by Rhialto
Add an option (default off) to map and unmap workspaces in the "best"
436
{
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
437
	if(after == NULL) {
438
		move_to_head(t);
439
		return;
440
	}
441
	if(t == NULL) {
442
		return;
443
	}
444
	if(after->next == t) {
445
		return;
446
	}
447
448
	/* Unlink t from current position */
449
	if(t->prev) {
450
		t->prev->next = t->next;
451
	}
452
	if(t->next) {
453
		t->next->prev = t->prev;
454
	}
455
456
	/* Re-link t after 'after' */
457
	t->next = after->next;
458
	if(after->next) {
459
		after->next->prev = t;
460
	}
461
	t->prev = after;
462
	after->next = t;
240.1.1 by Rhialto
Add an option (default off) to map and unmap workspaces in the "best"
463
}
520.1.1 by Matthew Fuller
These functions appear to have been unused for several years at least,
464
#endif
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
465
240.1.1 by Rhialto
Add an option (default off) to map and unmap workspaces in the "best"
466
648.1.8 by Matthew Fuller
Some whitespace/commenting of util.c funcs.
467
468
/**
469
 * Backend for f.rescuewindows
470
 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
471
void RescueWindows(void)
472
{
473
	TwmWindow *twm_win = Scr->FirstWindow;
474
475
	while(twm_win) {
476
		VirtualScreen *vs = twm_win->vs;
477
		if(vs) {
478
			/*
479
			 * Check if this window seems completely out of sight.
480
			 */
481
			int x = twm_win->frame_x;
482
			int y = twm_win->frame_y;
483
			int w = twm_win->frame_width;
484
			int h = twm_win->frame_height;
485
			int bw = twm_win->frame_bw;
486
			int fullw = w + 2 * bw;
487
			int fullh = h + 2 * bw;
488
			int old_x = x, old_y = y;
489
			struct Icon *i;
490
491
#define MARGIN  20
492
493
			if(x >= vs->w - MARGIN) {
494
				x = vs->w - fullw;
495
			}
496
			if(y >= vs->h - MARGIN) {
497
				y = vs->h - fullh;
498
			}
499
			if((x + fullw <= MARGIN)) {
500
				x = 0;
501
			}
502
			if((y + fullh <= MARGIN)) {
503
				y = 0;
504
			}
505
506
			if(x != old_x || y != old_y) {
507
				SetupWindow(twm_win, x, y, w, h, -1);
508
			}
509
510
			/*
511
			 * If there is an icon, check it too.
512
			 */
513
			i = twm_win->icon;
514
			if(i != NULL) {
515
				x = i->w_x;
516
				y = i->w_y;
517
				w = i->w_width;
518
				h = i->w_height;
519
				old_x = x;
520
				old_y = y;
521
522
				if(x >= vs->w - MARGIN) {
523
					x = vs->w - w;
524
				}
525
				if(y >= vs->h - MARGIN) {
526
					y = vs->h - h;
527
				}
528
				if((x + w <= MARGIN)) {
529
					x = 0;
530
				}
531
				if((y + h <= MARGIN)) {
532
					y = 0;
533
				}
534
535
				if(x != old_x || y != old_y) {
536
					XMoveWindow(dpy, i->w, x, y);
537
					i->w_x = x;
538
					i->w_y = y;
539
				}
540
			}
240.1.2 by Rhialto
3 - Selected a number of cleanups from Stefan Monnier
541
#undef MARGIN
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
542
		}
543
		twm_win = twm_win->next;
544
	}
545
}
546
648.1.8 by Matthew Fuller
Some whitespace/commenting of util.c funcs.
547
548
549
/**
550
 * Backend for f.trace
551
 */
552
void
553
DebugTrace(char *file)
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
554
{
555
	if(!file) {
556
		return;
557
	}
558
	if(tracefile) {
559
		fprintf(stderr, "stop logging events\n");
560
		if(tracefile != stderr) {
561
			fclose(tracefile);
562
		}
563
		tracefile = NULL;
564
	}
565
	else {
566
		if(strcmp(file, "stderr")) {
567
			tracefile = fopen(file, "w");
568
		}
569
		else {
570
			tracefile = stderr;
571
		}
572
		fprintf(stderr, "logging events to : %s\n", file);
573
	}
574
}
575
576
648.1.8 by Matthew Fuller
Some whitespace/commenting of util.c funcs.
577
503.1.43 by Matthew Fuller
Rename safecopy() to safe_strncpy(), move it to util.c where it better
578
/*
579
 * A safe strncpy(), which always ensures NUL-termination.
580
 *
581
 * XXX This is really just a slightly pessimized implementation of
582
 * strlcpy().  Maybe we should use that instead, with a local
583
 * implementation for systems like glibc-users that lack it?
584
 */
585
void
586
safe_strncpy(char *dest, const char *src, size_t size)
587
{
588
	strncpy(dest, src, size - 1);
589
	dest[size - 1] = '\0';
590
}