2 /* This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "libs/wild.h"
21 #include "FvwmIconMan.h"
23 #define HASHTAB_SIZE 257
25 typedef WinList HashTab
[HASHTAB_SIZE
];
26 static HashTab hash_tab
;
28 void print_stringlist (StringList
*list
)
33 ConsoleDebug (WINLIST
, "\tmask = 0x%x\n", list
->mask
);
34 for (p
= list
->list
; p
; p
= p
->next
) {
59 ConsoleDebug (WINLIST
, "\t%s = %s\n", s
, p
->string
);
63 void add_to_stringlist (StringList
*list
, char *s
)
69 ConsoleDebug (WINLIST
, "In add_to_stringlist: %s\n", s
);
71 pat
= strchr (s
, '=');
74 if (!strcasecmp (s
, "icon"))
76 else if (!strcasecmp (s
, "title"))
78 else if (!strcasecmp (s
, "resource"))
80 else if (!strcasecmp (s
, "class"))
83 ConsoleMessage ("Bad element in show/dontshow list: %s\n", s
);
92 ConsoleDebug (WINLIST
, "add_to_stringlist: %s %s\n",
93 type
== ALL_NAME
? "all" : s
, pat
);
95 new = (StringEl
*)safemalloc (sizeof (StringEl
));
96 new->string
= (char *)safemalloc ((strlen (pat
) + 1) * sizeof (char));
99 strcpy (new->string
, pat
);
100 new->next
= list
->list
;
107 ConsoleDebug (WINLIST
, "Exiting add_to_stringlist\n");
110 static int matches_string (NameType type
, char *pattern
, char *tname
,
111 char *iname
, char *rname
, char *cname
)
115 ConsoleDebug (WINLIST
, "matches_string: type: 0x%x pattern: %s\n",
117 ConsoleDebug (WINLIST
, "\tstrings: %s:%s %s:%s\n", tname
, iname
,
120 if (tname
&& (type
== ALL_NAME
|| type
== TITLE_NAME
)) {
121 ans
|= matchWildcards (pattern
, tname
);
123 if (iname
&& (type
== ALL_NAME
|| type
== ICON_NAME
)) {
124 ans
|= matchWildcards (pattern
, iname
);
126 if (rname
&& (type
== ALL_NAME
|| type
== RESOURCE_NAME
)) {
127 ans
|= matchWildcards (pattern
, rname
);
129 if (cname
&& (type
== ALL_NAME
|| type
== CLASS_NAME
)) {
130 ans
|= matchWildcards (pattern
, cname
);
133 ConsoleDebug (WINLIST
, "\tmatches_string: %d\n", ans
);
137 int check_resolution(WinManager
*manager
, WinData
*win
)
145 if (IS_ICONIFIED(win
) && !IS_ICON_SUPPRESSED(win
))
153 g
.width
= win
->width
;
154 g
.height
= win
->height
;
156 switch (manager
->res
) {
161 case NO_SHOW_DESKTOP
:
163 /* fall through to next case */
165 if (IS_STICKY_ACROSS_PAGES(win
) || win
->desknum
== globals
.desknum
)
171 /* fall through to next case */
173 if (IS_STICKY_ACROSS_PAGES(win
)) {
175 } else if (win
->desknum
== globals
.desknum
) {
176 /* win and screen intersect if they are not disjoint in x and y */
177 flag
= fvwmrect_do_rectangles_intersect(&g
, &manager
->managed_g
);
183 /* fall through to next case */
185 if (win
->desknum
== globals
.desknum
) {
186 /* win and screen intersect if they are not disjoint in x and y */
187 flag
= fvwmrect_do_rectangles_intersect(&g
, &manager
->managed_g
);
196 static int iconmanager_show (WinManager
*man
, char *tname
, char *iname
,
197 char *rname
, char *cname
)
200 int in_showlist
= 0, in_dontshowlist
= 0;
204 #ifdef FVWM_DEBUG_MSGS
205 ConsoleDebug (WINLIST
, "In iconmanager_show: %s:%s : %s %s\n", tname
, iname
,
207 ConsoleDebug (WINLIST
, "dontshow:\n");
208 print_stringlist (&man
->dontshow
);
209 ConsoleDebug (WINLIST
, "show:\n");
210 print_stringlist (&man
->show
);
211 #endif /* FVWM_DEBUG_MSGS */
213 for (string
= man
->dontshow
.list
; string
; string
= string
->next
) {
214 ConsoleDebug (WINLIST
, "Matching: %s\n", string
->string
);
215 if (matches_string (string
->type
, string
->string
, tname
, iname
,
217 ConsoleDebug (WINLIST
, "Dont show\n");
223 if (!in_dontshowlist
) {
224 if (man
->show
.list
== NULL
) {
228 for (string
= man
->show
.list
; string
; string
= string
->next
) {
229 ConsoleDebug (WINLIST
, "Matching: %s\n", string
->string
);
230 if (matches_string (string
->type
, string
->string
, tname
, iname
,
232 ConsoleDebug (WINLIST
, "Show\n");
240 ConsoleDebug (WINLIST
, "returning: %d %d %d\n", in_dontshowlist
,
241 in_showlist
, !in_dontshowlist
&& in_showlist
);
243 return (!in_dontshowlist
&& in_showlist
);
246 WinData
*new_windata (void)
248 WinData
*new = (WinData
*)safemalloc (sizeof (WinData
));
250 memset(new, 0, sizeof(WinData
));
251 new->desknum
= ULONG_MAX
;
254 new->app_id
= ULONG_MAX
;
259 void free_windata (WinData
*p
)
261 if (globals
.select_win
== p
) {
262 ConsoleMessage ("Internal error in free_windata\n");
263 globals
.select_win
= NULL
;
271 Free (p
->display_string
);
276 /* This ALWAYS gets called when one of the name strings changes */
278 WinManager
*figure_win_manager (WinData
*win
, Uchar name_mask
)
281 char *tname
= win
->titlename
;
282 char *iname
= win
->iconname
;
283 char *rname
= win
->resname
;
284 char *cname
= win
->classname
;
287 assert (tname
|| iname
|| rname
|| cname
);
288 ConsoleDebug (WINLIST
, "set_win_manager: %s %s %s %s\n", tname
, iname
, rname
, cname
);
290 for (i
= 0, man
= &globals
.managers
[0]; i
< globals
.num_managers
;
292 if (iconmanager_show (man
, tname
, iname
, rname
, cname
) &&
293 check_resolution(man
, win
)) {
294 if (man
!= win
->manager
) {
295 assert (man
->magic
== 0x12344321);
301 /* No manager wants this window */
305 int check_win_complete (WinData
*p
)
310 ConsoleDebug (WINLIST
, "Checking completeness:\n");
311 ConsoleDebug (WINLIST
, "\ttitlename: %s\n",
312 (p
->titlename
? p
->titlename
: "No Title name"));
313 ConsoleDebug (WINLIST
, "\ticonname: %s\n",
314 (p
->iconname
? p
->iconname
: "No Icon name"));
315 ConsoleDebug (WINLIST
, "\tres: %s\n",
316 (p
->resname
? p
->resname
: "No p->resname"));
317 ConsoleDebug (WINLIST
, "\tclass: %s\n",
318 (p
->classname
? p
->classname
: "No p->classname"));
319 ConsoleDebug (WINLIST
, "\tdisplaystring: %s\n",
320 (p
->display_string
? p
->display_string
:
321 "No p->display_string"));
322 ConsoleDebug (WINLIST
, "\t(x, y): (%ld, %ld)\n", p
->x
, p
->y
);
323 ConsoleDebug (WINLIST
, "\tapp_id: 0x%lx %d\n", p
->app_id
, p
->app_id_set
);
324 ConsoleDebug (WINLIST
, "\tdesknum: %ld\n", p
->desknum
);
325 ConsoleDebug (WINLIST
, "\tmanager: 0x%lx\n", (unsigned long)p
->manager
);
327 if (p
->geometry_set
&&
334 ConsoleDebug (WINLIST
, "\tcomplete: 1\n\n");
338 ConsoleDebug (WINLIST
, "\tcomplete: 0\n\n");
342 void init_winlists (void)
345 for (i
= 0; i
< HASHTAB_SIZE
; i
++) {
347 hash_tab
[i
].head
= NULL
;
348 hash_tab
[i
].tail
= NULL
;
352 void delete_win_hashtab (WinData
*win
)
357 entry
= win
->app_id
& 0xff;
358 list
= &hash_tab
[entry
];
361 win
->win_prev
->win_next
= win
->win_next
;
363 list
->head
= win
->win_next
;
365 win
->win_next
->win_prev
= win
->win_prev
;
367 list
->tail
= win
->win_prev
;
371 void insert_win_hashtab (WinData
*win
)
377 entry
= win
->app_id
& 0xff;
378 list
= &hash_tab
[entry
];
380 for (p
= list
->head
; p
&& win
->app_id
> p
->app_id
;
384 /* insert win before p */
386 win
->win_prev
= p
->win_prev
;
388 p
->win_prev
->win_next
= win
;
394 /* put win at end of list */
395 win
->win_next
= NULL
;
396 win
->win_prev
= list
->tail
;
398 list
->tail
->win_next
= win
;
406 WinData
*find_win_hashtab (Ulong id
)
409 int entry
= id
& 0xff;
412 list
= &hash_tab
[entry
];
414 for (p
= list
->head
; p
&& p
->app_id
!= id
; p
= p
->win_next
);
419 void walk_hashtab (void (*func
)(void *))
424 for (i
= 0; i
< HASHTAB_SIZE
; i
++) {
425 for (p
= hash_tab
[i
].head
; p
; p
= p
->win_next
)
430 int accumulate_walk_hashtab (int (*func
)(void *))
435 for (i
= 0; i
< HASHTAB_SIZE
; i
++) {
436 for (p
= hash_tab
[i
].head
; p
; p
= p
->win_next
)