From 66a26917a0631463df7f72c34cbeb39df466918a Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Thu, 2 Jan 2003 20:36:14 +0000 Subject: [PATCH] new code for bindings/callbacks. much sexier. now passes python classes back to the callbacks, and the storage of the callbacks in the code is much more clear. huzzah. --- scripts/clicks.py | 48 ++-- scripts/clientmotion.py | 29 ++- src/Makefile.am | 3 +- src/actions.cc | 126 +++++++-- src/actions.hh | 26 ++ src/bindings.cc | 75 +++--- src/bindings.hh | 40 ++- src/openbox.cc | 11 +- src/openbox.hh | 11 +- src/openbox.i | 114 ++++++++- src/openbox_wrap.cc | 550 ++++++++++++++++++++-------------------- src/python.cc | 446 ++++++++++++++++---------------- src/python.hh | 52 +--- src/screen.cc | 3 +- 14 files changed, 868 insertions(+), 666 deletions(-) diff --git a/scripts/clicks.py b/scripts/clicks.py index c6f47d58..a9c2fec1 100644 --- a/scripts/clicks.py +++ b/scripts/clicks.py @@ -1,26 +1,28 @@ -def def_click_client(action, win, type, modifiers, button, time): - client = Openbox_findClient(openbox, win) +def def_click_client(data): + client = Openbox_findClient(openbox, data.window()) if not client: return - if button == Button1 and type == Type_CloseButton: + button = data.button() + type = data.target() + if button == 1 and type == Type_CloseButton: OBClient_close(client) - elif button <= Button3 and type == Type_MaximizeButton: + elif button <= 3 and type == Type_MaximizeButton: print "OBClient_maximize(client)" - elif button == Button1 and type == Type_IconifyButton: + elif button == 1 and type == Type_IconifyButton: print "OBClient_iconify(client)" - elif button == Button1 and type == Type_StickyButton: + elif button == 1 and type == Type_StickyButton: print "OBClient_sendtodesktop(client, 0xffffffff)" elif type == Type_Titlebar or type == Type_CloseButton or \ type == Type_MaximizeButton or type == Type_IconifyButton or \ type == Type_StickyButton or type == Type_Label: - if button == Button4: + if button == 4: print "OBClient_shade(client)" - elif button == Button5: + elif button == 5: print "OBClient_unshade(client)" -def def_press_model(action, win, type, modifiers, button, xroot, yroot, time): - if button != Button1: return - client = Openbox_findClient(openbox, win) +def def_press_model(data): + if data.button() != 1: return + client = Openbox_findClient(openbox, data.window()) if not client or (type == Type_StickyButton or type == Type_IconifyButton or type == Type_MaximizeButton or @@ -31,32 +33,34 @@ def def_press_model(action, win, type, modifiers, button, xroot, yroot, time): if click_raise != 0: print "OBClient_raise(client)" -def def_click_root(action, win, type, modifiers, button, time): +def def_press_root(data): + button = data.button() if type == Type_Root: - if button == Button1: + if button == 1: print "nothing probly.." client = Openbox_focusedClient(openbox) if client: OBClient_unfocus(client) - elif button == Button2: + elif button == 2: print "workspace menu" - elif button == Button3: + elif button == 3: print "root menu" - elif button == Button4: + elif button == 4: print "next workspace" - elif button == Button5: + elif button == 5: print "previous workspace" -def def_doubleclick_client(action, win, type, modifiers, button, time): - client = Openbox_findClient(openbox, win) +def def_doubleclick_client(data): + client = Openbox_findClient(openbox, data.window()) if not client: return - if button == Button1 and (type == Type_Titlebar or type == Type_Label): + button = data.button() + if button == 1 and (type == Type_Titlebar or type == Type_Label): print "OBClient_toggleshade(client)" -preregister(Action_ButtonPress, def_press_model) +register(Action_ButtonPress, def_press_model, 1) register(Action_Click, def_click_client) -register(Action_Click, def_click_root) +register(Action_ButtonPress, def_press_root) register(Action_DoubleClick, def_doubleclick_client) print "Loaded clicks.py" diff --git a/scripts/clientmotion.py b/scripts/clientmotion.py index 24b16e63..dc584893 100644 --- a/scripts/clientmotion.py +++ b/scripts/clientmotion.py @@ -1,34 +1,35 @@ posqueue = []; -def def_motion_press(action, win, type, modifiers, button, xroot, yroot, time): - client = Openbox_findClient(openbox, win) +def def_motion_press(data): + client = Openbox_findClient(openbox, data.window()) global posqueue - newi = [button, xroot, yroot] + newi = [data.button(), data.xroot(), data.yroot()] if client: newi.append(new_Rect(OBClient_area(client))) posqueue.append(newi) -def def_motion_release(action, win, type, modifiers, button, xroot, yroot, - time): +def def_motion_release(data): global posqueue + button = data.button() for i in posqueue: if i[0] == button: - client = Openbox_findClient(openbox, win) + client = Openbox_findClient(openbox, data.window()) if client: delete_Rect(i[3]) posqueue.remove(i) break -def def_motion(action, win, type, modifiers, xroot, yroot, time): - client = Openbox_findClient(openbox, win) +def def_motion(data): + client = Openbox_findClient(openbox, data.window()) if not client: return global posqueue - dx = xroot - posqueue[0][1] - dy = yroot - posqueue[0][2] + dx = data.xroot() - posqueue[0][1] + dy = data.yroot() - posqueue[0][2] area = posqueue[0][3] # A Rect + type = data.target() if (type == Type_Titlebar) or (type == Type_Label): OBClient_move(client, Rect_x(area) + dx, Rect_y(area) + dy) elif type == Type_LeftGrip: @@ -38,14 +39,14 @@ def def_motion(action, win, type, modifiers, xroot, yroot, time): OBClient_resize(client, OBClient_TopLeft, Rect_width(area) + dx, Rect_height(area) + dy) -def def_enter(action, win, type, modifiers): - client = Openbox_findClient(openbox, win) +def def_enter(data): + client = Openbox_findClient(openbox, data.window()) if not client: return if enter_focus != 0: OBClient_focus(client) -def def_leave(action, win, type, modifiers): - client = Openbox_findClient(openbox, win) +def def_leave(data): + client = Openbox_findClient(openbox, data.window()) if not client: return if leave_unfocus != 0: OBClient_unfocus(client) diff --git a/src/Makefile.am b/src/Makefile.am index a8995148..10c93be6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,7 +19,8 @@ openbox3_LDADD=-L../otk -lotk @LIBINTL@ openbox3_SOURCES= actions.cc client.cc frame.cc openbox.cc screen.cc \ main.cc rootwindow.cc backgroundwidget.cc labelwidget.cc \ - buttonwidget.cc python.cc bindings.cc openbox_wrap.cc + buttonwidget.cc python.cc bindings.cc \ + openbox_wrap.cc MAINTAINERCLEANFILES= Makefile.in diff --git a/src/actions.cc b/src/actions.cc index 50259c89..b6f1dad8 100644 --- a/src/actions.cc +++ b/src/actions.cc @@ -39,9 +39,9 @@ void OBActions::buttonPressHandler(const XButtonEvent &e) OBWidget *w = dynamic_cast (Openbox::instance->findHandler(e.window)); - python_callback(Action_ButtonPress, e.window, - (OBWidget::WidgetType)(w ? w->type():-1), - e.state, e.button, e.x_root, e.y_root, e.time); + doCallback(Action_ButtonPress, e.window, + (OBWidget::WidgetType)(w ? w->type():-1), + e.state, e.button, e.x_root, e.y_root, e.time); if (_button) return; // won't count toward CLICK events @@ -57,9 +57,9 @@ void OBActions::buttonReleaseHandler(const XButtonEvent &e) (Openbox::instance->findHandler(e.window)); // run the RELEASE python hook - python_callback(Action_ButtonRelease, e.window, - (OBWidget::WidgetType)(w ? w->type():-1), - e.state, e.button, e.x_root, e.y_root, e.time); + doCallback(Action_ButtonRelease, e.window, + (OBWidget::WidgetType)(w ? w->type():-1), + e.state, e.button, e.x_root, e.y_root, e.time); // not for the button we're watching? if (_button != e.button) return; @@ -76,17 +76,17 @@ void OBActions::buttonReleaseHandler(const XButtonEvent &e) return; // run the CLICK python hook - python_callback(Action_Click, e.window, - (OBWidget::WidgetType)(w ? w->type():-1), - e.state, e.button, e.time); + doCallback(Action_Click, e.window, + (OBWidget::WidgetType)(w ? w->type():-1), + e.state, e.button, e.x_root, e.y_root, e.time); if (e.time - _release.time < DOUBLECLICKDELAY && _release.win == e.window && _release.button == e.button) { // run the DOUBLECLICK python hook - python_callback(Action_DoubleClick, e.window, - (OBWidget::WidgetType)(w ? w->type():-1), - e.state, e.button, e.time); + doCallback(Action_DoubleClick, e.window, + (OBWidget::WidgetType)(w ? w->type():-1), + e.state, e.button, e.x_root, e.y_root, e.time); // reset so you cant triple click for 2 doubleclicks _release.win = 0; @@ -109,8 +109,8 @@ void OBActions::enterHandler(const XCrossingEvent &e) (Openbox::instance->findHandler(e.window)); // run the ENTER python hook - python_callback(Action_EnterWindow, e.window, - (OBWidget::WidgetType)(w ? w->type():-1), e.state); + doCallback(Action_EnterWindow, e.window, + (OBWidget::WidgetType)(w ? w->type():-1), e.state, 0, 0, 0, 0); } @@ -122,8 +122,8 @@ void OBActions::leaveHandler(const XCrossingEvent &e) (Openbox::instance->findHandler(e.window)); // run the LEAVE python hook - python_callback(Action_LeaveWindow, e.window, - (OBWidget::WidgetType)(w ? w->type():-1), e.state); + doCallback(Action_LeaveWindow, e.window, + (OBWidget::WidgetType)(w ? w->type():-1), e.state, 0, 0, 0, 0); } @@ -132,7 +132,7 @@ void OBActions::keyPressHandler(const XKeyEvent &e) // OBWidget *w = dynamic_cast // (Openbox::instance->findHandler(e.window)); - Openbox::instance->bindings()->fire(e.window, e.state, e.keycode, e.time); + Openbox::instance->bindings()->fire(e.state, e.keycode, e.time); } @@ -161,21 +161,107 @@ void OBActions::motionHandler(const XMotionEvent &e) // XXX: i can envision all sorts of crazy shit with this.. gestures, etc // maybe that should all be done via python tho.. (or radial menus!) // run the simple MOTION python hook for now... - python_callback(Action_MouseMotion, e.window, - (OBWidget::WidgetType)(w ? w->type():-1), - e.state, e.x_root, e.y_root, e.time); + doCallback(Action_MouseMotion, e.window, + (OBWidget::WidgetType)(w ? w->type():-1), + e.state, (unsigned)-1, e.x_root, e.y_root, e.time); } void OBActions::mapRequestHandler(const XMapRequestEvent &e) { + doCallback(Action_NewWindow, e.window, (OBWidget::WidgetType)-1, + 0, 0, 0, 0, 0); } void OBActions::unmapHandler(const XUnmapEvent &e) { + (void)e; + doCallback(Action_CloseWindow, e.window, (OBWidget::WidgetType)-1, + 0, 0, 0, 0, 0); } void OBActions::destroyHandler(const XDestroyWindowEvent &e) { + (void)e; + doCallback(Action_CloseWindow, e.window, (OBWidget::WidgetType)-1, + 0, 0, 0, 0, 0); +} + +void OBActions::doCallback(ActionType action, Window window, + OBWidget::WidgetType type, unsigned int state, + unsigned int button, int xroot, int yroot, + Time time) +{ + std::pair it_pair = + _callbacks.equal_range(action); + + CallbackMap::iterator it; + for (it = it_pair.first; it != it_pair.second; ++it) + python_callback(it->second, action, window, type, state, + button, xroot, yroot, time); +} + +bool OBActions::registerCallback(ActionType action, PyObject *func, + bool atfront) +{ + if (action < 0 || action >= OBActions::NUM_ACTIONS || + action == OBActions::Action_KeyPress) { + return false; + } + if (!func) + return false; + + std::pair it_pair = + _callbacks.equal_range(action); + + CallbackMap::iterator it; + for (it = it_pair.first; it != it_pair.second; ++it) + if (it->second == func) + break; + if (it == it_pair.second) // not already in there + if (atfront) + _callbacks.insert(_callbacks.begin(), CallbackMapPair(action, func)); + else + _callbacks.insert(CallbackMapPair(action, func)); + Py_INCREF(func); + return true; +} + +bool OBActions::unregisterCallback(ActionType action, PyObject *func) +{ + if (action < 0 || action >= OBActions::NUM_ACTIONS || + action == OBActions::Action_KeyPress) { + return false; + } + if (!func) + return false; + + std::pair it_pair = + _callbacks.equal_range(action); + + CallbackMap::iterator it; + for (it = it_pair.first; it != it_pair.second; ++it) + if (it->second == func) + break; + if (it != it_pair.second) { // its been registered before + Py_DECREF(func); + _callbacks.erase(it); + } + return true; +} + +bool OBActions::unregisterAllCallbacks(ActionType action) +{ + if (action < 0 || action >= OBActions::NUM_ACTIONS || + action == OBActions::Action_KeyPress) { + return false; + } + + while (!_callbacks.empty()) { + CallbackMap::iterator it = _callbacks.begin(); + Py_DECREF(it->second); + _callbacks.erase(it); + } + return true; } } diff --git a/src/actions.hh b/src/actions.hh index 8b6633be..50df838b 100644 --- a/src/actions.hh +++ b/src/actions.hh @@ -6,14 +6,18 @@ @brief The action interface for user-available actions */ +#include "widget.hh" #include "otk/point.hh" #include "otk/rect.hh" #include "otk/eventhandler.hh" extern "C" { #include +#include } +#include + namespace ob { //! The action interface for user-available actions @@ -54,6 +58,14 @@ private: //! The last button release processed for CLICKs ButtonReleaseAction _release; + typedef std::multimap CallbackMap; + typedef std::pair CallbackMapPair; + CallbackMap _callbacks; + + void doCallback(ActionType action, Window window, OBWidget::WidgetType type, + unsigned int state, unsigned int button, + int xroot, int yroot, Time time); + public: //! Constructs an OBActions object OBActions(); @@ -73,6 +85,20 @@ public: virtual void mapRequestHandler(const XMapRequestEvent &e); virtual void unmapHandler(const XUnmapEvent &e); virtual void destroyHandler(const XDestroyWindowEvent &e); + + + //! Add a callback funtion to the back of the hook list + /*! + Registering functions for KeyPress events is pointless. Use + OBSCript::bindKey instead to do this. + */ + bool registerCallback(ActionType action, PyObject *func, bool atfront); + + //! Remove a callback function from the hook list + bool unregisterCallback(ActionType action, PyObject *func); + + //! Remove all callback functions from the hook list + bool unregisterAllCallbacks(ActionType action); }; } diff --git a/src/bindings.cc b/src/bindings.cc index 42a92591..fade3e69 100644 --- a/src/bindings.cc +++ b/src/bindings.cc @@ -111,7 +111,8 @@ static void destroytree(BindingTree *tree) } } -BindingTree *OBBindings::buildtree(const StringVect &keylist, int id) const +BindingTree *OBBindings::buildtree(const StringVect &keylist, + PyObject *callback) const { if (keylist.empty()) return 0; // nothing in the list.. return 0 @@ -120,7 +121,7 @@ BindingTree *OBBindings::buildtree(const StringVect &keylist, int id) const StringVect::const_reverse_iterator it, end = keylist.rend(); for (it = keylist.rbegin(); it != end; ++it) { p = ret; - ret = new BindingTree(id); + ret = new BindingTree(callback); if (!p) ret->chain = false; // only the first built node ret->first_child = p; if (!translate(*it, ret->binding)) { @@ -148,7 +149,7 @@ OBBindings::OBBindings() OBBindings::~OBBindings() { grabKeys(false); - remove_all(); + removeAll(); } @@ -184,7 +185,8 @@ void OBBindings::assimilate(BindingTree *node) } -int OBBindings::find(BindingTree *search) const { +PyObject *OBBindings::find(BindingTree *search, bool *conflict) const { + *conflict = false; BindingTree *a, *b; a = _tree.first_child; b = search; @@ -194,27 +196,30 @@ int OBBindings::find(BindingTree *search) const { } else { if (a->chain == b->chain) { if (!a->chain) { - return a->id; // found it! (return the actual id, not the search's) + // found it! (return the actual id, not the search's) + return a->callback; } } else { - return -2; // the chain status' don't match (conflict!) + *conflict = true; + return 0; // the chain status' don't match (conflict!) } b = b->first_child; a = a->first_child; } } - return -1; // it just isn't in here + return 0; // it just isn't in here } -bool OBBindings::add(const StringVect &keylist, int id) +bool OBBindings::add(const StringVect &keylist, PyObject *callback) { BindingTree *tree; + bool conflict; - if (!(tree = buildtree(keylist, id))) + if (!(tree = buildtree(keylist, callback))) return false; // invalid binding requested - if (find(tree) != -1) { + if (find(tree, &conflict) || conflict) { // conflicts with another binding destroytree(tree); return false; @@ -225,40 +230,37 @@ bool OBBindings::add(const StringVect &keylist, int id) // assimilate this built tree into the main tree assimilate(tree); // assimilation destroys/uses the tree + Py_INCREF(callback); + grabKeys(true); return true; } -int OBBindings::find(const StringVect &keylist) +bool OBBindings::remove(const StringVect &keylist) { + assert(false); // XXX: function not implemented yet + BindingTree *tree; - bool ret; + bool conflict; if (!(tree = buildtree(keylist, 0))) return false; // invalid binding requested - ret = find(tree) >= 0; - - destroytree(tree); - - return ret; -} - - -int OBBindings::remove(const StringVect &keylist) -{ - (void)keylist; - assert(false); // XXX: function not implemented yet - - grabKeys(false); - _curpos = &_tree; - - // do shit here... - - grabKeys(true); + PyObject *func = find(tree, &conflict); + if (func) { + grabKeys(false); + _curpos = &_tree; + + // XXX do shit here ... + Py_DECREF(func); + + grabKeys(true); + return true; + } + return false; } @@ -282,13 +284,14 @@ static void remove_branch(BindingTree *first) if (p->first_child) remove_branch(p->first_child); BindingTree *s = p->next_sibling; + Py_XDECREF(p->callback); delete p; p = s; } } -void OBBindings::remove_all() +void OBBindings::removeAll() { if (_tree.first_child) { remove_branch(_tree.first_child); @@ -326,8 +329,7 @@ void OBBindings::grabKeys(bool grab) } -void OBBindings::fire(Window window, unsigned int modifiers, unsigned int key, - Time time) +void OBBindings::fire(unsigned int modifiers, unsigned int key, Time time) { if (key == _resetkey.key && modifiers == _resetkey.modifiers) { reset(this); @@ -341,7 +343,10 @@ void OBBindings::fire(Window window, unsigned int modifiers, unsigned int key, _curpos = p; grabKeys(true); } else { - python_callback_binding(p->id, window, modifiers, key, time); + Window win = None; + OBClient *c = Openbox::instance->focusedClient(); + if (c) win = c->window(); + python_callback(p->callback, win, modifiers, key, time); reset(this); } break; diff --git a/src/bindings.hh b/src/bindings.hh index 0ae03576..9d55b751 100644 --- a/src/bindings.hh +++ b/src/bindings.hh @@ -9,7 +9,12 @@ #include "actions.hh" #include "otk/timer.hh" +extern "C" { +#include +} + #include +#include #include namespace ob { @@ -29,18 +34,18 @@ typedef struct Binding { typedef struct BindingTree { Binding binding; - int id; // the id given for the binding in add() - bool chain; // true if this is a chain to another key (not an action) + PyObject *callback; // the callback given for the binding in add() + bool chain; // true if this is a chain to another key (not an action) struct BindingTree *next_sibling; // the next binding in the tree at the same // level struct BindingTree *first_child; // the first child of this binding (next // binding in a chained sequence). - BindingTree(int id) : binding(0, 0) { - this->id = id; chain = true; next_sibling = first_child = 0; + BindingTree(PyObject *callback) : binding(0, 0) { + this->callback = callback; chain = true; next_sibling = first_child = 0; } BindingTree() : binding(0, 0) { - this->id = -1; chain = true; next_sibling = first_child = 0; + this->callback = 0; chain = true; next_sibling = first_child = 0; } } BindingTree; @@ -57,12 +62,12 @@ private: otk::OBTimer _timer; - int find(BindingTree *search) const; + PyObject *find(BindingTree *search, bool *conflict) const; bool translate(const std::string &str, Binding &b) const; - BindingTree *buildtree(const StringVect &keylist, int id) const; + BindingTree *buildtree(const StringVect &keylist, PyObject *callback) const; void assimilate(BindingTree *node); - static void reset(OBBindings *self); + static void reset(OBBindings *self); // the timer's timeout function public: //! Initializes an OBBinding object @@ -76,26 +81,19 @@ public: 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(const StringVect &keylist, PyObject *callback); //! Removes a key binding /*! - @return The id of the binding that was removed, or '< 0' if none were - removed. + @return The callbackid of the binding, or '< 0' if there was no binding to + be removed. */ - int remove(const StringVect &keylist); + bool remove(const StringVect &keylist); //! Removes all key bindings - void remove_all(); - - //! Finds a keybinding and returns its id or '< 0' if it isn't found. - /*! - @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); + void removeAll(); - void fire(Window window, unsigned int modifiers,unsigned int key, Time time); + void fire(unsigned int modifiers,unsigned int key, Time time); void setResetKey(const std::string &key); diff --git a/src/openbox.cc b/src/openbox.cc index 01316d79..f7f2098b 100644 --- a/src/openbox.cc +++ b/src/openbox.cc @@ -128,8 +128,10 @@ Openbox::Openbox(int argc, char **argv) _cursors.ul_angle = XCreateFontCursor(otk::OBDisplay::display, XC_ul_angle); _cursors.ur_angle = XCreateFontCursor(otk::OBDisplay::display, XC_ur_angle); - // start up python and load config values + // initialize scripting python_init(argv[0]); + + // load config values python_exec(SCRIPTDIR"/config.py"); // load openbox config values // initialize all the screens @@ -179,6 +181,8 @@ Openbox::~Openbox() delete _property; + python_destroy(); + // close the X display otk::OBDisplay::destroy(); } @@ -325,10 +329,5 @@ void Openbox::setFocusedClient(OBClient *c) } } - -bool Openbox::getConfigString(const char *name, std::string *value) { - return python_get_string(name, value); -} - } diff --git a/src/openbox.hh b/src/openbox.hh index b5956e46..1a537dcd 100644 --- a/src/openbox.hh +++ b/src/openbox.hh @@ -6,10 +6,6 @@ @brief The main class for the Openbox window manager */ -/* - cuz girls look soooo goood.. on the end of my DICK -*/ - extern "C" { #include } @@ -185,7 +181,10 @@ public: //! Returns the otk::OBProperty instance for the window manager inline const otk::OBProperty *property() const { return _property; } - //! Returns the OBBinding instance for the window manager + //! Returns the OBActions instance for the window manager + inline OBActions *actions() const { return _actions; } + + //! Returns the OBBindings instance for the window manager inline OBBindings *bindings() const { return _bindings; } //! Returns a managed screen @@ -241,8 +240,6 @@ public: manager can be destroyed. */ inline void shutdown() { _doshutdown = true; } - - bool getConfigString(const char *name, std::string *value); }; } diff --git a/src/openbox.i b/src/openbox.i index 0bfad27f..b5e7f09e 100644 --- a/src/openbox.i +++ b/src/openbox.i @@ -10,11 +10,12 @@ #include "openbox.hh" #include "screen.hh" #include "client.hh" -#include "python.hh" #include "bindings.hh" +#include "actions.hh" %} %include stl.i +%include exception.i //%include std_list.i //%template(ClientList) std::list; @@ -51,15 +52,106 @@ Type_Root }; %} -%ignore ob::python_callback; -%rename(register) ob::python_register; -%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(unbind_all) ob::python_unbind_all; -%rename(set_reset_key) ob::python_set_reset_key; +%rename(register) python_register; +%inline %{ +PyObject * python_register(int action, PyObject *func, bool infront = false) +{ + if (!PyCallable_Check(func)) { + PyErr_SetString(PyExc_TypeError, "Invalid callback function."); + return NULL; + } + + if (!ob::Openbox::instance->actions()->registerCallback( + (ob::OBActions::ActionType)action, func, infront)) { + PyErr_SetString(PyExc_RuntimeError, "Unable to register action callback."); + return NULL; + } + Py_INCREF(Py_None); return Py_None; +} + +PyObject * unregister(int action, PyObject *func) +{ + if (!PyCallable_Check(func)) { + PyErr_SetString(PyExc_TypeError, "Invalid callback function."); + return NULL; + } + + if (!ob::Openbox::instance->actions()->unregisterCallback( + (ob::OBActions::ActionType)action, func)) { + PyErr_SetString(PyExc_RuntimeError, "Unable to unregister action callback."); + return NULL; + } + Py_INCREF(Py_None); return Py_None; +} + +PyObject * unregister_all(int action) +{ + if (!ob::Openbox::instance->actions()->unregisterAllCallbacks( + (ob::OBActions::ActionType)action)) { + PyErr_SetString(PyExc_RuntimeError, + "Unable to unregister action callbacks."); + return NULL; + } + Py_INCREF(Py_None); return Py_None; +} + +PyObject * bind(PyObject *keylist, PyObject *func) +{ + if (!PyList_Check(keylist)) { + PyErr_SetString(PyExc_TypeError, "Invalid keylist. Not a list."); + return NULL; + } + + ob::OBBindings::StringVect vectkeylist; + for (int i = 0, end = PyList_Size(keylist); i < end; ++i) { + PyObject *str = PyList_GetItem(keylist, i); + if (!PyString_Check(str)) { + PyErr_SetString(PyExc_TypeError, + "Invalid keylist. It must contain only strings."); + return NULL; + } + vectkeylist.push_back(PyString_AsString(str)); + } + + if (!ob::Openbox::instance->bindings()->add(vectkeylist, func)) { + PyErr_SetString(PyExc_RuntimeError,"Unable to add binding."); + return NULL; + } + Py_INCREF(Py_None); return Py_None; +} + +PyObject * unbind(PyObject *keylist) +{ + if (!PyList_Check(keylist)) { + PyErr_SetString(PyExc_TypeError, "Invalid keylist. Not a list."); + return NULL; + } + + ob::OBBindings::StringVect vectkeylist; + for (int i = 0, end = PyList_Size(keylist); i < end; ++i) { + PyObject *str = PyList_GetItem(keylist, i); + if (!PyString_Check(str)) { + PyErr_SetString(PyExc_TypeError, + "Invalid keylist. It must contain only strings."); + return NULL; + } + vectkeylist.push_back(PyString_AsString(str)); + } + + ob::Openbox::instance->bindings()->remove(vectkeylist); + Py_INCREF(Py_None); return Py_None; +} + +void unbind_all() +{ + ob::Openbox::instance->bindings()->removeAll(); +} + +void set_reset_key(const std::string &key) +{ + ob::Openbox::instance->bindings()->setResetKey(key); +} +%} %ignore ob::OBScreen::clients; %{ @@ -81,11 +173,11 @@ %import "../otk/eventdispatcher.hh" %import "../otk/eventhandler.hh" %import "widget.hh" +%import "actions.hh" %include "openbox.hh" %include "screen.hh" %include "client.hh" -%include "python.hh" // for Mod1Mask etc %include "X11/X.h" diff --git a/src/openbox_wrap.cc b/src/openbox_wrap.cc index 587e1abb..ada473b6 100644 --- a/src/openbox_wrap.cc +++ b/src/openbox_wrap.cc @@ -646,17 +646,17 @@ SWIG_InstallConstants(PyObject *d, swig_const_info constants[]) { /* -------- TYPES TABLE (BEGIN) -------- */ #define SWIGTYPE_p_otk__OBTimerQueueManager swig_types[0] -#define SWIGTYPE_p_ob__Cursors swig_types[1] -#define SWIGTYPE_p_ob__OBScreen swig_types[2] -#define SWIGTYPE_p_otk__Style swig_types[3] -#define SWIGTYPE_p_ob__OBFrame swig_types[4] -#define SWIGTYPE_p_XReparentEvent swig_types[5] -#define SWIGTYPE_p_ob__OBClient swig_types[6] -#define SWIGTYPE_p_ob__Openbox swig_types[7] -#define SWIGTYPE_p_otk__Strut swig_types[8] -#define SWIGTYPE_p_XShapeEvent swig_types[9] -#define SWIGTYPE_p_XConfigureRequestEvent swig_types[10] -#define SWIGTYPE_p_std__string swig_types[11] +#define SWIGTYPE_p_ob__OBActions swig_types[1] +#define SWIGTYPE_p_ob__Cursors swig_types[2] +#define SWIGTYPE_p_ob__OBScreen swig_types[3] +#define SWIGTYPE_p_otk__Style swig_types[4] +#define SWIGTYPE_p_ob__OBFrame swig_types[5] +#define SWIGTYPE_p_XReparentEvent swig_types[6] +#define SWIGTYPE_p_ob__OBClient swig_types[7] +#define SWIGTYPE_p_ob__Openbox swig_types[8] +#define SWIGTYPE_p_otk__Strut swig_types[9] +#define SWIGTYPE_p_XShapeEvent swig_types[10] +#define SWIGTYPE_p_XConfigureRequestEvent swig_types[11] #define SWIGTYPE_p_otk__OtkEventHandler swig_types[12] #define SWIGTYPE_p_otk__Rect swig_types[13] #define SWIGTYPE_p_ob__OBWidget swig_types[14] @@ -666,8 +666,8 @@ SWIG_InstallConstants(PyObject *d, swig_const_info constants[]) { #define SWIGTYPE_p_otk__OtkEventDispatcher swig_types[18] #define SWIGTYPE_p_XPropertyEvent swig_types[19] #define SWIGTYPE_p_XDestroyWindowEvent swig_types[20] -#define SWIGTYPE_p_otk__BImageControl swig_types[21] -#define SWIGTYPE_p_PyObject swig_types[22] +#define SWIGTYPE_p_PyObject swig_types[21] +#define SWIGTYPE_p_otk__BImageControl swig_types[22] #define SWIGTYPE_p_ob__OBBindings swig_types[23] #define SWIGTYPE_p_ob__MwmHints swig_types[24] #define SWIGTYPE_p_XUnmapEvent swig_types[25] @@ -690,8 +690,8 @@ static swig_type_info *swig_types[27]; #include "openbox.hh" #include "screen.hh" #include "client.hh" -#include "python.hh" #include "bindings.hh" +#include "actions.hh" #define SWIG_MemoryError 1 @@ -805,6 +805,105 @@ static std::string SwigString_AsString(PyObject* o) { }; +PyObject * python_register(int action, PyObject *func, bool infront = false) +{ + if (!PyCallable_Check(func)) { + PyErr_SetString(PyExc_TypeError, "Invalid callback function."); + return NULL; + } + + if (!ob::Openbox::instance->actions()->registerCallback( + (ob::OBActions::ActionType)action, func, infront)) { + PyErr_SetString(PyExc_RuntimeError, "Unable to register action callback."); + return NULL; + } + Py_INCREF(Py_None); return Py_None; +} + +PyObject * unregister(int action, PyObject *func) +{ + if (!PyCallable_Check(func)) { + PyErr_SetString(PyExc_TypeError, "Invalid callback function."); + return NULL; + } + + if (!ob::Openbox::instance->actions()->unregisterCallback( + (ob::OBActions::ActionType)action, func)) { + PyErr_SetString(PyExc_RuntimeError, "Unable to unregister action callback."); + return NULL; + } + Py_INCREF(Py_None); return Py_None; +} + +PyObject * unregister_all(int action) +{ + if (!ob::Openbox::instance->actions()->unregisterAllCallbacks( + (ob::OBActions::ActionType)action)) { + PyErr_SetString(PyExc_RuntimeError, + "Unable to unregister action callbacks."); + return NULL; + } + Py_INCREF(Py_None); return Py_None; +} + +PyObject * bind(PyObject *keylist, PyObject *func) +{ + if (!PyList_Check(keylist)) { + PyErr_SetString(PyExc_TypeError, "Invalid keylist. Not a list."); + return NULL; + } + + ob::OBBindings::StringVect vectkeylist; + for (int i = 0, end = PyList_Size(keylist); i < end; ++i) { + PyObject *str = PyList_GetItem(keylist, i); + if (!PyString_Check(str)) { + PyErr_SetString(PyExc_TypeError, + "Invalid keylist. It must contain only strings."); + return NULL; + } + vectkeylist.push_back(PyString_AsString(str)); + } + + if (!ob::Openbox::instance->bindings()->add(vectkeylist, func)) { + PyErr_SetString(PyExc_RuntimeError,"Unable to add binding."); + return NULL; + } + Py_INCREF(Py_None); return Py_None; +} + +PyObject * unbind(PyObject *keylist) +{ + if (!PyList_Check(keylist)) { + PyErr_SetString(PyExc_TypeError, "Invalid keylist. Not a list."); + return NULL; + } + + ob::OBBindings::StringVect vectkeylist; + for (int i = 0, end = PyList_Size(keylist); i < end; ++i) { + PyObject *str = PyList_GetItem(keylist, i); + if (!PyString_Check(str)) { + PyErr_SetString(PyExc_TypeError, + "Invalid keylist. It must contain only strings."); + return NULL; + } + vectkeylist.push_back(PyString_AsString(str)); + } + + ob::Openbox::instance->bindings()->remove(vectkeylist); + Py_INCREF(Py_None); return Py_None; +} + +void unbind_all() +{ + ob::Openbox::instance->bindings()->removeAll(); +} + +void set_reset_key(const std::string &key) +{ + ob::Openbox::instance->bindings()->setResetKey(key); +} + + #include ob::OBClient *ob_OBScreen_client(ob::OBScreen *self,int i){ @@ -834,6 +933,137 @@ static PyObject *_wrap_Openbox_instance(PyObject *self, PyObject *args) { } +static PyObject *_wrap_register(PyObject *self, PyObject *args) { + PyObject *resultobj; + int arg1 ; + PyObject *arg2 = (PyObject *) 0 ; + bool arg3 = (bool) false ; + PyObject *result; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + + if(!PyArg_ParseTuple(args,(char *)"iO|O:register",&arg1,&obj1,&obj2)) goto fail; + arg2 = obj1; + if (obj2) { + arg3 = (bool) PyInt_AsLong(obj2); + if (PyErr_Occurred()) SWIG_fail; + } + result = (PyObject *)python_register(arg1,arg2,arg3); + + resultobj = result; + return resultobj; + fail: + return NULL; +} + + +static PyObject *_wrap_unregister(PyObject *self, PyObject *args) { + PyObject *resultobj; + int arg1 ; + PyObject *arg2 = (PyObject *) 0 ; + PyObject *result; + PyObject * obj1 = 0 ; + + if(!PyArg_ParseTuple(args,(char *)"iO:unregister",&arg1,&obj1)) goto fail; + arg2 = obj1; + result = (PyObject *)unregister(arg1,arg2); + + resultobj = result; + return resultobj; + fail: + return NULL; +} + + +static PyObject *_wrap_unregister_all(PyObject *self, PyObject *args) { + PyObject *resultobj; + int arg1 ; + PyObject *result; + + if(!PyArg_ParseTuple(args,(char *)"i:unregister_all",&arg1)) goto fail; + result = (PyObject *)unregister_all(arg1); + + resultobj = result; + return resultobj; + fail: + return NULL; +} + + +static PyObject *_wrap_bind(PyObject *self, PyObject *args) { + PyObject *resultobj; + PyObject *arg1 = (PyObject *) 0 ; + PyObject *arg2 = (PyObject *) 0 ; + PyObject *result; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if(!PyArg_ParseTuple(args,(char *)"OO:bind",&obj0,&obj1)) goto fail; + arg1 = obj0; + arg2 = obj1; + result = (PyObject *)bind(arg1,arg2); + + resultobj = result; + return resultobj; + fail: + return NULL; +} + + +static PyObject *_wrap_unbind(PyObject *self, PyObject *args) { + PyObject *resultobj; + PyObject *arg1 = (PyObject *) 0 ; + PyObject *result; + PyObject * obj0 = 0 ; + + if(!PyArg_ParseTuple(args,(char *)"O:unbind",&obj0)) goto fail; + arg1 = obj0; + result = (PyObject *)unbind(arg1); + + resultobj = result; + return resultobj; + fail: + return NULL; +} + + +static PyObject *_wrap_unbind_all(PyObject *self, PyObject *args) { + PyObject *resultobj; + + if(!PyArg_ParseTuple(args,(char *)":unbind_all")) goto fail; + unbind_all(); + + Py_INCREF(Py_None); resultobj = Py_None; + return resultobj; + fail: + return NULL; +} + + +static PyObject *_wrap_set_reset_key(PyObject *self, PyObject *args) { + PyObject *resultobj; + std::string *arg1 = 0 ; + std::string temp1 ; + PyObject * obj0 = 0 ; + + if(!PyArg_ParseTuple(args,(char *)"O:set_reset_key",&obj0)) goto fail; + { + if (PyString_Check(obj0)) { + temp1 = std::string(PyString_AsString(obj0)); + arg1 = &temp1; + }else { + SWIG_exception(SWIG_TypeError, "string expected"); + } + } + set_reset_key((std::string const &)*arg1); + + Py_INCREF(Py_None); resultobj = Py_None; + return resultobj; + fail: + return NULL; +} + + static PyObject *_wrap_Cursors_session_set(PyObject *self, PyObject *args) { PyObject *resultobj; ob::Cursors *arg1 = (ob::Cursors *) 0 ; @@ -1114,6 +1344,23 @@ static PyObject *_wrap_Openbox_property(PyObject *self, PyObject *args) { } +static PyObject *_wrap_Openbox_actions(PyObject *self, PyObject *args) { + PyObject *resultobj; + ob::Openbox *arg1 = (ob::Openbox *) 0 ; + ob::OBActions *result; + PyObject * obj0 = 0 ; + + if(!PyArg_ParseTuple(args,(char *)"O:Openbox_actions",&obj0)) goto fail; + if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__Openbox,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail; + result = (ob::OBActions *)((ob::Openbox const *)arg1)->actions(); + + resultobj = SWIG_NewPointerObj((void *) result, SWIGTYPE_p_ob__OBActions, 0); + return resultobj; + fail: + return NULL; +} + + static PyObject *_wrap_Openbox_bindings(PyObject *self, PyObject *args) { PyObject *resultobj; ob::Openbox *arg1 = (ob::Openbox *) 0 ; @@ -1319,27 +1566,6 @@ static PyObject *_wrap_Openbox_shutdown(PyObject *self, PyObject *args) { } -static PyObject *_wrap_Openbox_getConfigString(PyObject *self, PyObject *args) { - PyObject *resultobj; - ob::Openbox *arg1 = (ob::Openbox *) 0 ; - char *arg2 ; - std::string *arg3 = (std::string *) 0 ; - bool result; - PyObject * obj0 = 0 ; - PyObject * obj2 = 0 ; - - if(!PyArg_ParseTuple(args,(char *)"OsO:Openbox_getConfigString",&obj0,&arg2,&obj2)) goto fail; - if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__Openbox,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail; - if ((SWIG_ConvertPtr(obj2,(void **) &arg3, SWIGTYPE_p_std__string,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail; - result = (bool)(arg1)->getConfigString((char const *)arg2,arg3); - - resultobj = PyInt_FromLong((long)result); - return resultobj; - fail: - return NULL; -} - - static PyObject * Openbox_swigregister(PyObject *self, PyObject *args) { PyObject *obj; if (!PyArg_ParseTuple(args,(char*)"O", &obj)) return NULL; @@ -2500,228 +2726,15 @@ static PyObject * OBClient_swigregister(PyObject *self, PyObject *args) { Py_INCREF(obj); return Py_BuildValue((char *)""); } -static PyObject *_wrap_python_init(PyObject *self, PyObject *args) { - PyObject *resultobj; - char *arg1 ; - - if(!PyArg_ParseTuple(args,(char *)"s:python_init",&arg1)) goto fail; - ob::python_init(arg1); - - Py_INCREF(Py_None); resultobj = Py_None; - return resultobj; - fail: - return NULL; -} - - -static PyObject *_wrap_python_exec(PyObject *self, PyObject *args) { - PyObject *resultobj; - char *arg1 ; - bool result; - - if(!PyArg_ParseTuple(args,(char *)"s:python_exec",&arg1)) goto fail; - result = (bool)ob::python_exec((char const *)arg1); - - resultobj = PyInt_FromLong((long)result); - return resultobj; - fail: - return NULL; -} - - -static PyObject *_wrap_python_get_string(PyObject *self, PyObject *args) { - PyObject *resultobj; - char *arg1 ; - std::string *arg2 = (std::string *) 0 ; - bool result; - PyObject * obj1 = 0 ; - - if(!PyArg_ParseTuple(args,(char *)"sO:python_get_string",&arg1,&obj1)) goto fail; - if ((SWIG_ConvertPtr(obj1,(void **) &arg2, SWIGTYPE_p_std__string,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail; - result = (bool)ob::python_get_string((char const *)arg1,arg2); - - resultobj = PyInt_FromLong((long)result); - return resultobj; - fail: - return NULL; -} - - -static PyObject *_wrap_register(PyObject *self, PyObject *args) { - PyObject *resultobj; - int arg1 ; - PyObject *arg2 = (PyObject *) 0 ; - bool result; - PyObject * obj1 = 0 ; - - if(!PyArg_ParseTuple(args,(char *)"iO:register",&arg1,&obj1)) goto fail; - arg2 = obj1; - result = (bool)ob::python_register(arg1,arg2); - - resultobj = PyInt_FromLong((long)result); - return resultobj; - fail: - return NULL; -} - - -static PyObject *_wrap_preregister(PyObject *self, PyObject *args) { - PyObject *resultobj; - int arg1 ; - PyObject *arg2 = (PyObject *) 0 ; - bool result; - PyObject * obj1 = 0 ; - - if(!PyArg_ParseTuple(args,(char *)"iO:preregister",&arg1,&obj1)) goto fail; - arg2 = obj1; - result = (bool)ob::python_preregister(arg1,arg2); - - resultobj = PyInt_FromLong((long)result); - return resultobj; - fail: - return NULL; -} - - -static PyObject *_wrap_unregister(PyObject *self, PyObject *args) { - PyObject *resultobj; - int arg1 ; - PyObject *arg2 = (PyObject *) 0 ; - bool result; - PyObject * obj1 = 0 ; - - if(!PyArg_ParseTuple(args,(char *)"iO:unregister",&arg1,&obj1)) goto fail; - arg2 = obj1; - result = (bool)ob::python_unregister(arg1,arg2); - - resultobj = PyInt_FromLong((long)result); - return resultobj; - fail: - return NULL; -} - - -static PyObject *_wrap_unregister_all(PyObject *self, PyObject *args) { - PyObject *resultobj; - int arg1 ; - bool result; - - if(!PyArg_ParseTuple(args,(char *)"i:unregister_all",&arg1)) goto fail; - result = (bool)ob::python_unregister_all(arg1); - - resultobj = PyInt_FromLong((long)result); - return resultobj; - fail: - return NULL; -} - - -static PyObject *_wrap_bind(PyObject *self, PyObject *args) { - PyObject *resultobj; - PyObject *arg1 = (PyObject *) 0 ; - PyObject *arg2 = (PyObject *) 0 ; - bool result; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - - if(!PyArg_ParseTuple(args,(char *)"OO:bind",&obj0,&obj1)) goto fail; - arg1 = obj0; - arg2 = obj1; - result = (bool)ob::python_bind(arg1,arg2); - - resultobj = PyInt_FromLong((long)result); - return resultobj; - fail: - return NULL; -} - - -static PyObject *_wrap_unbind(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; - arg1 = obj0; - result = (bool)ob::python_unbind(arg1); - - resultobj = PyInt_FromLong((long)result); - return resultobj; - fail: - return NULL; -} - - -static PyObject *_wrap_set_reset_key(PyObject *self, PyObject *args) { - PyObject *resultobj; - std::string *arg1 = 0 ; - std::string temp1 ; - PyObject * obj0 = 0 ; - - if(!PyArg_ParseTuple(args,(char *)"O:set_reset_key",&obj0)) goto fail; - { - if (PyString_Check(obj0)) { - temp1 = std::string(PyString_AsString(obj0)); - arg1 = &temp1; - }else { - SWIG_exception(SWIG_TypeError, "string expected"); - } - } - ob::python_set_reset_key((std::string const &)*arg1); - - Py_INCREF(Py_None); resultobj = Py_None; - return resultobj; - fail: - return NULL; -} - - -static PyObject *_wrap_unbind_all(PyObject *self, PyObject *args) { - PyObject *resultobj; - - if(!PyArg_ParseTuple(args,(char *)":unbind_all")) goto fail; - ob::python_unbind_all(); - - Py_INCREF(Py_None); resultobj = Py_None; - return resultobj; - fail: - return NULL; -} - - -static PyObject *_wrap_python_callback_binding(PyObject *self, PyObject *args) { - PyObject *resultobj; - int arg1 ; - Window arg2 ; - unsigned int arg3 ; - unsigned int arg4 ; - Time arg5 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - PyObject * obj3 = 0 ; - PyObject * obj4 = 0 ; - - if(!PyArg_ParseTuple(args,(char *)"iOOOO:python_callback_binding",&arg1,&obj1,&obj2,&obj3,&obj4)) goto fail; - arg2 = (Window) PyInt_AsLong(obj1); - if (PyErr_Occurred()) SWIG_fail; - arg3 = (unsigned int) PyInt_AsLong(obj2); - if (PyErr_Occurred()) SWIG_fail; - arg4 = (unsigned int) PyInt_AsLong(obj3); - if (PyErr_Occurred()) SWIG_fail; - arg5 = (Time) PyInt_AsLong(obj4); - if (PyErr_Occurred()) SWIG_fail; - ob::python_callback_binding(arg1,arg2,arg3,arg4,arg5); - - Py_INCREF(Py_None); resultobj = Py_None; - return resultobj; - fail: - return NULL; -} - - static PyMethodDef SwigMethods[] = { { (char *)"Openbox_instance", _wrap_Openbox_instance, METH_VARARGS }, + { (char *)"register", _wrap_register, 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 *)"unbind_all", _wrap_unbind_all, METH_VARARGS }, + { (char *)"set_reset_key", _wrap_set_reset_key, METH_VARARGS }, { (char *)"Cursors_session_set", _wrap_Cursors_session_set, METH_VARARGS }, { (char *)"Cursors_session_get", _wrap_Cursors_session_get, METH_VARARGS }, { (char *)"Cursors_move_set", _wrap_Cursors_move_set, METH_VARARGS }, @@ -2738,6 +2751,7 @@ static PyMethodDef SwigMethods[] = { { (char *)"Openbox_state", _wrap_Openbox_state, METH_VARARGS }, { (char *)"Openbox_timerManager", _wrap_Openbox_timerManager, METH_VARARGS }, { (char *)"Openbox_property", _wrap_Openbox_property, METH_VARARGS }, + { (char *)"Openbox_actions", _wrap_Openbox_actions, METH_VARARGS }, { (char *)"Openbox_bindings", _wrap_Openbox_bindings, METH_VARARGS }, { (char *)"Openbox_screen", _wrap_Openbox_screen, METH_VARARGS }, { (char *)"Openbox_screenCount", _wrap_Openbox_screenCount, METH_VARARGS }, @@ -2749,7 +2763,6 @@ static PyMethodDef SwigMethods[] = { { (char *)"Openbox_setFocusedClient", _wrap_Openbox_setFocusedClient, METH_VARARGS }, { (char *)"Openbox_focusedScreen", _wrap_Openbox_focusedScreen, METH_VARARGS }, { (char *)"Openbox_shutdown", _wrap_Openbox_shutdown, METH_VARARGS }, - { (char *)"Openbox_getConfigString", _wrap_Openbox_getConfigString, METH_VARARGS }, { (char *)"Openbox_swigregister", Openbox_swigregister, METH_VARARGS }, { (char *)"OBScreen_client", _wrap_OBScreen_client, METH_VARARGS }, { (char *)"OBScreen_clientCount", _wrap_OBScreen_clientCount, METH_VARARGS }, @@ -2815,24 +2828,15 @@ static PyMethodDef SwigMethods[] = { { (char *)"OBClient_destroyHandler", _wrap_OBClient_destroyHandler, METH_VARARGS }, { (char *)"OBClient_reparentHandler", _wrap_OBClient_reparentHandler, METH_VARARGS }, { (char *)"OBClient_swigregister", OBClient_swigregister, METH_VARARGS }, - { (char *)"python_init", _wrap_python_init, METH_VARARGS }, - { (char *)"python_exec", _wrap_python_exec, METH_VARARGS }, - { (char *)"python_get_string", _wrap_python_get_string, METH_VARARGS }, - { (char *)"register", _wrap_register, METH_VARARGS }, - { (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 *)"set_reset_key", _wrap_set_reset_key, METH_VARARGS }, - { (char *)"unbind_all", _wrap_unbind_all, METH_VARARGS }, - { (char *)"python_callback_binding", _wrap_python_callback_binding, METH_VARARGS }, { NULL, NULL } }; /* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ +static void *_p_ob__OBActionsTo_p_otk__OtkEventHandler(void *x) { + return (void *)((otk::OtkEventHandler *) ((ob::OBActions *) x)); +} static void *_p_ob__OpenboxTo_p_otk__OtkEventHandler(void *x) { return (void *)((otk::OtkEventHandler *) ((ob::Openbox *) x)); } @@ -2846,6 +2850,7 @@ static void *_p_ob__OpenboxTo_p_otk__OtkEventDispatcher(void *x) { return (void *)((otk::OtkEventDispatcher *) ((ob::Openbox *) x)); } static swig_type_info _swigt__p_otk__OBTimerQueueManager[] = {{"_p_otk__OBTimerQueueManager", 0, "otk::OBTimerQueueManager *", 0},{"_p_otk__OBTimerQueueManager"},{0}}; +static swig_type_info _swigt__p_ob__OBActions[] = {{"_p_ob__OBActions", 0, "ob::OBActions *", 0},{"_p_ob__OBActions"},{0}}; static swig_type_info _swigt__p_ob__Cursors[] = {{"_p_ob__Cursors", 0, "ob::Cursors *", 0},{"_p_ob__Cursors"},{0}}; static swig_type_info _swigt__p_ob__OBScreen[] = {{"_p_ob__OBScreen", 0, "ob::OBScreen *", 0},{"_p_ob__OBScreen"},{0}}; static swig_type_info _swigt__p_otk__Style[] = {{"_p_otk__Style", 0, "otk::Style *", 0},{"_p_otk__Style"},{0}}; @@ -2856,8 +2861,7 @@ static swig_type_info _swigt__p_ob__Openbox[] = {{"_p_ob__Openbox", 0, "ob::Open static swig_type_info _swigt__p_otk__Strut[] = {{"_p_otk__Strut", 0, "otk::Strut *", 0},{"_p_otk__Strut"},{0}}; static swig_type_info _swigt__p_XShapeEvent[] = {{"_p_XShapeEvent", 0, "XShapeEvent *", 0},{"_p_XShapeEvent"},{0}}; static swig_type_info _swigt__p_XConfigureRequestEvent[] = {{"_p_XConfigureRequestEvent", 0, "XConfigureRequestEvent *", 0},{"_p_XConfigureRequestEvent"},{0}}; -static swig_type_info _swigt__p_std__string[] = {{"_p_std__string", 0, "std::string *", 0},{"_p_std__string"},{0}}; -static swig_type_info _swigt__p_otk__OtkEventHandler[] = {{"_p_otk__OtkEventHandler", 0, "otk::OtkEventHandler *", 0},{"_p_otk__OtkEventHandler"},{"_p_ob__Openbox", _p_ob__OpenboxTo_p_otk__OtkEventHandler},{"_p_ob__OBClient", _p_ob__OBClientTo_p_otk__OtkEventHandler},{0}}; +static swig_type_info _swigt__p_otk__OtkEventHandler[] = {{"_p_otk__OtkEventHandler", 0, "otk::OtkEventHandler *", 0},{"_p_ob__OBActions", _p_ob__OBActionsTo_p_otk__OtkEventHandler},{"_p_otk__OtkEventHandler"},{"_p_ob__Openbox", _p_ob__OpenboxTo_p_otk__OtkEventHandler},{"_p_ob__OBClient", _p_ob__OBClientTo_p_otk__OtkEventHandler},{0}}; static swig_type_info _swigt__p_otk__Rect[] = {{"_p_otk__Rect", 0, "otk::Rect *", 0},{"_p_otk__Rect"},{0}}; static swig_type_info _swigt__p_ob__OBWidget[] = {{"_p_ob__OBWidget", 0, "ob::OBWidget *", 0},{"_p_ob__OBWidget"},{"_p_ob__OBClient", _p_ob__OBClientTo_p_ob__OBWidget},{0}}; static swig_type_info _swigt__p_XFocusChangeEvent[] = {{"_p_XFocusChangeEvent", 0, "XFocusChangeEvent *", 0},{"_p_XFocusChangeEvent"},{0}}; @@ -2866,14 +2870,15 @@ static swig_type_info _swigt__p_otk__OBProperty[] = {{"_p_otk__OBProperty", 0, " static swig_type_info _swigt__p_otk__OtkEventDispatcher[] = {{"_p_otk__OtkEventDispatcher", 0, "otk::OtkEventDispatcher *", 0},{"_p_otk__OtkEventDispatcher"},{"_p_ob__Openbox", _p_ob__OpenboxTo_p_otk__OtkEventDispatcher},{0}}; static swig_type_info _swigt__p_XPropertyEvent[] = {{"_p_XPropertyEvent", 0, "XPropertyEvent *", 0},{"_p_XPropertyEvent"},{0}}; static swig_type_info _swigt__p_XDestroyWindowEvent[] = {{"_p_XDestroyWindowEvent", 0, "XDestroyWindowEvent *", 0},{"_p_XDestroyWindowEvent"},{0}}; -static swig_type_info _swigt__p_otk__BImageControl[] = {{"_p_otk__BImageControl", 0, "otk::BImageControl *", 0},{"_p_otk__BImageControl"},{0}}; static swig_type_info _swigt__p_PyObject[] = {{"_p_PyObject", 0, "PyObject *", 0},{"_p_PyObject"},{0}}; +static swig_type_info _swigt__p_otk__BImageControl[] = {{"_p_otk__BImageControl", 0, "otk::BImageControl *", 0},{"_p_otk__BImageControl"},{0}}; static swig_type_info _swigt__p_ob__OBBindings[] = {{"_p_ob__OBBindings", 0, "ob::OBBindings *", 0},{"_p_ob__OBBindings"},{0}}; static swig_type_info _swigt__p_ob__MwmHints[] = {{"_p_ob__MwmHints", 0, "ob::MwmHints *", 0},{"_p_ob__MwmHints"},{0}}; static swig_type_info _swigt__p_XUnmapEvent[] = {{"_p_XUnmapEvent", 0, "XUnmapEvent *", 0},{"_p_XUnmapEvent"},{0}}; static swig_type_info *swig_types_initial[] = { _swigt__p_otk__OBTimerQueueManager, +_swigt__p_ob__OBActions, _swigt__p_ob__Cursors, _swigt__p_ob__OBScreen, _swigt__p_otk__Style, @@ -2884,7 +2889,6 @@ _swigt__p_ob__Openbox, _swigt__p_otk__Strut, _swigt__p_XShapeEvent, _swigt__p_XConfigureRequestEvent, -_swigt__p_std__string, _swigt__p_otk__OtkEventHandler, _swigt__p_otk__Rect, _swigt__p_ob__OBWidget, @@ -2894,8 +2898,8 @@ _swigt__p_otk__OBProperty, _swigt__p_otk__OtkEventDispatcher, _swigt__p_XPropertyEvent, _swigt__p_XDestroyWindowEvent, -_swigt__p_otk__BImageControl, _swigt__p_PyObject, +_swigt__p_otk__BImageControl, _swigt__p_ob__OBBindings, _swigt__p_ob__MwmHints, _swigt__p_XUnmapEvent, diff --git a/src/python.cc b/src/python.cc index ddd10d0f..8fec3b15 100644 --- a/src/python.cc +++ b/src/python.cc @@ -2,14 +2,12 @@ #include "python.hh" #include "openbox.hh" +#include "actions.hh" +#include "python.hh" +#include "bindings.hh" #include "otk/display.hh" -#include -#include - extern "C" { -#include - // The initializer in openbox_wrap.cc extern void init_openbox(void); // The initializer in otk_wrap.cc @@ -18,271 +16,291 @@ extern void init_otk(void); namespace ob { -typedef std::vector FunctionList; - -static FunctionList callbacks[OBActions::NUM_ACTIONS]; -static FunctionList bindfuncs; - -static PyObject *obdict; - -void python_init(char *argv0) +static PyObject *obdict = NULL; + +// ************************************************************* // +// Define some custom types which are passed to python callbacks // +// ************************************************************* // + +typedef struct { + PyObject_HEAD; + OBActions::ActionType action; + Window window; + OBWidget::WidgetType type; + unsigned int state; + unsigned int button; + int xroot; + int yroot; + Time time; +} ActionData; + +typedef struct { + PyObject_HEAD; + Window window; + unsigned int state; + unsigned int key; + Time time; +} BindingData; + +static void ActionDataDealloc(ActionData *self) { - Py_SetProgramName(argv0); - Py_Initialize(); - init_otk(); - init_openbox(); - PyRun_SimpleString("from _otk import *; from _openbox import *;"); - - // set up access to the python global variables - PyObject *obmodule = PyImport_AddModule("__main__"); - obdict = PyModule_GetDict(obmodule); + PyObject_Del((PyObject*)self); } -bool python_exec(const char *file) { - FILE *rcpyfd = fopen(file, "r"); - if (!rcpyfd) { - printf("failed to load python file %s\n", file); - return false; - } - PyRun_SimpleFile(rcpyfd, const_cast(file)); - fclose(rcpyfd); - return true; +static void BindingDataDealloc(BindingData *self) +{ + PyObject_Del((PyObject*)self); } -bool python_get_string(const char *name, std::string *value) +PyObject *ActionData_action(ActionData *self, PyObject *args) { - PyObject *val = PyDict_GetItemString(obdict, const_cast(name)); - if (!val) return false; - - *value = PyString_AsString(val); - return true; + if(!PyArg_ParseTuple(args,":action")) return NULL; + return PyLong_FromLong((int)self->action); } - -bool python_register(int action, PyObject *callback) +PyObject *ActionData_window(ActionData *self, PyObject *args) { - if (action < 0 || action >= OBActions::NUM_ACTIONS || - action == OBActions::Action_KeyPress) { - PyErr_SetString(PyExc_AssertionError, "Invalid action type."); - return false; - } - if (!PyCallable_Check(callback)) { - PyErr_SetString(PyExc_AssertionError, "Invalid callback function."); - return false; - } - - FunctionList::iterator it = std::find(callbacks[action].begin(), - callbacks[action].end(), - callback); - if (it == callbacks[action].end()) { // not already in there - Py_XINCREF(callback); // Add a reference to new callback - callbacks[action].push_back(callback); - } - return true; + if(!PyArg_ParseTuple(args,":window")) return NULL; + return PyLong_FromLong(self->window); } -bool python_preregister(int action, PyObject *callback) +PyObject *ActionData_target(ActionData *self, PyObject *args) { - if (action < 0 || action >= OBActions::NUM_ACTIONS || - action == OBActions::Action_KeyPress) { - PyErr_SetString(PyExc_AssertionError, "Invalid action type."); - return false; - } - if (!PyCallable_Check(callback)) { - PyErr_SetString(PyExc_AssertionError, "Invalid callback function."); - return false; - } - - FunctionList::iterator it = std::find(callbacks[action].begin(), - callbacks[action].end(), - callback); - if (it == callbacks[action].end()) { // not already in there - Py_XINCREF(callback); // Add a reference to new callback - callbacks[action].insert(callbacks[action].begin(), callback); - } - return true; + if(!PyArg_ParseTuple(args,":target")) return NULL; + return PyLong_FromLong((int)self->type); } -bool python_unregister(int action, PyObject *callback) +PyObject *ActionData_modifiers(ActionData *self, PyObject *args) { - if (action < 0 || action >= OBActions::NUM_ACTIONS || - action == OBActions::Action_KeyPress) { - PyErr_SetString(PyExc_AssertionError, "Invalid action type."); - return false; - } - if (!PyCallable_Check(callback)) { - PyErr_SetString(PyExc_AssertionError, "Invalid callback function."); - return false; - } - - FunctionList::iterator it = std::find(callbacks[action].begin(), - callbacks[action].end(), - callback); - if (it != callbacks[action].end()) { // its been registered before - Py_XDECREF(*it); // Dispose of previous callback - callbacks[action].erase(it); - } - return true; + if(!PyArg_ParseTuple(args,":modifiers")) return NULL; + return PyLong_FromUnsignedLong(self->state); } -bool python_unregister_all(int action) +PyObject *ActionData_button(ActionData *self, PyObject *args) { - if (action < 0 || action >= OBActions::NUM_ACTIONS) { - PyErr_SetString(PyExc_AssertionError, "Invalid action type."); - return false; + if(!PyArg_ParseTuple(args,":button")) return NULL; + int b = 0; + switch (self->button) { + case Button5: b++; + case Button4: b++; + case Button3: b++; + case Button2: b++; + case Button1: b++; + default: ; } - - while (!callbacks[action].empty()) { - Py_XDECREF(callbacks[action].back()); - callbacks[action].pop_back(); - } - return true; + return PyLong_FromLong(b); } -void python_callback(OBActions::ActionType action, Window window, - OBWidget::WidgetType type, unsigned int state, - long d1, long d2, long d3, long d4) +PyObject *ActionData_xroot(ActionData *self, PyObject *args) { - PyObject *arglist; - PyObject *result; - - assert(action >= 0 && action < OBActions::NUM_ACTIONS); - - if (d4 != LONG_MIN) - arglist = Py_BuildValue("iliillll", action, window, type, state, - d1, d2, d3, d4); - else if (d3 != LONG_MIN) - arglist = Py_BuildValue("iliilll", action, window, type, state, - d1, d2, d3); - else if (d2 != LONG_MIN) - arglist = Py_BuildValue("iliill", action, window, type, state, d1, d2); - else if (d1 != LONG_MIN) - arglist = Py_BuildValue("iliil", action, window, type, state, d1); - else - arglist = Py_BuildValue("ilii", action, window, type, state); - - FunctionList::iterator it, end = callbacks[action].end(); - for (it = callbacks[action].begin(); it != end; ++it) { - // call the callback - result = PyEval_CallObject(*it, arglist); - if (result) { - Py_DECREF(result); - } else { - // an exception occured in the script, display it - PyErr_Print(); - } - } + if(!PyArg_ParseTuple(args,":xroot")) return NULL; + return PyLong_FromLong(self->xroot); +} - Py_DECREF(arglist); +PyObject *ActionData_yroot(ActionData *self, PyObject *args) +{ + if(!PyArg_ParseTuple(args,":yroot")) return NULL; + return PyLong_FromLong(self->yroot); } +PyObject *ActionData_time(ActionData *self, PyObject *args) +{ + if(!PyArg_ParseTuple(args,":time")) return NULL; + return PyLong_FromLong(self->time); +} +static PyMethodDef ActionData_methods[] = { + {"action", (PyCFunction)ActionData_action, METH_VARARGS, + "Return the action being executed."}, + {"window", (PyCFunction)ActionData_window, METH_VARARGS, + "Return the client window id."}, + {"target", (PyCFunction)ActionData_target, METH_VARARGS, + "Return the target type that the action is occuring on."}, + {"modifiers", (PyCFunction)ActionData_modifiers, METH_VARARGS, + "Return the modifier keys state."}, + {"button", (PyCFunction)ActionData_button, METH_VARARGS, + "Return the number of the pressed button (1-5)."}, + {"xroot", (PyCFunction)ActionData_xroot, METH_VARARGS, + "Return the X-position of the mouse cursor on the root window."}, + {"yroot", (PyCFunction)ActionData_yroot, METH_VARARGS, + "Return the Y-position of the mouse cursor on the root window."}, + {"time", (PyCFunction)ActionData_time, METH_VARARGS, + "Return the time at which the event occured."}, + {NULL, NULL, 0, NULL} +}; + +PyObject *BindingData_window(BindingData *self, PyObject *args) +{ + if(!PyArg_ParseTuple(args,":window")) return NULL; + return PyLong_FromLong(self->window); +} +PyObject *BindingData_modifiers(BindingData *self, PyObject *args) +{ + if(!PyArg_ParseTuple(args,":modifiers")) return NULL; + return PyLong_FromUnsignedLong(self->state); +} +PyObject *BindingData_key(BindingData *self, PyObject *args) +{ + if(!PyArg_ParseTuple(args,":key")) return NULL; + return PyString_FromString( + XKeysymToString(XKeycodeToKeysym(otk::OBDisplay::display, self->key, 0))); +} -bool python_bind(PyObject *keylist, PyObject *callback) +PyObject *BindingData_time(BindingData *self, PyObject *args) { - if (!PyList_Check(keylist)) { - PyErr_SetString(PyExc_AssertionError, "Invalid keylist. Not a list."); - return false; - } - if (!PyCallable_Check(callback)) { - PyErr_SetString(PyExc_AssertionError, "Invalid callback function."); - return false; - } + if(!PyArg_ParseTuple(args,":time")) return NULL; + return PyLong_FromLong(self->time); +} - OBBindings::StringVect vectkeylist; - for (int i = 0, end = PyList_Size(keylist); i < end; ++i) { - PyObject *str = PyList_GetItem(keylist, i); - if (!PyString_Check(str)) { - PyErr_SetString(PyExc_AssertionError, - "Invalid keylist. It must contain only strings."); - return false; - } - vectkeylist.push_back(PyString_AsString(str)); - } +static PyMethodDef BindingData_methods[] = { + {"window", (PyCFunction)BindingData_window, METH_VARARGS, + "Return the client window id."}, + {"modifiers", (PyCFunction)BindingData_modifiers, METH_VARARGS, + "Return the modifier keys state."}, + {"key", (PyCFunction)BindingData_key, METH_VARARGS, + "Return the name of the pressed key."}, + {"time", (PyCFunction)BindingData_time, METH_VARARGS, + "Return the time at which the event occured."}, + {NULL, NULL, 0, NULL} +}; + +static PyObject *ActionDataGetAttr(PyObject *obj, char *name) +{ + return Py_FindMethod(ActionData_methods, obj, name); +} - // 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)) { - Py_XINCREF(callback); // Add a reference to new callback - bindfuncs.push_back(callback); - return true; - } else { - PyErr_SetString(PyExc_AssertionError,"Unable to create binding. Invalid."); - return false; - } +static PyObject *BindingDataGetAttr(PyObject *obj, char *name) +{ + return Py_FindMethod(BindingData_methods, obj, name); } -bool python_unbind(PyObject *keylist) +static PyTypeObject ActionData_Type = { + PyObject_HEAD_INIT(NULL) + 0, + "ActionData", + sizeof(ActionData), + 0, + (destructor)ActionDataDealloc, + 0, + (getattrfunc)ActionDataGetAttr, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; + +static PyTypeObject BindingData_Type = { + PyObject_HEAD_INIT(NULL) + 0, + "BindingData", + sizeof(BindingData), + 0, + (destructor)BindingDataDealloc, + 0, + (getattrfunc)BindingDataGetAttr, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; + +// **************** // +// End custom types // +// **************** // + +void python_init(char *argv0) { - if (!PyList_Check(keylist)) { - PyErr_SetString(PyExc_AssertionError, "Invalid keylist. Not a list."); - return false; - } + Py_SetProgramName(argv0); + Py_Initialize(); + init_otk(); + init_openbox(); + PyRun_SimpleString("from _otk import *; from _openbox import *;"); - OBBindings::StringVect vectkeylist; - for (int i = 0, end = PyList_Size(keylist); i < end; ++i) { - PyObject *str = PyList_GetItem(keylist, i); - if (!PyString_Check(str)) { - PyErr_SetString(PyExc_AssertionError, - "Invalid keylist. It must contain only strings."); - return false; - } - vectkeylist.push_back(PyString_AsString(str)); - } + // set up access to the python global variables + PyObject *obmodule = PyImport_AddModule("__main__"); + obdict = PyModule_GetDict(obmodule); - 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 - // 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; - return true; - } - - return false; + // set up the custom types + ActionData_Type.ob_type = &PyType_Type; + BindingData_Type.ob_type = &PyType_Type; } -void python_set_reset_key(const std::string &key) +void python_destroy() { - Openbox::instance->bindings()->setResetKey(key); + Py_DECREF(obdict); } -void python_unbind_all() +bool python_exec(const std::string &path) { - Openbox::instance->bindings()->remove_all(); + FILE *rcpyfd = fopen(path.c_str(), "r"); + if (!rcpyfd) { + printf("failed to load python file %s\n", path.c_str()); + return false; + } + PyRun_SimpleFile(rcpyfd, const_cast(path.c_str())); + fclose(rcpyfd); + return true; } - -void python_callback_binding(int id, Window window, unsigned int state, - unsigned int keybutton, Time time) +static void call(PyObject *func, PyObject *data) { - if (!bindfuncs[id]) return; // the key was unbound - PyObject *arglist; PyObject *result; - arglist = Py_BuildValue("lisl", window, state, - XKeysymToString( - XKeycodeToKeysym(otk::OBDisplay::display, - keybutton, 0)), - time); - + arglist = Py_BuildValue("(O)", data); + // call the callback - result = PyEval_CallObject(bindfuncs[id], arglist); - if (result) { - Py_DECREF(result); - } else { + result = PyEval_CallObject(func, arglist); + if (!result) { // an exception occured in the script, display it PyErr_Print(); } + Py_XDECREF(result); Py_DECREF(arglist); } +void python_callback(PyObject *func, OBActions::ActionType action, + Window window, OBWidget::WidgetType type, + unsigned int state, unsigned int button, + int xroot, int yroot, Time time) +{ + assert(func); + + ActionData *data = PyObject_New(ActionData, &ActionData_Type); + data->action = action; + data->window = window; + data->type = type; + data->state = state; + data->button = button; + data->xroot = xroot; + data->yroot = yroot; + data->time = time; + + call(func, (PyObject*)data); + Py_DECREF(data); +} + +void python_callback(PyObject *func, Window window, unsigned int state, + unsigned int key, Time time) +{ + if (!func) return; + + BindingData *data = PyObject_New(BindingData, &BindingData_Type); + data->window = window; + data->state = state; + data->key = key; + data->time = time; + + call(func, (PyObject*)data); + Py_DECREF(data); +} + +bool python_get_string(const char *name, std::string *value) +{ + PyObject *val = PyDict_GetItemString(obdict, const_cast(name)); + if (!(val && PyString_Check(val))) return false; + + *value = PyString_AsString(val); + return true; +} + + } diff --git a/src/python.hh b/src/python.hh index 7566f817..0870c9ad 100644 --- a/src/python.hh +++ b/src/python.hh @@ -19,50 +19,20 @@ extern "C" { namespace ob { void python_init(char *argv0); -bool python_exec(const char *file); -bool python_get_string(const char *name, std::string *value); - -//! Add a python callback funtion to the back of the hook list -/*! - Registering functions for KeyPress events is pointless. Use python_bind - instead to do this. -*/ -bool python_register(int action, PyObject *callback); -//! Add a python callback funtion to the front of the hook list -/*! - Registering functions for KeyPress events is pointless. Use python_bind - instead to do this. -*/ -bool python_preregister(int action, PyObject *callback); -//! Remove a python callback function from the hook list -bool python_unregister(int action, PyObject *callback); - -//! Removes all python callback functions from the hook list -bool python_unregister_all(int action); +void python_destroy(); +bool python_exec(const std::string &path); + +void python_callback(PyObject *func, OBActions::ActionType action, + Window window, OBWidget::WidgetType type, + unsigned int state, unsigned int button, + int xroot, int yroot, Time time); -//! 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_unbind(PyObject *keylist); - -void python_set_reset_key(const std::string &key); +void python_callback(PyObject *func, Window window, unsigned int state, + unsigned int key, Time time); -void python_unbind_all(); -//! Fire a python callback function -void python_callback(OBActions::ActionType action, Window window, - OBWidget::WidgetType type, unsigned int state, - long d1 = LONG_MIN, long d2 = LONG_MIN, - long d3 = LONG_MIN, long d4 = LONG_MIN); - -//! Fire a python callback function for a key binding -void python_callback_binding(int id, Window window, unsigned int state, - unsigned int keybutton, Time time); +bool python_get_string(const char *name, std::string *value); +bool python_getstringlist(const char *name, std::vector *value); } diff --git a/src/screen.cc b/src/screen.cc index 80b9083d..da603ed8 100644 --- a/src/screen.cc +++ b/src/screen.cc @@ -23,6 +23,7 @@ extern "C" { #include "openbox.hh" #include "frame.hh" #include "bindings.hh" +#include "python.hh" #include "otk/display.hh" static bool running; @@ -75,7 +76,7 @@ OBScreen::OBScreen(int screen) // initialize the screen's style _style.setImageControl(_image_control); std::string stylepath; - Openbox::instance->getConfigString("theme", &stylepath); + python_get_string("theme", &stylepath); otk::Configuration sconfig(false); sconfig.setFile(otk::expandTilde(stylepath)); if (!sconfig.load()) { -- 2.39.2