#include "kernel/action.h" #include "kernel/parse.h" #include "kernel/prop.h" #include "mouse.h" void mouseparse(ParseToken *token) { static char *top = NULL; static char *context = NULL, *button = NULL; static char *arg_str = NULL; static int arg_int = 0; static MouseAction event = -1; static Action *action = NULL; static gboolean err = FALSE; if (err) { if (token->type == TOKEN_NEWLINE) err = FALSE; /* just fall through and free the token */ } else if (top == NULL) { if (token->type == TOKEN_IDENTIFIER && !g_ascii_strcasecmp("mbind", token->data.identifier)) { top = token->data.identifier; return; } else { yyerror("syntax error (expected mbind)"); err = TRUE; } } else if (context == NULL) { if (token->type == TOKEN_IDENTIFIER) { context = token->data.identifier; return; } else { yyerror("syntax error (expected Key)"); err = TRUE; } } else if (event == (unsigned) -1) { if (token->type == TOKEN_IDENTIFIER) { if (!g_ascii_strcasecmp("press", token->data.identifier)) event = MouseAction_Press; else if (!g_ascii_strcasecmp("release", token->data.identifier)) event = MouseAction_Release; else if (!g_ascii_strcasecmp("click", token->data.identifier)) event = MouseAction_Click; else if (!g_ascii_strcasecmp("doubleclick",token->data.identifier)) event = MouseAction_DClick; else if (!g_ascii_strcasecmp("drag", token->data.identifier)) event = MouseAction_Motion; if (event != (unsigned) -1) return; else { yyerror("invalid event"); err = TRUE; } } else { yyerror("syntax error (expected event)"); err = TRUE; } } else if (button == NULL) { if (token->type == TOKEN_IDENTIFIER) { button = token->data.identifier; return; } else { yyerror("syntax error (expected button)"); err = TRUE; } } else if (action == NULL) { if (token->type == TOKEN_IDENTIFIER) { action = action_from_string(token->data.identifier); /* check for valid actions for motion events */ if (action->func == action_moveresize) g_message("%d", action->data.moveresize.corner); if (event == MouseAction_Motion) { if (action && (action->func != action_moveresize || action->data.moveresize.corner == prop_atoms.net_wm_moveresize_move_keyboard || action->data.moveresize.corner == prop_atoms.net_wm_moveresize_size_keyboard)) { action_free(action); action = NULL; } } else { if (action && action->func == action_moveresize && action->data.moveresize.corner != prop_atoms.net_wm_moveresize_move_keyboard && action->data.moveresize.corner != prop_atoms.net_wm_moveresize_size_keyboard) { action_free(action); action = NULL; } } if (action != NULL) { return; } else { yyerror("invalid action"); err = TRUE; } } else { yyerror("syntax error (expected action)"); err = TRUE; } } else if (token->type == TOKEN_STRING) { arg_str = token->data.string; return; } else if (token->type == TOKEN_INTEGER) { arg_int = token->data.integer; return; } else if (token->type != TOKEN_NEWLINE) { yyerror("syntax error (unexpected trailing token)"); } else { /* these use the argument */ if (action->func == action_execute || action->func == action_restart) action->data.execute.path = g_strdup(arg_str); else if (action->func == action_showmenu) action->data.showmenu.name = g_strdup(arg_str); if ((action->func == action_desktop || action->func == action_send_to_desktop) && arg_int) action->data.desktop.desk = (unsigned) arg_int - 1; if (action->func == action_move_relative_horz || action->func == action_move_relative_vert || action->func == action_resize_relative_horz || action->func == action_resize_relative_vert) action->data.relative.delta = arg_int; if (mbind(button, context, event, action)) action = NULL; /* don't free this if mbind succeeds */ else yyerror("failed to add mouse binding"); } g_free(top); top = NULL; g_free(context); context = NULL; g_free(button); button = NULL; g_free(arg_str); arg_str = NULL; arg_int = 0; event = -1; action_free(action); action = NULL; parse_free_token(token); }