]>
Dogcows Code - chaz/openbox/blob - src/python.cc
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
5 #include "otk/display.hh"
13 // The initializer in openbox_wrap.cc
14 extern void init_openbox(void);
15 // The initializer in otk_wrap.cc
16 extern void init_otk(void);
21 typedef std::vector
<PyObject
*> FunctionList
;
23 static FunctionList callbacks
[OBActions::NUM_ACTIONS
];
24 static FunctionList bindfuncs
;
26 static PyObject
*obdict
;
28 void python_init(char *argv0
)
30 Py_SetProgramName(argv0
);
34 PyRun_SimpleString("from _otk import *; from _openbox import *;");
36 // set up access to the python global variables
37 PyObject
*obmodule
= PyImport_AddModule("__main__");
38 obdict
= PyModule_GetDict(obmodule
);
41 bool python_exec(const char *file
) {
42 FILE *rcpyfd
= fopen(file
, "r");
44 printf("failed to load python file %s\n", file
);
47 PyRun_SimpleFile(rcpyfd
, const_cast<char*>(file
));
52 bool python_get_string(const char *name
, std::string
*value
)
54 PyObject
*val
= PyDict_GetItemString(obdict
, const_cast<char*>(name
));
55 if (!val
) return false;
57 *value
= PyString_AsString(val
);
62 bool python_register(int action
, PyObject
*callback
)
64 if (action
< 0 || action
>= OBActions::NUM_ACTIONS
||
65 action
== OBActions::Action_KeyPress
) {
66 PyErr_SetString(PyExc_AssertionError
, "Invalid action type.");
69 if (!PyCallable_Check(callback
)) {
70 PyErr_SetString(PyExc_AssertionError
, "Invalid callback function.");
74 FunctionList::iterator it
= std::find(callbacks
[action
].begin(),
75 callbacks
[action
].end(),
77 if (it
== callbacks
[action
].end()) { // not already in there
78 Py_XINCREF(callback
); // Add a reference to new callback
79 callbacks
[action
].push_back(callback
);
84 bool python_preregister(int action
, PyObject
*callback
)
86 if (action
< 0 || action
>= OBActions::NUM_ACTIONS
||
87 action
== OBActions::Action_KeyPress
) {
88 PyErr_SetString(PyExc_AssertionError
, "Invalid action type.");
91 if (!PyCallable_Check(callback
)) {
92 PyErr_SetString(PyExc_AssertionError
, "Invalid callback function.");
96 FunctionList::iterator it
= std::find(callbacks
[action
].begin(),
97 callbacks
[action
].end(),
99 if (it
== callbacks
[action
].end()) { // not already in there
100 Py_XINCREF(callback
); // Add a reference to new callback
101 callbacks
[action
].insert(callbacks
[action
].begin(), callback
);
106 bool python_unregister(int action
, PyObject
*callback
)
108 if (action
< 0 || action
>= OBActions::NUM_ACTIONS
||
109 action
== OBActions::Action_KeyPress
) {
110 PyErr_SetString(PyExc_AssertionError
, "Invalid action type.");
113 if (!PyCallable_Check(callback
)) {
114 PyErr_SetString(PyExc_AssertionError
, "Invalid callback function.");
118 FunctionList::iterator it
= std::find(callbacks
[action
].begin(),
119 callbacks
[action
].end(),
121 if (it
!= callbacks
[action
].end()) { // its been registered before
122 Py_XDECREF(*it
); // Dispose of previous callback
123 callbacks
[action
].erase(it
);
128 bool python_unregister_all(int action
)
130 if (action
< 0 || action
>= OBActions::NUM_ACTIONS
) {
131 PyErr_SetString(PyExc_AssertionError
, "Invalid action type.");
135 while (!callbacks
[action
].empty()) {
136 Py_XDECREF(callbacks
[action
].back());
137 callbacks
[action
].pop_back();
142 void python_callback(OBActions::ActionType action
, Window window
,
143 OBWidget::WidgetType type
, unsigned int state
,
144 long d1
, long d2
, long d3
, long d4
)
149 assert(action
>= 0 && action
< OBActions::NUM_ACTIONS
);
152 arglist
= Py_BuildValue("iliillll", action
, window
, type
, state
,
154 else if (d3
!= LONG_MIN
)
155 arglist
= Py_BuildValue("iliilll", action
, window
, type
, state
,
157 else if (d2
!= LONG_MIN
)
158 arglist
= Py_BuildValue("iliill", action
, window
, type
, state
, d1
, d2
);
159 else if (d1
!= LONG_MIN
)
160 arglist
= Py_BuildValue("iliil", action
, window
, type
, state
, d1
);
162 arglist
= Py_BuildValue("ilii", action
, window
, type
, state
);
164 FunctionList::iterator it
, end
= callbacks
[action
].end();
165 for (it
= callbacks
[action
].begin(); it
!= end
; ++it
) {
167 result
= PyEval_CallObject(*it
, arglist
);
171 // an exception occured in the script, display it
184 bool python_bind(PyObject
*keylist
, PyObject
*callback
)
186 if (!PyList_Check(keylist
)) {
187 PyErr_SetString(PyExc_AssertionError
, "Invalid keylist. Not a list.");
190 if (!PyCallable_Check(callback
)) {
191 PyErr_SetString(PyExc_AssertionError
, "Invalid callback function.");
195 OBBindings::StringVect vectkeylist
;
196 for (int i
= 0, end
= PyList_Size(keylist
); i
< end
; ++i
) {
197 PyObject
*str
= PyList_GetItem(keylist
, i
);
198 if (!PyString_Check(str
)) {
199 PyErr_SetString(PyExc_AssertionError
,
200 "Invalid keylist. It must contain only strings.");
203 vectkeylist
.push_back(PyString_AsString(str
));
206 // the id is what the binding class can call back with so it doesnt have to
207 // worry about the python function pointer
208 int id
= bindfuncs
.size();
209 if (Openbox::instance
->bindings()->add(vectkeylist
, id
)) {
210 Py_XINCREF(callback
); // Add a reference to new callback
211 bindfuncs
.push_back(callback
);
214 PyErr_SetString(PyExc_AssertionError
,"Unable to create binding. Invalid.");
219 bool python_unbind(PyObject
*keylist
)
221 if (!PyList_Check(keylist
)) {
222 PyErr_SetString(PyExc_AssertionError
, "Invalid keylist. Not a list.");
226 OBBindings::StringVect vectkeylist
;
227 for (int i
= 0, end
= PyList_Size(keylist
); i
< end
; ++i
) {
228 PyObject
*str
= PyList_GetItem(keylist
, i
);
229 if (!PyString_Check(str
)) {
230 PyErr_SetString(PyExc_AssertionError
,
231 "Invalid keylist. It must contain only strings.");
234 vectkeylist
.push_back(PyString_AsString(str
));
239 Openbox::instance
->bindings()->remove(vectkeylist
)) >= 0) {
240 assert(bindfuncs
[id
]); // shouldn't be able to remove it twice
241 Py_XDECREF(bindfuncs
[id
]); // Dispose of previous callback
242 // important note: we don't erase the item from the list cuz that would
243 // ruin all the id's that are in use. simply nullify it.
251 void python_set_reset_key(const std::string
&key
)
253 Openbox::instance
->bindings()->setResetKey(key
);
256 void python_unbind_all()
258 Openbox::instance
->bindings()->remove_all();
262 void python_callback_binding(int id
, Window window
, unsigned int state
,
263 unsigned int keybutton
, Time time
)
265 if (!bindfuncs
[id
]) return; // the key was unbound
270 arglist
= Py_BuildValue("lisl", window
, state
,
272 XKeycodeToKeysym(otk::OBDisplay::display
,
277 result
= PyEval_CallObject(bindfuncs
[id
], arglist
);
281 // an exception occured in the script, display it
This page took 0.052211 seconds and 5 git commands to generate.