all repos — openbox @ 98c0c676dd5cc45a92bb9c90902de7f4c7d16528

openbox fork - make it a bit more like ryudo

plugins/keyboard/keyparse.c (raw)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include "kernel/parse.h"
#include "keyboard.h"

void keyparse(ParseToken *token)
{
    static char *top = NULL;
    static Action *action = NULL;
    static GList *chain = NULL;
    static gboolean err = FALSE;
    static char *arg_str = NULL;
    static int arg_int = 0;
    GList *it;

    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("key", token->data.identifier)) {
            top = token->data.identifier;
            return;
        } else {
            yyerror("syntax error (expected Key)");
            err = TRUE;
        }
    } else if (chain == NULL) {
        if (token->type == TOKEN_LIST) {
            for (it = token->data.list; it; it = it->next)
                if (((ParseToken*)it->data)->type != TOKEN_IDENTIFIER) break;
            if (it == NULL) {
                chain = token->data.list;
                return;
            } else {
                yyerror("invalid element in key chain");
                err = TRUE;
            }
        } else {
            yyerror("syntax error (expected key chain)");
            err = TRUE;
        }
    } else if (action == NULL) {
        if (token->type == TOKEN_IDENTIFIER) {
            action = action_from_string(token->data.identifier);

            /* no move/resize with the keyboard */
            if (action &&
                (action->func == action_move ||
                 action->func == action_resize)) {
                action_free(action);
                action = NULL;
            }

            if (action != NULL) {
                parse_free_token(token); /* its data isnt saved */
                return;
            } else {
                yyerror("invalid action");
                err = TRUE;
            }
        } else {
            yyerror("syntax error (expected action)");
            err = TRUE;
        }
    } else if (token->type == TOKEN_STRING) { /* string argument */
        arg_str = token->data.string;
        return;
    } else if (token->type == TOKEN_INTEGER) { /* number argument */
        arg_int = token->data.integer;
        return;
    } else if (token->type != TOKEN_NEWLINE) {
        yyerror("syntax error (unexpected trailing token)");
        err = TRUE;
    } else {
        GList *strchain = NULL;

        /* build a list of just char*'s */
        for (it = chain; it; it = it->next)
            strchain = g_list_append(strchain,
                                     ((ParseToken*)it->data)->data.identifier);

        /* these use the argument */
        if (action->func == action_execute || action->func == action_restart)
            action->data.execute.path = 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 (kbind(strchain, action))
            action = NULL; /* don't free this if kbind succeeds */
        else
            yyerror("failed to add binding");
        /* free the char*'s */
        g_list_free(strchain);

        err = FALSE;
    }    

    g_free(top); top = NULL;
    action_free(action); action = NULL;
    g_free(arg_str); arg_str = NULL;
    arg_int = 0;
    for (it = chain; it; it = it->next) {
        parse_free_token(it->data);
        g_free(it->data);
    }
    g_list_free(chain); chain = NULL;
    parse_free_token(token);
}