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
|
tree.lo
|
||||||
translate.lo
|
translate.lo
|
||||||
keyaction.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
|
plugindir=$(libdir)/openbox/plugins
|
||||||
|
rcdir=$(datadir)/openbox
|
||||||
|
|
||||||
CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) @CPPFLAGS@ \
|
CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) @CPPFLAGS@ \
|
||||||
-DPLUGINDIR=\"$(plugindir)\" \
|
-DPLUGINDIR=\"$(plugindir)\" \
|
||||||
|
-DRCDIR=\"$(rcdir)\" \
|
||||||
-DG_LOG_DOMAIN=\"Plugin-Keyboard\"
|
-DG_LOG_DOMAIN=\"Plugin-Keyboard\"
|
||||||
|
|
||||||
plugin_LTLIBRARIES=keyboard.la
|
plugin_LTLIBRARIES=keyboard.la
|
||||||
|
|
||||||
keyboard_la_LDFLAGS=-module -avoid-version
|
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
|
MAINTAINERCLEANFILES= Makefile.in
|
||||||
|
|
||||||
|
clean-local:
|
||||||
|
$(RM) y.tab.c lex.kparse.c
|
||||||
|
|
||||||
distclean-local:
|
distclean-local:
|
||||||
$(RM) *\~ *.orig *.rej .\#*
|
$(RM) *\~ *.orig *.rej .\#*
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "../../kernel/action.h"
|
#include "../../kernel/action.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
|
#include "keysrc.h"
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
void plugin_setup_config()
|
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;
|
KeyBindingTree *tree, *t;
|
||||||
gboolean conflict;
|
gboolean conflict;
|
||||||
|
@ -123,63 +124,11 @@ static void press(ObEvent *e, void *foo)
|
||||||
XAllowEvents(ob_display, AsyncKeyboard, e->data.x.e->xkey.time);
|
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()
|
void plugin_startup()
|
||||||
{
|
{
|
||||||
dispatch_register(Event_X_KeyPress, (EventHandler)press, NULL);
|
dispatch_register(Event_X_KeyPress, (EventHandler)press, NULL);
|
||||||
|
|
||||||
/* XXX parse config file! */
|
keysrc_parse();
|
||||||
binddef();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void plugin_shutdown()
|
void plugin_shutdown()
|
||||||
|
|
|
@ -7,6 +7,6 @@
|
||||||
|
|
||||||
extern KeyBindingTree *firstnode;
|
extern KeyBindingTree *firstnode;
|
||||||
|
|
||||||
guint keyboard_translate_modifier(char *str);
|
gboolean kbind(GList *keylist, Action *action);
|
||||||
|
|
||||||
#endif
|
#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) {
|
for (it = g_list_last(keylist); it != NULL; it = it->prev) {
|
||||||
p = ret;
|
p = ret;
|
||||||
ret = g_new(KeyBindingTree, 1);
|
ret = g_new0(KeyBindingTree, 1);
|
||||||
ret->next_sibling = NULL;
|
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
GList *it;
|
GList *it;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue