Fix move command parsing.
[fvwm.git] / modules / FvwmGtk / windowlist.c
blob097d27bf31a311ede63f690138675ec3c9bbe397
1 /* -*-c-*- */
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
17 #include "config.h"
19 #include <stdio.h>
20 #include <X11/Xlib.h>
22 #include <glib.h>
23 #include <gtk/gtk.h>
25 #include "libs/fvwmlib.h"
26 #include "libs/wild.h"
28 #include "menu.h"
29 #include "windowlist.h"
32 extern GtkWidget *current;
33 extern GHashTable *window_list_entries;
34 extern long current_desk;
37 static void
38 window_list_item (window_list_entry *wle, window_list_options *opts)
40 char *argv[4];
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",
45 wle->w,
46 opts->function ? opts->function : "WindowListFunc",
47 wle->w);
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);
58 argv[1] = cmd;
59 argv[2] = ((opts->no_mini_icon || !wle->mini_icon) ? "" : wle->mini_icon);
60 argv[3] = geo;
62 menu_item (4, argv);
65 void
66 window_list (int argc, char **argv)
68 GtkWidget *item;
69 window_list_options *opts;
70 int i;
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)
82 if (i+1 < argc)
84 if (opts->title)
86 free (opts->title);
87 opts->title = NULL;
89 i++;
90 if (strcmp (argv[i], "") != 0)
92 opts->title = safestrdup (argv[i]);
95 if (i+1 < argc)
97 if (opts->title_icon)
99 free (opts->title_icon);
100 opts->title_icon = NULL;
102 i++;
103 if (strcmp (argv[i], "") != 0)
105 opts->title_icon = safestrdup (argv[i]);
108 if (i+1 < argc)
110 if (opts->right_title)
112 free (opts->right_title);
113 opts->right_title = NULL;
115 i++;
116 if (strcmp (argv[i], "") != 0)
118 opts->right_title = safestrdup (argv[i]);
122 else if (strcasecmp (argv[i], "Function") == 0)
124 if (i+1 < argc)
126 if (opts->function)
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)
147 if (i+1 < argc)
149 opts->one_desk = 1;
150 opts->desk = atoi (argv[++i]);
151 opts->sorting |= NO_DESK_SORT;
154 else if (strcasecmp (argv[i], "CurrentDesk") == 0)
156 opts->one_desk = 1;
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;
210 else
212 if (opts->pattern)
214 free (opts->pattern);
216 opts->pattern = safestrdup (argv[i]);
220 gtk_object_set_data (GTK_OBJECT (item), "window_list", opts);
224 window_list_entry *
225 lookup_window_list_entry (unsigned long w)
227 window_list_entry *wle;
229 wle = g_hash_table_lookup (window_list_entries, &w);
230 if (!wle)
232 wle = (window_list_entry *) malloc (sizeof (window_list_entry));
233 wle->w = w;
234 wle->name = NULL;
235 wle->icon_name = NULL;
236 wle->mini_icon = NULL;
237 wle->desk = 0;
238 wle->layer = 0;
239 wle->iconified = 0;
240 wle->sticky = 0;
241 wle->skip = 0;
242 wle->x = 0;
243 wle->y = 0;
244 wle->width = 0;
245 wle->height = 0;
247 g_hash_table_insert (window_list_entries, &(wle->w), wle);
250 return wle;
253 static window_list_entry **unsorted_window_list = NULL;
254 static int unsorted_window_list_entries = 0;
256 void
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;
262 if ( !(wle->skip ||
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) ||
268 (opts->pattern &&
269 !matchWildcards (opts->pattern, wle->icon_name) &&
270 !matchWildcards (opts->pattern, wle->name))) )
272 unsorted_window_list[unsorted_window_list_entries++] = wle;
276 static int
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);
283 static int
284 compare_name (const window_list_entry **u1, const window_list_entry **u2)
286 return strcasecmp((*u1)->name, (*u2)->name);
289 static int
290 compare_icon_name (const window_list_entry **u1, const window_list_entry **u2)
292 return strcasecmp((*u1)->icon_name, (*u2)->icon_name);
295 void
296 construct_window_list (void)
298 window_list_options *opts;
299 int i;
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);
321 else
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)
337 char *argv[3];
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) &&
348 (i > 0) &&
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);