fields must not start or end with '-'
[mikachu/openbox.git] / plugins / mouse / mouserc_parse.l
1 %{
2 #include "mouse.h"
3 #include <glib.h>
4 #ifdef HAVE_STDIO_H
5 #  include <stdio.h>
6 #endif
7
8 static int lineno;
9 static char *path;
10 static gboolean comment;
11 static gboolean error;
12
13 static char *context;
14 static char *event;
15 static char *button;
16 static char *action;
17
18 static void endofline();
19 static int mparsewrap();
20 static void gotfield();
21 static void addbinding();
22 %}
23
24 field [A-Za-z0-9][-A-Za-z0-9]*[^-]
25 sep [ \t]+
26 white [ \t]*
27
28 %%
29
30 ^{white}# comment = TRUE;
31 {field} gotfield();
32 \n endofline();
33 [ \t]
34 . error = TRUE;
35
36 %%
37
38 static void gotfield()
39 {
40     if (context == NULL)
41         context = g_strdup(mparsetext);
42     else if (event == NULL)
43         event = g_strdup(mparsetext);
44     else if (button == NULL)
45         button = g_strdup(mparsetext);
46     else if (action == NULL)
47         action = g_strdup(mparsetext);
48     else
49         error = TRUE;
50 }
51
52 static void endofline()
53 {
54     if (!comment) {
55         if (!error && context && event && button && action)
56             addbinding();
57         else if (error || context || event || button || action)
58             g_warning("Parser error in '%s' on line %d", path, lineno);
59     }
60
61     comment = error = FALSE;
62     g_free(context); g_free(event); g_free(button); g_free(action);
63     context = event = button = action = NULL;
64
65     ++lineno;
66 }
67
68 static void addbinding()
69 {
70     Action *a;
71     MouseAction mact;
72
73     if (!g_ascii_strcasecmp(event, "press"))
74         mact = MouseAction_Press;
75     else if (!g_ascii_strcasecmp(event, "release"))
76         mact = MouseAction_Release;
77     else if (!g_ascii_strcasecmp(event, "click"))
78         mact = MouseAction_Click;
79     else if (!g_ascii_strcasecmp(event, "doubleclick"))
80         mact = MouseAction_DClick;
81     else if (!g_ascii_strcasecmp(event, "drag"))
82         mact = MouseAction_Motion;
83     else {
84         g_warning("Invalid event '%s' in '%s' on line %d", event, path,
85                   lineno);
86         return;
87     }
88
89     if (!g_ascii_strcasecmp(action, "focus")) {
90         a = action_new(action_focus);
91     } else if (!g_ascii_strcasecmp(action, "unfocus")) {
92         a = action_new(action_unfocus);
93     } else if (!g_ascii_strcasecmp(action, "iconify")) {
94         a = action_new(action_iconify);
95     } else if (!g_ascii_strcasecmp(action, "raise")) {
96         a = action_new(action_raise);
97     } else if (!g_ascii_strcasecmp(action, "lower")) {
98         a = action_new(action_lower);
99     } else if (!g_ascii_strcasecmp(action, "focusraise")) {
100         a = action_new(action_focusraise);
101     } else if (!g_ascii_strcasecmp(action, "close")) {
102         a = action_new(action_close);
103     } else if (!g_ascii_strcasecmp(action, "kill")) {
104         a = action_new(action_kill);
105     } else if (!g_ascii_strcasecmp(action, "shade")) {
106         a = action_new(action_shade);
107     } else if (!g_ascii_strcasecmp(action, "unshade")) {
108         a = action_new(action_unshade);
109     } else if (!g_ascii_strcasecmp(action, "toggleshade")) {
110         a = action_new(action_toggle_shade);
111     } else if (!g_ascii_strcasecmp(action, "toggleomnipresent")) {
112         a = action_new(action_toggle_omnipresent);
113     } else if (!g_ascii_strcasecmp(action, "maximizefull")) {
114         a = action_new(action_maximize_full);
115     } else if (!g_ascii_strcasecmp(action, "unmaximizefull")) {
116         a = action_new(action_unmaximize_full);
117     } else if (!g_ascii_strcasecmp(action, "togglemaximizefull")) {
118         a = action_new(action_toggle_maximize_full);
119     } else if (!g_ascii_strcasecmp(action, "maximizehorz")) {
120         a = action_new(action_maximize_horz);
121     } else if (!g_ascii_strcasecmp(action, "unmaximizehorz")) {
122         a = action_new(action_unmaximize_horz);
123     } else if (!g_ascii_strcasecmp(action, "togglemaximizehorz")) {
124         a = action_new(action_toggle_maximize_horz);
125     } else if (!g_ascii_strcasecmp(action, "maximizevert")) {
126         a = action_new(action_maximize_vert);
127     } else if (!g_ascii_strcasecmp(action, "unmaximizevert")) {
128         a = action_new(action_unmaximize_vert);
129     } else if (!g_ascii_strcasecmp(action, "togglemaximizevert")) {
130         a = action_new(action_toggle_maximize_vert);
131     } else if (!g_ascii_strcasecmp(action, "sendtonextdesktop")) {
132         a = action_new(action_send_to_next_desktop);
133         a->data.sendtonextprev.wrap = FALSE;
134         a->data.sendtonextprev.follow = TRUE;
135     } else if (!g_ascii_strcasecmp(action, "sendtonextdesktopwrap")) {
136         a = action_new(action_send_to_next_desktop);
137         a->data.sendtonextprev.wrap = TRUE;
138         a->data.sendtonextprev.follow = TRUE;
139     } else if (!g_ascii_strcasecmp(action, "sendtopreviousdesktop")) {
140         a = action_new(action_send_to_previous_desktop);
141         a->data.sendtonextprev.wrap = FALSE;
142         a->data.sendtonextprev.follow = TRUE;
143     } else if (!g_ascii_strcasecmp(action, "sendtopreviousdesktopwrap")) {
144         a = action_new(action_send_to_previous_desktop);
145         a->data.sendtonextprev.wrap = TRUE;
146         a->data.sendtonextprev.follow = TRUE;
147     } else if (!g_ascii_strcasecmp(action, "nextdesktop")) {
148         a = action_new(action_next_desktop);
149         a->data.nextprevdesktop.wrap = FALSE;
150     } else if (!g_ascii_strcasecmp(action, "nextdesktopwrap")) {
151         a = action_new(action_next_desktop);
152         a->data.nextprevdesktop.wrap = TRUE;
153     } else if (!g_ascii_strcasecmp(action, "previousdesktop")) {
154         a = action_new(action_previous_desktop);
155         a->data.nextprevdesktop.wrap = FALSE;
156     } else if (!g_ascii_strcasecmp(action, "previousdesktopwrap")) {
157         a = action_new(action_previous_desktop);
158         a->data.nextprevdesktop.wrap = TRUE;
159     } else if (!g_ascii_strcasecmp(action, "nextdesktopcolumn")) {
160         a = action_new(action_next_desktop_column);
161         a->data.nextprevdesktop.wrap = FALSE;
162     } else if (!g_ascii_strcasecmp(action, "nextdesktopcolumnwrap")) {
163         a = action_new(action_next_desktop_column);
164         a->data.nextprevdesktop.wrap = TRUE;
165     } else if (!g_ascii_strcasecmp(action, "previousdesktopcolumn")) {
166         a = action_new(action_previous_desktop_column);
167         a->data.nextprevdesktop.wrap = FALSE;
168     } else if (!g_ascii_strcasecmp(action, "previousdesktopcolumnwrap")) {
169         a = action_new(action_previous_desktop_column);
170         a->data.nextprevdesktop.wrap = TRUE;
171     } else if (!g_ascii_strcasecmp(action, "nextdesktoprow")) {
172         a = action_new(action_next_desktop_row);
173         a->data.nextprevdesktop.wrap = FALSE;
174     } else if (!g_ascii_strcasecmp(action, "nextdesktoprowwrap")) {
175         a = action_new(action_next_desktop_row);
176         a->data.nextprevdesktop.wrap = TRUE;
177     } else if (!g_ascii_strcasecmp(action, "previousdesktoprow")) {
178         a = action_new(action_previous_desktop_row);
179         a->data.nextprevdesktop.wrap = FALSE;
180     } else if (!g_ascii_strcasecmp(action, "previousdesktoprowwrap")) {
181         a = action_new(action_previous_desktop_row);
182         a->data.nextprevdesktop.wrap = TRUE;
183     } else if (!g_ascii_strcasecmp(action, "move") &&
184                mact == MouseAction_Motion) {
185         a = action_new(action_move);
186     } else if (!g_ascii_strcasecmp(action, "resize") &&
187                mact == MouseAction_Motion) {
188         a = action_new(action_resize);
189     } else {
190         g_warning("Invalid action '%s' in '%s' on line %d", action, path,
191                   lineno);
192         return;
193     }
194
195     if (!mbind(button, context, mact, a)) {
196         action_free(a);
197         g_warning("Unable to add binding '%s %s %s %s'",
198                   context, event, button, action);
199     }
200 }
201
202
203 static int mparsewrap()
204 {
205     g_free(context); g_free(event); g_free(button); g_free(action);
206     return 1;
207 }
208
209 void mouserc_parse()
210 {
211     path = g_build_filename(g_get_home_dir(), ".openbox", "mouserc", NULL);
212     if ((mparsein = fopen(path, "r")) == NULL) {
213         g_free(path);
214         path = g_build_filename(RCDIR, "mouserc", NULL);
215         if ((mparsein = fopen(path, "r")) == NULL) {
216             g_warning("No mouserc file found!");
217             g_free(path);
218             return;
219         }
220     }
221
222     lineno = 1;
223     comment = FALSE;
224     error = FALSE;
225     context = event = button = action = NULL;
226
227     mparselex();
228
229     g_free(path);
230 }