~ctwm/ctwm/trunk

1 by Claude Lecommandeur
CTWM version 1.1
1
/*
2
 * Copyright 1989 Massachusetts Institute of Technology
554.1.12 by Matthew Fuller
Collapse these MIT/Claude licenses down to the copyright statements,
3
 * Copyright 1992 Claude Lecommandeur.
11 by Claude Lecommandeur
CTWM version 3.2p1
4
 */
1 by Claude Lecommandeur
CTWM version 1.1
5
6
/**********************************************************************
7
 *
8
 * $XConsortium: icons.c,v 1.22 91/07/12 09:58:38 dave Exp $
9
 *
10
 * Icon releated routines
11
 *
12
 * 10-Apr-89 Tom LaStrange        Initial Version.
13
 *
14
 * Do the necessary modification to be integrated in ctwm.
15
 * Can no longer be used for the standard twm.
16
 *
17
 * 22-April-92 Claude Lecommandeur.
18
 *
19
 *
20
 **********************************************************************/
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>
340.1.1 by Matthew Fuller
Rearrange includes to be in what we'll call the Proper Order.
26
492.2.15 by Matthew Fuller
Extract the shape.h include into just the .c files that need it.
27
#include <X11/extensions/shape.h>
28
518.1.3 by Matthew Fuller
Move PaintIcon() into icons.c.
29
#include "drawing.h"
1 by Claude Lecommandeur
CTWM version 1.1
30
#include "screen.h"
518.1.10 by Matthew Fuller
Move RedoIcon*() into icons.c.
31
#include "iconmgr.h"
1 by Claude Lecommandeur
CTWM version 1.1
32
#include "icons.h"
240.1.3 by Rhialto
4 - Added the remaining OnTopPriority changes from Stefan Monnier
33
#include "otp.h"
9 by Claude Lecommandeur
CTWM version 3.1
34
#include "list.h"
1 by Claude Lecommandeur
CTWM version 1.1
35
#include "parse.h"
36
#include "util.h"
481.1.5 by Matthew Fuller
Pull the animation funcs/vars out into their own file.
37
#include "animate.h"
479.1.27 by Matthew Fuller
Move the remaining image bits out of util.h and into image.h, and add
38
#include "image.h"
523.1.16 by Matthew Fuller
Move visible() into win_utils.
39
#include "win_utils.h"
518.1.10 by Matthew Fuller
Move RedoIcon*() into icons.c.
40
#include "workspace_manager.h"
614.1.24 by Maxime Soulé
Icon{Region,Manager{s,Geometry} accept monitor relative geometries
41
#include "xparsegeometry.h"
42
1 by Claude Lecommandeur
CTWM version 1.1
43
518.1.17 by Matthew Fuller
Stick prototypes for the static functions up top. Most of them are
44
static void splitIconRegionEntry(IconEntry *ie, RegGravity grav1,
45
                                 RegGravity grav2, int w, int h);
46
static void PlaceIcon(TwmWindow *tmp_win, int def_x, int def_y,
47
                      int *final_x, int *final_y);
48
static IconEntry *FindIconEntry(TwmWindow *tmp_win, IconRegion **irp);
49
static IconEntry *prevIconEntry(IconEntry *ie, IconRegion *ir);
50
static void mergeEntries(IconEntry *old, IconEntry *ie);
518.1.20 by Matthew Fuller
Reorder and sectionalize icons.s to related functions are grouped
51
static void ReshapeIcon(Icon *icon);
52
static int roundUp(int v, int multiple);
518.1.17 by Matthew Fuller
Stick prototypes for the static functions up top. Most of them are
53
static Image *LookupIconNameOrClass(TwmWindow *tmp_win, Icon *icon,
54
                                    char **pattern);
518.1.20 by Matthew Fuller
Reorder and sectionalize icons.s to related functions are grouped
55
56
57
58
/*
59
 ****************************************************************
60
 *
61
 * First some bits related to figuring out where icons go.  Lots of
62
 * IconRegion handling stuff, handling of IconEntry tracking, etc.
63
 *
64
 ****************************************************************
65
 */
498.1.10 by Matthew Fuller
staticize ReshapeIcon, it's only called from one place.
66
1 by Claude Lecommandeur
CTWM version 1.1
67
513.1.15 by Matthew Fuller
Add comments about nuttiness of these funcs and why I'm not resolving
68
/*
69
 * This function operates in very weird and obtuse ways, especially in
70
 * how it handles vertical vs. horizontal in weird recursive calls.  Part
71
 * of this is what previously allowed specs with "hgrav vgrav" instead of
72
 * the proper "vgrav hgrav" to sorta-work.  This should be broken up at
73
 * some point into clean h/v functions, but because of the recursion it's
74
 * not exactly trivial.  The parsing code now enforces v/h, so at least
75
 * things can be known to come in in the right order initially.  Revisit
76
 * someday.
77
 */
498.1.2 by Matthew Fuller
Rename splitEntry to splitIconRegionEntry. THis makes it more
78
static void
513.1.10 by Matthew Fuller
Switch split functions over to using enum too.
79
splitIconRegionEntry(IconEntry *ie, RegGravity grav1, RegGravity grav2,
513.1.11 by Matthew Fuller
Split def and make indent
80
                     int w, int h)
1 by Claude Lecommandeur
CTWM version 1.1
81
{
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
82
	switch(grav1) {
513.1.8 by Matthew Fuller
Swap to the new enum for these gravity values, and retire the old
83
		case GRAV_NORTH:
84
		case GRAV_SOUTH:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
85
			if(w != ie->w) {
498.1.2 by Matthew Fuller
Rename splitEntry to splitIconRegionEntry. THis makes it more
86
				splitIconRegionEntry(ie, grav2, grav1, w, ie->h);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
87
			}
88
			if(h != ie->h) {
498.1.14 by Matthew Fuller
Go ahead and localize these vars in the split functions for
89
				IconEntry *new = calloc(1, sizeof(IconEntry));
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
90
				new->next = ie->next;
91
				ie->next = new;
92
				new->x = ie->x;
93
				new->h = (ie->h - h);
94
				new->w = ie->w;
95
				ie->h = h;
513.1.8 by Matthew Fuller
Swap to the new enum for these gravity values, and retire the old
96
				if(grav1 == GRAV_SOUTH) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
97
					new->y = ie->y;
98
					ie->y = new->y + new->h;
99
				}
100
				else {
101
					new->y = ie->y + ie->h;
102
				}
103
			}
104
			break;
513.1.8 by Matthew Fuller
Swap to the new enum for these gravity values, and retire the old
105
		case GRAV_EAST:
106
		case GRAV_WEST:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
107
			if(h != ie->h) {
498.1.2 by Matthew Fuller
Rename splitEntry to splitIconRegionEntry. THis makes it more
108
				splitIconRegionEntry(ie, grav2, grav1, ie->w, h);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
109
			}
110
			if(w != ie->w) {
498.1.14 by Matthew Fuller
Go ahead and localize these vars in the split functions for
111
				IconEntry *new = calloc(1, sizeof(IconEntry));
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
112
				new->next = ie->next;
113
				ie->next = new;
114
				new->y = ie->y;
115
				new->w = (ie->w - w);
116
				new->h = ie->h;
117
				ie->w = w;
513.1.8 by Matthew Fuller
Swap to the new enum for these gravity values, and retire the old
118
				if(grav1 == GRAV_EAST) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
119
					new->x = ie->x;
120
					ie->x = new->x + new->w;
121
				}
122
				else {
123
					new->x = ie->x + ie->w;
124
				}
125
			}
126
			break;
127
	}
1 by Claude Lecommandeur
CTWM version 1.1
128
}
129
518.1.20 by Matthew Fuller
Reorder and sectionalize icons.s to related functions are grouped
130
131
/*
132
 * Backend for parsing IconRegion config
133
 */
134
name_list **
135
AddIconRegion(const char *geom, RegGravity grav1, RegGravity grav2,
136
              int stepx, int stepy,
137
              const char *ijust, const char *just, const char *align)
