Add reminder to investigate recursive commands for 2.6
[fvwm.git] / fvwm / modconf.c
blobc70672902d8f9cd8e5b4a90261690c86b69f52c5
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
19 * code for processing module configuration commands
21 * Modification History
23 * Created 09/23/98 by Dan Espen:
25 * - Some of this logic used to reside in "read.c", preceeded by a
26 * comment about whether it belonged there. Time tells.
28 * - Added logic to execute module config commands by passing to the
29 * modules that want "active command pipes".
31 * ********************************************************************
34 #include "config.h"
36 #include <stdio.h>
38 #include "libs/fvwmlib.h"
39 #include "libs/Parse.h"
40 #include "libs/Strings.h"
41 #include "libs/wild.h"
42 #include "fvwm.h"
43 #include "externs.h"
44 #include "cursor.h"
45 #include "functions.h"
46 #include "bindings.h"
47 #include "misc.h"
48 #include "screen.h"
49 #include "module_list.h"
50 #include "module_interface.h"
51 #include "colorset.h"
52 #include "libs/FScreen.h"
54 extern int nColorsets; /* in libs/Colorset.c */
56 /* do not send ColorLimit, it is not used anymore but maybe by non
57 * "official" modules */
58 #define DISABLE_COLORLIMIT_CONFIG_INFO
60 #define MODULE_CONFIG_DELIM ':'
62 struct moduleInfoList
64 char *data;
65 unsigned char alias_len;
66 struct moduleInfoList *next;
69 struct moduleInfoList *modlistroot = NULL;
71 static struct moduleInfoList *AddToModList(char *tline);
72 static void SendConfigToModule(
73 fmodule *module, const struct moduleInfoList *entry, char *match,
74 int match_len);
78 * ModuleConfig handles commands starting with "*".
80 * Each command is added to a list from which modules request playback
81 * thru "sendconfig".
83 * Some modules request that module config commands be sent to them
84 * as the commands are entered. Send to modules that want it.
86 void ModuleConfig(char *action)
88 int end;
89 fmodule_list_itr moditr;
90 fmodule *module;
91 struct moduleInfoList *new_entry;
93 end = strlen(action) - 1;
94 if (action[end] == '\n')
95 action[end] = '\0';
96 /* save for config request */
97 new_entry = AddToModList(action);
98 /* look at all possible pipes */
99 module_list_itr_init(&moditr);
100 while ( (module = module_list_itr_next(&moditr)) != NULL)
102 if (IS_MESSAGE_SELECTED(module, M_SENDCONFIG))
104 /* module wants config cmds */
105 char *name = MOD_NAME(module);
106 if (MOD_ALIAS(module))
108 name = MOD_ALIAS(module);
110 SendConfigToModule(
111 module, new_entry, CatString2("*", name), 0);
115 return;
118 static struct moduleInfoList *AddToModList(char *tline)
120 struct moduleInfoList *t, *prev, *this;
121 char *rline = tline;
122 char *alias_end = skipModuleAliasToken(tline + 1);
124 /* Find end of list */
125 t = modlistroot;
126 prev = NULL;
128 while(t != NULL)
130 prev = t;
131 t = t->next;
134 this = (struct moduleInfoList *)safemalloc(
135 sizeof(struct moduleInfoList));
137 this->alias_len = 0;
138 if (alias_end && alias_end[0] == MODULE_CONFIG_DELIM)
140 /* migo (01-Sep-2000): construct an old-style config line */
141 char *conf_start = alias_end + 1;
142 while (isspace(*conf_start)) conf_start++;
143 *alias_end = '\0';
144 rline = CatString2(tline, conf_start);
145 *alias_end = MODULE_CONFIG_DELIM;
146 this->alias_len = alias_end - tline;
149 this->data = (char *)safemalloc(strlen(rline)+1);
150 strcpy(this->data, rline);
152 this->next = NULL;
153 if(prev == NULL)
155 modlistroot = this;
157 else
159 prev->next = this;
162 return this;
166 * delete from module configuration
168 void CMD_DestroyModuleConfig(F_CMD_ARGS)
170 struct moduleInfoList *current, *next, *prev;
171 char *info; /* info to be deleted - may contain wildcards */
172 char *mi;
173 char *alias_end;
174 int alias_len = 0;
176 while (isspace(*action))
178 action++;
180 alias_end = skipModuleAliasToken(action);
182 if (alias_end && alias_end[0] == MODULE_CONFIG_DELIM)
184 /* migo: construct an old-style config line */
185 char *conf_start = alias_end + 1;
186 while (isspace(*conf_start)) conf_start++;
187 *alias_end = '\0';
188 GetNextToken(conf_start, &conf_start);
189 if (conf_start == NULL)
191 return;
193 info = stripcpy(CatString2(action, conf_start));
194 *alias_end = MODULE_CONFIG_DELIM;
195 /* +1 for a leading '*' */
196 alias_len = alias_end - action + 1;
197 free(conf_start);
199 else
201 GetNextToken(action, &info);
202 if (info == NULL)
204 return;
208 current = modlistroot;
209 prev = NULL;
211 while (current != NULL)
213 GetNextToken(current->data, &mi);
214 next = current->next;
215 if ((!alias_len || !current->alias_len ||
216 alias_len == current->alias_len) &&
217 matchWildcards(info, mi+1))
219 free(current->data);
220 free(current);
221 if( prev )
223 prev->next = next;
225 else
227 modlistroot = next;
230 else
232 prev = current;
234 current = next;
235 if (mi)
237 free(mi);
240 free(info);
242 return;
245 static void send_xinerama_state(fmodule *module)
247 SendName(module, M_CONFIG_INFO, 0, 0, 0, FScreenGetConfiguration());
249 return;
252 static void send_desktop_names(fmodule *module)
254 DesktopsInfo *d;
255 char *name;
257 for (d = Scr.Desktops->next; d != NULL; d = d->next)
259 if (d->name != NULL)
261 name = (char *)safemalloc(strlen(d->name) + 44);
262 sprintf(name,"DesktopName %d %s", d->desk, d->name);
263 SendName(module, M_CONFIG_INFO, 0, 0, 0, name);
264 free(name);
268 return;
271 static void send_desktop_geometry(fmodule *module)
273 char msg[64];
275 sprintf(msg, "DesktopSize %d %d\n", Scr.VxMax / Scr.MyDisplayWidth + 1,
276 Scr.VyMax / Scr.MyDisplayHeight + 1);
277 SendName(module, M_CONFIG_INFO, 0, 0, 0, msg);
279 return;
282 static void send_image_path(fmodule *module)
284 char *msg;
285 char *ImagePath = PictureGetImagePath();
287 if (ImagePath && *ImagePath != 0)
289 msg = safemalloc(strlen(ImagePath) + 12);
290 sprintf(msg, "ImagePath %s\n", ImagePath);
291 SendName(module, M_CONFIG_INFO, 0, 0, 0, msg);
292 free(msg);
295 return;
298 static void send_color_limit(fmodule *module)
300 #ifndef DISABLE_COLORLIMIT_CONFIG_INFO
301 char msg[64];
303 sprintf(msg, "ColorLimit %d\n", Scr.ColorLimit);
304 SendName(module, M_CONFIG_INFO, 0, 0, 0, msg);
305 #endif
306 return;
309 static void send_colorsets(fmodule *module)
311 int n;
313 /* dump the colorsets (0 first as others copy it) */
314 for (n = 0; n < nColorsets; n++)
316 SendName(
317 module, M_CONFIG_INFO, 0, 0, 0,
318 DumpColorset(n, &Colorset[n]));
321 return;
324 static void send_click_time(fmodule *module)
326 char msg[64];
328 /* Dominik Vogt (8-Nov-1998): Scr.ClickTime patch to set ClickTime to
329 * 'not at all' during InitFunction and RestartFunction. */
330 sprintf(msg,"ClickTime %d\n", (Scr.ClickTime < 0) ?
331 -Scr.ClickTime : Scr.ClickTime);
332 SendName(module, M_CONFIG_INFO, 0, 0, 0, msg);
334 return;
337 static void send_move_threshold(fmodule *module)
339 char msg[64];
341 sprintf(msg, "MoveThreshold %d\n", Scr.MoveThreshold);
342 SendName(module, M_CONFIG_INFO, 0, 0, 0, msg);
344 return;
347 void send_ignore_modifiers(fmodule *module)
349 char msg[64];
351 sprintf(msg, "IgnoreModifiers %d\n", GetUnusedModifiers());
352 SendName(module, M_CONFIG_INFO, 0, 0, 0, msg);
354 return;
357 void CMD_Send_ConfigInfo(F_CMD_ARGS)
359 struct moduleInfoList *t;
360 /* matching criteria for module cmds */
361 char *match;
362 /* get length once for efficiency */
363 int match_len = 0;
364 fmodule *mod = exc->m.module;
366 send_desktop_geometry(mod);
367 /* send ImagePath and ColorLimit first */
368 send_image_path(mod);
369 send_color_limit(mod);
370 send_xinerama_state(mod);
371 send_colorsets(mod);
372 send_click_time(mod);
373 send_move_threshold(mod);
374 match = PeekToken(action, &action);
375 if (match)
377 match_len = strlen(match);
379 for (t = modlistroot; t != NULL; t = t->next)
381 SendConfigToModule(mod, t, match, match_len);
383 send_desktop_names(mod);
384 send_ignore_modifiers(mod);
385 SendPacket(
386 mod, M_END_CONFIG_INFO, (long)0, (long)0, (long)0, (long)0,
387 (long)0, (long)0, (long)0, (long)0);
389 return;
392 static void SendConfigToModule(
393 fmodule *module, const struct moduleInfoList *entry, char *match,
394 int match_len)
396 if (match)
398 if (match_len == 0)
400 match_len = strlen(match);
402 if (entry->alias_len > 0 && entry->alias_len != match_len)
404 return;
406 /* migo: this should be strncmp not strncasecmp probably. */
407 if (strncasecmp(entry->data, match, match_len) != 0)
409 return;
412 SendName(module, M_CONFIG_INFO, 0, 0, 0, entry->data);
414 return;