load keybindings from keysrc
This commit is contained in:
parent
59ad2e319a
commit
91ebde9e88
9 changed files with 186 additions and 59 deletions
|
@ -7,3 +7,8 @@ Makefile.in
|
|||
tree.lo
|
||||
translate.lo
|
||||
keyaction.lo
|
||||
lex.kparse.c
|
||||
lex.kparse.lo
|
||||
y.tab.c
|
||||
y.tab.h
|
||||
y.tab.lo
|
||||
|
|
|
@ -1,17 +1,30 @@
|
|||
plugindir=$(libdir)/openbox/plugins
|
||||
rcdir=$(datadir)/openbox
|
||||
|
||||
CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) @CPPFLAGS@ \
|
||||
-DPLUGINDIR=\"$(plugindir)\" \
|
||||
-DRCDIR=\"$(rcdir)\" \
|
||||
-DG_LOG_DOMAIN=\"Plugin-Keyboard\"
|
||||
|
||||
plugin_LTLIBRARIES=keyboard.la
|
||||
|
||||
keyboard_la_LDFLAGS=-module -avoid-version
|
||||
keyboard_la_SOURCES=keyboard.c tree.c translate.c
|
||||
keyboard_la_SOURCES=keyboard.c tree.c translate.c y.tab.c lex.kparse.c
|
||||
|
||||
noinst_HEADERS=keyboard.h tree.h translate.h
|
||||
lex.kparse.c: keysrc.l y.tab.c
|
||||
$(FLEX) -Pkparse $<
|
||||
|
||||
y.tab.c: keysrc.yacc
|
||||
$(YACC) -d -p kparse $<
|
||||
|
||||
rc_DATA=keysrc
|
||||
|
||||
noinst_HEADERS=keyboard.h tree.h translate.h keysrc.h
|
||||
|
||||
MAINTAINERCLEANFILES= Makefile.in
|
||||
|
||||
clean-local:
|
||||
$(RM) y.tab.c lex.kparse.c
|
||||
|
||||
distclean-local:
|
||||
$(RM) *\~ *.orig *.rej .\#*
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "../../kernel/action.h"
|
||||
#include "tree.h"
|
||||
#include "keyboard.h"
|
||||
#include "keysrc.h"
|
||||
#include <glib.h>
|
||||
|
||||
void plugin_setup_config()
|
||||
|
@ -40,7 +41,7 @@ static void reset_chains()
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean kbind(GList *keylist, Action *action)
|
||||
gboolean kbind(GList *keylist, Action *action)
|
||||
{
|
||||
KeyBindingTree *tree, *t;
|
||||
gboolean conflict;
|
||||
|
@ -123,63 +124,11 @@ static void press(ObEvent *e, void *foo)
|
|||
XAllowEvents(ob_display, AsyncKeyboard, e->data.x.e->xkey.time);
|
||||
}
|
||||
|
||||
static void binddef()
|
||||
{
|
||||
GList *list = g_list_append(NULL, NULL);
|
||||
Action *a;
|
||||
|
||||
/* When creating an Action struct, all of the data elements in the
|
||||
appropriate struct need to be set, except the Client*, which will be set
|
||||
at call-time when then action function is used.
|
||||
*/
|
||||
|
||||
list->data = "A-Right";
|
||||
a = action_new(action_next_desktop);
|
||||
a->data.nextprevdesktop.wrap = TRUE;
|
||||
kbind(list, a);
|
||||
|
||||
list->data = "A-Left";
|
||||
a = action_new(action_previous_desktop);
|
||||
a->data.nextprevdesktop.wrap = TRUE;
|
||||
kbind(list, a);
|
||||
|
||||
list->data = "A-1";
|
||||
a = action_new(action_desktop);
|
||||
a->data.desktop.desk = 0;
|
||||
kbind(list, a);
|
||||
|
||||
list->data = "A-2";
|
||||
a = action_new(action_desktop);
|
||||
a->data.desktop.desk = 1;
|
||||
kbind(list, a);
|
||||
|
||||
list->data = "A-3";
|
||||
a = action_new(action_desktop);
|
||||
a->data.desktop.desk = 2;
|
||||
kbind(list, a);
|
||||
|
||||
list->data = "A-4";
|
||||
a = action_new(action_desktop);
|
||||
a->data.desktop.desk = 3;
|
||||
kbind(list, a);
|
||||
|
||||
list->data = "A-space";
|
||||
a = action_new(action_execute);
|
||||
a->data.execute.path = g_strdup("xterm");
|
||||
kbind(list, a);
|
||||
|
||||
list->data = "C-A-Escape";
|
||||
a = action_new(action_execute);
|
||||
a->data.execute.path = g_strdup("xlock -nolock -mode puzzle");
|
||||
kbind(list, a);
|
||||
}
|
||||
|
||||
void plugin_startup()
|
||||
{
|
||||
dispatch_register(Event_X_KeyPress, (EventHandler)press, NULL);
|
||||
|
||||
/* XXX parse config file! */
|
||||
binddef();
|
||||
keysrc_parse();
|
||||
}
|
||||
|
||||
void plugin_shutdown()
|
||||
|
|
|
@ -7,6 +7,6 @@
|
|||
|
||||
extern KeyBindingTree *firstnode;
|
||||
|
||||
guint keyboard_translate_modifier(char *str);
|
||||
gboolean kbind(GList *keylist, Action *action);
|
||||
|
||||
#endif
|
||||
|
|
10
plugins/keyboard/keysrc
Normal file
10
plugins/keyboard/keysrc
Normal file
|
@ -0,0 +1,10 @@
|
|||
A-space execute "xterm"
|
||||
C-A-Escape execute "xlock -nolock -mode puzzle"
|
||||
|
||||
A-Left PreviousDesktopWrap
|
||||
A-Right NextDesktopWrap
|
||||
|
||||
A-1 Desktop 1
|
||||
A-2 Desktop 2
|
||||
A-3 Desktop 3
|
||||
A-4 Desktop 4
|
6
plugins/keyboard/keysrc.h
Normal file
6
plugins/keyboard/keysrc.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef __plugin_keyboard_keysrc_h
|
||||
#define __plugin_keyboard_keysrc_h
|
||||
|
||||
void keysrc_parse();
|
||||
|
||||
#endif
|
44
plugins/keyboard/keysrc.l
Normal file
44
plugins/keyboard/keysrc.l
Normal file
|
@ -0,0 +1,44 @@
|
|||
%{
|
||||
#include <glib.h>
|
||||
#include "y.tab.h"
|
||||
|
||||
extern void kparseerror(char *s);
|
||||
int kparselineno;
|
||||
%}
|
||||
|
||||
field [A-Za-z0-9][-A-Za-z0-9]*
|
||||
number [0-9]+
|
||||
desktop [dD][eE][sS][kK][tT][oO][pP]
|
||||
execute [eE][xX][eE][cC][uU][tT][eE]
|
||||
restart [rR][eE][sS][tT][aA][rR][tT]
|
||||
string \"[^"\n]*\"
|
||||
|
||||
%%
|
||||
|
||||
^[ \t]*#.*\n kparselineno++;
|
||||
{number} kparselval.integer = atoi(kparsetext); return INTEGER;
|
||||
{execute} kparselval.string = g_strdup(kparsetext); return EXECUTE;
|
||||
{restart} kparselval.string = g_strdup(kparsetext); return RESTART;
|
||||
{desktop} kparselval.string = g_strdup(kparsetext); return DESKTOP;
|
||||
{field} kparselval.string = g_strdup(kparsetext); return FIELD;
|
||||
{string} {
|
||||
/* drop the quotes */
|
||||
kparselval.string = g_strdup(kparsetext+1);
|
||||
if (kparselval.string[kparseleng-2] != '"') {
|
||||
g_warning("improperly terminated string on line %d\n",
|
||||
kparselineno);
|
||||
kparseerror("");
|
||||
} else
|
||||
kparselval.string[kparseleng-2] = '\0';
|
||||
return STRING;
|
||||
}
|
||||
|
||||
[ \t]
|
||||
\n kparselineno++; return *yytext;
|
||||
. kparseerror("");
|
||||
|
||||
%%
|
||||
|
||||
int kparsewrap() {
|
||||
return 1;
|
||||
}
|
101
plugins/keyboard/keysrc.yacc
Normal file
101
plugins/keyboard/keysrc.yacc
Normal file
|
@ -0,0 +1,101 @@
|
|||
%{
|
||||
#include "keyboard.h"
|
||||
#include "../../kernel/action.h"
|
||||
#include <glib.h>
|
||||
#ifdef HAVE_STDIO_H
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
|
||||
extern int kparselex();
|
||||
extern int kparselineno;
|
||||
extern FILE *kparsein; /* lexer input */
|
||||
|
||||
void kparseerror(char *s);
|
||||
static void addbinding(GList *keylist, char *action, char *path, int num);
|
||||
|
||||
static char *path;
|
||||
%}
|
||||
|
||||
%union {
|
||||
char *string;
|
||||
int integer;
|
||||
GList *list;
|
||||
}
|
||||
|
||||
%token <integer> INTEGER;
|
||||
%token <string> STRING
|
||||
%token <string> FIELD
|
||||
%token <string> EXECUTE
|
||||
%token <string> RESTART
|
||||
%token <string> DESKTOP
|
||||
|
||||
%type <list> fields
|
||||
|
||||
%%
|
||||
|
||||
config:
|
||||
| config '\n'
|
||||
| config fields FIELD '\n' { addbinding($2, $3, NULL, 0); }
|
||||
| config fields DESKTOP INTEGER '\n' { addbinding($2, $3, NULL, $4); }
|
||||
| config fields RESTART '\n' { addbinding($2, $3, NULL, 0); }
|
||||
| config fields EXECUTE STRING '\n' { addbinding($2, $3, $4, 0); }
|
||||
| config fields RESTART STRING '\n' { addbinding($2, $3, $4, 0); }
|
||||
;
|
||||
|
||||
fields:
|
||||
FIELD { $$ = g_list_prepend(NULL, $1); }
|
||||
| fields FIELD { $$ = g_list_prepend($1, $2); }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
void kparseerror(char *s) {
|
||||
g_warning("Parser error in '%s' on line %d", path, kparselineno);
|
||||
}
|
||||
|
||||
void keysrc_parse()
|
||||
{
|
||||
path = g_build_filename(g_get_home_dir(), ".openbox", "keysrc", NULL);
|
||||
if ((kparsein = fopen(path, "r")) == NULL) {
|
||||
g_free(path);
|
||||
path = g_build_filename(RCDIR, "keysrc", NULL);
|
||||
if ((kparsein = fopen(path, "r")) == NULL) {
|
||||
g_warning("No keysrc file found!");
|
||||
g_free(path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
kparselineno = 1;
|
||||
|
||||
kparseparse();
|
||||
}
|
||||
|
||||
static void addbinding(GList *keylist, char *action, char *apath, int num)
|
||||
{
|
||||
Action *a;
|
||||
|
||||
a = action_from_string(action);
|
||||
|
||||
/* no move/resize with the keyboard */
|
||||
if (a && (a->func == action_move || a->func == action_resize)) {
|
||||
action_free(a);
|
||||
a = NULL;
|
||||
}
|
||||
if (a == NULL) {
|
||||
g_warning("Invalid action '%s' in '%s' on line %d", action, apath,
|
||||
kparselineno - 1);
|
||||
return;
|
||||
}
|
||||
/* these have extra data! */
|
||||
if (a->func == action_execute || a->func == action_restart)
|
||||
a->data.execute.path = apath;
|
||||
if (a->func == action_desktop)
|
||||
a->data.desktop.desk = (unsigned) num + 1;
|
||||
|
||||
if (!kbind(keylist, a)) {
|
||||
action_free(a);
|
||||
g_warning("Unable to add binding in '%s' on line %d", path,
|
||||
kparselineno - 1);
|
||||
}
|
||||
}
|
|
@ -31,8 +31,7 @@ KeyBindingTree *tree_build(GList *keylist)
|
|||
|
||||
for (it = g_list_last(keylist); it != NULL; it = it->prev) {
|
||||
p = ret;
|
||||
ret = g_new(KeyBindingTree, 1);
|
||||
ret->next_sibling = NULL;
|
||||
ret = g_new0(KeyBindingTree, 1);
|
||||
if (p == NULL) {
|
||||
GList *it;
|
||||
|
||||
|
|
Loading…
Reference in a new issue