521 lines
9.8 KiB
C
521 lines
9.8 KiB
C
#include "FvwmIconMan.h"
|
|
#include "readconfig.h"
|
|
#include "xmanager.h"
|
|
|
|
static char const rcsid[] =
|
|
"$Id: functions.c,v 1.1.1.1 2006/11/26 10:53:49 matthieu Exp $";
|
|
|
|
static Button *get_select_button (void);
|
|
|
|
static struct {
|
|
Button *current_button;
|
|
Function *fp;
|
|
} function_context;
|
|
|
|
static void init_function_context (Function *func)
|
|
{
|
|
function_context.current_button = get_select_button();
|
|
function_context.fp = func;
|
|
}
|
|
|
|
void run_function_list (Function *func)
|
|
{
|
|
init_function_context (func);
|
|
|
|
while (function_context.fp) {
|
|
function_context.fp->func (function_context.fp->numargs,
|
|
function_context.fp->args);
|
|
if (function_context.fp)
|
|
function_context.fp = function_context.fp->next;
|
|
}
|
|
}
|
|
|
|
static Button *get_select_button (void)
|
|
{
|
|
if (globals.select_win)
|
|
return globals.select_win->button;
|
|
return NULL;
|
|
}
|
|
|
|
static Button *get_focus_button (void)
|
|
{
|
|
if (globals.focus_win)
|
|
return globals.focus_win->button;
|
|
return NULL;
|
|
}
|
|
|
|
static WinManager *get_current_man (void)
|
|
{
|
|
Button *b = function_context.current_button;
|
|
|
|
if (globals.num_managers==1)
|
|
return globals.managers;
|
|
if (b && b->drawn_state.win)
|
|
return b->drawn_state.win->manager;
|
|
return NULL;
|
|
}
|
|
|
|
static WinData *get_current_win (void)
|
|
{
|
|
Button *b = function_context.current_button;
|
|
|
|
if (b && b->drawn_state.win)
|
|
return b->drawn_state.win;
|
|
return NULL;
|
|
}
|
|
|
|
static Button *get_current_button (void)
|
|
{
|
|
return function_context.current_button;
|
|
}
|
|
|
|
static Button *button_move (ButtonValue *bv)
|
|
{
|
|
Button *b = NULL, *cur;
|
|
WinManager *man;
|
|
int i;
|
|
|
|
cur = get_current_button();
|
|
|
|
switch (bv->base) {
|
|
case NoButton:
|
|
ConsoleMessage ("gotobutton: need a button to change to\n");
|
|
return cur;
|
|
|
|
case SelectButton:
|
|
b = get_select_button();
|
|
break;
|
|
|
|
case FocusButton:
|
|
b = get_focus_button();
|
|
break;
|
|
|
|
case AbsoluteButton:
|
|
man = get_current_man();
|
|
if (man && man->buttons.num_windows > 0) {
|
|
i = bv->offset % man->buttons.num_windows;
|
|
if (i < 0)
|
|
i += man->buttons.num_windows;
|
|
b = man->buttons.buttons[i];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
man = get_current_man();
|
|
if (!cur) {
|
|
ConsoleDebug (FUNCTIONS, "\tno current button, skipping\n");
|
|
return NULL;
|
|
}
|
|
|
|
switch (bv->base) {
|
|
case UpButton:
|
|
b = button_above (man, cur);
|
|
break;
|
|
|
|
case DownButton:
|
|
b = button_below (man, cur);
|
|
break;
|
|
|
|
case LeftButton:
|
|
b = button_left (man, cur);
|
|
break;
|
|
|
|
case RightButton:
|
|
b = button_right (man, cur);
|
|
break;
|
|
|
|
case NextButton:
|
|
b = button_next (man, cur);
|
|
break;
|
|
|
|
case PrevButton:
|
|
b = button_prev (man, cur);
|
|
break;
|
|
|
|
default:
|
|
ConsoleMessage ("Internal error in gotobutton\n");
|
|
break;
|
|
}
|
|
}
|
|
|
|
return b;
|
|
}
|
|
|
|
int builtin_gotobutton (int numargs, BuiltinArg *args)
|
|
{
|
|
Button *b;
|
|
ButtonValue *bv;
|
|
|
|
ConsoleDebug (FUNCTIONS, "gotobutton: ");
|
|
print_args (numargs, args);
|
|
|
|
bv = &args[0].value.button_value;
|
|
|
|
b = button_move (bv);
|
|
|
|
if (b)
|
|
function_context.current_button = b;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int builtin_gotomanager (int numargs, BuiltinArg *args)
|
|
{
|
|
ButtonValue *bv;
|
|
WinManager *man, *new;
|
|
int i;
|
|
|
|
ConsoleDebug (FUNCTIONS, "gotomanager: ");
|
|
print_args (numargs, args);
|
|
|
|
bv = &args[0].value.button_value;
|
|
|
|
new = man = get_current_man();
|
|
|
|
switch (bv->base) {
|
|
case NoButton:
|
|
ConsoleMessage ("gotomanager: need a manager argument\n");
|
|
return 1;
|
|
|
|
case SelectButton:
|
|
case FocusButton:
|
|
ConsoleMessage ("gotomanger: \"select\" or \"focus\" does not specify"
|
|
" a manager\n");
|
|
break;
|
|
|
|
case AbsoluteButton:
|
|
{
|
|
/* Now we find the manager modulo the VISIBLE managers */
|
|
static WinManager **wa = NULL;
|
|
int i, num_mapped, n;
|
|
|
|
n = globals.num_managers;
|
|
if (n) {
|
|
if (wa == NULL) {
|
|
wa = (WinManager **)safemalloc (n * sizeof (WinManager *));
|
|
}
|
|
for (i = 0, num_mapped = 0; i < n; i++) {
|
|
if (globals.managers[i].buttons.num_windows > 0 &&
|
|
globals.managers[i].window_mapped) {
|
|
wa[num_mapped++] = &globals.managers[i];
|
|
}
|
|
}
|
|
if (num_mapped) {
|
|
i = bv->offset % num_mapped;
|
|
if (i < 0)
|
|
i += num_mapped;
|
|
new = wa[i];
|
|
}
|
|
else {
|
|
new = NULL;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case NextButton:
|
|
if (man) {
|
|
for (i = man->index + 1, new = man + 1;
|
|
i < globals.num_managers && new->buttons.num_windows == 0;
|
|
i++, new++)
|
|
;
|
|
if (i == globals.num_managers)
|
|
new = man;
|
|
}
|
|
break;
|
|
|
|
case PrevButton:
|
|
if (man) {
|
|
for (i = man->index - 1, new = man - 1;
|
|
i > -1 && new->buttons.num_windows == 0;
|
|
i--, new--)
|
|
;
|
|
if (i == -1)
|
|
new = man;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
ConsoleMessage ("gotomanager: bad argument\n");
|
|
break;
|
|
}
|
|
|
|
if (new && new != man && new->buttons.num_windows > 0) {
|
|
function_context.current_button = new->buttons.buttons[0];
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int builtin_select (int numargs, BuiltinArg *args)
|
|
{
|
|
WinManager *man = get_current_man();
|
|
if (man) {
|
|
move_highlight (man, get_current_button());
|
|
if (get_current_button())
|
|
run_binding (man, SELECT);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int builtin_sendcommand (int numargs, BuiltinArg *args)
|
|
{
|
|
WinData *win = get_current_win();
|
|
|
|
if (!win) {
|
|
return 0;
|
|
}
|
|
|
|
SendFvwmPipe (args[0].value.string_value, win->app_id);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int builtin_printdebug (int numargs, BuiltinArg *args)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < globals.num_managers; i++) {
|
|
ConsoleDebug (FUNCTIONS, "Manager %d\n---------\n", i);
|
|
ConsoleDebug (FUNCTIONS, "Keys:\n");
|
|
print_bindings (globals.managers[i].bindings[KEYPRESS]);
|
|
ConsoleDebug (FUNCTIONS, "Mice:\n");
|
|
print_bindings (globals.managers[i].bindings[MOUSE]);
|
|
ConsoleDebug (FUNCTIONS, "Select:\n");
|
|
print_bindings (globals.managers[i].bindings[SELECT]);
|
|
ConsoleDebug (FUNCTIONS, "\n");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int builtin_quit (int numargs, BuiltinArg *args)
|
|
{
|
|
ConsoleDebug (FUNCTIONS, "quit: ");
|
|
print_args (numargs, args);
|
|
ShutMeDown (0);
|
|
return 0;
|
|
}
|
|
|
|
static void do_jmp (int off)
|
|
{
|
|
int i;
|
|
ConsoleDebug (FUNCTIONS, "jmp: %d\n", off);
|
|
|
|
if (off < 0) {
|
|
ConsoleMessage ("Can't have a negative relative jump offset\n");
|
|
return;
|
|
}
|
|
for (i = 0; i < off; i++) {
|
|
if (function_context.fp)
|
|
function_context.fp = function_context.fp->next;
|
|
}
|
|
}
|
|
|
|
static int eval_if (ButtonValue *bv)
|
|
{
|
|
Button *cur;
|
|
WinManager *man;
|
|
|
|
switch (bv->base) {
|
|
case NoButton:
|
|
ConsoleMessage ("Internal error in eval_if: 1\n");
|
|
break;
|
|
|
|
case SelectButton:
|
|
if (get_select_button())
|
|
return 1;
|
|
break;
|
|
|
|
case FocusButton:
|
|
if (get_focus_button())
|
|
return 1;
|
|
break;
|
|
|
|
case AbsoluteButton:
|
|
if (bv->offset != 0)
|
|
return 1;
|
|
break;
|
|
|
|
default:
|
|
cur = get_current_button();
|
|
man = get_current_man();
|
|
if (!cur || !man) {
|
|
return 0;
|
|
}
|
|
|
|
switch (bv->base) {
|
|
case UpButton:
|
|
return (button_above (man, cur) != cur);
|
|
|
|
case DownButton:
|
|
return (button_below (man, cur) != cur);
|
|
|
|
case LeftButton:
|
|
return (button_left (man, cur) != cur);
|
|
|
|
case RightButton:
|
|
return (button_right (man, cur) != cur);
|
|
|
|
case NextButton:
|
|
return (button_next (man, cur) != cur);
|
|
|
|
case PrevButton:
|
|
return (button_prev (man, cur) != cur);
|
|
|
|
default:
|
|
ConsoleMessage ("Internal error in eval_if: 2\n");
|
|
break;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int builtin_bif (int numargs, BuiltinArg *args)
|
|
{
|
|
int off = args[1].value.int_value;
|
|
ConsoleDebug (FUNCTIONS, "bif: off = %d\n", off);
|
|
|
|
if (eval_if (&args[0].value.button_value)) {
|
|
do_jmp (off);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int builtin_bifn (int numargs, BuiltinArg *args)
|
|
{
|
|
int off = args[1].value.int_value;
|
|
ConsoleDebug (FUNCTIONS, "bifn: off = %d\n", off);
|
|
|
|
if (eval_if (&args[0].value.button_value) == 0) {
|
|
do_jmp (off);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int builtin_jmp (int numargs, BuiltinArg *args)
|
|
{
|
|
int off = args[0].value.int_value;
|
|
ConsoleDebug (FUNCTIONS, "jmp: off = %d\n", off);
|
|
|
|
do_jmp (off);
|
|
return 0;
|
|
}
|
|
|
|
int builtin_ret (int numargs, BuiltinArg *args)
|
|
{
|
|
function_context.fp = NULL;
|
|
return 0;
|
|
}
|
|
|
|
int builtin_print (int numargs, BuiltinArg *args)
|
|
{
|
|
char *s, buf[256];
|
|
|
|
ConsoleDebug (FUNCTIONS, "print: %s\n", args[0].value.string_value);
|
|
|
|
s = args[0].value.string_value;
|
|
if (strlen (s) > 250) {
|
|
ConsoleMessage ("String too long\n");
|
|
}
|
|
else {
|
|
sprintf (buf, "%s\n", s);
|
|
ConsoleMessage (buf);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int builtin_searchforward (int numargs, BuiltinArg *args)
|
|
{
|
|
char *s;
|
|
Button *b, *cur;
|
|
WinManager *man;
|
|
|
|
s = args[0].value.string_value;
|
|
|
|
ConsoleDebug (FUNCTIONS, "searchforward: %s\n", s);
|
|
|
|
cur = get_current_button();
|
|
man = get_current_man();
|
|
b = cur;
|
|
if (cur) {
|
|
while (1) {
|
|
if (cur->drawn_state.display_string &&
|
|
matchWildcards (s, cur->drawn_state.display_string))
|
|
break;
|
|
b = button_next (man, cur);
|
|
if (b == cur) {
|
|
cur = NULL;
|
|
break;
|
|
}
|
|
cur = b;
|
|
}
|
|
}
|
|
if (cur)
|
|
function_context.current_button = cur;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int builtin_searchback (int numargs, BuiltinArg *args)
|
|
{
|
|
char *s;
|
|
Button *b, *cur;
|
|
WinManager *man;
|
|
|
|
s = args[0].value.string_value;
|
|
|
|
ConsoleDebug (FUNCTIONS, "searchback: %s\n", s);
|
|
|
|
cur = get_current_button();
|
|
man = get_current_man();
|
|
b = cur;
|
|
if (cur) {
|
|
while (1) {
|
|
if (cur->drawn_state.display_string &&
|
|
matchWildcards (s, cur->drawn_state.display_string))
|
|
break;
|
|
b = button_prev (man, cur);
|
|
if (b == cur) {
|
|
cur = NULL;
|
|
break;
|
|
}
|
|
cur = b;
|
|
}
|
|
}
|
|
if (cur)
|
|
function_context.current_button = cur;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int builtin_warp (int numargs, BuiltinArg *args)
|
|
{
|
|
Button *cur;
|
|
WinManager *man;
|
|
int x, y;
|
|
|
|
ConsoleDebug (FUNCTIONS, "warp\n");
|
|
|
|
cur = get_current_button();
|
|
if (cur) {
|
|
man = get_current_man();
|
|
x = cur->x + cur->w / 2;
|
|
y = cur->y + cur->h / 2;
|
|
XWarpPointer (theDisplay, None, man->theWindow, 0, 0, 0, 0, x, y);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int builtin_refresh (int numargs, BuiltinArg *args)
|
|
{
|
|
draw_managers();
|
|
return 0;
|
|
}
|