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
25 #include "libs/fvwmlib.h"
26 #include "libs/wild.h"
29 #include "windowlist.h"
32 extern GtkWidget
*current
;
33 extern GHashTable
*window_list_entries
;
34 extern long current_desk
;
38 window_list_item (window_list_entry
*wle
, window_list_options
*opts
)
41 char desk
[10], cmd
[200], geo
[200];
43 /* support two ways for now: window context (new) and window id param (old) */
44 g_snprintf (cmd
, sizeof (cmd
), "WindowId %#lx %s %#lx",
46 opts
->function
? opts
->function
: "WindowListFunc",
48 g_snprintf(desk
, sizeof (desk
), "%d", wle
->desk
);
49 g_snprintf (geo
, sizeof (geo
), " %s%s:%dx%d%s%d%s%d%s",
50 wle
->iconified
? "(" : "",
51 wle
->sticky
? "*" : desk
,
52 wle
->width
, wle
->height
,
53 (wle
->x
>= 0) ? "+" : "", wle
->x
,
54 (wle
->y
>= 0) ? "+" : "", wle
->y
,
55 wle
->iconified
? ")" : "");
57 argv
[0] = (opts
->use_icon_name
? wle
->icon_name
: wle
->name
);
59 argv
[2] = ((opts
->no_mini_icon
|| !wle
->mini_icon
) ? "" : wle
->mini_icon
);
66 window_list (int argc
, char **argv
)
69 window_list_options
*opts
;
72 g_return_if_fail (argc
>= 1);
74 item
= find_or_create_menu (argv
[0]);
75 opts
= (window_list_options
*) safemalloc (sizeof (window_list_options
));
76 memset (opts
, '\0', sizeof (window_list_options
));
78 for (i
= 1; i
< argc
; i
++)
80 if (strcasecmp (argv
[i
], "Title") == 0)
90 if (strcmp (argv
[i
], "") != 0)
92 opts
->title
= safestrdup (argv
[i
]);
99 free (opts
->title_icon
);
100 opts
->title_icon
= NULL
;
103 if (strcmp (argv
[i
], "") != 0)
105 opts
->title_icon
= safestrdup (argv
[i
]);
110 if (opts
->right_title
)
112 free (opts
->right_title
);
113 opts
->right_title
= NULL
;
116 if (strcmp (argv
[i
], "") != 0)
118 opts
->right_title
= safestrdup (argv
[i
]);
122 else if (strcasecmp (argv
[i
], "Function") == 0)
128 free (opts
->function
);
130 opts
->function
= safestrdup (argv
[++i
]);
133 else if (strcasecmp (argv
[i
], "NoDeskSort") == 0)
135 opts
->sorting
|= NO_DESK_SORT
;
137 else if (strcasecmp (argv
[i
], "Alphabetic") == 0)
139 opts
->sorting
|= SORT_ALPHABETIC
;
141 else if (strcasecmp (argv
[i
], "NoGeometry") == 0)
143 opts
->no_geometry
= 1;
145 else if (strcasecmp (argv
[i
], "Desk") == 0)
150 opts
->desk
= atoi (argv
[++i
]);
151 opts
->sorting
|= NO_DESK_SORT
;
154 else if (strcasecmp (argv
[i
], "CurrentDesk") == 0)
157 opts
->current_desk
= 1;
158 opts
->sorting
|= NO_DESK_SORT
;
160 else if (strcasecmp (argv
[i
], "UseIconName") == 0)
162 opts
->use_icon_name
= 1;
164 else if (strcasecmp (argv
[i
], "NoMiniIcon") == 0)
166 opts
->no_mini_icon
= 1;
168 else if (strcasecmp (argv
[i
], "Icons") == 0)
170 opts
->omit_iconified
= 0;
172 else if (strcasecmp (argv
[i
], "NoIcons") == 0)
174 opts
->omit_iconified
= 1;
176 else if (strcasecmp (argv
[i
], "OnlyIcons") == 0)
178 opts
->omit_iconified
= 0;
179 opts
->omit_sticky
= 1;
180 opts
->omit_normal
= 1;
182 else if (strcasecmp (argv
[i
], "Sticky") == 0)
184 opts
->omit_sticky
= 0;
186 else if (strcasecmp (argv
[i
], "NoSticky") == 0)
188 opts
->omit_sticky
= 1;
190 else if (strcasecmp (argv
[i
], "OnlySticky") == 0)
192 opts
->omit_sticky
= 0;
193 opts
->omit_iconified
= 1;
194 opts
->omit_normal
= 1;
196 else if (strcasecmp (argv
[i
], "Normal") == 0)
198 opts
->omit_normal
= 0;
200 else if (strcasecmp (argv
[i
], "NoNormal") == 0)
202 opts
->omit_normal
= 1;
204 else if (strcasecmp (argv
[i
], "OnlyNormal") == 0)
206 opts
->omit_normal
= 0;
207 opts
->omit_iconified
= 1;
208 opts
->omit_sticky
= 1;
214 free (opts
->pattern
);
216 opts
->pattern
= safestrdup (argv
[i
]);
220 gtk_object_set_data (GTK_OBJECT (item
), "window_list", opts
);
225 lookup_window_list_entry (unsigned long w
)
227 window_list_entry
*wle
;
229 wle
= g_hash_table_lookup (window_list_entries
, &w
);
232 wle
= (window_list_entry
*) malloc (sizeof (window_list_entry
));
235 wle
->icon_name
= NULL
;
236 wle
->mini_icon
= NULL
;
247 g_hash_table_insert (window_list_entries
, &(wle
->w
), wle
);
253 static window_list_entry
**unsorted_window_list
= NULL
;
254 static int unsorted_window_list_entries
= 0;
257 append_unsorted (gpointer key
, gpointer value
, gpointer data
)
259 window_list_entry
*wle
= (window_list_entry
*) value
;
260 window_list_options
*opts
= (window_list_options
*) data
;
263 (opts
->one_desk
&& (opts
->desk
!= wle
->desk
)) ||
264 (opts
->current_desk
&& (current_desk
!= wle
->desk
)) ||
265 (opts
->omit_iconified
&& wle
->iconified
) ||
266 (opts
->omit_sticky
&& wle
->sticky
) ||
267 (opts
->omit_normal
&& !wle
->iconified
&& !wle
->sticky
) ||
269 !matchWildcards (opts
->pattern
, wle
->icon_name
) &&
270 !matchWildcards (opts
->pattern
, wle
->name
))) )
272 unsorted_window_list
[unsorted_window_list_entries
++] = wle
;
277 compare_desk (const window_list_entry
**u1
, const window_list_entry
**u2
)
279 int r
= (*u1
)->desk
- (*u2
)->desk
;
280 return ((r
!= 0) ? r
: (long) u1
- (long) u2
);
284 compare_name (const window_list_entry
**u1
, const window_list_entry
**u2
)
286 return strcasecmp((*u1
)->name
, (*u2
)->name
);
290 compare_icon_name (const window_list_entry
**u1
, const window_list_entry
**u2
)
292 return strcasecmp((*u1
)->icon_name
, (*u2
)->icon_name
);
296 construct_window_list (void)
298 window_list_options
*opts
;
301 unsorted_window_list
= (window_list_entry
**)
302 realloc (unsorted_window_list
,
303 g_hash_table_size (window_list_entries
) *
304 sizeof (window_list_entry
*));
306 unsorted_window_list_entries
= 0;
308 opts
= (window_list_options
*)
309 gtk_object_get_data (GTK_OBJECT (current
), "window_list");
311 g_hash_table_foreach (window_list_entries
, append_unsorted
, opts
);
313 if (opts
->sorting
& SORT_ALPHABETIC
)
315 if (opts
->use_icon_name
)
317 qsort (unsorted_window_list
, unsorted_window_list_entries
,
318 sizeof(window_list_entry
*),
319 (int(*)(const void*,const void*))compare_icon_name
);
323 qsort (unsorted_window_list
, unsorted_window_list_entries
,
324 sizeof(window_list_entry
*),
325 (int(*)(const void*,const void*))compare_name
);
328 if (!(opts
->sorting
& NO_DESK_SORT
))
330 qsort (unsorted_window_list
, unsorted_window_list_entries
,
331 sizeof(window_list_entry
*),
332 (int(*)(const void*,const void*))compare_desk
);
335 if (opts
->title
|| opts
->right_title
)
338 argv
[0] = opts
->title
;
339 argv
[1] = opts
->title_icon
;
340 argv
[2] = opts
->right_title
;
341 menu_title (3, argv
);
342 menu_separator (0, NULL
);
345 for (i
= 0; i
< unsorted_window_list_entries
; i
++)
347 if (!(opts
->sorting
& NO_DESK_SORT
) &&
349 (unsorted_window_list
[i
-1]->desk
!= unsorted_window_list
[i
]->desk
))
351 menu_separator (0, NULL
);
353 window_list_item (unsorted_window_list
[i
], opts
);