1 by Claude Lecommandeur
CTWM version 1.1
138
{
518.1.20 by Matthew Fuller
Reorder and sectionalize icons.s to related functions are grouped
139
	IconRegion *ir;
140
	int mask, tmp;
141
142
	ir = malloc(sizeof(IconRegion));
143
	ir->next = NULL;
144
145
	if(Scr->LastRegion) {
146
		Scr->LastRegion->next = ir;
147
	}
148
	Scr->LastRegion = ir;
149
	if(!Scr->FirstRegion) {
150
		Scr->FirstRegion = ir;
151
	}
152
153
	ir->entries = NULL;
154
	ir->clientlist = NULL;
155
	ir->grav1 = grav1;
156
	ir->grav2 = grav2;
157
	if(stepx <= 0) {
158
		stepx = 1;
159
	}
160
	if(stepy <= 0) {
161
		stepy = 1;
162
	}
163
	ir->stepx = stepx;
164
	ir->stepy = stepy;
165
	ir->x = ir->y = ir->w = ir->h = 0;
166
614.1.24 by Maxime Soulé
Icon{Region,Manager{s,Geometry} accept monitor relative geometries
167
	mask = RLayoutXParseGeometry(Scr->Layout, geom, &ir->x, &ir->y,
168
	                             (unsigned int *)&ir->w, (unsigned int *)&ir->h);
518.1.20 by Matthew Fuller
Reorder and sectionalize icons.s to related functions are grouped
169
170
	if(mask & XNegative) {
171
		ir->x += Scr->rootw - ir->w;
172
	}
173
	if(mask & YNegative) {
174
		ir->y += Scr->rooth - ir->h;
175
	}
176
177
	ir->entries = calloc(1, sizeof(IconEntry));
178
	ir->entries->x = ir->x;
179
	ir->entries->y = ir->y;
180
	ir->entries->w = ir->w;
181
	ir->entries->h = ir->h;
182
183
	if((tmp = ParseTitleJustification(ijust)) < 0) {
184
		twmrc_error_prefix();
185
		fprintf(stderr, "ignoring invalid IconRegion argument \"%s\"\n", ijust);
186
		tmp = TJ_UNDEF;
187
	}
188
	ir->TitleJustification = tmp;
189
190
	if((tmp = ParseIRJustification(just)) < 0) {
191
		twmrc_error_prefix();
192
		fprintf(stderr, "ignoring invalid IconRegion argument \"%s\"\n", just);
193
		tmp = IRJ_UNDEF;
194
	}
195
	ir->Justification = tmp;
196
197
	if((tmp = ParseAlignement(align)) < 0) {
198
		twmrc_error_prefix();
199
		fprintf(stderr, "ignoring invalid IconRegion argument \"%s\"\n", align);
200
		tmp = IRA_UNDEF;
201
	}
202
	ir->Alignement = tmp;
203
204
	return(&(ir->clientlist));
1 by Claude Lecommandeur
CTWM version 1.1
205
}
206
498.1.3 by Matthew Fuller
Limit down the scope of these macros a little.
207
498.1.8 by Matthew Fuller
Add some comments/whitespace through PlaceIcon.
208
/*
209
 * Figure out where to put a window's icon based on the IconRegion
210
 * specifications given in config.  Passed def_[xy] which are used
211
 * if we don't find a better location ourselves.  Returns the chosen
212
 * location in final_[xy], and also sets the IconRegion in tmp_win->icon
213
 * if we chose one.
214
 */
215
static void
216
PlaceIcon(TwmWindow *tmp_win, int def_x, int def_y,
217
          int *final_x, int *final_y)
1 by Claude Lecommandeur
CTWM version 1.1
218
{
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
219
	IconRegion  *ir, *oldir;
220
	IconEntry   *ie;
498.1.9 by Matthew Fuller
Don't need to initialize these to 0, they're set when appropriate.
221
	int         w, h;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
222
518.1.19 by Matthew Fuller
Actually, these macros are evaluating a constant since they're always
223
	const int iconWidth = tmp_win->icon->border_width * 2
224
	                      + (Scr->ShrinkIconTitles ? tmp_win->icon->width
225
	                         : tmp_win->icon->w_width);
226
	const int iconHeight = tmp_win->icon->border_width * 2
227
	                       + tmp_win->icon->w_height;
518.1.18 by Matthew Fuller
Go ahead and move these #define/#undef's inside the function body to
228
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
229
	/*
230
	 * First, check to see if the window is in a region's client list
498.1.8 by Matthew Fuller
Add some comments/whitespace through PlaceIcon.
231
	 * (i.e., the win-list on an IconRegion specifier in the config).
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
232
	 */
498.1.1 by Matthew Fuller
0 -> NULL
233
	ie = NULL;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
234
	for(ir = Scr->FirstRegion; ir; ir = ir->next) {
563.1.4 by Matthew Fuller
Mechanically translate all these full_name references to name.
235
		if(LookInList(ir->clientlist, tmp_win->name, &tmp_win->class)) {
498.1.8 by Matthew Fuller
Add some comments/whitespace through PlaceIcon.
236
			/*
237
			 * Found one that claims it.  Figure the necessary local
238
			 * size, based on the icon's side itself and the grid for
239
			 * this IR.
240
			 */
518.1.19 by Matthew Fuller
Actually, these macros are evaluating a constant since they're always
241
			w = roundUp(iconWidth, ir->stepx);
242
			h = roundUp(iconHeight, ir->stepy);
498.1.8 by Matthew Fuller
Add some comments/whitespace through PlaceIcon.
243
244
			/* Find a currently-unused region that's big enough */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
245
			for(ie = ir->entries; ie; ie = ie->next) {
246
				if(ie->used) {
247
					continue;
248
				}
249
				if(ie->w >= w && ie->h >= h) {
498.1.8 by Matthew Fuller
Add some comments/whitespace through PlaceIcon.
250
					/* Bingo */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
251
					break;
252
				}
253
			}
498.1.8 by Matthew Fuller
Add some comments/whitespace through PlaceIcon.
254
255
			/* If we found one, we're done here */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
256
			if(ie) {
257
				break;
258
			}
259
		}
260
	}
261
498.1.8 by Matthew Fuller
Add some comments/whitespace through PlaceIcon.
262
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
263
	/*
498.1.8 by Matthew Fuller
Add some comments/whitespace through PlaceIcon.
264
	 * If we found a slot in a region claiming it, ie is set to the
265
	 * IconEntry.  If not, start over and find the first available berth.
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
266
	 */
267
	if(!ie) {
268
		for(ir = Scr->FirstRegion; ir; ir = ir->next) {
518.1.19 by Matthew Fuller
Actually, these macros are evaluating a constant since they're always
269
			w = roundUp(iconWidth, ir->stepx);
270
			h = roundUp(iconHeight, ir->stepy);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
271
			for(ie = ir->entries; ie; ie = ie->next) {
272
				if(ie->used) {
273
					continue;
274
				}
275
				if(ie->w >= w && ie->h >= h) {
498.1.8 by Matthew Fuller
Add some comments/whitespace through PlaceIcon.
276
					/* Bingo */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
277
					break;
278
				}
279
			}
280
			if(ie) {
281
				break;
282
			}
283
		}
284
	}
498.1.8 by Matthew Fuller
Add some comments/whitespace through PlaceIcon.
285
286
	/* Stash for comparison */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
287
	oldir = tmp_win->icon->ir;
498.1.8 by Matthew Fuller
Add some comments/whitespace through PlaceIcon.
288
289
	/*
290
	 * If we found an appropriate region, use it.  Else, we have no
291
	 * better idea, so use the x/y coords the caller passed us as our
292
	 * basis.
293
	 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
294
	if(ie) {
498.1.13 by Matthew Fuller
A little more commenting, and move some lines down a bit for more
295
		/* XXX whatever sIRE() does */
498.1.2 by Matthew Fuller
Rename splitEntry to splitIconRegionEntry. THis makes it more
296
		splitIconRegionEntry(ie, ir->grav1, ir->grav2, w, h);
498.1.13 by Matthew Fuller
A little more commenting, and move some lines down a bit for more
297
298
		/* Adjust horizontal positioning based on IconRegionJustification */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
299
		switch(ir->Justification) {
496.1.17 by Matthew Fuller
Convert IconRegion Justification to its own enum type too. This is
300
			case IRJ_LEFT:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
301
				*final_x = ie->x;
302
				break;
496.1.17 by Matthew Fuller
Convert IconRegion Justification to its own enum type too. This is
303
			case IRJ_UNDEF:
304
			case IRJ_CENTER:
518.1.19 by Matthew Fuller
Actually, these macros are evaluating a constant since they're always
305
				*final_x = ie->x + (ie->w - iconWidth) / 2;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
306
				break;
496.1.17 by Matthew Fuller
Convert IconRegion Justification to its own enum type too. This is
307
			case IRJ_RIGHT:
518.1.19 by Matthew Fuller
Actually, these macros are evaluating a constant since they're always
308
				*final_x = ie->x + ie->w - iconWidth;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
309
				break;
496.1.17 by Matthew Fuller
Convert IconRegion Justification to its own enum type too. This is
310
			case IRJ_BORDER:
513.1.8 by Matthew Fuller
Swap to the new enum for these gravity values, and retire the old
311
				if(ir->grav2 == GRAV_EAST) {
518.1.19 by Matthew Fuller
Actually, these macros are evaluating a constant since they're always
312
					*final_x = ie->x + ie->w - iconWidth;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
313
				}
314
				else {
315
					*final_x = ie->x;
316
				}
317
				break;
318
		}
498.1.13 by Matthew Fuller
A little more commenting, and move some lines down a bit for more
319
320
		/* And vertical based on IconRegionAlignement */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
321
		switch(ir->Alignement) {
496.1.14 by Matthew Fuller
Create an enum for the IconRegion Alignement (misspelling preserved
322
			case IRA_TOP :
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
323
				*final_y = ie->y;
324
				break;
496.1.14 by Matthew Fuller
Create an enum for the IconRegion Alignement (misspelling preserved
325
			case IRA_UNDEF :
326
			case IRA_CENTER :
518.1.19 by Matthew Fuller
Actually, these macros are evaluating a constant since they're always
327
				*final_y = ie->y + (ie->h - iconHeight) / 2;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
328
				break;
496.1.14 by Matthew Fuller
Create an enum for the IconRegion Alignement (misspelling preserved
329
			case IRA_BOTTOM :
518.1.19 by Matthew Fuller
Actually, these macros are evaluating a constant since they're always
330
				*final_y = ie->y + ie->h - iconHeight;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
331
				break;
496.1.14 by Matthew Fuller
Create an enum for the IconRegion Alignement (misspelling preserved
332
			case IRA_BORDER :
513.1.8 by Matthew Fuller
Swap to the new enum for these gravity values, and retire the old
333
				if(ir->grav1 == GRAV_SOUTH) {
518.1.19 by Matthew Fuller
Actually, these macros are evaluating a constant since they're always
334
					*final_y = ie->y + ie->h - iconHeight;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
335
				}
336
				else {
337
					*final_y = ie->y;
338
				}
339
				break;
340
		}
498.1.13 by Matthew Fuller
A little more commenting, and move some lines down a bit for more
341
342
		/* Tell the win/icon what region it's in, and the entry what's in it */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
343
		tmp_win->icon->ir = ir;
498.1.13 by Matthew Fuller
A little more commenting, and move some lines down a bit for more
344
		ie->used = true;
345
		ie->twm_win = tmp_win;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
346
	}
347
	else {
498.1.8 by Matthew Fuller
Add some comments/whitespace through PlaceIcon.
348
		/* No better idea, tell caller to use theirs */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
349
		*final_x = def_x;
350
		*final_y = def_y;
492.2.80 by Matthew Fuller
Mechanical replacement of inline "(sometype *)0" constructs with NULL,
351
		tmp_win->icon->ir = NULL;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
352
		return;
498.1.12 by Matthew Fuller
Leave another XXX about something unclear.
353
		/* XXX Should we be doing the below in this case too? */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
354
	}
498.1.8 by Matthew Fuller
Add some comments/whitespace through PlaceIcon.
355
356
	/* Alterations if ShrinkIconTitles is set */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
357
	if(Scr->ShrinkIconTitles && tmp_win->icon->has_title) {
358
		*final_x -= GetIconOffset(tmp_win->icon);
359
		if(tmp_win->icon->ir != oldir) {
360
			ReshapeIcon(tmp_win->icon);
361
		}
362
	}
498.1.8 by Matthew Fuller
Add some comments/whitespace through PlaceIcon.
363
518.1.18 by Matthew Fuller
Go ahead and move these #define/#undef's inside the function body to
364
	return;
365
}
366
518.1.3 by Matthew Fuller
Move PaintIcon() into icons.c.
367
368
/*
518.1.14 by Matthew Fuller
Add header comments and tweak whitespace through icons.c. No code
369
 * Look up an IconEntry holding the icon for a given window, and
370
 * optionally stash its IconRegion in irp.  Used internally in
371
 * IconDown().
372
 */
518.1.20 by Matthew Fuller
Reorder and sectionalize icons.s to related functions are grouped
373
static IconEntry *
374
FindIconEntry(TwmWindow *tmp_win, IconRegion **irp)
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
375
{
376
	IconRegion  *ir;
377
	IconEntry   *ie;
378
379
	for(ir = Scr->FirstRegion; ir; ir = ir->next) {
380
		for(ie = ir->entries; ie; ie = ie->next)
381
			if(ie->twm_win == tmp_win) {
382
				if(irp) {
383
					*irp = ir;
384
				}
385
				return ie;
386
			}
1 by Claude Lecommandeur
CTWM version 1.1
387
	}
498.1.5 by Matthew Fuller
Replace some pointer 0's with NULL.
388
	return NULL;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
389
}
390
518.1.14 by Matthew Fuller
Add header comments and tweak whitespace through icons.c. No code
391
392
/*
393
 * Find prior IE in list.  Used internally in IconDown().
394
 */
518.1.20 by Matthew Fuller
Reorder and sectionalize icons.s to related functions are grouped
395
static IconEntry *
396
prevIconEntry(IconEntry *ie, IconRegion *ir)
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
397
{
398
	IconEntry   *ip;
399
400
	if(ie == ir->entries) {
498.1.5 by Matthew Fuller
Replace some pointer 0's with NULL.
401
		return NULL;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
402
	}
403
	for(ip = ir->entries; ip->next != ie; ip = ip->next)
404
		;
405
	return ip;
1 by Claude Lecommandeur
CTWM version 1.1
406
}
407
518.1.14 by Matthew Fuller
Add header comments and tweak whitespace through icons.c. No code
408
409
/*
410
 * Merge two adjacent IconEntry's.  old is being freed; and is adjacent
411
 * to ie.  Merge regions together.
1 by Claude Lecommandeur
CTWM version 1.1
412
 */
518.1.20 by Matthew Fuller
Reorder and sectionalize icons.s to related functions are grouped
413
static void
414
mergeEntries(IconEntry *old, IconEntry *ie)
1 by Claude Lecommandeur
CTWM version 1.1
415
{
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
416
	if(old->y == ie->y) {
417
		ie->w = old->w + ie->w;
418
		if(old->x < ie->x) {
419
			ie->x = old->x;
420
		}
421
	}
422
	else {
423
		ie->h = old->h + ie->h;
424
		if(old->y < ie->y) {
425
			ie->y = old->y;
426
		}
427
	}
1 by Claude Lecommandeur
CTWM version 1.1
428
}
429
518.1.14 by Matthew Fuller
Add header comments and tweak whitespace through icons.c. No code
430
518.1.20 by Matthew Fuller
Reorder and sectionalize icons.s to related functions are grouped
431
432
433
/*
434
 ****************************************************************
435
 *
436
 * Next, the bits related to creating and putting together the icon
437
 * windows, as well as destroying them.
438
 *
439
 ****************************************************************
440
 */
302.1.16 by Olaf 'Rhialto' Seibert
Unify duplicate code; remember that an icon was matched from _NET_WM_ICON.
441
518.1.14 by Matthew Fuller
Add header comments and tweak whitespace through icons.c. No code
442
443
/*
444
 * Create the window scaffolding for an icon.  Called when we need to
445
 * make one, e.g. the first time a window is iconified.
446
 */
518.1.20 by Matthew Fuller
Reorder and sectionalize icons.s to related functions are grouped
447
void
448
CreateIconWindow(TwmWindow *tmp_win, int def_x, int def_y)
1 by Claude Lecommandeur
CTWM version 1.1
449
{
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
450
	unsigned long event_mask;
451
	unsigned long valuemask;            /* mask for create windows */
452
	XSetWindowAttributes attributes;    /* attributes for create windows */
453
	int final_x, final_y;
454
	int x;
455
	Icon        *icon;
501.1.10 by Matthew Fuller
None -> NULL for pointer values. This should clear up most of the
456
	Image       *image = NULL;
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
457
	char        *pattern;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
458
491.1.8 by Matthew Fuller
Stop casting return values of [mc]alloc(). void * has existed for 27
459
	icon = malloc(sizeof(struct Icon));
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
460
461
	icon->otp           = NULL;
462
	icon->border        = Scr->IconBorderColor;
463
	icon->iconc.fore    = Scr->IconC.fore;
464
	icon->iconc.back    = Scr->IconC.back;
492.2.83 by Matthew Fuller
bool-ify these boolean params in icons.h.
465
	icon->title_shrunk  = false;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
466
563.1.4 by Matthew Fuller
Mechanically translate all these full_name references to name.
467
	GetColorFromList(Scr->IconBorderColorL, tmp_win->name, &tmp_win->class,
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
468
	                 &icon->border);
563.1.4 by Matthew Fuller
Mechanically translate all these full_name references to name.
469
	GetColorFromList(Scr->IconForegroundL, tmp_win->name, &tmp_win->class,
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
470
	                 &icon->iconc.fore);
563.1.4 by Matthew Fuller
Mechanically translate all these full_name references to name.
471
	GetColorFromList(Scr->IconBackgroundL, tmp_win->name, &tmp_win->class,
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
472
	                 &icon->iconc.back);
473
	if(Scr->use3Diconmanagers && !Scr->BeNiceToColormap) {
474
		GetShadeColors(&icon->iconc);
475
	}
476
477
	FB(icon->iconc.fore, icon->iconc.back);
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
478
479
	icon->match   = match_none;
501.1.10 by Matthew Fuller
None -> NULL for pointer values. This should clear up most of the
480
	icon->image   = NULL;
492.2.80 by Matthew Fuller
Mechanical replacement of inline "(sometype *)0" constructs with NULL,
481
	icon->ir      = NULL;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
482
492.2.75 by Matthew Fuller
Convert a bunch of boolean flags in the TwmWindow structure
483
	tmp_win->forced = false;
492.2.83 by Matthew Fuller
bool-ify these boolean params in icons.h.
484
	icon->w_not_ours = false;
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
485
486
	pattern = NULL;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
487
488
	/* now go through the steps to get an icon window,  if ForceIcon is
489
	 * set, then no matter what else is defined, the bitmap from the
490
	 * .twmrc file is used
491
	 */
492
	if(Scr->ForceIcon) {
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
493
		image = LookupIconNameOrClass(tmp_win, icon, &pattern);
494
	}
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
495
302.1.12 by Olaf 'Rhialto' Seibert
First version of NET_WM_ICON.
496
#ifdef EWMH
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
497
	/*
498
	 * Look to see if there is a _NET_WM_ICON property to provide an icon.
499
	 */
501.1.10 by Matthew Fuller
None -> NULL for pointer values. This should clear up most of the
500
	if(image == NULL) {
501.1.11 by Matthew Fuller
Ewhm -> Ewmh in a couple function names.
501
		image = EwmhGetIcon(Scr, tmp_win);
501.1.10 by Matthew Fuller
None -> NULL for pointer values. This should clear up most of the
502
		if(image != NULL) {
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
503
			icon->match   = match_net_wm_icon;
504
			icon->width   = image->width;
505
			icon->height  = image->height;
506
			icon->image   = image;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
507
		}
508
	}
302.1.12 by Olaf 'Rhialto' Seibert
First version of NET_WM_ICON.
509
#endif /* EWMH */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
510
511
	/* if the pixmap is still NULL, we didn't get one from the above code,
512
	 * that could mean that ForceIcon was not set, or that the window
513
	 * was not in the Icons list, now check the WM hints for an icon
514
	 */
557.1.3 by Matthew Fuller
GC now-unnecessary NULL checks of wmhints.
515
	if(image == NULL && tmp_win->wmhints->flags & IconPixmapHint) {
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
516
		unsigned int IconDepth, IconWidth, IconHeight;
517
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
518
		if(XGetGeometry(dpy, tmp_win->wmhints->icon_pixmap,
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
519
		                &JunkRoot, &JunkX, &JunkY, &IconWidth, &IconHeight, &JunkBW, &IconDepth)) {
480.1.19 by Matthew Fuller
Add an AllocImage() to ensure new Image's are initialized properly,
520
			image = AllocImage();
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
521
			image->width  = IconWidth;
522
			image->height = IconHeight;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
523
			image->pixmap = XCreatePixmap(dpy, Scr->Root, image->width,
524
			                              image->height, Scr->d_depth);
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
525
			if(IconDepth == Scr->d_depth)
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
526
				XCopyArea(dpy, tmp_win->wmhints->icon_pixmap, image->pixmap, Scr->NormalGC,
527
				          0, 0, image->width, image->height, 0, 0);
528
			else
529
				XCopyPlane(dpy, tmp_win->wmhints->icon_pixmap, image->pixmap, Scr->NormalGC,
530
				           0, 0, image->width, image->height, 0, 0, 1);
531
532
			icon->width   = image->width;
533
			icon->height  = image->height;
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
534
			icon->match   = match_icon_pixmap_hint;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
535
536
			if((tmp_win->wmhints->flags & IconMaskHint) &&
537
			                XGetGeometry(dpy, tmp_win->wmhints->icon_mask,
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
538
			                             &JunkRoot, &JunkX, &JunkY, &IconWidth, &IconHeight, &JunkBW, &IconDepth) &&
539
			                (IconDepth == 1)) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
540
				GC gc;
541
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
542
				image->mask = XCreatePixmap(dpy, Scr->Root, IconWidth, IconHeight, 1);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
543
				if(image->mask) {
544
					gc = XCreateGC(dpy, image->mask, 0, NULL);
545
					if(gc) {
546
						XCopyArea(dpy, tmp_win->wmhints->icon_mask, image->mask, gc,
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
547
						          0, 0, IconWidth, IconHeight, 0, 0);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
548
						XFreeGC(dpy, gc);
549
					}
550
				}
551
			}
552
			icon->image = image;
553
		}
554
	}
555
556
	/* if we still haven't got an icon, let's look in the Icon list
557
	 * if ForceIcon is not set
558
	 */
501.1.10 by Matthew Fuller
None -> NULL for pointer values. This should clear up most of the
559
	if(image == NULL && !Scr->ForceIcon) {
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
560
		image = LookupIconNameOrClass(tmp_win, icon, &pattern);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
561
	}
562
563
	/* if we still don't have an icon, assign the UnknownIcon */
501.1.10 by Matthew Fuller
None -> NULL for pointer values. This should clear up most of the
564
	if(image == NULL && Scr->UnknownImage != NULL) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
565
		image = Scr->UnknownImage;
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
566
		icon->match   = match_unknown_default;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
567
		icon->width   = image->width;
568
		icon->height  = image->height;
569
		icon->image   = image;
570
	}
571
501.1.10 by Matthew Fuller
None -> NULL for pointer values. This should clear up most of the
572
	if(image == NULL) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
573
		icon->height = 0;
574
		icon->width  = 0;
575
		valuemask    = 0;
576
	}
577
	else {
578
		valuemask = CWBackPixmap;
579
		attributes.background_pixmap = image->pixmap;
580
	}
581
582
	icon->border_width = Scr->IconBorderWidth;
583
	if(Scr->NoIconTitlebar ||
584
	                LookInNameList(Scr->NoIconTitle, tmp_win->icon_name) ||
563.1.4 by Matthew Fuller
Mechanically translate all these full_name references to name.
585
	                LookInList(Scr->NoIconTitle, tmp_win->name, &tmp_win->class)) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
586
		icon->w_width  = icon->width;
587
		icon->w_height = icon->height;
588
		icon->x = 0;
589
		icon->y = 0;
492.2.83 by Matthew Fuller
bool-ify these boolean params in icons.h.
590
		icon->has_title = false;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
591
	}
592
	else {
593
		XRectangle inc_rect;
594
		XRectangle logical_rect;
595
596
		XmbTextExtents(Scr->IconFont.font_set,
597
		               tmp_win->icon_name, strlen(tmp_win->icon_name),
598
		               &inc_rect, &logical_rect);
599
		icon->w_width = logical_rect.width;
600
601
		icon->w_width += 2 * (Scr->IconManagerShadowDepth + ICON_MGR_IBORDER);
602
		if(icon->w_width > Scr->MaxIconTitleWidth) {
603
			icon->w_width = Scr->MaxIconTitleWidth;
604
		}
605
		if(icon->w_width < icon->width) {
606
			icon->x  = (icon->width - icon->w_width) / 2;
607
			icon->x += Scr->IconManagerShadowDepth + ICON_MGR_IBORDER;
608
			icon->w_width = icon->width;
609
		}
610
		else {
611
			icon->x = Scr->IconManagerShadowDepth + ICON_MGR_IBORDER;
612
		}
613
		icon->y = icon->height + Scr->IconFont.height + Scr->IconManagerShadowDepth;
614
		icon->w_height = icon->height + Scr->IconFont.height +
615
		                 2 * (Scr->IconManagerShadowDepth + ICON_MGR_IBORDER);
492.2.83 by Matthew Fuller
bool-ify these boolean params in icons.h.
616
		icon->has_title = true;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
617
		if(icon->height) {
618
			icon->border_width = 0;
619
		}
620
	}
621
622
	event_mask = 0;
557.1.3 by Matthew Fuller
GC now-unnecessary NULL checks of wmhints.
623
	if(tmp_win->wmhints->flags & IconWindowHint) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
624
		icon->w = tmp_win->wmhints->icon_window;
625
		if(tmp_win->forced ||
626
		                XGetGeometry(dpy, icon->w, &JunkRoot, &JunkX, &JunkY,
627
		                             (unsigned int *)&icon->w_width, (unsigned int *)&icon->w_height,
628
		                             &JunkBW, &JunkDepth) == 0) {
629
			icon->w = None;
630
			tmp_win->wmhints->flags &= ~IconWindowHint;
631
		}
632
		else {
501.1.10 by Matthew Fuller
None -> NULL for pointer values. This should clear up most of the
633
			image = NULL;
492.2.83 by Matthew Fuller
bool-ify these boolean params in icons.h.
634
			icon->w_not_ours = true;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
635
			icon->width  = icon->w_width;
636
			icon->height = icon->w_height;
637
			icon->image  = image;
492.2.83 by Matthew Fuller
bool-ify these boolean params in icons.h.
638
			icon->has_title = false;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
639
			event_mask = 0;
640
		}
641
	}
