]> Dogcows Code - chaz/openbox/commitdiff
new code for bindings/callbacks. much sexier. now passes python classes back to the...
authorDana Jansens <danakj@orodu.net>
Thu, 2 Jan 2003 20:36:14 +0000 (20:36 +0000)
committerDana Jansens <danakj@orodu.net>
Thu, 2 Jan 2003 20:36:14 +0000 (20:36 +0000)
14 files changed:
scripts/clicks.py
scripts/clientmotion.py
src/Makefile.am
src/actions.cc
src/actions.hh
src/bindings.cc
src/bindings.hh
src/openbox.cc
src/openbox.hh
src/openbox.i
src/openbox_wrap.cc
src/python.cc
src/python.hh
src/screen.cc

index c6f47d5886bd80f6eb12c8008f48b999cbcc7e2a..a9c2fec1f3d029f5ad4536250340fca3a9713655 100644 (file)
@@ -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"
index 24b16e63fc13899127a7c8553fab82f193593c49..dc58489366d3e8d5243e062ca251ebd246702dfe 100644 (file)
@@ -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)
index a8995148e8d5be8a3068c332eab004a6d457916c..10c93be6f03431705ce226d0f637c18fe4950c9c 100644 (file)
@@ -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
 
index 50259c89e518f1223150b8a8473db24eefe50ab2..b6f1dad8a1026c4ff00b75b72ef54acd5bdfcf92 100644 (file)
@@ -39,9 +39,9 @@ void OBActions::buttonPressHandler(const XButtonEvent &e)
   OBWidget *w = dynamic_cast<OBWidget*>
     (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<OBWidget*>
 //    (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<CallbackMap::iterator, CallbackMap::iterator> 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<CallbackMap::iterator, CallbackMap::iterator> 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<CallbackMap::iterator, CallbackMap::iterator> 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;
 }
 
 }
index 8b6633be5e66d1a861fc0d1c4d612ee986a9e925..50df838b22dd3eada79ba6f8f416b0d2b333a904 100644 (file)
@@ -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 <X11/Xlib.h>
+#include <Python.h>
 }
 
+#include <map>
+
 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<ActionType, PyObject*> CallbackMap;
+  typedef std::pair<ActionType, PyObject*> 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);
 };
 
 }
index 42a92591724249b2779f9ec2f931a2b4b384bf1b..fade3e6957db76ff8e7e72584b70f0cc730d4998 100644 (file)
@@ -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;
index 0ae035761437ba5890860684d351e80ce4d6aedc..9d55b7512c2b58ce4ea539ed88565988eb9c7971 100644 (file)
@@ -9,7 +9,12 @@
 #include "actions.hh"
 #include "otk/timer.hh"
 
+extern "C" {
+#include <Python.h>
+}
+
 #include <string>
+#include <list>
 #include <vector>
 
 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);
 
index 01316d795c276762d6c6c23b1e698eb2196db16a..f7f2098b1bc1d608952f3a522e0470fbb6186538 100644 (file)
@@ -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);
-}
-
 }
 
index b5956e46e86e0b3846114a3518f9ea9dd51b6cf9..1a537dcd7dfc1c387a9f18bb8d815e192bf4c97f 100644 (file)
@@ -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 <X11/Xlib.h>
 }
@@ -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);
 };
 
 }
index 0bfad27f291442184c66311b74fc6664dba1dbe4..b5e7f09e4799791ff7cef4a4f4f8fa70e15615e3 100644 (file)
 #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<OBClient*>;
 
     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;
 %{
 %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"
index 587e1abbc48228a52968483179f4653c4320e4c9..ada473b6b6ccca6350549da16907984acf517fbe 100644 (file)
@@ -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 <iterator>
 
 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, 
index ddd10d0f29acd098d11533a2f7514b538a5c253b..8fec3b15a3aced85d0f2e76cb5267fcc1bc513df 100644 (file)
@@ -2,14 +2,12 @@
 
 #include "python.hh"
 #include "openbox.hh"
+#include "actions.hh"
+#include "python.hh"
+#include "bindings.hh"
 #include "otk/display.hh"
 
-#include <vector>
-#include <algorithm>
-
 extern "C" {
-#include <Python.h>
-  
 // 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<PyObject*> 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<char*>(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<char*>(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<char*>(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<char*>(name));
+  if (!(val && PyString_Check(val))) return false;
+  
+  *value = PyString_AsString(val);
+  return true;
+}
+
+
 }
index 7566f817bdea3862480966a753d573e700884a8c..0870c9ad312d391889b07e8802899a0ccd11fadc 100644 (file)
@@ -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<std::string> *value);
 
 }
 
index 80b9083d6992d5e2db1c2551272a2e68cdd21886..da603ed8cb3d690152853fa13c5cc46539651f78 100644 (file)
@@ -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()) {
This page took 0.073234 seconds and 4 git commands to generate.