]>
Dogcows Code - chaz/openbox/blob - src/python.cc
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
5 #include "otk/display.hh"
12 typedef std::vector
<PyObject
*> FunctionList
;
14 static FunctionList callbacks
[OBActions::NUM_ACTIONS
];
15 static FunctionList bindfuncs
;
17 bool python_register(int action
, PyObject
*callback
)
19 if (action
< 0 || action
>= OBActions::NUM_ACTIONS
||
20 action
== OBActions::Action_KeyPress
) {
21 PyErr_SetString(PyExc_AssertionError
, "Invalid action type.");
24 if (!PyCallable_Check(callback
)) {
25 PyErr_SetString(PyExc_AssertionError
, "Invalid callback function.");
29 FunctionList::iterator it
= std::find(callbacks
[action
].begin(),
30 callbacks
[action
].end(),
32 if (it
== callbacks
[action
].end()) { // not already in there
33 Py_XINCREF(callback
); // Add a reference to new callback
34 callbacks
[action
].push_back(callback
);
39 bool python_preregister(int action
, PyObject
*callback
)
41 if (action
< 0 || action
>= OBActions::NUM_ACTIONS
||
42 action
== OBActions::Action_KeyPress
) {
43 PyErr_SetString(PyExc_AssertionError
, "Invalid action type.");
46 if (!PyCallable_Check(callback
)) {
47 PyErr_SetString(PyExc_AssertionError
, "Invalid callback function.");
51 FunctionList::iterator it
= std::find(callbacks
[action
].begin(),
52 callbacks
[action
].end(),
54 if (it
== callbacks
[action
].end()) { // not already in there
55 Py_XINCREF(callback
); // Add a reference to new callback
56 callbacks
[action
].insert(callbacks
[action
].begin(), callback
);
61 bool python_unregister(int action
, PyObject
*callback
)
63 if (action
< 0 || action
>= OBActions::NUM_ACTIONS
||
64 action
== OBActions::Action_KeyPress
) {
65 PyErr_SetString(PyExc_AssertionError
, "Invalid action type.");
68 if (!PyCallable_Check(callback
)) {
69 PyErr_SetString(PyExc_AssertionError
, "Invalid callback function.");
73 FunctionList::iterator it
= std::find(callbacks
[action
].begin(),
74 callbacks
[action
].end(),
76 if (it
!= callbacks
[action
].end()) { // its been registered before
77 Py_XDECREF(*it
); // Dispose of previous callback
78 callbacks
[action
].erase(it
);
83 bool python_unregister_all(int action
)
85 if (action
< 0 || action
>= OBActions::NUM_ACTIONS
) {
86 PyErr_SetString(PyExc_AssertionError
, "Invalid action type.");
90 while (!callbacks
[action
].empty()) {
91 Py_XDECREF(callbacks
[action
].back());
92 callbacks
[action
].pop_back();
97 void python_callback(OBActions::ActionType action
, Window window
,
98 OBWidget::WidgetType type
, unsigned int state
,
99 long d1
, long d2
, long d3
, long d4
)
104 assert(action
>= 0 && action
< OBActions::NUM_ACTIONS
);
107 arglist
= Py_BuildValue("iliillll", action
, window
, type
, state
,
109 else if (d3
!= LONG_MIN
)
110 arglist
= Py_BuildValue("iliilll", action
, window
, type
, state
,
112 else if (d2
!= LONG_MIN
)
113 arglist
= Py_BuildValue("iliill", action
, window
, type
, state
, d1
, d2
);
114 else if (d1
!= LONG_MIN
)
115 arglist
= Py_BuildValue("iliil", action
, window
, type
, state
, d1
);
117 arglist
= Py_BuildValue("ilii", action
, window
, type
, state
);
119 FunctionList::iterator it
, end
= callbacks
[action
].end();
120 for (it
= callbacks
[action
].begin(); it
!= end
; ++it
) {
122 result
= PyEval_CallObject(*it
, arglist
);
126 // an exception occured in the script, display it
139 bool python_bind(PyObject
*keylist
, PyObject
*callback
)
141 if (!PyList_Check(keylist
)) {
142 PyErr_SetString(PyExc_AssertionError
, "Invalid keylist. Not a list.");
145 if (!PyCallable_Check(callback
)) {
146 PyErr_SetString(PyExc_AssertionError
, "Invalid callback function.");
150 OBBindings::StringVect vectkeylist
;
151 for (int i
= 0, end
= PyList_Size(keylist
); i
< end
; ++i
) {
152 PyObject
*str
= PyList_GetItem(keylist
, i
);
153 if (!PyString_Check(str
)) {
154 PyErr_SetString(PyExc_AssertionError
,
155 "Invalid keylist. It must contain only strings.");
158 vectkeylist
.push_back(PyString_AsString(str
));
161 // the id is what the binding class can call back with so it doesnt have to
162 // worry about the python function pointer
163 int id
= bindfuncs
.size();
164 if (Openbox::instance
->bindings()->add(vectkeylist
, id
)) {
165 Py_XINCREF(callback
); // Add a reference to new callback
166 bindfuncs
.push_back(callback
);
169 PyErr_SetString(PyExc_AssertionError
,"Unable to create binding. Invalid.");
174 bool python_unbind(PyObject
*keylist
)
176 if (!PyList_Check(keylist
)) {
177 PyErr_SetString(PyExc_AssertionError
, "Invalid keylist. Not a list.");
181 OBBindings::StringVect vectkeylist
;
182 for (int i
= 0, end
= PyList_Size(keylist
); i
< end
; ++i
) {
183 PyObject
*str
= PyList_GetItem(keylist
, i
);
184 if (!PyString_Check(str
)) {
185 PyErr_SetString(PyExc_AssertionError
,
186 "Invalid keylist. It must contain only strings.");
189 vectkeylist
.push_back(PyString_AsString(str
));
194 Openbox::instance
->bindings()->remove(vectkeylist
)) >= 0) {
195 assert(bindfuncs
[id
]); // shouldn't be able to remove it twice
196 Py_XDECREF(bindfuncs
[id
]); // Dispose of previous callback
197 // important note: we don't erase the item from the list cuz that would
198 // ruin all the id's that are in use. simply nullify it.
206 void python_set_reset_key(const std::string
&key
)
208 Openbox::instance
->bindings()->setResetKey(key
);
211 void python_unbind_all()
213 Openbox::instance
->bindings()->remove_all();
217 void python_callback_binding(int id
, Window window
, unsigned int state
,
218 unsigned int keybutton
, Time time
)
220 if (!bindfuncs
[id
]) return; // the key was unbound
225 arglist
= Py_BuildValue("lisl", window
, state
,
227 XKeycodeToKeysym(otk::OBDisplay::display
,
232 result
= PyEval_CallObject(bindfuncs
[id
], arglist
);
236 // an exception occured in the script, display it
This page took 0.048399 seconds and 5 git commands to generate.