642
	else {
643
		icon->w = None;
644
	}
645
501.1.10 by Matthew Fuller
None -> NULL for pointer values. This should clear up most of the
646
	if((image != NULL) &&
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
647
	                image->mask != None &&
557.1.3 by Matthew Fuller
GC now-unnecessary NULL checks of wmhints.
648
	                !(tmp_win->wmhints->flags & IconWindowHint)) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
649
		icon->border_width = 0;
650
	}
651
	if(icon->w == None) {
652
		icon->w = XCreateSimpleWindow(dpy, Scr->Root,
653
		                              0, 0,
654
		                              icon->w_width, icon->w_height,
655
		                              icon->border_width, icon->border, icon->iconc.back);
656
		event_mask = ExposureMask;
657
	}
658
659
	if(Scr->AutoRaiseIcons || Scr->ShrinkIconTitles) {
660
		event_mask |= EnterWindowMask | LeaveWindowMask;
661
	}
662
	event_mask |= KeyPressMask | ButtonPressMask | ButtonReleaseMask;
663
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
664
	if(icon->w_not_ours) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
665
		XWindowAttributes wattr;
666
667
		XGetWindowAttributes(dpy, icon->w, &wattr);
668
		if(wattr.all_event_masks & ButtonPressMask) {
669
			event_mask &= ~ButtonPressMask;
670
		}
