void OBBindings::display()
{
- if (_tree.first_child)
- print_branch(_tree.first_child, "");
+ if (_keytree.first_child) {
+ printf("Key Tree:\n");
+ print_branch(_keytree.first_child, "");
+ }
+ if (_mousetree.next_sibling) {
+ printf("Mouse Tree:\n");
+ BindingTree *p = _mousetree.next_sibling;
+ while (p) {
+ printf("%d %s\n", p->id, p->text.c_str());
+ p = p->next_sibling;
+ }
+ }
}
+static bool buttonvalue(const std::string &button, unsigned int *val)
+{
+ if (button == "1" || button == "Button1") {
+ *val |= Button1;
+ } else if (button == "2" || button == "Button2") {
+ *val |= Button2;
+ } else if (button == "3" || button == "Button3") {
+ *val |= Button3;
+ } else if (button == "4" || button == "Button4") {
+ *val |= Button4;
+ } else if (button == "5" || button == "Button5") {
+ *val |= Button5;
+ } else
+ return false;
+ return true;
+}
+
static bool modvalue(const std::string &mod, unsigned int *val)
{
if (mod == "C") { // control
return true;
}
-bool OBBindings::translate(const std::string &str, Binding &b)
+bool OBBindings::translate(const std::string &str, Binding &b, bool askey)
{
// parse out the base key name
std::string::size_type keybegin = str.find_last_of('-');
std::string mod(str, begin, end-begin);
if (!modvalue(mod, &modval)) {
- printf(_("Invalid modifier element in key binding: %s\n"), mod.c_str());
+// printf(_("Invalid modifier element in key binding: %s\n"), mod.c_str());
return false;
}
}
// set the binding
- KeySym sym = XStringToKeysym(const_cast<char *>(key.c_str()));
- if (sym == NoSymbol) return false;
b.modifiers = modval;
- b.key = XKeysymToKeycode(otk::OBDisplay::display, sym);
- return b.key != 0;
+ if (askey) {
+ KeySym sym = XStringToKeysym(const_cast<char *>(key.c_str()));
+ if (sym == NoSymbol) return false;
+ b.key = XKeysymToKeycode(otk::OBDisplay::display, sym);
+ return b.key != 0;
+ } else {
+ return buttonvalue(key, &b.key);
+ }
}
static void destroytree(BindingTree *tree)
ret = new BindingTree(id);
if (!p) ret->chain = false;
ret->first_child = p;
- if (!translate(*it, ret->binding)) {
+ if (!translate(*it, ret->binding, true)) {
destroytree(ret);
ret = 0;
break;
OBBindings::OBBindings()
+ : _curpos(&_keytree)
{
}
}
+bool OBBindings::add_mouse(const std::string &button, int id)
+{
+ BindingTree n;
+
+ if (!translate(button, n.binding, false))
+ return false;
+
+ BindingTree *p = _mousetree.next_sibling, *last = &_mousetree;
+ while (p) {
+ if (p->binding == n.binding)
+ return false; // conflict
+ last = p;
+ p = p->next_sibling;
+ }
+ display();
+ last->next_sibling = new BindingTree(id);
+ display();
+ last->next_sibling->chain = false;
+ last->next_sibling->binding.key = n.binding.key;
+ last->next_sibling->binding.modifiers = n.binding.modifiers;
+
+ return true;
+}
+
+
+int OBBindings::remove_mouse(const std::string &button)
+{
+ (void)button;
+ assert(false); // XXX: function not implemented yet
+}
+
+
void OBBindings::assimilate(BindingTree *node)
{
BindingTree *a, *b, *tmp, *last;
- if (!_tree.first_child) {
+ if (!_keytree.first_child) {
// there are no nodes at this level yet
- _tree.first_child = node;
+ _keytree.first_child = node;
return;
} else {
- a = _tree.first_child;
+ a = _keytree.first_child;
last = a;
b = node;
while (a) {
}
-int OBBindings::find(BindingTree *search) {
+int OBBindings::find_key(BindingTree *search) {
BindingTree *a, *b;
- a = _tree.first_child;
+ a = _keytree.first_child;
b = search;
while (a && b) {
if (a->binding != b->binding) {
return -1; // it just isn't in here
}
-/*
-static int find(BindingTree *parent, BindingTree *node) {
- BindingTree *p, *lastsib, *nextparent, *nextnode = node->first_child;
-
- if (!parent->first_child)
- return -1;
-
- p = parent->first_child;
- while (p) {
- if (node->binding == p->binding) {
- if (node->chain == p->chain) {
- if (!node->chain) {
- return p->id; // found it! (return the actual id, not the search's)
- } else {
- break; // go on to the next child in the chain
- }
- } else {
- return -2; // the chain status' don't match (conflict!)
- }
- }
- p = p->next_sibling;
- }
- if (!p) return -1; // doesn't exist
-
- if (node->chain) {
- assert(node->first_child);
- return find(p, node->first_child);
- } else
- return -1; // it just isnt in here
-}
-*/
-
-bool OBBindings::add(const StringVect &keylist, int id)
+bool OBBindings::add_key(const StringVect &keylist, int id)
{
BindingTree *tree;
if (!(tree = buildtree(keylist, id)))
return false; // invalid binding requested
- if (find(tree) < -1) {
+ if (find_key(tree) < -1) {
// conflicts with another binding
destroytree(tree);
return false;
}
-int OBBindings::find(const StringVect &keylist)
+int OBBindings::find_key(const StringVect &keylist)
{
BindingTree *tree;
bool ret;
if (!(tree = buildtree(keylist, 0)))
return false; // invalid binding requested
- ret = find(tree) >= 0;
+ ret = find_key(tree) >= 0;
destroytree(tree);
}
-int OBBindings::remove(const StringVect &keylist)
+int OBBindings::remove_key(const StringVect &keylist)
{
(void)keylist;
assert(false); // XXX: function not implemented yet
void OBBindings::remove_all()
{
- if (_tree.first_child)
- remove_branch(_tree.first_child);
+ if (_keytree.first_child) {
+ remove_branch(_keytree.first_child);
+ _keytree.first_child = 0;
+ }
+ BindingTree *p = _mousetree.next_sibling;
+ while (p) {
+ BindingTree *n = p->next_sibling;
+ delete p;
+ p = n;
+ }
+ _mousetree.next_sibling = 0;
+}
+
+
+void OBBindings::process(unsigned int modifiers, unsigned int key)
+{
+ BindingTree *c = _curpos->first_child;
+
+ while (c) {
+ if (c->binding.key == key && c->binding.modifiers == modifiers) {
+ _curpos = c;
+ break;
+ }
+ }
+ if (c) {
+ if (!_curpos->chain) {
+ // XXX execute command for _curpos->id
+ _curpos = &_keytree; // back to the start
+ }
+ }
}
}
typedef std::vector<std::string> StringVect;
private:
- BindingTree _tree;// root node of the tree (this doesn't have siblings!)
+ BindingTree _keytree; // root node of the tree (this doesn't have siblings!)
+ BindingTree *_curpos; // position in the keytree
- int find(BindingTree *search);
- bool translate(const std::string &str, Binding &b);
+ BindingTree _mousetree; // this tree is a list. it has only siblings
+
+ int find_key(BindingTree *search);
+ bool translate(const std::string &str, Binding &b, bool askey);
BindingTree *buildtree(const StringVect &keylist, int id);
void OBBindings::assimilate(BindingTree *node);
//! Destroys the OBBinding object
virtual ~OBBindings();
- //! Adds a new binding
+ //! Adds a new mouse binding
+ /*!
+ A binding will fail to be added if the binding already exists, or if the
+ string is invalid.
+ @return true if the binding could be added; false if it could not.
+ */
+ bool add_mouse(const std::string &button, int id);
+
+ //! Removes a mouse binding
+ /*!
+ @return The id of the binding that was removed, or '< 0' if none were
+ removed.
+ */
+ int remove_mouse(const std::string &button);
+
+ //! Adds a new key binding
/*!
A binding will fail to be added if the binding already exists (as part of
a chain or not), or if any of the strings in the keylist are invalid.
@return true if the binding could be added; false if it could not.
*/
- bool add(const StringVect &keylist, int id);
+ bool add_key(const StringVect &keylist, int id);
//! Removes a key binding
/*!
@return The id of the binding that was removed, or '< 0' if none were
removed.
*/
- int remove(const StringVect &keylist);
+ int remove_key(const StringVect &keylist);
//! Removes all key bindings
void remove_all();
@return -1 if the keybinding was not found but does not conflict with
any others; -2 if the keybinding conflicts with another.
*/
- int find(const StringVect &keylist);
+ int find_key(const StringVect &keylist);
+
+ void process(unsigned int modifiers, unsigned int key);
// XXX: need an exec() function or something that will be used by openbox
// and hold state for which chain we're in etc. (it could have a timer
v.push_back("C-A-x");
v.push_back("C-y");
v.push_back("v");
- _bindings->add(v, 1);
+ _bindings->add_key(v, 1);
v.clear();
// v.push_back("C-x");
// v.push_back("C-z");
v.push_back("a");
- _bindings->add(v, 2);
+ _bindings->add_key(v, 2);
+
+ _bindings->add_mouse("A-1", 1);
printf("CHAINS:\n");
_bindings->display();
%rename(preregister) ob::python_preregister;
%rename(unregister) ob::python_unregister;
%rename(unregister_all) ob::python_unregister_all;
-%rename(bind) ob::python_bind;
-%rename(unbind) ob::python_unbind;
+%rename(bind_key) ob::python_bind_key;
+%rename(unbind_key) ob::python_unbind_key;
+%rename(bind_mouse) ob::python_bind_mouse;
+%rename(unbind_mouse) ob::python_unbind_mouse;
%rename(unbind_all) ob::python_unbind_all;
%ignore ob::OBScreen::clients;
}
-static PyObject *_wrap_bind(PyObject *self, PyObject *args) {
+static PyObject *_wrap_bind_key(PyObject *self, PyObject *args) {
PyObject *resultobj;
PyObject *arg1 = (PyObject *) 0 ;
PyObject *arg2 = (PyObject *) 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
- if(!PyArg_ParseTuple(args,(char *)"OO:bind",&obj0,&obj1)) goto fail;
+ if(!PyArg_ParseTuple(args,(char *)"OO:bind_key",&obj0,&obj1)) goto fail;
arg1 = obj0;
arg2 = obj1;
- result = (bool)ob::python_bind(arg1,arg2);
+ result = (bool)ob::python_bind_key(arg1,arg2);
resultobj = PyInt_FromLong((long)result);
return resultobj;
}
-static PyObject *_wrap_unbind(PyObject *self, PyObject *args) {
+static PyObject *_wrap_unbind_key(PyObject *self, PyObject *args) {
PyObject *resultobj;
PyObject *arg1 = (PyObject *) 0 ;
bool result;
PyObject * obj0 = 0 ;
- if(!PyArg_ParseTuple(args,(char *)"O:unbind",&obj0)) goto fail;
+ if(!PyArg_ParseTuple(args,(char *)"O:unbind_key",&obj0)) goto fail;
arg1 = obj0;
- result = (bool)ob::python_unbind(arg1);
+ result = (bool)ob::python_unbind_key(arg1);
+
+ resultobj = PyInt_FromLong((long)result);
+ return resultobj;
+ fail:
+ return NULL;
+}
+
+
+static PyObject *_wrap_bind_mouse(PyObject *self, PyObject *args) {
+ PyObject *resultobj;
+ std::string *arg1 = 0 ;
+ PyObject *arg2 = (PyObject *) 0 ;
+ bool result;
+ std::string temp1 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if(!PyArg_ParseTuple(args,(char *)"OO:bind_mouse",&obj0,&obj1)) goto fail;
+ {
+ if (PyString_Check(obj0)) {
+ temp1 = std::string(PyString_AsString(obj0));
+ arg1 = &temp1;
+ }else {
+ SWIG_exception(SWIG_TypeError, "string expected");
+ }
+ }
+ arg2 = obj1;
+ result = (bool)ob::python_bind_mouse((std::string const &)*arg1,arg2);
+
+ resultobj = PyInt_FromLong((long)result);
+ return resultobj;
+ fail:
+ return NULL;
+}
+
+
+static PyObject *_wrap_unbind_mouse(PyObject *self, PyObject *args) {
+ PyObject *resultobj;
+ std::string *arg1 = 0 ;
+ bool result;
+ std::string temp1 ;
+ PyObject * obj0 = 0 ;
+
+ if(!PyArg_ParseTuple(args,(char *)"O:unbind_mouse",&obj0)) goto fail;
+ {
+ if (PyString_Check(obj0)) {
+ temp1 = std::string(PyString_AsString(obj0));
+ arg1 = &temp1;
+ }else {
+ SWIG_exception(SWIG_TypeError, "string expected");
+ }
+ }
+ result = (bool)ob::python_unbind_mouse((std::string const &)*arg1);
resultobj = PyInt_FromLong((long)result);
return resultobj;
{ (char *)"preregister", _wrap_preregister, METH_VARARGS },
{ (char *)"unregister", _wrap_unregister, METH_VARARGS },
{ (char *)"unregister_all", _wrap_unregister_all, METH_VARARGS },
- { (char *)"bind", _wrap_bind, METH_VARARGS },
- { (char *)"unbind", _wrap_unbind, METH_VARARGS },
+ { (char *)"bind_key", _wrap_bind_key, METH_VARARGS },
+ { (char *)"unbind_key", _wrap_unbind_key, METH_VARARGS },
+ { (char *)"bind_mouse", _wrap_bind_mouse, METH_VARARGS },
+ { (char *)"unbind_mouse", _wrap_unbind_mouse, METH_VARARGS },
{ (char *)"unbind_all", _wrap_unbind_all, METH_VARARGS },
{ NULL, NULL }
};
typedef std::vector<PyObject*> FunctionList;
static FunctionList callbacks[OBActions::NUM_ACTIONS];
-static FunctionList bindfuncs;
+static FunctionList keyfuncs;
+static FunctionList mousefuncs;
bool python_register(int action, PyObject *callback)
{
-bool python_bind(PyObject *keylist, PyObject *callback)
+bool python_bind_key(PyObject *keylist, PyObject *callback)
{
if (!PyList_Check(keylist)) {
PyErr_SetString(PyExc_AssertionError, "Invalid keylist. Not a list.");
// the id is what the binding class can call back with so it doesnt have to
// worry about the python function pointer
- int id = bindfuncs.size();
- if (Openbox::instance->bindings()->add(vectkeylist, id)) {
+ int id = keyfuncs.size();
+ if (Openbox::instance->bindings()->add_key(vectkeylist, id)) {
Py_XINCREF(callback); // Add a reference to new callback
- bindfuncs.push_back(callback);
+ keyfuncs.push_back(callback);
return true;
} else {
PyErr_SetString(PyExc_AssertionError,"Unable to create binding. Invalid.");
}
}
-bool python_unbind(PyObject *keylist)
+bool python_unbind_key(PyObject *keylist)
{
if (!PyList_Check(keylist)) {
PyErr_SetString(PyExc_AssertionError, "Invalid keylist. Not a list.");
int id;
if ((id =
- Openbox::instance->bindings()->remove(vectkeylist)) >= 0) {
- assert(bindfuncs[id]); // shouldn't be able to remove it twice
- Py_XDECREF(bindfuncs[id]); // Dispose of previous callback
+ Openbox::instance->bindings()->remove_key(vectkeylist)) >= 0) {
+ assert(keyfuncs[id]); // shouldn't be able to remove it twice
+ Py_XDECREF(keyfuncs[id]); // Dispose of previous callback
// important note: we don't erase the item from the list cuz that would
// ruin all the id's that are in use. simply nullify it.
- bindfuncs[id] = 0;
+ keyfuncs[id] = 0;
+ return true;
+ }
+
+ return false;
+}
+
+bool python_bind_mouse(const std::string &button, PyObject *callback)
+{
+ if (!PyCallable_Check(callback)) {
+ PyErr_SetString(PyExc_AssertionError, "Invalid callback function.");
+ return false;
+ }
+
+ // the id is what the binding class can call back with so it doesnt have to
+ // worry about the python function pointer
+ int id = mousefuncs.size();
+ if (Openbox::instance->bindings()->add_mouse(button, id)) {
+ Py_XINCREF(callback); // Add a reference to new callback
+ mousefuncs.push_back(callback);
+ return true;
+ } else {
+ PyErr_SetString(PyExc_AssertionError,"Unable to create binding. Invalid.");
+ return false;
+ }
+}
+
+bool python_unbind_mouse(const std::string &button)
+{
+ int id;
+ if ((id =
+ Openbox::instance->bindings()->remove_mouse(button)) >= 0) {
+ assert(mousefuncs[id]); // shouldn't be able to remove it twice
+ Py_XDECREF(mousefuncs[id]); // Dispose of previous callback
+ // important note: we don't erase the item from the list cuz that would
+ // ruin all the id's that are in use. simply nullify it.
+ mousefuncs[id] = 0;
return true;
}
//! Removes all python callback functions from the hook list
bool python_unregister_all(int action);
-//! Add a mouse/keybinding
+//! Add a keybinding
/*!
@param keylist A python list of modifier/key/buttons, in the form:
"C-A-space" or "A-Button1" etc.
@param callback A python function to call when the binding is used.
*/
-bool python_bind(PyObject *keylist, PyObject *callback);
+bool python_bind_key(PyObject *keylist, PyObject *callback);
-bool python_unbind(PyObject *keylist);
+bool python_unbind_key(PyObject *keylist);
+
+//! Adds a mouse binding
+bool python_bind_mouse(const std::string &button, PyObject *callback);
+
+bool python_unbind_mouse(const std::string &button);
bool python_unbind_all();