#include #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; }