671
	}
672
	XSelectInput(dpy, icon->w, event_mask);
673
674
	if(icon->width == 0) {
675
		icon->width = icon->w_width;
676
	}
677
	icon->bm_w = None;
557.1.3 by Matthew Fuller
GC now-unnecessary NULL checks of wmhints.
678
	if(image && !(tmp_win->wmhints->flags & IconWindowHint)) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
679
		XRectangle rect;
680
681
		x = GetIconOffset(icon);
682
		icon->bm_w = XCreateWindow(dpy, icon->w, x, 0,
505.1.19 by Matthew Fuller
Remove casts from XCreateWindow() calls. Some of these were probably
683
		                           icon->width,
684
		                           icon->height,
685
		                           0, Scr->d_depth,
686
		                           CopyFromParent,
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
687
		                           Scr->d_visual, valuemask,
688
		                           &attributes);
689
		if(image->mask) {
690
			XShapeCombineMask(dpy, icon->bm_w, ShapeBounding, 0, 0, image->mask, ShapeSet);
691
			XShapeCombineMask(dpy, icon->w,    ShapeBounding, x, 0, image->mask, ShapeSet);
692
		}
693
		else if(icon->has_title) {
694
			rect.x      = x;
695
			rect.y      = 0;
696
			rect.width  = icon->width;
697
			rect.height = icon->height;
698
			XShapeCombineRectangles(dpy, icon->w, ShapeBounding,
699
			                        0, 0, &rect, 1, ShapeSet, 0);
700
		}
