xenocara/app/fvwm/modules/FvwmIconMan/winlist.c

379 lines
8.5 KiB
C
Raw Normal View History

#include <limits.h>
#include "FvwmIconMan.h"
static char const rcsid[] =
"$Id: winlist.c,v 1.1.1.1 2006/11/26 10:53:50 matthieu Exp $";
#define HASHTAB_SIZE 257
typedef WinList HashTab[HASHTAB_SIZE];
static HashTab hash_tab;
void print_stringlist (StringList *list)
{
StringEl *p;
char *s;
ConsoleDebug (WINLIST, "\tmask = 0x%x\n", list->mask);
for (p = list->list; p; p = p->next) {
switch (p->type) {
case ALL_NAME:
s = "all";
break;
case TITLE_NAME:
s = "title";
break;
case ICON_NAME:
s = "icon";
break;
case RESOURCE_NAME:
s = "resource";
break;
case CLASS_NAME:
s = "class";
break;
default:
s = "unknown type";
}
ConsoleDebug (WINLIST, "\t%s = %s\n", s, p->string);
}
}
void add_to_stringlist (StringList *list, char *s)
{
StringEl *new;
NameType type;
char *pat;
ConsoleDebug (WINLIST, "In add_to_stringlist: %s\n", s);
pat = strchr (s, '=');
if (pat) {
*pat++ = '\0';
if (!strcasecmp (s, "icon"))
type = ICON_NAME;
else if (!strcasecmp (s, "title"))
type = TITLE_NAME;
else if (!strcasecmp (s, "resource"))
type = RESOURCE_NAME;
else if (!strcasecmp (s, "class"))
type = CLASS_NAME;
else {
ConsoleMessage ("Bad element in show/dontshow list: %s\n", s);
return;
}
}
else {
pat = s;
type = ALL_NAME;
}
ConsoleDebug (WINLIST, "add_to_stringlist: %s %s\n",
type == ALL_NAME ? "all" : s, pat);
new = (StringEl *)safemalloc (sizeof (StringEl));
new->string = (char *)safemalloc ((strlen (pat) + 1) * sizeof (char));
new->type = type;
strcpy (new->string, pat);
new->next = list->list;
if (list->list)
list->mask |= type;
else
list->mask = type;
list->list = new;
ConsoleDebug (WINLIST, "Exiting add_to_stringlist\n");
}
static int matches_string (NameType type, char *pattern, char *tname,
char *iname, char *rname, char *cname)
{
int ans = 0;
ConsoleDebug (WINLIST, "matches_string: type: 0x%x pattern: %s\n",
type, pattern);
ConsoleDebug (WINLIST, "\tstrings: %s:%s %s:%s\n", tname, iname,
rname, cname);
if (tname && (type == ALL_NAME || type == TITLE_NAME)) {
ans |= matchWildcards (pattern, tname);
}
if (iname && (type == ALL_NAME || type == ICON_NAME)) {
ans |= matchWildcards (pattern, iname);
}
if (rname && (type == ALL_NAME || type == RESOURCE_NAME)) {
ans |= matchWildcards (pattern, rname);
}
if (cname && (type == ALL_NAME || type == CLASS_NAME)) {
ans |= matchWildcards (pattern, cname);
}
ConsoleDebug (WINLIST, "\tmatches_string: %d\n", ans);
return ans;
}
static int iconmanager_show (WinManager *man, char *tname, char *iname,
char *rname, char *cname)
{
StringEl *string;
int in_showlist = 0, in_dontshowlist = 0;
assert (man);
#ifdef PRINT_DEBUG
ConsoleDebug (WINLIST, "In iconmanager_show: %s:%s : %s %s\n", tname, iname,
rname, cname);
ConsoleDebug (WINLIST, "dontshow:\n");
print_stringlist (&man->dontshow);
ConsoleDebug (WINLIST, "show:\n");
print_stringlist (&man->show);
#endif /*PRINT_DEBUG*/
for (string = man->dontshow.list; string; string = string->next) {
ConsoleDebug (WINLIST, "Matching: %s\n", string->string);
if (matches_string (string->type, string->string, tname, iname,
rname, cname)) {
ConsoleDebug (WINLIST, "Dont show\n");
in_dontshowlist = 1;
break;
}
}
if (!in_dontshowlist) {
if (man->show.list == NULL) {
in_showlist = 1;
}
else {
for (string = man->show.list; string; string = string->next) {
ConsoleDebug (WINLIST, "Matching: %s\n", string->string);
if (matches_string (string->type, string->string, tname, iname,
rname, cname)) {
ConsoleDebug (WINLIST, "Show\n");
in_showlist = 1;
break;
}
}
}
}
ConsoleDebug (WINLIST, "returning: %d %d %d\n", in_dontshowlist,
in_showlist, !in_dontshowlist && in_showlist);
return (!in_dontshowlist && in_showlist);
}
WinData *new_windata (void)
{
WinData *new = (WinData *)safemalloc (sizeof (WinData));
new->desknum = ULONG_MAX;
new->x = ULONG_MAX;
new->y = ULONG_MAX;
new->geometry_set = 0;
new->app_id = ULONG_MAX;
new->app_id_set = 0;
new->resname = NULL;
new->classname = NULL;
new->iconname = NULL;
new->titlename = NULL;
new->display_string = NULL;
new->manager = NULL;
new->win_prev = new->win_next = NULL;
new->iconified = 0;
new->button = NULL;
new->state = 0;
new->complete = 0;
new->fvwm_flags = 0;
#ifdef MINI_ICONS
new->pic.picture = 0;
#endif
return new;
}
void free_windata (WinData *p)
{
if (globals.select_win == p) {
ConsoleMessage ("Internal error in free_windata\n");
globals.select_win = NULL;
abort();
}
Free (p->resname);
Free (p->classname);
Free (p->iconname);
Free (p);
}
/* This ALWAYS gets called when one of the name strings changes */
WinManager *figure_win_manager (WinData *win, Uchar name_mask)
{
int i;
char *tname = win->titlename;
char *iname = win->iconname;
char *rname = win->resname;
char *cname = win->classname;
WinManager *man;
assert (tname || iname || rname || cname);
ConsoleDebug (WINLIST, "set_win_manager: %s %s %s %s\n", tname, iname, rname, cname);
for (i = 0, man = &globals.managers[0]; i < globals.num_managers;
i++, man++) {
if (iconmanager_show (man, tname, iname, rname, cname)) {
if (man != win->manager) {
assert (man->magic == 0x12344321);
}
return man;
}
}
/* No manager wants this window */
return NULL;
}
int check_win_complete (WinData *p)
{
if (p->complete)
return 1;
ConsoleDebug (WINLIST, "Checking completeness:\n");
ConsoleDebug (WINLIST, "\ttitlename: %s\n",
(p->titlename ? p->titlename : "No Title name"));
ConsoleDebug (WINLIST, "\ticonname: %s\n",
(p->iconname ? p->iconname : "No Icon name"));
ConsoleDebug (WINLIST, "\tres: %s\n",
(p->resname ? p->resname : "No p->resname"));
ConsoleDebug (WINLIST, "\tclass: %s\n",
(p->classname ? p->classname : "No p->classname"));
ConsoleDebug (WINLIST, "\tdisplaystring: %s\n",
(p->display_string ? p->display_string :
"No p->display_string"));
ConsoleDebug (WINLIST, "\t(x, y): (%ld, %ld)\n", p->x, p->y);
ConsoleDebug (WINLIST, "\tapp_id: 0x%lx %d\n", p->app_id, p->app_id_set);
ConsoleDebug (WINLIST, "\tdesknum: %ld\n", p->desknum);
ConsoleDebug (WINLIST, "\tmanager: 0x%lx\n", (unsigned long)p->manager);
if (p->geometry_set &&
p->resname &&
p->classname &&
p->iconname &&
p->titlename &&
p->manager &&
p->app_id_set) {
p->complete = 1;
ConsoleDebug (WINLIST, "\tcomplete: 1\n\n");
return 1;
}
ConsoleDebug (WINLIST, "\tcomplete: 0\n\n");
return 0;
}
void init_winlists (void)
{
int i;
for (i = 0; i < HASHTAB_SIZE; i++) {
hash_tab[i].n = 0;
hash_tab[i].head = NULL;
hash_tab[i].tail = NULL;
}
}
void delete_win_hashtab (WinData *win)
{
int entry;
WinList *list;
entry = win->app_id & 0xff;
list = &hash_tab[entry];
if (win->win_prev)
win->win_prev->win_next = win->win_next;
else
list->head = win->win_next;
if (win->win_next)
win->win_next->win_prev = win->win_prev;
else
list->tail = win->win_prev;
list->n--;
}
void insert_win_hashtab (WinData *win)
{
int entry;
WinList *list;
WinData *p;
entry = win->app_id & 0xff;
list = &hash_tab[entry];
for (p = list->head; p && win->app_id > p->app_id;
p = p->win_next);
if (p) {
/* insert win before p */
win->win_next = p;
win->win_prev = p->win_prev;
if (p->win_prev)
p->win_prev->win_next = win;
else
list->head = win;
p->win_prev = win;
}
else {
/* put win at end of list */
win->win_next = NULL;
win->win_prev = list->tail;
if (list->tail)
list->tail->win_next = win;
else
list->head = win;
list->tail = win;
}
list->n++;
}
WinData *find_win_hashtab (Ulong id)
{
WinList *list;
int entry = id & 0xff;
WinData *p;
list = &hash_tab[entry];
for (p = list->head; p && p->app_id != id; p = p->win_next);
return p;
}
void walk_hashtab (void (*func)(void *))
{
int i;
WinData *p;
for (i = 0; i < HASHTAB_SIZE; i++) {
for (p = hash_tab[i].head; p; p = p->win_next)
func (p);
}
}
int accumulate_walk_hashtab (int (*func)(void *))
{
int i, ret = 0;
WinData *p;
for (i = 0; i < HASHTAB_SIZE; i++) {
for (p = hash_tab[i].head; p; p = p->win_next)
ret += func (p);
}
return ret;
}