]> icculus.org git repositories - dana/openbox.git/blob - plugins/keyboard/keyparse.c
more namespacing with Rr*
[dana/openbox.git] / plugins / keyboard / keyparse.c
1 #include "kernel/parse.h"
2 #include "kernel/prop.h"
3 #include "keyboard.h"
4
5 void keyparse(ParseToken *token)
6 {
7     static char *top = NULL;
8     static Action *action = NULL;
9     static GList *chain = NULL;
10     static gboolean err = FALSE;
11     static char *arg_str = NULL;
12     static int arg_int = 0;
13     GList *it;
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("kbind", token->data.identifier)) {
22             top = token->data.identifier;
23             return;
24         } else {
25             yyerror("syntax error (expected kbind)");
26             err = TRUE;
27         }
28     } else if (chain == NULL) {
29         if (token->type == TOKEN_LIST) {
30             for (it = token->data.list; it; it = it->next)
31                 if (((ParseToken*)it->data)->type != TOKEN_IDENTIFIER) break;
32             if (it == NULL) {
33                 chain = token->data.list;
34                 return;
35             } else {
36                 yyerror("invalid element in key chain");
37                 err = TRUE;
38             }
39         } else {
40             yyerror("syntax error (expected key chain)");
41             err = TRUE;
42         }
43     } else if (action == NULL) {
44         if (token->type == TOKEN_IDENTIFIER) {
45             action = action_from_string(token->data.identifier);
46
47             /* no move/resize with the keyboard */
48             if (action && action->func == action_moveresize &&
49                 action->data.moveresize.corner !=
50                 prop_atoms.net_wm_moveresize_move_keyboard &&
51                 action->data.moveresize.corner !=
52                 prop_atoms.net_wm_moveresize_size_keyboard) {
53                 action_free(action);
54                 action = NULL;
55             }
56
57             if (action != NULL) {
58                 parse_free_token(token); /* its data isnt saved */
59                 return;
60             } else {
61                 yyerror("invalid action");
62                 err = TRUE;
63             }
64         } else {
65             yyerror("syntax error (expected action)");
66             err = TRUE;
67         }
68     } else if (token->type == TOKEN_STRING) { /* string argument */
69         arg_str = token->data.string;
70         return;
71     } else if (token->type == TOKEN_INTEGER) { /* number argument */
72         arg_int = token->data.integer;
73         return;
74     } else if (token->type != TOKEN_NEWLINE) {
75         yyerror("syntax error (unexpected trailing token)");
76         err = TRUE;
77     } else {
78         GList *strchain = NULL;
79
80         /* build a list of just char*'s */
81         for (it = chain; it; it = it->next)
82             strchain = g_list_append(strchain,
83                                      ((ParseToken*)it->data)->data.identifier);
84
85         /* these use the argument */
86         if (action->func == action_execute || action->func == action_restart)
87             action->data.execute.path = g_strdup(arg_str);
88         else if (action->func == action_showmenu)
89             action->data.showmenu.name = g_strdup(arg_str);
90         if ((action->func == action_desktop ||
91              action->func == action_send_to_desktop) &&
92             arg_int)
93             action->data.desktop.desk = (unsigned) arg_int - 1;
94         if (action->func == action_move_relative_horz ||
95             action->func == action_move_relative_vert ||
96             action->func == action_resize_relative_horz ||
97             action->func == action_resize_relative_vert)
98             action->data.relative.delta = arg_int;
99
100         if (kbind(strchain, action))
101             action = NULL; /* don't free this if kbind succeeds */
102         else
103             yyerror("failed to add key binding");
104         /* free the char*'s */
105         g_list_free(strchain);
106
107         err = FALSE;
108     }    
109
110     g_free(top); top = NULL;
111     action_free(action); action = NULL;
112     g_free(arg_str); arg_str = NULL;
113     arg_int = 0;
114     for (it = chain; it; it = it->next) {
115         parse_free_token(it->data);
116         g_free(it->data);
117     }
118     g_list_free(chain); chain = NULL;
119     parse_free_token(token);
120 }