701
		if(icon->has_title) {
702
			if(Scr->ShrinkIconTitles) {
703
				rect.x      = x;
704
				rect.y      = icon->height;
705
				rect.width  = icon->width;
706
				rect.height = icon->w_height - icon->height;
492.2.83 by Matthew Fuller
bool-ify these boolean params in icons.h.
707
				icon->title_shrunk = true;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
708
			}
709
			else {
710
				rect.x      = 0;
711
				rect.y      = icon->height;
712
				rect.width  = icon->w_width;
713
				rect.height = icon->w_height - icon->height;
492.2.83 by Matthew Fuller
bool-ify these boolean params in icons.h.
714
				icon->title_shrunk = false;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
715
			}
716
			XShapeCombineRectangles(dpy, icon->w, ShapeBounding,
717
			                        0, 0, &rect, 1, ShapeUnion, 0);
718
		}
719
	}
720
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
721
	if(pattern != NULL) {
337.1.4 by Matthew Fuller
Reap a bunch of (char *) casts in AddToList() calls.
722
		AddToList(&tmp_win->iconslist, pattern, icon);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
723
	}
724
725
	tmp_win->icon = icon;
726
	/* I need to figure out where to put the icon window now, because
727
	 * getting here means that I am going to make the icon visible
728
	 */
311.1.8 by Matthew Fuller
Actually both these could potentially wind up uninitialized, so
729
	final_x = final_y = 0;
557.1.3 by Matthew Fuller
GC now-unnecessary NULL checks of wmhints.
730
	if(tmp_win->wmhints->flags & IconPositionHint) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
731
		final_x = tmp_win->wmhints->icon_x;
732
		final_y = tmp_win->wmhints->icon_y;
733
	}
734
	else {
735
		if(visible(tmp_win)) {
736
			PlaceIcon(tmp_win, def_x, def_y, &final_x, &final_y);
737
		}
738
	}
739
557.1.3 by Matthew Fuller
GC now-unnecessary NULL checks of wmhints.
740
	if(visible(tmp_win) || (tmp_win->wmhints->flags & IconPositionHint)) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
741
		if(final_x > Scr->rootw) {
742
			final_x = Scr->rootw - icon->w_width - (2 * Scr->IconBorderWidth);
743
		}
744
		if(Scr->ShrinkIconTitles && icon->bm_w) {
745
			if(final_x + (icon->w_width - icon->width) < 0) {
746
				final_x = 0;
747
			}
748
		}
749
		else {
750
			if(final_x < 0) {
751
				final_x = 0;
752
			}
753
		}
754
		if(final_y > Scr->rooth)
755
			final_y = Scr->rooth - icon->height -
756
			          Scr->IconFont.height - 6 - (2 * Scr->IconBorderWidth);
757
		if(final_y < 0) {
758
			final_y = 0;
759
		}
760
761
		XMoveWindow(dpy, icon->w, final_x, final_y);
762
		icon->w_x = final_x;
763
		icon->w_y = final_y;
764
	}
492.2.75 by Matthew Fuller
Convert a bunch of boolean flags in the TwmWindow structure
765
	tmp_win->iconified = true;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
766
	OtpAdd(tmp_win, IconWin);
767
768
	XMapSubwindows(dpy, icon->w);
769
	XSaveContext(dpy, icon->w, TwmContext, (XPointer)tmp_win);
770
	XSaveContext(dpy, icon->w, ScreenContext, (XPointer)Scr);
771
	XDefineCursor(dpy, icon->w, Scr->IconCursor);
492.2.44 by Matthew Fuller
bool-ify animation flags.
772
	MaybeAnimate = true;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
773
}
774
518.1.14 by Matthew Fuller
Add header comments and tweak whitespace through icons.c. No code
775
776
/*
302.1.21 by Olaf 'Rhialto' Seibert
Improve tracking where Icon's Images come from, so that they can be freed
777
 * Delete TwmWindow.iconslist.
778
 * Call it before deleting TwmWindow.icon, since we need to check
779
 * that we're not deleting that Icon.
780
 */
518.1.20 by Matthew Fuller
Reorder and sectionalize icons.s to related functions are grouped
781
void
782
DeleteIconsList(TwmWindow *tmp_win)
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
783
{
784
	/*
785
	 * Only the list itself needs to be freed, since the pointers it
786
	 * contains point into various lists that belong to Scr.
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
787
	 *
788
	 * Rhialto: Hmmmm not quite sure about that! CreateIconWindow() above
789
	 * always allocates a struct Icon, and doesn't attach it to Scr...
790
	 * It is probably correct for the Image pointers inside those Icons though.
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
791
	 */
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
792
	name_list *nptr;
793
	name_list *next;
794
795
	for(nptr = tmp_win->iconslist; nptr != NULL;) {
796
		next = nptr->next;
797
		Icon *icon = (Icon *)nptr->ptr;
798
		if(icon != tmp_win->icon) {
799
			DeleteIcon(icon);
800
		}
801
		free(nptr->name);
491.1.11 by Matthew Fuller
Stop casting arg to free(), especially to char *.
802
		free(nptr);
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
803
		nptr = next;
804
	}
805
	tmp_win->iconslist = NULL;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
806
}
807
518.1.14 by Matthew Fuller
Add header comments and tweak whitespace through icons.c. No code
808
809
/*
518.1.20 by Matthew Fuller
Reorder and sectionalize icons.s to related functions are grouped
810
 * Delete a single Icon.  Called iteratively from DeleteIconList(), and
811
 * directly during window destruction.
812
 */
