#include "FvwmIconMan.h"
static HashTab hash_tab;
void print_stringlist (StringList *list)
{
StringEl *p;
char *s;
printf ("\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;
}
ConsoleDebug ("\t%s = %s\n", s, p->string);
}
}
void add_to_stringlist (StringList *list, char *s)
{
StringEl *new;
NameType type;
char *pat;
ConsoleDebug ("In add_to_stringlist: %s\n", s);
pat = strchr (s, '=');
if (pat) {
*pat++ = '\0';
if (!strcmp (s, "icon"))
type = ICON_NAME;
else if (!strcmp (s, "title"))
type = TITLE_NAME;
else if (!strcmp (s, "resource"))
type = RESOURCE_NAME;
else if (!strcmp (s, "class"))
type = CLASS_NAME;
else {
ConsoleMessage ("Bad element in show/dontshow list: %s\n", s);
return;
}
}
else {
pat = s;
type = ALL_NAME;
}
ConsoleDebug ("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 ("Exiting add_to_stringlist\n");
}
static int matches_string (NameType type, char *pattern, char *tname,
char *iname, char *rname, char *cname)
{
int ans = 0;
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);
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 ("In iconmanager_show: %s:%s : %s %s\n", tname, iname,
rname, cname);
ConsoleDebug ("dontshow:\n");
print_stringlist (&man->dontshow);
ConsoleDebug ("show:\n");
print_stringlist (&man->show);
#endif /*PRINT_DEBUG*/
for (string = man->dontshow.list; string; string = string->next) {
ConsoleDebug ("Matching: %s\n", string->string);
if (matches_string (string->type, string->string, tname, iname,
rname, cname)) {
ConsoleDebug ("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 ("Matching: %s\n", string->string);
if (matches_string (string->type, string->string, tname, iname,
rname, cname)) {
ConsoleDebug ("Show\n");
in_showlist = 1;
break;
}
}
}
}
ConsoleDebug ("returning: %d %d %d\n", in_dontshowlist,
in_showlist, !in_dontshowlist && in_showlist);
return (!in_dontshowlist && in_showlist);
}
void print_iconlist (void)
{
#ifdef PRINT_DEBUG
WinData *p;
int i;
ConsoleDebug ("Global Icon List:\n");
for (i = 0; i < globals.num_managers; i++) {
ConsoleDebug ("Manager: %d\n", i);
ConsoleDebug ("Size: %d\n", globals.managers[i].icon_list.n);
for (p = globals.managers[i].icon_list.head; p; p = p->icon_next) {
ConsoleDebug ("\ttitlename: %s\n", p->titlename);
ConsoleDebug ("\ticonname: %s\n", p->iconname);
ConsoleDebug ("\tresname: %s\n", p->resname);
ConsoleDebug ("\tclassname: %s\n", p->classname);
if (p->sticky)
ConsoleDebug ("\tSticky\n");
else
ConsoleDebug ("\tNot sticky\n");
ConsoleDebug ("\twhere: %d (%d, %d)\n", p->desknum, p->x, p->y);
if (p->iconified)
ConsoleDebug ("\tIconified\n");
else
ConsoleDebug ("\tUniconified\n");
ConsoleDebug ("\tID: %d\n", p->app_id);
ConsoleDebug ("\n");
}
}
#endif
}
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->name = NULL;
new->manager = NULL;
new->win_prev = new->win_next = NULL;
new->icon_prev = new->icon_next = NULL;
new->iconified = 0;
new->in_iconlist = 0;
new->complete = 0;
new->focus = 0;
new->sticky = 0;
new->winlistskip = 0;
return new;
}
void free_windata (WinData *p)
{
Free (p->resname);
Free (p->classname);
Free (p->iconname);
Free (p);
}
int set_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);
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) {
win->manager = man;
if (win->manager->use_titlename)
win->name = &win->titlename;
else
win->name = &win->iconname;
return 1;
}
else {
return 0;
}
}
}
return 0;
}
int check_win_complete (WinData *p)
{
if (p->complete)
return 1;
ConsoleDebug ("Checking completeness:\n");
ConsoleDebug ("\ttitlename: %s\n", p->titlename);
ConsoleDebug ("\ticonname: %s\n", p->iconname);
ConsoleDebug ("\tres: %s\n", p->resname);
ConsoleDebug ("\tclass: %s\n", p->classname);
ConsoleDebug ("\t(x, y): (%d, %d)\n", p->x, p->y);
ConsoleDebug ("\tapp_id: 0x%x %d\n", p->app_id, p->app_id_set);
ConsoleDebug ("\tdesknum: %d\n", p->desknum);
ConsoleDebug ("\tmanager: 0x%x\n", (int)p->manager);
if (p->geometry_set &&
p->resname &&
p->classname &&
p->iconname &&
p->titlename &&
p->manager &&
p->app_id_set) {
p->complete = 1;
ConsoleDebug ("\tcomplete: 1\n\n");
return 1;
}
ConsoleDebug ("\tcomplete: 0\n\n");
return 0;
}
void init_winlists (void)
{
int i;
for (i = 0; i < 256; i++) {
hash_tab[i].n = 0;
hash_tab[i].head = NULL;
hash_tab[i].tail = NULL;
}
}
static void insert_before (WinData *win, WinData *p)
{
WinList *list;
ConsoleDebug ("in insert_before\n");
assert (win->manager);
list = &win->manager->icon_list;
if (p) {
/* insert win before p */
win->icon_next = p;
win->icon_prev = p->icon_prev;
if (p->icon_prev)
p->icon_prev->icon_next = win;
else
list->head = win;
p->icon_prev = win;
}
else {
/* put win at end of list */
win->icon_next = NULL;
win->icon_prev = list->tail;
if (list->tail)
list->tail->icon_next = win;
else
list->head = win;
list->tail = win;
}
ConsoleDebug ("leaving insert_before\n");
}
static WinData *find_win_insert (WinData *win)
{
WinList *list;
WinData *p;
ConsoleDebug ("in find_win_insert\n");
assert (win->manager);
assert (win->name);
list = &win->manager->icon_list;
if (win->manager->sort) {
for (p = list->head;
p && strcmp (*win->name, *p->name) > 0;
p = p->icon_next)
;
}
else {
p = NULL;
}
ConsoleDebug ("leaving find_win_insert\n");
return p;
}
int move_win_iconlist (WinData *win)
{
WinData *next;
int changed = 0;
ConsoleDebug ("in move_win_iconlist\n");
if (!win->complete) {
ConsoleMessage ("Internal error in move_win_iconlist\n");
ShutMeDown (1);
}
if (win->in_iconlist) {
next = win->icon_next;
delete_win_iconlist (win, win->manager);
}
else {
changed = 1;
next = NULL;
}
insert_win_iconlist (win);
changed = (win->icon_next != next);
ConsoleDebug ("leaving move_win_iconlist: %d\n", changed);
return changed;
}
void insert_win_iconlist (WinData *win)
{
WinData *p;
ConsoleDebug ("in insert_win_iconlist\n");
if (!win->complete) {
ConsoleMessage ("Internal error in insert_win_iconlist\n");
ShutMeDown (1);
}
assert (win->manager);
if (win->in_iconlist) {
ConsoleMessage ("Internal error in insert_win_iconlist: already there\n");
return;
}
p = find_win_insert (win);
insert_before (win, p);
win->in_iconlist = 1;
win->manager->icon_list.n++;
ConsoleDebug ("leaving insert_win_iconlist\n");
}
void delete_win_iconlist (WinData *win, WinManager *man)
{
WinList *list;
ConsoleDebug ("In delete_win_iconlist\n");
assert (man);
if (win->in_iconlist) {
list = &man->icon_list;
if (win->icon_prev)
win->icon_prev->icon_next = win->icon_next;
else
list->head = win->icon_next;
if (win->icon_next)
win->icon_next->icon_prev = win->icon_prev;
else
list->tail = win->icon_prev;
list->n--;
win->in_iconlist = 0;
}
ConsoleDebug ("Exiting delete_win_iconlist\n");
}
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 < 256; i++) {
for (p = hash_tab[i].head; p; p = p->win_next)
func (p);
}
}
syntax highlighted by Code2HTML, v. 0.9.1