cvsimport
[fvwm.git] / modules / FvwmButtons / dynamic.c
blob9c75e7d8fe2362ec84c17f12797bfffc5baa88ae
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 /* ---------------------------- included header files ----------------------- */
19 #include "config.h"
20 #include <stdarg.h>
21 #include <stdio.h>
23 /* the following 5 are just to satisfy X11/extensions/shape.h on some systems */
24 #include <X11/Xlib.h>
25 #include <X11/Xutil.h>
26 #include <X11/Xproto.h>
27 #include <X11/Xatom.h>
28 #include <X11/Intrinsic.h>
30 #include "libs/Module.h"
31 #include "libs/Strings.h"
32 #include "libs/Parse.h"
33 #include "FvwmButtons.h"
34 #include "button.h"
35 #include "draw.h"
36 #include "icons.h"
38 /* ---------------------------- local definitions --------------------------- */
40 /* ---------------------------- local macros -------------------------------- */
42 /* ---------------------------- imports ------------------------------------- */
44 extern int Width, Height;
45 extern int screen;
47 /* ---------------------------- included code files ------------------------- */
49 /* ---------------------------- local types --------------------------------- */
51 /* ---------------------------- forward declarations ------------------------ */
53 /* ---------------------------- local variables ----------------------------- */
55 static Bool silent = False;
57 /* ---------------------------- exported variables (globals) ---------------- */
59 /* ---------------------------- local functions ----------------------------- */
61 static void show_error(const char *msg, ...)
63 va_list args;
65 if (silent == True)
67 return;
69 va_start(args, msg);
70 vfprintf(stderr, CatString3(MyName, ": ", msg), args);
71 va_end(args);
76 #if 0
77 /* to be used in module_expand_action */
78 static module_expand_vars mev =
80 /* number of vars */
82 /* array of var names */
83 { "title", "icon", }
84 /* array of values, void *, will be filled later */
85 { NULL, NULL },
86 /* array of booleans, 0 if string, 1 if int */
87 { 0, 0, },
89 #endif
91 static char *expand_button_vars(const button_info *b, const char *line)
93 /* not fully implemented yet, should expand $title, $icon and so on */
94 rectangle r;
95 char *expanded_line;
97 /* there should be a function evaluating fore/back from colorset */
98 char *fore = (b->flags.b_Fore) ? b->fore : "black";
99 char *back = (b->flags.b_Back) ? b->back : "gray";
101 get_button_root_geometry(&r, b);
102 expanded_line = module_expand_action(
103 Dpy, screen, (char *)line, &r, fore, back);
105 return expanded_line;
108 static button_info *parse_button_id(char **line)
110 button_info *b = NULL, *ub = UberButton;
111 int mask;
112 int x, y;
113 int count, i;
114 char *rest;
115 char *s;
117 s = PeekToken(*line, &rest);
118 *line = NULL;
119 if (!s)
121 show_error("No button id specified\n");
122 return NULL;
125 if (*s == '+')
127 unsigned int JunkWidth;
128 unsigned int JunkHeight;
130 mask = XParseGeometry(s, &x, &y, &JunkWidth, &JunkHeight);
131 if (!(mask & XValue) || (mask & XNegative) ||
132 !(mask & YValue) || (mask & YNegative))
134 show_error("Illegal button position '%s'\n", s);
135 return NULL;
137 if (x < 0 || y < 0)
139 show_error("Button column/row must not be negative\n");
140 return NULL;
142 b = get_xy_button(ub, y, x);
143 if (b == NULL)
145 show_error(
146 "Button at column %d row %d not found\n", x, y);
147 return NULL;
150 else if (isdigit(*s))
152 x = atoi(s);
153 i = count = -1;
154 /* find the button */
155 while (NextButton(&ub, &b, &i, 0))
157 if (++count == x)
158 break;
160 if (count != x || b == NULL)
162 show_error("Button number %d not found\n", x);
163 return NULL;
166 else if (isalpha(*s))
168 Bool found = False;
169 i = -1;
170 /* find the button */
171 while (NextButton(&ub, &b, &i, 0))
173 if (b->flags.b_Id && StrEquals(b->id, s))
175 found = True;
176 break;
179 if (found == False)
181 show_error("Button id '%s' does not exist\n", s);
182 return NULL;
185 else
187 show_error("Invalid button id '%s' specified\n", s);
188 return NULL;
191 *line = rest;
192 return b;
195 /* ---------------------------- interface functions ------------------------- */
197 static char *actions[] =
199 "Silent", "ChangeButton", "ExpandButtonVars", "PressButton", NULL
202 static char *button_options[] =
204 "Title", "Icon", "ActiveTitle", "ActiveIcon", "PressTitle", "PressIcon", NULL
207 void parse_message_line(char *line)
209 char *rest;
210 int action = -1;
211 button_info *b;
212 char *act;
213 char *buttonn;
214 int mousebutton;
216 silent = False;
219 action = GetTokenIndex(line, actions, -1, &rest);
220 if (action == -1)
222 show_error("Message not understood: %s", line);
223 return;
225 if (action == 0)
227 silent = True;
228 line = rest;
230 } while (action == 0);
232 /* find out which button */
233 b = parse_button_id(&rest);
234 if (!b || !rest)
236 return;
239 switch (action)
241 case 1:
242 /* ChangeButton */
243 /* The dimensions of individual buttons (& the overall size of
244 * the FvwmButtons window) is based on the initial
245 * configuration for the module. In some configurations,
246 * dynamically adding/changing a title/icon may mean it no
247 * longer fits on a button. Currently, there are no checks for
248 * this occurance. */
249 while (rest && rest[0] != '\0')
251 char *option_pair;
252 int option;
253 char *value0, *value;
254 FvwmPicture *icon;
256 /* parse option and value and give diagnostics */
257 rest = GetQuotedString(
258 rest, &option_pair, ",", NULL, NULL, NULL);
259 while (isspace(*rest))
261 rest++;
263 if (!option_pair)
264 continue;
266 option = GetTokenIndex(
267 option_pair, button_options, -1, &value0);
268 if (option < 0)
270 show_error(
271 "Unsupported button option line '%s'\n",
272 option_pair);
273 free(option_pair);
274 continue;
277 GetNextToken(value0, &value);
278 free(option_pair);
280 if (value == NULL)
282 show_error(
283 "No title/icon to change specified.\n");
284 continue;
286 switch (option)
288 case 0:
289 /* Title */
290 if (b->flags.b_Title)
291 free(b->title);
292 b->flags.b_Title = 1;
293 CopyString(&b->title, value);
294 break;
295 case 2:
296 /* ActiveTitle */
297 if (b->flags.b_ActiveTitle)
298 free(b->activeTitle);
299 b->flags.b_ActiveTitle = 1;
300 CopyString(&b->activeTitle, value);
301 break;
302 case 4:
303 /* PressTitle */
304 if (b->flags.b_PressTitle)
305 free(b->pressTitle);
306 b->flags.b_PressTitle = 1;
307 CopyString(&b->pressTitle, value);
308 break;
309 default:
310 if (
311 LoadIconFile(
312 value, &icon, b->colorset) == 0)
314 show_error(
315 "Cannot load icon \"%s\"\n",
316 value);
318 else
320 switch (option)
322 case 1: /* Icon */
323 if (b->flags.b_Icon)
325 free(b->icon_file);
326 PDestroyFvwmPicture(
327 Dpy, b->icon);
329 b->flags.b_Icon = 1;
330 CopyString(
331 &b->icon_file, value);
332 b->icon = icon;
333 break;
334 case 3: /* ActiveIcon */
335 if (b->flags.b_ActiveIcon)
337 free(b->active_icon_file);
338 PDestroyFvwmPicture(
339 Dpy,
340 b->activeicon);
342 b->flags.b_ActiveIcon = 1;
343 CopyString(
344 &b->active_icon_file,
345 value);
346 b->activeicon = icon;
347 break;
348 case 5: /* PressIcon */
349 if (b->flags.b_PressIcon)
351 free(b->press_icon_file);
352 PDestroyFvwmPicture(
353 Dpy,
354 b->pressicon);
356 b->flags.b_PressIcon = 1;
357 CopyString(
358 &b->press_icon_file,
359 value);
360 b->pressicon = icon;
361 break;
364 break;
367 if (value)
369 free(value);
373 RedrawButton(b, DRAW_FORCE, NULL);
374 if (UberButton->c->flags.b_TransBack)
376 SetTransparentBackground(UberButton, Width, Height);
378 break;
380 case 2:
381 /* ExpandButtonVars */
382 line = expand_button_vars(b, rest);
383 if (line)
385 SendText(fd, line, 0);
386 free(line);
388 break;
389 case 3:
390 /* PressButton */
391 rest = GetQuotedString(rest, &buttonn, "", NULL, NULL, NULL);
392 if (buttonn)
394 mousebutton = atoi(buttonn);
395 free(buttonn);
396 if (
397 mousebutton <= 0 ||
398 mousebutton > NUMBER_OF_EXTENDED_MOUSE_BUTTONS)
400 mousebutton = 1;
403 else
405 mousebutton = 1;
407 CurrentButton = b;
408 act = GetButtonAction(b, mousebutton);
409 ButtonPressProcess(b, &act);
410 if (act)
412 free(act);
414 CurrentButton = NULL;
416 break;
419 return;