add the keyboard plugin into the build systems

keyboard bindings are parsed from the rc file
This commit is contained in:
Dana Jansens 2003-04-04 20:19:12 +00:00
parent c8ff993e08
commit 68ff2eb3d2
13 changed files with 195 additions and 281 deletions

View file

@ -25,6 +25,10 @@ all: $(target)
$(target): $(objects) render/librender.a $(target): $(objects) render/librender.a
$(LINK) -o $@ $^ $(LIBS) $(LDFLAGS) $(LINK) -o $@ $^ $(LIBS) $(LDFLAGS)
# kill the implicit .c.y rule
$(srcdir)/%.c: $(srcdir)/%.y
@
$(dir)/%.o: $(srcdir)/%.c $(depdir)/%.d $(dir)/%.o: $(srcdir)/%.c $(depdir)/%.d
$(COMPILE) -c -o $@ $< $(COMPILE) -c -o $@ $<
@ -58,4 +62,4 @@ distclean:
-include $(deps) -include $(deps)
.PHONY: kernel-install kernel-uninstall kernel-clean .PHONY: all install uninstall clean distclean

View file

@ -3,15 +3,18 @@ include build/Makefile.incl
all clean distclean: all clean distclean:
@$(MAKE) -$(MAKEFLAGS) -f build/Makefile.plugins.resistance $@ @$(MAKE) -$(MAKEFLAGS) -f build/Makefile.plugins.resistance $@
@$(MAKE) -$(MAKEFLAGS) -f build/Makefile.plugins.placement $@ @$(MAKE) -$(MAKEFLAGS) -f build/Makefile.plugins.placement $@
@$(MAKE) -$(MAKEFLAGS) -f build/Makefile.plugins.keyboard $@
install: install:
@$(MAKE) -$(MAKEFLAGS) -f build/Makefile.plugins.resistance $@ @$(MAKE) -$(MAKEFLAGS) -f build/Makefile.plugins.resistance $@
@$(MAKE) -$(MAKEFLAGS) -f build/Makefile.plugins.placement $@ @$(MAKE) -$(MAKEFLAGS) -f build/Makefile.plugins.placement $@
@$(MAKE) -$(MAKEFLAGS) -f build/Makefile.plugins.keyboard $@
$(LIBTOOL) --mode=finish $(DESTDIR)$(plugindir) $(LIBTOOL) --mode=finish $(DESTDIR)$(plugindir)
uninstall: uninstall:
@$(MAKE) -$(MAKEFLAGS) -f build/Makefile.plugins.resistance $@ @$(MAKE) -$(MAKEFLAGS) -f build/Makefile.plugins.resistance $@
@$(MAKE) -$(MAKEFLAGS) -f build/Makefile.plugins.placement $@ @$(MAKE) -$(MAKEFLAGS) -f build/Makefile.plugins.placement $@
@$(MAKE) -$(MAKEFLAGS) -f build/Makefile.plugins.keyboard $@
-rmdir $(DESTDIR)$(plugindir) -rmdir $(DESTDIR)$(plugindir)
.PHONY: all clean distclean install uninstall .PHONY: all clean distclean install uninstall

View file

