better error msgs
[dana/openbox.git] / plugins / mouse / mouseparse.c
1 #include "kernel/action.h"
2 #include "kernel/parse.h"
3 #include "mouse.h"
4
5 void mouseparse(ParseToken *token)
6 {
7     static char *top = NULL;
8     static char *context = NULL, *button = NULL;
9     static char *arg_str = NULL;
10     static int arg_int = 0;
11     static MouseAction event = -1;
12     static Action *action = NULL;
13     static gboolean err = FALSE;
14
15     if (err) {
16         if (token->type == TOKEN_NEWLINE)
17             err = FALSE;
18         /* just fall through and free the token */
19     } else if (top == NULL) {
20         if (token->type == TOKEN_IDENTIFIER &&
21             !g_ascii_strcasecmp("mbind", token->data.identifier)) {
22             top = token->data.identifier;
23             return;
24         } else {
25             yyerror("syntax error (expected mbind)");
26             err = TRUE;
27         }
28     } else if (context == NULL) {
29         if (token->type == TOKEN_IDENTIFIER) {
30             context = token->data.identifier;
31             return;
32         } else {
33             yyerror("syntax error (expected Key)");
34             err = TRUE;
35         }
36     } else if (event == (unsigned) -1) {
37         if (token->type == TOKEN_IDENTIFIER) {
38             if (!g_ascii_strcasecmp("press", token->data.identifier))
39                 event = MouseAction_Press;
40             else if (!g_ascii_strcasecmp("release", token->data.identifier))
41                 event = MouseAction_Release;
42             else if (!g_ascii_strcasecmp("click", token->data.identifier))
43                 event = MouseAction_Click;
44             else if (!g_ascii_strcasecmp("doubleclick",token->data.identifier))
45                 event = MouseAction_DClick;
46             else if (!g_ascii_strcasecmp("drag", token->data.identifier))
47                 event = MouseAction_Motion;
48             if (event != (unsigned) -1)
49                 return;
50             else {
51                 yyerror("invalid event");
52                 err = TRUE;
53             }
54         } else {
55             yyerror("syntax error (expected event)");
56             err = TRUE;
57         }
58     } else if (button == NULL) {
59         if (token->type == TOKEN_IDENTIFIER) {
60             button = token->data.identifier;
61             return;
62         } else {
63             yyerror("syntax error (expected button)");
64             err = TRUE;
65         }
66     } else if (action == NULL) {
67         if (token->type == TOKEN_IDENTIFIER) {
68             action = action_from_string(token->data.identifier);
69
70             /* check for valid actions for motion events */
71             if ((event == MouseAction_Motion) ^
72                 (action &&
73                  (action->func == action_move ||
74                   action->func == action_resize))) {
75                 action_free(action);
76                 action = NULL;
77             }
78
79             if (action != NULL) {
80                 return;
81             } else {
82                 yyerror("invalid action");
83                 err = TRUE;
84             }
85         } else {
86             yyerror("syntax error (expected action)");
87             err = TRUE;
88         }
89     } else if (token->type == TOKEN_STRING) {
90         arg_str = token->data.string;
91         return;
92     } else if (token->type == TOKEN_INTEGER) {
93         arg_int = token->data.integer;
94         return;
95     } else if (token->type != TOKEN_NEWLINE) {
96         yyerror("syntax error (unexpected trailing token)");
97     } else {
98
99         /* these use the argument */
100         if (action->func == action_execute || action->func == action_restart)
101             action->data.execute.path = g_strdup(arg_str);
102         if ((action->func == action_desktop ||
103              action->func == action_send_to_desktop) &&
104             arg_int)
105             action->data.desktop.desk = (unsigned) arg_int - 1;
106         if (action->func == action_move_relative_horz ||
107             action->func == action_move_relative_vert ||
108             action->func == action_resize_relative_horz ||
109             action->func == action_resize_relative_vert)
110             action->data.relative.delta = arg_int;
111
112         if (mbind(button, context, event, action))
113             action = NULL; /* don't free this if mbind succeeds */
114         else
115             yyerror("failed to add mouse binding");
116     }
117
118     g_free(top); top = NULL;
119     g_free(context); context = NULL;
120     g_free(button); button = NULL;
121     g_free(arg_str); arg_str = NULL;
122     arg_int = 0;
123     event = -1;
124     action_free(action); action = NULL;
125     parse_free_token(token);
126 }