00001
00002
00003 #include "python.hh"
00004 #include "openbox.hh"
00005 #include "actions.hh"
00006 #include "python.hh"
00007 #include "bindings.hh"
00008 #include "otk/display.hh"
00009 #include "otk/util.hh"
00010
00011 extern "C" {
00012
00013 extern void init_ob(void);
00014 extern void init_otk(void);
00015 }
00016
00017 namespace ob {
00018
00019 static PyObject *obdict = NULL;
00020
00021 void python_init(char *argv0)
00022 {
00023
00024 Py_SetProgramName(argv0);
00025 Py_Initialize();
00026
00027 init_otk();
00028 init_ob();
00029
00030 PyRun_SimpleString("import sys");
00031 PyRun_SimpleString("sys.path.insert(0, '" SCRIPTDIR "')");
00032 PyRun_SimpleString(const_cast<char*>(("sys.path.insert(0, '" +
00033 otk::expandTilde("~/.openbox/python") +
00034 "')").c_str()));
00035 PyRun_SimpleString("import ob; import otk; import config;");
00036
00037 PyRun_SimpleString("ob.openbox = ob.Openbox_instance()");
00038 PyRun_SimpleString("otk.display = otk.Display_instance()");
00039
00040
00041 PyObject *obmodule = PyImport_AddModule("config");
00042 obdict = PyModule_GetDict(obmodule);
00043 }
00044
00045 void python_destroy()
00046 {
00047 Py_Finalize();
00048 }
00049
00050 bool python_exec(const std::string &path)
00051 {
00052 FILE *rcpyfd = fopen(path.c_str(), "r");
00053 if (!rcpyfd) {
00054 printf("Failed to load python file %s\n", path.c_str());
00055 return false;
00056 }
00057 PyRun_SimpleFile(rcpyfd, const_cast<char*>(path.c_str()));
00058 fclose(rcpyfd);
00059 return true;
00060 }
00061
00062 bool python_get_long(const char *name, long *value)
00063 {
00064 PyObject *val = PyDict_GetItemString(obdict, const_cast<char*>(name));
00065 if (!(val && PyInt_Check(val))) return false;
00066
00067 *value = PyInt_AsLong(val);
00068 return true;
00069 }
00070
00071 bool python_get_string(const char *name, otk::ustring *value)
00072 {
00073 PyObject *val = PyDict_GetItemString(obdict, const_cast<char*>(name));
00074 if (!(val && PyString_Check(val))) return false;
00075
00076 *value = PyString_AsString(val);
00077 return true;
00078 }
00079
00080 bool python_get_stringlist(const char *name, std::vector<otk::ustring> *value)
00081 {
00082 PyObject *val = PyDict_GetItemString(obdict, const_cast<char*>(name));
00083 if (!(val && PyList_Check(val))) return false;
00084
00085 for (int i = 0, end = PyList_Size(val); i < end; ++i) {
00086 PyObject *str = PyList_GetItem(val, i);
00087 if (PyString_Check(str))
00088 value->push_back(PyString_AsString(str));
00089 }
00090 return true;
00091 }
00092
00093
00094
00095
00096
00097 PyObject *mbind(const std::string &button, ob::MouseContext::MC context,
00098 ob::MouseAction::MA action, PyObject *func)
00099 {
00100 if (!PyCallable_Check(func)) {
00101 PyErr_SetString(PyExc_TypeError, "Invalid callback function.");
00102 return NULL;
00103 }
00104 if(context < 0 || context >= MouseContext::NUM_MOUSE_CONTEXT) {
00105 PyErr_SetString(PyExc_ValueError, "Invalid MouseContext");
00106 return NULL;
00107 }
00108 if(action < 0 || action >= MouseAction::NUM_MOUSE_ACTION) {
00109 PyErr_SetString(PyExc_ValueError, "Invalid MouseAction");
00110 return NULL;
00111 }
00112
00113 if (!ob::openbox->bindings()->addButton(button, context,
00114 action, func)) {
00115 PyErr_SetString(PyExc_RuntimeError,"Unable to add binding.");
00116 return NULL;
00117 }
00118 Py_INCREF(Py_None); return Py_None;
00119 }
00120
00121 PyObject *ebind(ob::EventAction::EA action, PyObject *func)
00122 {
00123 if (!PyCallable_Check(func)) {
00124 PyErr_SetString(PyExc_TypeError, "Invalid callback function.");
00125 return NULL;
00126 }
00127
00128 if (!ob::openbox->bindings()->addEvent(action, func)) {
00129 PyErr_SetString(PyExc_RuntimeError,"Unable to add binding.");
00130 return NULL;
00131 }
00132 Py_INCREF(Py_None); return Py_None;
00133 }
00134
00135 PyObject *kgrab(int screen, PyObject *func)
00136 {
00137 if (!PyCallable_Check(func)) {
00138 PyErr_SetString(PyExc_TypeError, "Invalid callback function.");
00139 return NULL;
00140 }
00141
00142 if (!ob::openbox->bindings()->grabKeyboard(screen, func)) {
00143 PyErr_SetString(PyExc_RuntimeError,"Unable to grab keybaord.");
00144 return NULL;
00145 }
00146 Py_INCREF(Py_None); return Py_None;
00147 }
00148
00149 PyObject *kungrab()
00150 {
00151 ob::openbox->bindings()->ungrabKeyboard();
00152 Py_INCREF(Py_None); return Py_None;
00153 }
00154
00155 PyObject *mgrab(int screen)
00156 {
00157 if (!ob::openbox->bindings()->grabPointer(screen)) {
00158 PyErr_SetString(PyExc_RuntimeError,"Unable to grab pointer.");
00159 return NULL;
00160 }
00161 Py_INCREF(Py_None); return Py_None;
00162 }
00163
00164 PyObject *mungrab()
00165 {
00166 ob::openbox->bindings()->ungrabPointer();
00167 Py_INCREF(Py_None); return Py_None;
00168 }
00169
00170 PyObject *kbind(PyObject *keylist, ob::KeyContext::KC context, PyObject *func)
00171 {
00172 if (!PyCallable_Check(func)) {
00173 PyErr_SetString(PyExc_TypeError, "Invalid callback function.");
00174 return NULL;
00175 }
00176 if (!PyList_Check(keylist)) {
00177 PyErr_SetString(PyExc_TypeError, "Invalid keylist. Not a list.");
00178 return NULL;
00179 }
00180
00181 ob::Bindings::StringVect vectkeylist;
00182 for (int i = 0, end = PyList_Size(keylist); i < end; ++i) {
00183 PyObject *str = PyList_GetItem(keylist, i);
00184 if (!PyString_Check(str)) {
00185 PyErr_SetString(PyExc_TypeError,
00186 "Invalid keylist. It must contain only strings.");
00187 return NULL;
00188 }
00189 vectkeylist.push_back(PyString_AsString(str));
00190 }
00191
00192 (void)context;
00193 if (!ob::openbox->bindings()->addKey(vectkeylist, func)) {
00194 PyErr_SetString(PyExc_RuntimeError,"Unable to add binding.");
00195 return NULL;
00196 }
00197 Py_INCREF(Py_None); return Py_None;
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 void kunbind_all()
00232 {
00233 ob::openbox->bindings()->removeAllKeys();
00234 }
00235
00236 void set_reset_key(const std::string &key)
00237 {
00238 ob::openbox->bindings()->setResetKey(key);
00239 }
00240
00241 PyObject *send_client_msg(Window target, Atom type, Window about,
00242 long data, long data1, long data2,
00243 long data3, long data4)
00244 {
00245 XEvent e;
00246 e.xclient.type = ClientMessage;
00247 e.xclient.format = 32;
00248 e.xclient.message_type = type;
00249 e.xclient.window = about;
00250 e.xclient.data.l[0] = data;
00251 e.xclient.data.l[1] = data1;
00252 e.xclient.data.l[2] = data2;
00253 e.xclient.data.l[3] = data3;
00254 e.xclient.data.l[4] = data4;
00255
00256 XSendEvent(**otk::display, target, false,
00257 SubstructureRedirectMask | SubstructureNotifyMask,
00258 &e);
00259 Py_INCREF(Py_None); return Py_None;
00260 }
00261
00262 void execute(const std::string &bin, int screen)
00263 {
00264 if (screen >= ScreenCount(**otk::display))
00265 screen = 0;
00266 otk::bexec(bin, otk::display->screenInfo(screen)->displayString());
00267 }
00268
00269 }