813
void
814
DeleteIcon(Icon *icon)
815
{
816
	if(icon->w && !icon->w_not_ours) {
817
		XDestroyWindow(dpy, icon->w);
818
	}
819
	ReleaseIconImage(icon);
820
	free(icon);
821
}
822
823
824
/*
825
 * Delete the Image from an icon, if it is not a shared one.  match_list
826
 * ands match_unknown_default need not be freed.
827
 *
828
 * Formerly ReleaseImage()
829
 */
830
void
831
ReleaseIconImage(Icon *icon)
832
{
833
	if(icon->match == match_icon_pixmap_hint ||
834
	                icon->match == match_net_wm_icon) {
835
		FreeImage(icon->image);
836
	}
837
}
838
839
840
841
842
/*
843
 ****************************************************************
844
 *
845
 * Bringing an icon up or down.
846
 *
847
 ****************************************************************
848
 */
849
850
851
/*
852
 * Show up an icon.  Note that neither IconUp nor IconDown actually map
853
 * or unmap the icon window; that's handled by the callers.  These
854
 * functions limit themselves to figuring out where it should be, moving
855
 * it (still unmapped) there, and linking/unlinking it from the iconentry
856
 * lists.
857
 */
858
void
859
IconUp(TwmWindow *tmp_win)
860
{
861
	int         x, y;
862
	int         defx, defy;
863
864
	/*
865
	 * If the client specified a particular location, let's use it (this might
866
	 * want to be an option at some point).  Otherwise, try to fit within the
867
	 * icon region.
868
	 */
557.1.3 by Matthew Fuller
GC now-unnecessary NULL checks of wmhints.
869
	if(tmp_win->wmhints->flags & IconPositionHint) {
518.1.20 by Matthew Fuller
Reorder and sectionalize icons.s to related functions are grouped
870
		return;
871
	}
872
873
	if(tmp_win->icon_moved) {
874
		struct IconRegion *ir;
875
		unsigned int iww, iwh;
876
877
		if(!XGetGeometry(dpy, tmp_win->icon->w, &JunkRoot, &defx, &defy,
878
		                 &iww, &iwh, &JunkBW, &JunkDepth)) {
879
			return;
880
		}
881
882
		x = defx + ((int) iww) / 2;
883
		y = defy + ((int) iwh) / 2;
884
885
		for(ir = Scr->FirstRegion; ir; ir = ir->next) {
886
			if(x >= ir->x && x < (ir->x + ir->w) &&
887
			                y >= ir->y && y < (ir->y + ir->h)) {
888
				break;
889
			}
890
		}
891
		if(!ir) {
892
			return;        /* outside icon regions, leave alone */
893
		}
894
	}
895
896
	defx = -100;
897
	defy = -100;
898
	PlaceIcon(tmp_win, defx, defy, &x, &y);
899
	if(x != defx || y != defy) {
900
		XMoveWindow(dpy, tmp_win->icon->w, x, y);
901
		tmp_win->icon->w_x = x;
902
		tmp_win->icon->w_y = y;
903
		tmp_win->icon_moved = false;    /* since we've restored it */
904
	}
905
	MaybeAnimate = true;
906
	return;
907
}
908
909
910
/*
911
 * Remove an icon from its displayed IconEntry.  x-ref comment on
912
 * IconUp().
913
 */
914
void
915
IconDown(TwmWindow *tmp_win)
916
{
917
	IconEntry   *ie, *ip, *in;
918
	IconRegion  *ir;
919
920
	ie = FindIconEntry(tmp_win, &ir);
921
	if(ie) {
922
		ie->twm_win = NULL;
923
		ie->used = false;
924
		ip = prevIconEntry(ie, ir);
925
		in = ie->next;
926
		for(;;) {
927
			if(ip && ip->used == false &&
928
			                ((ip->x == ie->x && ip->w == ie->w) ||
929
			                 (ip->y == ie->y && ip->h == ie->h))) {
930
				ip->next = ie->next;
931
				mergeEntries(ie, ip);
932
				free(ie);
933
				ie = ip;
934
				ip = prevIconEntry(ip, ir);
935
			}
936
			else if(in && in->used == false &&
937
			                ((in->x == ie->x && in->w == ie->w) ||
938
			                 (in->y == ie->y && in->h == ie->h))) {
939
				ie->next = in->next;
940
				mergeEntries(in, ie);
941
				free(in);
942
				in = ie->next;
943
			}
944
			else {
945
				break;
946
			}
947
		}
948
	}
949
}
950
951
952
953
954
/*
955
 ****************************************************************
956
 *
957
 * Funcs related to drawing the icon.
958
 *
959
 ****************************************************************
960
 */
961
962
963
/*
964
 * Slightly misnamed: draws the text label under an icon.
965
 */
966
void
967
PaintIcon(TwmWindow *tmp_win)
968
{
969
	int         width, twidth, mwidth, len, x;
970
	Icon        *icon;
971
	XRectangle ink_rect;
972
	XRectangle logical_rect;
973
974
	if(!tmp_win || !tmp_win->icon) {
975
		return;
976
	}
977
	icon = tmp_win->icon;
978
	if(!icon->has_title) {
979
		return;
980
	}
981
982
	x     = 0;
983
	width = icon->w_width;
984
	if(Scr->ShrinkIconTitles && icon->title_shrunk) {
985
		x     = GetIconOffset(icon);
986
		width = icon->width;
987
	}
988
	len    = strlen(tmp_win->icon_name);
989
	XmbTextExtents(Scr->IconFont.font_set,
990
	               tmp_win->icon_name, len,
991
	               &ink_rect, &logical_rect);
992
	twidth = logical_rect.width;
993
	mwidth = width - 2 * (Scr->IconManagerShadowDepth + ICON_MGR_IBORDER);
994
	if(Scr->use3Diconmanagers) {
995
		Draw3DBorder(icon->w, x, icon->height, width,
996
		             Scr->IconFont.height +
997
		             2 * (Scr->IconManagerShadowDepth + ICON_MGR_IBORDER),
998
		             Scr->IconManagerShadowDepth, icon->iconc, off, false, false);
999
	}
1000
	while((len > 0) && (twidth > mwidth)) {
1001
		len--;
1002
		XmbTextExtents(Scr->IconFont.font_set,
1003
		               tmp_win->icon_name, len,
1004
		               &ink_rect, &logical_rect);
1005
		twidth = logical_rect.width;
1006
	}
1007
	FB(icon->iconc.fore, icon->iconc.back);
1008
	XmbDrawString(dpy, icon->w, Scr->IconFont.font_set, Scr->NormalGC,
1009
	              x + ((mwidth - twidth) / 2) +
1010
	              Scr->IconManagerShadowDepth + ICON_MGR_IBORDER,
1011
	              icon->y, tmp_win->icon_name, len);
1012
}
1013
1014
1015
/*
518.1.14 by Matthew Fuller
Add header comments and tweak whitespace through icons.c. No code
1016
 * Handling for ShrinkIconTitles; when pointer is away from them, shrink
1017
 * the titles down to the width of the image, and expand back out when it
1018
 * enters.
1019
 */
518.1.20 by Matthew Fuller
Reorder and sectionalize icons.s to related functions are grouped
1020
void
1021
ShrinkIconTitle(TwmWindow *tmp_win)
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1022
{
1023
	Icon        *icon;
1024
	XRectangle  rect;
1025
1026
	if(!tmp_win || !tmp_win->icon) {
1027
		return;
1028
	}
1029
	icon = tmp_win->icon;
1030
	if(!icon->has_title) {
1031
		return;
1032
	}
1033
	if(icon->w_width == icon->width) {
1034
		return;
1035
	}
1036
	if(icon->height  == 0) {
1037
		return;
1038
	}
1039
1040
	rect.x      = GetIconOffset(icon);
1041
	rect.y      = 0;
1042
	rect.width  = icon->width;
1043
	rect.height = icon->w_height;
1044
	XShapeCombineRectangles(dpy, icon->w, ShapeBounding, 0, 0, &rect, 1,
1045
	                        ShapeIntersect, 0);
492.2.83 by Matthew Fuller
bool-ify these boolean params in icons.h.
1046
	icon->title_shrunk = true;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1047
	XClearArea(dpy, icon->w, 0, icon->height, icon->w_width,
1048
	           icon->w_height - icon->height, True);
1049
}
1050
518.1.14 by Matthew Fuller
Add header comments and tweak whitespace through icons.c. No code
1051
518.1.20 by Matthew Fuller
Reorder and sectionalize icons.s to related functions are grouped
1052
void
1053
ExpandIconTitle(TwmWindow *tmp_win)
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1054
{
1055
	Icon        *icon;
1056
	XRectangle  rect;
1057
1058
	if(!tmp_win || !tmp_win->icon) {
1059
		return;
1060
	}
1061
	icon = tmp_win->icon;
1062
	if(!icon->has_title) {
1063
		return;
1064
	}
1065
	if(icon->w_width == icon->width) {
1066
		return;
1067
	}
1068
	if(icon->height  == 0) {
1069
		return;
1070
	}
1071
1072
	rect.x      = 0;
1073
	rect.y      = icon->height;
1074
	rect.width  = icon->w_width;
1075
	rect.height = icon->w_height - icon->height;
1076
	XShapeCombineRectangles(dpy, icon->w, ShapeBounding, 0, 0, &rect, 1, ShapeUnion,
1077
	                        0);
492.2.83 by Matthew Fuller
bool-ify these boolean params in icons.h.
1078
	icon->title_shrunk = false;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1079
	XClearArea(dpy, icon->w, 0, icon->height, icon->w_width,
1080
	           icon->w_height - icon->height, True);
1081
}
1082
518.1.14 by Matthew Fuller
Add header comments and tweak whitespace through icons.c. No code
1083
498.1.11 by Matthew Fuller
Add a comment on ReshapeIcon, with a note about something odd to look
1084
/*
1085
 * Setup X Shape'ing around icons and their titles.
1086
 *
1087
 * XXX should this be checking HasShape?  It seems to be called
1088
 * unconditionally...
1089
 */
498.1.10 by Matthew Fuller
staticize ReshapeIcon, it's only called from one place.
1090
static void
1091
ReshapeIcon(Icon *icon)
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1092
{
1093
	int x;
1094
	XRectangle  rect;
1095
1096
	if(!icon) {
1097
		return;
1098
	}
1099
	x = GetIconOffset(icon);
1100
	XMoveWindow(dpy, icon->bm_w, x, 0);
1101
1102
	if(icon->image && icon->image->mask) {
1103
		XShapeCombineMask(dpy, icon->w, ShapeBounding, x, 0, icon->image->mask,
1104
		                  ShapeSet);
1105
	}
1106
	else {
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
1107
		rect.x      = x;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1108
		rect.y      = 0;
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
1109
		rect.width  = icon->width;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1110
		rect.height = icon->height;
1111
		XShapeCombineRectangles(dpy, icon->w, ShapeBounding, 0, 0, &rect, 1, ShapeSet,
1112
		                        0);
302.1.31 by Olaf 'Rhialto' Seibert
Code re-indented.
1113
	}
16 by Claude Lecommandeur
CTWM version 3.4pl2
1114
	rect.x      = x;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1115
	rect.y      = icon->height;
16 by Claude Lecommandeur
CTWM version 3.4pl2
1116
	rect.width  = icon->width;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1117
	rect.height = icon->w_height - icon->height;
1118
	XShapeCombineRectangles(dpy, icon->w, ShapeBounding, 0, 0, &rect, 1, ShapeUnion,
1119
	                        0);
1120
}
1121
518.1.14 by Matthew Fuller
Add header comments and tweak whitespace through icons.c. No code
1122
1123
/*
1124
 * Figure horizontal positioning/offset for the icon image within its
1125
 * window.
1126
 */
518.1.20 by Matthew Fuller
Reorder and sectionalize icons.s to related functions are grouped
1127
int
1128
GetIconOffset(Icon *icon)
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1129
{
496.1.16 by Matthew Fuller
Convert TitleJustification elements to their own enum type, and fixup
1130
	TitleJust justif;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1131
1132
	if(!icon) {
498.1.6 by Matthew Fuller
Take out parens for local consistency.
1133
		return 0;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1134
	}
1135
1136
	justif = icon->ir ? icon->ir->TitleJustification : Scr->IconJustification;
1137
	switch(justif) {
496.1.16 by Matthew Fuller
Convert TitleJustification elements to their own enum type, and fixup
1138
		case TJ_LEFT:
1139
			return 0;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1140
496.1.16 by Matthew Fuller
Convert TitleJustification elements to their own enum type, and fixup
1141
		case TJ_CENTER:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1142
			return ((icon->w_width - icon->width) / 2);
1143
496.1.16 by Matthew Fuller
Convert TitleJustification elements to their own enum type, and fixup
1144
		case TJ_RIGHT:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1145
			return (icon->w_width - icon->width);
1146
496.1.16 by Matthew Fuller
Convert TitleJustification elements to their own enum type, and fixup
1147
		default:
1148
			/* Can't happen? */
1149
			fprintf(stderr, "%s(): Invalid TitleJustification %d\n",
1150
			        __func__, justif);
1151
			return 0;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1152
	}
1153
}
518.1.10 by Matthew Fuller
Move RedoIcon*() into icons.c.
1154
1155
1156
/*
1157
 * [Re-]lookup the image for an icon and [re-]layout it.
1158
 */
1159
void
1160
RedoIcon(TwmWindow *win)
1161
{
1162
	Icon *icon, *old_icon;
1163
	char *pattern;
1164
1165
	old_icon = win->icon;
1166
1167
	if(old_icon && (old_icon->w_not_ours || old_icon->match != match_list)) {
1168
		RedoIconName(win);
1169
		return;
1170
	}
1171
	icon = NULL;
1172
	if((pattern = LookPatternInNameList(Scr->IconNames, win->icon_name))) {
1173
		icon = LookInNameList(win->iconslist, pattern);
1174
	}
563.1.4 by Matthew Fuller
Mechanically translate all these full_name references to name.
1175
	else if((pattern = LookPatternInNameList(Scr->IconNames, win->name))) {
518.1.10 by Matthew Fuller
Move RedoIcon*() into icons.c.
1176
		icon = LookInNameList(win->iconslist, pattern);
1177
	}
563.1.4 by Matthew Fuller
Mechanically translate all these full_name references to name.
1178
	else if((pattern = LookPatternInList(Scr->IconNames, win->name,
518.1.10 by Matthew Fuller
Move RedoIcon*() into icons.c.
1179
	                                     &win->class))) {
1180
		icon = LookInNameList(win->iconslist, pattern);
1181
	}
1182
	if(pattern == NULL) {
1183
		RedoIconName(win);
1184
		return;
1185
	}
1186
	if(icon != NULL) {
1187
		if(old_icon == icon) {
1188
			RedoIconName(win);
1189
			return;
1190
		}
1191
		if(win->icon_on && visible(win)) {
1192
			IconDown(win);
1193
			if(old_icon && old_icon->w) {
1194
				XUnmapWindow(dpy, old_icon->w);
1195
			}
1196
			win->icon = icon;
1197
			OtpReassignIcon(win, old_icon);
1198
			IconUp(win);
1199
			OtpRaise(win, IconWin);
1200
			XMapWindow(dpy, win->icon->w);
1201
		}
1202
		else {
1203
			win->icon = icon;
1204
			OtpReassignIcon(win, old_icon);
1205
		}
1206
		RedoIconName(win);
1207
	}
1208
	else {
1209
		if(win->icon_on && visible(win)) {
1210
			IconDown(win);
1211
			if(old_icon && old_icon->w) {
1212
				XUnmapWindow(dpy, old_icon->w);
1213
			}
1214
			/*
1215
			 * If the icon name/class was found on one of the above lists,
1216
			 * the call to CreateIconWindow() will find it again there
1217
			 * and keep track of it on win->iconslist for eventual
1218
			 * deallocation. (It is now checked that the current struct
1219
			 * Icon is also already on that list)
1220
			 */
1221
			OtpFreeIcon(win);
1222
			bool saveForceIcon = Scr->ForceIcon;
1223
			Scr->ForceIcon = true;
1224
			CreateIconWindow(win, -100, -100);
1225
			Scr->ForceIcon = saveForceIcon;
1226
			OtpRaise(win, IconWin);
1227
			XMapWindow(dpy, win->icon->w);
1228
		}
1229
		else {
1230
			OtpFreeIcon(win);
1231
			win->icon = NULL;
1232
			WMapUpdateIconName(win);
1233
		}
1234
		RedoIconName(win);
1235
	}
1236
}
1237
1238
1239
/*
1240
 * Resize the icon window, and reposition the image and name within it.
1241
 * (a lot of the actual repositioning gets done during the later expose).
1242
 */
1243
void
1244
RedoIconName(TwmWindow *win)
1245
{
1246
	int x;
1247
	XRectangle ink_rect;
1248
	XRectangle logical_rect;
1249
1250
	if(Scr->NoIconTitlebar ||
1251
	                LookInNameList(Scr->NoIconTitle, win->icon_name) ||
563.1.4 by Matthew Fuller
Mechanically translate all these full_name references to name.
1252
	                LookInList(Scr->NoIconTitle, win->name, &win->class)) {
518.1.12 by Matthew Fuller
De-ref these gotos; it's only one line and a return, so it's more
1253
		WMapUpdateIconName(win);
1254
		return;
518.1.10 by Matthew Fuller
Move RedoIcon*() into icons.c.
1255
	}
1256
	if(win->iconmanagerlist) {
1257
		/* let the expose event cause the repaint */
1258
		XClearArea(dpy, win->iconmanagerlist->w, 0, 0, 0, 0, True);
1259
1260
		if(Scr->SortIconMgr) {
1261
			SortIconManager(win->iconmanagerlist->iconmgr);
1262
		}
1263
	}
1264
1265
	if(!win->icon  || !win->icon->w) {
518.1.12 by Matthew Fuller
De-ref these gotos; it's only one line and a return, so it's more
1266
		WMapUpdateIconName(win);
1267
		return;
518.1.10 by Matthew Fuller
Move RedoIcon*() into icons.c.
1268
	}
1269
1270
	if(win->icon->w_not_ours) {
518.1.12 by Matthew Fuller
De-ref these gotos; it's only one line and a return, so it's more
1271
		WMapUpdateIconName(win);
1272
		return;
518.1.10 by Matthew Fuller
Move RedoIcon*() into icons.c.
1273
	}
1274
1275
	XmbTextExtents(Scr->IconFont.font_set,
1276
	               win->icon_name, strlen(win->icon_name),
1277
	               &ink_rect, &logical_rect);
1278
	win->icon->w_width = logical_rect.width;
1279
	win->icon->w_width += 2 * (Scr->IconManagerShadowDepth + ICON_MGR_IBORDER);
1280
	if(win->icon->w_width > Scr->MaxIconTitleWidth) {
1281
		win->icon->w_width = Scr->MaxIconTitleWidth;
1282
	}
1283
1284
	if(win->icon->w_width < win->icon->width) {
1285
		win->icon->x = (win->icon->width - win->icon->w_width) / 2;
1286
		win->icon->x += Scr->IconManagerShadowDepth + ICON_MGR_IBORDER;
1287
		win->icon->w_width = win->icon->width;
1288
	}
1289
	else {
1290
		win->icon->x = Scr->IconManagerShadowDepth + ICON_MGR_IBORDER;
1291
	}
1292
1293
	x = GetIconOffset(win->icon);
1294
	win->icon->y = win->icon->height + Scr->IconFont.height +
1295
	               Scr->IconManagerShadowDepth;
1296
	win->icon->w_height = win->icon->height + Scr->IconFont.height +
1297
	                      2 * (Scr->IconManagerShadowDepth + ICON_MGR_IBORDER);
1298
1299
	XResizeWindow(dpy, win->icon->w, win->icon->w_width,
1300
	              win->icon->w_height);
1301
	if(win->icon->bm_w) {
1302
		XRectangle rect;
1303
1304
		XMoveWindow(dpy, win->icon->bm_w, x, 0);
1305
		XMapWindow(dpy, win->icon->bm_w);
1306
		if(win->icon->image && win->icon->image->mask) {
1307
			XShapeCombineMask(dpy, win->icon->bm_w, ShapeBounding, 0, 0,
1308
			                  win->icon->image->mask, ShapeSet);
1309
			XShapeCombineMask(dpy, win->icon->w, ShapeBounding, x, 0,
1310
			                  win->icon->image->mask, ShapeSet);
1311
		}
1312
		else if(win->icon->has_title) {
1313
			rect.x      = x;
1314
			rect.y      = 0;
1315
			rect.width  = win->icon->width;
1316
			rect.height = win->icon->height;
1317
			XShapeCombineRectangles(dpy, win->icon->w, ShapeBounding,
1318
			                        0, 0, &rect, 1, ShapeSet, 0);
1319
		}
1320
		if(win->icon->has_title) {
1321
			if(Scr->ShrinkIconTitles && win->icon->title_shrunk) {
1322
				rect.x      = x;
1323
				rect.y      = win->icon->height;
1324
				rect.width  = win->icon->width;
1325
				rect.height = win->icon->w_height - win->icon->height;
1326
			}
1327
			else {
1328
				rect.x      = 0;
1329
				rect.y      = win->icon->height;
1330
				rect.width  = win->icon->w_width;
1331
				rect.height = win->icon->w_height - win->icon->height;
1332
			}
1333
			XShapeCombineRectangles(dpy,  win->icon->w, ShapeBounding, 0,
1334
			                        0, &rect, 1, ShapeUnion, 0);
1335
		}
1336
	}
1337
	if(Scr->ShrinkIconTitles &&
1338
	                win->icon->title_shrunk &&
1339
	                win->icon_on && (visible(win))) {
1340
		IconDown(win);
1341
		IconUp(win);
1342
	}
1343
	if(win->isicon) {
1344
		XClearArea(dpy, win->icon->w, 0, 0, 0, 0, True);
1345
	}
518.1.12 by Matthew Fuller
De-ref these gotos; it's only one line and a return, so it's more
1346
518.1.10 by Matthew Fuller
Move RedoIcon*() into icons.c.
1347
	WMapUpdateIconName(win);
1348
}
518.1.20 by Matthew Fuller
Reorder and sectionalize icons.s to related functions are grouped
1349
1350
1351
1352
1353
/*
1354
 ****************************************************************
1355
 *
1356
 * Misc internal utils.
1357
 *
1358
 ****************************************************************
1359
 */
1360
1361
1362
/*
1363
 * What it says on the tin.
1364
 */
1365
static int
1366
roundUp(int v, int multiple)
1367
{
1368
	return ((v + multiple - 1) / multiple) * multiple;
1369
}
1370
1371
1372
/*
1373
 * Find the image set in Icons{} for a TwmWindow if possible.  Return the
1374
 * image, record its provenance inside *icon, and pass back what pattern
1375
 * it matched in **pattern.
1376
 */
1377
static Image *
1378
LookupIconNameOrClass(TwmWindow *tmp_win, Icon *icon, char **pattern)
1379
{
1380
	char *icon_name = NULL;
1381
	Image *image;
1382
	Matchtype matched = match_none;
1383
1384
	icon_name = LookInNameList(Scr->IconNames, tmp_win->icon_name);
1385
	if(icon_name != NULL) {
1386
		*pattern = LookPatternInNameList(Scr->IconNames, tmp_win->icon_name);
1387
		matched = match_list;
1388
	}
1389
1390
	if(matched == match_none) {
563.1.4 by Matthew Fuller
Mechanically translate all these full_name references to name.
1391
		icon_name = LookInNameList(Scr->IconNames, tmp_win->name);
518.1.20 by Matthew Fuller
Reorder and sectionalize icons.s to related functions are grouped
1392
		if(icon_name != NULL) {
563.1.4 by Matthew Fuller
Mechanically translate all these full_name references to name.
1393
			*pattern = LookPatternInNameList(Scr->IconNames, tmp_win->name);
518.1.20 by Matthew Fuller
Reorder and sectionalize icons.s to related functions are grouped
1394
			matched = match_list;
1395
		}
1396
	}
1397
1398
	if(matched == match_none) {
563.1.4 by Matthew Fuller
Mechanically translate all these full_name references to name.
1399
		icon_name = LookInList(Scr->IconNames, tmp_win->name, &tmp_win->class);
518.1.20 by Matthew Fuller
Reorder and sectionalize icons.s to related functions are grouped
1400
		if(icon_name != NULL) {
563.1.4 by Matthew Fuller
Mechanically translate all these full_name references to name.
1401
			*pattern = LookPatternInList(Scr->IconNames, tmp_win->name,
518.1.20 by Matthew Fuller
Reorder and sectionalize icons.s to related functions are grouped
1402
			                             &tmp_win->class);
1403
			matched = match_list;
1404
		}
1405
	}
1406
1407
	if((image  = GetImage(icon_name, icon->iconc)) != NULL) {
1408
		icon->match  = matched;
1409
		icon->image  = image;
1410
		icon->width  = image->width;
1411
		icon->height = image->height;
1412
		tmp_win->forced = true;
1413
	}
1414
	else {
1415
		icon->match = match_none;
1416
		*pattern = NULL;
1417
	}
1418
1419
	return image;
1420
}