Restructure how we look for Read files slightly.
[fvwm.git] / modules / FvwmIconMan / functions.c
blob77f3910bbcce9976f139ee36101bbc78ba84b7c7
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 "FvwmIconMan.h"
20 #include "readconfig.h"
21 #include "xmanager.h"
22 #include "x.h"
23 #include "libs/Module.h"
24 #include "libs/wild.h"
26 static Button *get_select_button(void);
28 static struct {
29 Button *current_button;
30 Function *fp;
31 } function_context;
33 static void init_function_context(Function *func)
35 function_context.current_button = get_select_button();
36 function_context.fp = func;
39 void run_function_list(Function *func)
41 init_function_context(func);
43 while (function_context.fp)
45 function_context.fp->func(
46 function_context.fp->numargs,
47 function_context.fp->args);
48 if (function_context.fp)
50 function_context.fp = function_context.fp->next;
55 static Button *get_select_button(void)
57 if (globals.select_win)
59 return globals.select_win->button;
61 return NULL;
64 static Button *get_focus_button(void)
66 if (globals.focus_win)
68 return globals.focus_win->button;
70 return NULL;
73 static WinManager *get_current_man(void)
75 Button *b = function_context.current_button;
77 if (globals.num_managers==1)
79 return globals.managers;
81 if (b && b->drawn_state.win)
83 return b->drawn_state.win->manager;
85 return NULL;
88 static WinData *get_current_win(void)
90 Button *b = function_context.current_button;
92 if (b && b->drawn_state.win)
94 return b->drawn_state.win;
96 return NULL;
99 static Button *get_current_button(void)
101 return function_context.current_button;
104 static Button *button_move(ButtonValue *bv)
106 Button *b = NULL, *cur;
107 WinManager *man;
108 int i;
110 cur = get_current_button();
112 switch (bv->base)
114 case NoButton:
115 ConsoleMessage("gotobutton: need a button to change to\n");
116 return cur;
118 case SelectButton:
119 b = get_select_button();
120 break;
122 case FocusButton:
123 b = get_focus_button();
124 break;
126 case AbsoluteButton:
127 man = get_current_man();
128 if (man && man->buttons.num_windows > 0)
130 i = bv->offset % man->buttons.num_windows;
131 if (i < 0)
133 i += man->buttons.num_windows;
135 b = man->buttons.buttons[i];
137 break;
139 default:
140 man = get_current_man();
141 if (!cur)
143 ConsoleDebug(
144 FUNCTIONS, "\tno current button, skipping\n");
145 return NULL;
148 switch (bv->base)
150 case UpButton:
151 b = button_above(man, cur);
152 break;
154 case DownButton:
155 b = button_below(man, cur);
156 break;
158 case LeftButton:
159 b = button_left(man, cur);
160 break;
162 case RightButton:
163 b = button_right(man, cur);
164 break;
166 case NextButton:
167 b = button_next(man, cur);
168 break;
170 case PrevButton:
171 b = button_prev(man, cur);
172 break;
174 default:
175 ConsoleMessage("Internal error in gotobutton\n");
176 break;
180 return b;
183 int builtin_gotobutton(int numargs, BuiltinArg *args)
185 Button *b;
186 ButtonValue *bv;
188 ConsoleDebug(FUNCTIONS, "gotobutton: ");
189 print_args(numargs, args);
191 bv = &args[0].value.button_value;
193 b = button_move(bv);
195 if (b)
197 function_context.current_button = b;
200 return 0;
203 int builtin_gotomanager(int numargs, BuiltinArg *args)
205 ButtonValue *bv;
206 WinManager *man, *new;
207 int i;
209 ConsoleDebug(FUNCTIONS, "gotomanager: ");
210 print_args(numargs, args);
212 bv = &args[0].value.button_value;
214 new = man = get_current_man();
216 switch (bv->base)
218 case NoButton:
219 ConsoleMessage("gotomanager: need a manager argument\n");
220 return 1;
222 case SelectButton:
223 case FocusButton:
224 ConsoleMessage(
225 "gotomanager: \"select\" or \"focus\" does not specify"
226 " a manager\n");
227 break;
229 case AbsoluteButton:
231 /* Now we find the manager modulo the VISIBLE managers */
232 static WinManager **wa = NULL;
233 int i, num_mapped, n;
235 n = globals.num_managers;
236 if (n)
238 if (wa == NULL)
240 wa = (WinManager **)safemalloc(
241 n * sizeof(WinManager *));
243 for (i = 0, num_mapped = 0; i < n; i++)
245 if (globals.managers[i].buttons.num_windows > 0
246 && globals.managers[i].window_mapped)
248 wa[num_mapped++] = &globals.managers[i];
251 if (num_mapped)
253 i = bv->offset % num_mapped;
254 if (i < 0)
256 i += num_mapped;
258 new = wa[i];
260 else
262 new = NULL;
266 break;
268 case NextButton:
269 if (man)
271 for (i = man->index + 1, new = man + 1;
272 i < globals.num_managers &&
273 new->buttons.num_windows == 0;
274 i++, new++)
278 if (i == globals.num_managers)
280 new = man;
283 break;
285 case PrevButton:
286 if (man)
288 for (i = man->index - 1, new = man - 1;
289 i > -1 && new->buttons.num_windows == 0;
290 i--, new--)
294 if (i == -1)
296 new = man;
299 break;
301 default:
302 ConsoleMessage("gotomanager: bad argument\n");
303 break;
306 if (new && new != man && new->buttons.num_windows > 0)
308 function_context.current_button = new->buttons.buttons[0];
311 return 0;
314 int builtin_select(int numargs, BuiltinArg *args)
316 WinManager *man = get_current_man();
317 if (man)
319 move_highlight(man, get_current_button());
320 if (get_current_button())
322 run_binding(man, SELECT);
325 return 0;
328 int builtin_sendcommand(int numargs, BuiltinArg *args)
330 WinData *win = get_current_win();
332 char *command, *tmp;
333 Button *current_button;
334 rectangle r;
335 Window tmpw;
337 if (!win)
339 return 0;
342 command = args[0].value.string_value;
343 current_button = win->manager->select_button;
345 r.x = current_button->x;
346 r.y = current_button->y;
347 r.width = current_button->w;
348 r.height = current_button->h;
349 XTranslateCoordinates(theDisplay, win->manager->theWindow, theRoot,
350 r.x, r.y, &r.x, &r.y, &tmpw);
352 tmp = module_expand_action(
353 theDisplay, theScreen, command, &r, NULL, NULL);
354 if (tmp)
356 command = tmp;
359 SendFvwmPipe(fvwm_fd, command, win->app_id);
360 if (tmp)
362 free(tmp);
365 return 0;
368 int builtin_printdebug(int numargs, BuiltinArg *args)
370 int i;
372 for (i = 0; i < globals.num_managers; i++)
374 ConsoleDebug(FUNCTIONS, "Manager %d\n---------\n", i);
375 ConsoleDebug(FUNCTIONS, "Keys:\n");
376 print_bindings(globals.managers[i].bindings[KEYPRESS]);
377 ConsoleDebug(FUNCTIONS, "Mice:\n");
378 print_bindings(globals.managers[i].bindings[MOUSE]);
379 ConsoleDebug(FUNCTIONS, "Select:\n");
380 print_bindings(globals.managers[i].bindings[SELECT]);
381 ConsoleDebug(FUNCTIONS, "\n");
384 return 0;
387 int builtin_quit(int numargs, BuiltinArg *args)
389 ConsoleDebug(FUNCTIONS, "quit: ");
390 print_args(numargs, args);
391 ShutMeDown(0);
392 return 0;
395 static void do_jmp(int off)
397 int i;
398 ConsoleDebug(FUNCTIONS, "jmp: %d\n", off);
400 if (off < 0)
402 ConsoleMessage("Can't have a negative relative jump offset\n");
403 return;
405 for (i = 0; i < off; i++)
407 if (function_context.fp)
409 function_context.fp = function_context.fp->next;
414 static int eval_if(ButtonValue *bv)
416 Button *cur;
417 WinManager *man;
419 switch (bv->base)
421 case NoButton:
422 ConsoleMessage("Internal error in eval_if: 1\n");
423 break;
425 case SelectButton:
426 if (get_select_button())
428 return 1;
430 break;
432 case FocusButton:
433 if (get_focus_button())
435 return 1;
437 break;
439 case AbsoluteButton:
440 if (bv->offset != 0)
442 return 1;
444 break;
446 default:
447 cur = get_current_button();
448 man = get_current_man();
449 if (!cur || !man)
451 return 0;
454 switch (bv->base)
456 case UpButton:
457 return (button_above(man, cur) != cur);
459 case DownButton:
460 return (button_below(man, cur) != cur);
462 case LeftButton:
463 return (button_left(man, cur) != cur);
465 case RightButton:
466 return (button_right(man, cur) != cur);
468 case NextButton:
469 return (button_next(man, cur) != cur);
471 case PrevButton:
472 return (button_prev(man, cur) != cur);
474 default:
475 ConsoleMessage("Internal error in eval_if: 2\n");
476 break;
480 return 0;
483 int builtin_bif(int numargs, BuiltinArg *args)
485 int off = args[1].value.int_value;
486 ConsoleDebug(FUNCTIONS, "bif: off = %d\n", off);
488 if (eval_if(&args[0].value.button_value))
490 do_jmp(off);
493 return 0;
496 int builtin_bifn(int numargs, BuiltinArg *args)
498 int off = args[1].value.int_value;
499 ConsoleDebug(FUNCTIONS, "bifn: off = %d\n", off);
501 if (eval_if(&args[0].value.button_value) == 0)
503 do_jmp(off);
506 return 0;
509 int builtin_jmp(int numargs, BuiltinArg *args)
511 int off = args[0].value.int_value;
512 ConsoleDebug(FUNCTIONS, "jmp: off = %d\n", off);
514 do_jmp(off);
515 return 0;
518 int builtin_ret(int numargs, BuiltinArg *args)
520 function_context.fp = NULL;
521 return 0;
524 int builtin_print(int numargs, BuiltinArg *args)
526 char *s, buf[256];
528 ConsoleDebug(FUNCTIONS, "print: %s\n", args[0].value.string_value);
530 s = args[0].value.string_value;
531 if (strlen(s) > 250)
533 ConsoleMessage("String too long\n");
535 else
537 sprintf(buf, "%s\n", s);
538 ConsoleMessage(buf);
541 return 0;
544 int builtin_searchforward(int numargs, BuiltinArg *args)
546 char *s;
547 Button *b, *cur;
548 WinManager *man;
550 s = args[0].value.string_value;
552 ConsoleDebug(FUNCTIONS, "searchforward: %s\n", s);
554 cur = get_current_button();
555 man = get_current_man();
556 b = cur;
557 if (cur)
559 while (1)
561 if (cur->drawn_state.display_string && matchWildcards(
562 s, cur->drawn_state.display_string))
564 break;
566 b = button_next(man, cur);
567 if (b == cur)
569 cur = NULL;
570 break;
572 cur = b;
575 if (cur)
577 function_context.current_button = cur;
580 return 0;
583 int builtin_searchback(int numargs, BuiltinArg *args)
585 char *s;
586 Button *b, *cur;
587 WinManager *man;
589 s = args[0].value.string_value;
591 ConsoleDebug(FUNCTIONS, "searchback: %s\n", s);
593 cur = get_current_button();
594 man = get_current_man();
595 b = cur;
596 if (cur)
598 while (1)
600 if (cur->drawn_state.display_string && matchWildcards(
601 s, cur->drawn_state.display_string))
603 break;
605 b = button_prev(man, cur);
606 if (b == cur)
608 cur = NULL;
609 break;
611 cur = b;
614 if (cur)
616 function_context.current_button = cur;
619 return 0;
622 int builtin_warp(int numargs, BuiltinArg *args)
624 Button *cur;
625 WinManager *man;
626 int x, y;
628 ConsoleDebug(FUNCTIONS, "warp\n");
630 cur = get_current_button();
631 if (cur)
633 man = get_current_man();
634 x = cur->x + cur->w / 2;
635 y = cur->y + cur->h / 2;
636 FWarpPointer(
637 theDisplay, None, man->theWindow, 0, 0, 0, 0, x, y);
640 return 0;
643 int builtin_refresh(int numargs, BuiltinArg *args)
645 draw_managers();
646 return 0;