@ -0,0 +1,45 @@
include build/Makefile.incl
dir = plugins/keyboard
CPPFLAGS += $(GLIB_CFLAGS) $(XFT_CFLAGS) -DG_LOG_DOMAIN=\"Plugin-Placement\"
LDFLAGS = -module -avoid-version
target = keyboard.la
sources = keyboard.c tree.c translate.c keyparse.c
srcdir := $(srcdir)/$(dir)
target := $(addprefix $(dir)/,$(target))
objects := $(addprefix $(dir)/,$(sources:.c=.lo))
sources := $(addprefix $(srcdir)/,$(sources))
deps := $(addprefix $(depdir)/,$(objects:.lo=.d))
depdir := $(depdir)/$(dir)
all: $(target)
$(target): $(objects)
$(LINK) -rpath $(plugindir) -o $@ $^ $(LDFLAGS)
$(dir)/%.lo: $(srcdir)/%.c $(depdir)/%.d
$(LTCOMPILE) -c -o $@ $<
$(depdir)/%.d: $(srcdir)/%.c
@echo Building dependancies for $<
$(INSTALL) -d $(depdir)
@$(DEPCOMPILE) -w -MM -MF $@ -MQ $(<:.c=.lo) $<
install:
$(INSTALL) -d $(DESTDIR)$(plugindir)/
$(LIBTOOL) --mode=install $(INSTALL) $(target) \
$(DESTDIR)$(plugindir)/$(notdir $(target))
uninstall:
$(LTRM) $(DESTDIR)$(plugindir)/$(notdir $(target))
clean:
$(RM) $(target) $(objects)
$(RM) $(srcdir)/*\~
-include $(deps)
.PHONY: all install uninstall clean distclean

View file

@ -33,7 +33,7 @@ void parse_reg_section(char *section, ParseFunc func)
void parse_free_token(ParseToken *token) void parse_free_token(ParseToken *token)
{ {
GSList *it; GList *it;
switch (token->type) { switch (token->type) {
case TOKEN_STRING: case TOKEN_STRING:
@ -47,7 +47,7 @@ void parse_free_token(ParseToken *token)
parse_free_token(it->data); parse_free_token(it->data);
g_free(it->data); g_free(it->data);
} }
g_slist_free(token->data.list); g_list_free(token->data.list);
break; break;
case TOKEN_REAL: case TOKEN_REAL:
case TOKEN_INTEGER: case TOKEN_INTEGER:

View file

@ -13,7 +13,7 @@
char *identifier; char *identifier;
gboolean bool; gboolean bool;
char character; char character;
GSList *list; GList *list;
} }
%{ %{
@ -89,12 +89,12 @@ listtokens:
listtokens listtoken { ParseToken *nt = g_new(ParseToken, 1); listtokens listtoken { ParseToken *nt = g_new(ParseToken, 1);
nt->type = t.type; nt->type = t.type;
nt->data = t.data; nt->data = t.data;
$$ = g_slist_append($1, nt); $$ = g_list_append($1, nt);
} }
| token { ParseToken *nt = g_new(ParseToken, 1); | listtoken { ParseToken *nt = g_new(ParseToken, 1);
nt->type = t.type; nt->type = t.type;
nt->data = t.data; nt->data = t.data;
$$ = g_slist_append(NULL, nt); $$ = g_list_append(NULL, nt);
} }
; ;

View file

@ -3,3 +3,5 @@ keyboard.la
tree.lo tree.lo
translate.lo translate.lo
keyaction.lo keyaction.lo
.libs
keyparse.lo

View file

@ -1,17 +1,19 @@
#include "../../kernel/focus.h" #include "kernel/focus.h"
#include "../../kernel/dispatch.h" #include "kernel/dispatch.h"
#include "../../kernel/openbox.h" #include "kernel/openbox.h"
#include "../../kernel/event.h" #include "kernel/event.h"
#include "../../kernel/grab.h" #include "kernel/grab.h"
#include "../../kernel/action.h" #include "kernel/action.h"
#include "kernel/parse.h"
#include "tree.h" #include "tree.h"
#include "keyboard.h" #include "keyboard.h"
#include "keysrc.h" #include "keyparse.h"
#include "translate.h" #include "translate.h"
#include <glib.h> #include <glib.h>
void plugin_setup_config() void plugin_setup_config()
{ {
parse_reg_section("keyboard", keyparse);
} }
KeyBindingTree *firstnode; KeyBindingTree *firstnode;
@ -131,8 +133,6 @@ void plugin_startup()
dispatch_register(Event_X_KeyPress, (EventHandler)press, NULL); dispatch_register(Event_X_KeyPress, (EventHandler)press, NULL);
translate_key("C-g", &reset_state, &reset_key); translate_key("C-g", &reset_state, &reset_key);
keysrc_parse();
} }
void plugin_shutdown() void plugin_shutdown()

117
plugins/keyboard/keyparse.c Normal file
View file

@ -0,0 +1,117 @@
#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);
g_print("Chain %s\n", ((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);
}

View file

@ -0,0 +1,8 @@
#ifndef __plugin_keyboard_keyparse_h
#define __plugin_keyboard_keyparse_h
#include "kernel/parse.h"
void keyparse(ParseToken *token);
#endif

View file

@ -1,117 +0,0 @@
# Keysrc - Keybindings configuration for Openbox
# Key [Key...] Action [Argument]
# Key: A list of keys to form a key chain, or just a single key. Each key in
# the chain is separated by a space.
#
# Each Key is a string composed of [<modifier>-]<key>. A Key can have 0 or more
# modifiers. Valid modifiers are Control ('C' is an alias for this), Shift
# ('S' is an alias for this), Mod1 ('A' is an alias for this), Mod2, Mod3,
# Mod4 ('W' is an alias for this), and Mod5. Valid buttons are defined by the
# X server. The 'xev' utility can be used to look up the name of a key.
#
# When there is more than one Key in a binding, they form a chain, where you
# must press the first Key, then the second, etc, to fire the binding.
#
# The 'C-g' key combination can be used to abort a key chain in progress.
# Action: The action to be performed when the key binding is pressed.
#
# * Unfocus - Unfocus the focused client
# * Iconify - Iconify the focused client
# * Raise - Raise the focused client to the front
# * Lower - Lower the focused client to the back
# * Close - Close the focused client
# * Kill - Kill the focused client forcefully
# * Shade - Shade (roll up) the focused client
# * Unshade - Unshade (roll down) the focused client
# * ToggleShade - Shade and unshade the focused client
# * ShadeLower - Shades the window if it's not shaded, and lower it
# if it was already shaded
# * UnshadeRaise - Unshades the window if it's shaded, and raise it
# if it was already unshaded
# * ToggleOmnipresent - Place the focused client on all desktops or the
# current one
# * MaximizeFull - Maximize the focused window horizontally and vertically
# * UnmaximizeFull - Restore the focused window horizontally and vertically
# * ToggleMaximizeFull - Maximize or restore the focused window horizontally
# and vertically
# * MaximizeHorz - Maximize the focused window horizontally
# * UnmaximizeHorz - Restore the focused window horizontally
# * ToggleMaximizeHorz - Maximize or restore the focused window horizontally
# * MaximizeVert - Maximize the focused window vertically
# * UnmaximizeVert - Restore the focused window vertically
# * ToggleMaximizeVert - Maximize or restore the focused window vertically
# * SendToDesktop - Sends the focused window to a specified desktop
# * Takes a number argument which specifies the desktop to send the window
# to (starting at 1).
# * SendToNextDesktop - Sends the focused window to the next desktop
# * SendToNextDesktopWrap - Sends the focused window to the next desktop
# (wrapping around the first and last desktops)
# * SendToPreviousDesktop - Sends the focused window to the previous desktop
# * SendToPreviousDesktopWrap - Sends the focused window to the previous
# desktop (wrapping around the first and last
# desktops)
# * Desktop - Switches to the specified desktop
# * Takes a number argument which specifies the desktop to switch to
# (starting at 1).
# * NextDesktop - Switches to the next desktop
# * NextDesktopWrap - Switches to the next desktop (wrapping around the first
# and last desktops)
# * PreviousDesktop - Switches to the previous desktop
# * PreviousDesktopWrap - Switches to the previous desktop (wrapping around
# the first and last desktops)
# * NextDesktopColumn - Switches to the desktop in the next column, based on
# the desktop layout set by a pager
# * NextDesktopColumnWrap - Switches to the desktop in the next column, based
# on the desktop layout set by a pager (wrapping
# around the first and last columns)
# * PreviousDesktopColumn - Switches to the desktop in the previous column,
# based on the desktop layout set by a pager
# * PreviousDesktopColumnWrap - Switches to the desktop in the previous
# column, based on the desktop layout set by a
# pager (wrapping around the first and last
# columns)
# * NextDesktopRow - Switches to the desktop in the next row, based on the
# desktop layout set by a pager
# * NextDesktopRowWrap - Switches to the desktop in the next row, based on the
# desktop layout set by a pager (wrapping around the
# first and last rows)
# * PreviousDesktopRow - Switches to the desktop in the previous row, based on
# the desktop layout set by a pager
# * PreviousDesktopRowWrap - Switches to the desktop in the previous row,
# based on the desktop layout set by a pager
# (wrapping around the first and last rows)
# * ToggleDecorations - Toggles all decorations around a window on and off
# * MoveRelativeHorz - Moves the focused client horizontally
# * Takes a number argument which specifies the amount to move the window.
# A positive number moves to the right, negative to the left.
# * MoveRelativeVert - Moves the focused client vertcally
# * Takes a number argument which specifies the amount to move the window.
# A positive number moves down, negative up.
# * ResizeRelativeHorz - Resizes the focused client horizontally
# * Takes a number argument which specifies the amount to resize the
# window. A positive number grows it, a negative number shrinks it.
# * ResizeRelativeVert - Resizes the focused client vertically
# * Takes a number argument which specifies the amount to resize the
# window. A positive number grows it, a negative number shrinks it.
# * Execute - Executes a command
# * Takes a string argument "in quotes" that is the command to execute.
# * Restart - Restarts Openbox
# * Optionally takes a string argument "in quotes" that is the command to
# execute in place of restarting Openbox.
# * Exit - Exits Openbox
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

View file

@ -1,6 +0,0 @@
#ifndef __plugin_keyboard_keysrc_h
#define __plugin_keyboard_keysrc_h
void keysrc_parse();
#endif

View file

@ -1,38 +0,0 @@
%{
#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]|[0-9])[0-9]*
string \"[^"\n]*\"
%%
^[ \t]*#.*\n kparselineno++;
{number} kparselval.integer = atoi(kparsetext); return INTEGER;
{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;
}

View file

@ -1,104 +0,0 @@
%{
#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> DESKTOP
%type <list> fields
%%
config:
| config '\n'
| config fields FIELD '\n' { addbinding($2, $3, NULL, 0); }
| config fields FIELD INTEGER '\n' { addbinding($2, $3, NULL, $4); }
| config fields FIELD STRING '\n' { addbinding($2, $3, $4, 0); }
;
fields:
FIELD { $$ = g_list_append(NULL, $1); }
| fields FIELD { $$ = g_list_append($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;
else
g_free(apath);
if (a->func == action_desktop || a->func == action_send_to_desktop)
a->data.desktop.desk = (unsigned) num - 1;
if (a->func == action_move_relative_horz ||
a->func == action_move_relative_vert ||
a->func == action_resize_relative_horz ||
a->func == action_resize_relative_vert)
a->data.relative.delta = num;
if (!kbind(keylist, a)) {
action_free(a);
g_warning("Unable to add binding in '%s' on line %d", path,
kparselineno - 1);
}
}