/src/scim-python.cpp

http://scim-python.googlecode.com/ · C++ · 447 lines · 321 code · 99 blank · 27 comment · 56 complexity · c3bd9a8cc1ab821cbb1a7ca0c4bc61e9 MD5 · raw file

  1. /* vim:set noet ts=4: */
  2. /**
  3. * scim-python
  4. *
  5. * Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
  6. *
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2 of the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this program; if not, write to the
  20. * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  21. * Boston, MA 02111-1307 USA
  22. *
  23. * $Id: $
  24. */
  25. #include "../config.h"
  26. #include "scim-python.h"
  27. #include <assert.h>
  28. using namespace scim;
  29. using namespace std;
  30. static vector <IMEngineFactoryPointer> _factorys;
  31. static vector <HelperInfo> _helpers;
  32. static int _use_count = 0;
  33. static PyObject *
  34. scim_get_version (PyObject *self, PyObject *args)
  35. {
  36. return PyString_FromString (PACKAGE_VERSION);
  37. }
  38. static PyMethodDef _methods[] = {
  39. {"get_version", scim_get_version, METH_NOARGS, "get version string of scim-python" },
  40. {0, }
  41. };
  42. PyMODINIT_FUNC
  43. init_scim (void)
  44. {
  45. PyObject* m;
  46. m = Py_InitModule3("_scim", _methods,
  47. "SCIM.");
  48. if (m == NULL) {
  49. PyErr_Print ();
  50. return;
  51. }
  52. init_event (m);
  53. init_property (m);
  54. init_config (m);
  55. init_engine (m);
  56. init_factory (m);
  57. init_helper (m);
  58. init_attribute (m);
  59. init_lookup_table (m);
  60. }
  61. static PyObject *
  62. Py_CallFunction (const char *module, const char *function, PyObject *args)
  63. {
  64. PyObject *pName = NULL;
  65. PyObject *pModule = NULL;
  66. PyObject *pFunc = NULL;
  67. PyObject *pValue = NULL;
  68. pName = PyString_FromString (module);
  69. if (pName == NULL)
  70. goto _failed_out;
  71. pModule = PyImport_Import (pName);
  72. if (pModule == NULL)
  73. goto _failed_out;
  74. pFunc = PyObject_GetAttrString (pModule, function);
  75. if (pFunc == NULL)
  76. goto _failed_out;
  77. pValue = PyObject_CallObject (pFunc, args);
  78. if (pValue == NULL)
  79. goto _failed_out;
  80. goto _success_out;;
  81. _failed_out:
  82. PyErr_Print ();
  83. _success_out:
  84. Py_XDECREF (pName);
  85. Py_XDECREF (pFunc);
  86. Py_XDECREF (pModule);
  87. return pValue;
  88. }
  89. static PyObject *
  90. Py_CallModuleFunction (PyObject *module, const char *function, PyObject *args)
  91. {
  92. PyObject *pFunc = NULL;
  93. PyObject *pValue = NULL;
  94. pFunc = PyObject_GetAttrString (module, function);
  95. if (pFunc == NULL)
  96. goto _failed_out;
  97. pValue = PyObject_CallObject (pFunc, args);
  98. if (pValue == NULL)
  99. goto _failed_out;
  100. goto _success_out;;
  101. _failed_out:
  102. PyErr_Print ();
  103. _success_out:
  104. Py_XDECREF (pFunc);
  105. return pValue;
  106. }
  107. extern "C" void
  108. scim_module_init (void)
  109. {
  110. char * argv[] = {
  111. (char *)"scim-python",
  112. NULL
  113. };
  114. bindtextdomain (GETTEXT_PACKAGE, SCIM_PYTHON_LOCALEDIR);
  115. bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
  116. if (_use_count > 0) {
  117. goto out;
  118. }
  119. if (Py_IsInitialized ()) {
  120. goto out;
  121. }
  122. static int add_path = 0;
  123. if (add_path == 0) {
  124. char *pythonpath = NULL;
  125. char *old_pythonpath = getenv ("PYTHONPATH");
  126. if (old_pythonpath != NULL) {
  127. asprintf (&pythonpath,
  128. "PYTHONPATH=" SCIM_PYTHON_DATADIR ":%s", old_pythonpath);
  129. }
  130. else {
  131. asprintf (&pythonpath,
  132. "PYTHONPATH=" SCIM_PYTHON_DATADIR);
  133. }
  134. putenv (pythonpath);
  135. add_path = 1;
  136. }
  137. Py_Initialize ();
  138. PySys_SetArgv (1, argv);
  139. out:
  140. _use_count ++;
  141. }
  142. extern "C" void
  143. scim_module_exit (void)
  144. {
  145. if (_use_count == 0)
  146. return;
  147. _use_count --;
  148. if (_use_count == 0) {
  149. _factorys.clear ();
  150. Py_Finalize ();
  151. }
  152. }
  153. #ifndef DISABLE_IMENGINE
  154. extern "C" unsigned int
  155. scim_imengine_module_init (const ConfigPointer &config)
  156. {
  157. PyObject *pValue = NULL;
  158. PyObject *pArgs = NULL;
  159. PyObject *pyconfig = NULL;
  160. int size = 0;
  161. pyconfig = PyConfig_New (config);
  162. Py_DECREF (pyconfig);
  163. pyconfig = PyConfig_New (config);
  164. pArgs = Py_BuildValue ("(O)", pyconfig);
  165. pValue = Py_CallFunction ("engine", "query_engines", pArgs);
  166. Py_DECREF (pArgs);
  167. Py_DECREF (pyconfig);
  168. if (PyList_Check (pValue)) {
  169. PyObject * pTuple = PyList_AsTuple (pValue);
  170. Py_DECREF (pValue);
  171. pValue = pTuple;
  172. }
  173. if (!PyTuple_Check (pValue))
  174. return 0;
  175. size = PyTuple_Size (pValue);
  176. for (int i = 0; i < size; i++) {
  177. IMEngineFactoryPointer p = PyIMEngineFactory::from_pyobject (PyTuple_GetItem (pValue, i));
  178. _factorys.push_back (p);
  179. }
  180. Py_DECREF (pValue);
  181. return size;
  182. }
  183. extern "C" IMEngineFactoryPointer
  184. scim_imengine_module_create_factory (uint32 engine)
  185. {
  186. if ( engine < 0 || engine >= _factorys.size ())
  187. return IMEngineFactoryPointer (0);
  188. return _factorys[engine];
  189. }
  190. #endif //DISABLE_IMENGINE
  191. #ifndef DISABLE_SETUPUI
  192. #include <gtk/gtk.h>
  193. #include <pygobject.h>
  194. extern "C" GtkWidget *
  195. scim_setup_module_create_ui (void)
  196. {
  197. static GtkWidget *window = NULL;
  198. PyObject *pValue = NULL;
  199. if (window != NULL)
  200. return window;
  201. pValue = Py_CallFunction ("setupui", "create_ui", NULL);
  202. if (pValue != Py_None) {
  203. window = GTK_WIDGET (pygobject_get (pValue));
  204. gtk_object_ref (GTK_OBJECT (window));
  205. }
  206. Py_DECREF (pValue);
  207. return window;
  208. }
  209. extern "C" String
  210. scim_setup_module_get_category (void)
  211. {
  212. return String ("IMEngine");
  213. }
  214. extern "C" String
  215. scim_setup_module_get_name (void)
  216. {
  217. return String (_("Python"));
  218. }
  219. extern "C" String
  220. scim_setup_module_get_description (void)
  221. {
  222. return String (_("Setup UI for Python IM engines."));
  223. }
  224. extern "C" void
  225. scim_setup_module_load_config (const ConfigPointer &config)
  226. {
  227. PyObject *pValue = NULL;
  228. PyObject *pArgs = NULL;
  229. pArgs = Py_BuildValue ("(O)", PyConfig_New (config));
  230. pValue = Py_CallFunction ("setupui", "load_config", pArgs);
  231. if ( pValue == NULL) {
  232. PyErr_Clear ();
  233. }
  234. Py_XDECREF (pArgs);
  235. Py_XDECREF (pValue);
  236. }
  237. extern "C" void
  238. scim_setup_module_save_config (const ConfigPointer &config)
  239. {
  240. PyObject *pValue = NULL;
  241. PyObject *pArgs = NULL;
  242. pArgs = Py_BuildValue ("(O)", PyConfig_New (config));
  243. pValue = Py_CallFunction ("setupui", "save_config", pArgs);
  244. Py_XDECREF (pArgs);
  245. Py_XDECREF (pValue);
  246. }
  247. extern "C" bool
  248. scim_setup_module_query_changed ()
  249. {
  250. PyObject *pValue = NULL;
  251. bool retval = false;
  252. pValue = Py_CallFunction ("setupui", "query_changed", NULL);
  253. if (pValue == Py_True) {
  254. retval = true;
  255. }
  256. Py_XDECREF (pValue);
  257. return retval;
  258. }
  259. #if 0
  260. /*
  261. * Overide new and delete operator.
  262. **/
  263. static int __count = 0;
  264. void* operator new (size_t size)
  265. {
  266. fprintf (stderr, "new count = %d\n", __count++);
  267. if (size < 256) {
  268. size = 256;
  269. }
  270. void *p = PyObject_Malloc (size);
  271. assert (p != NULL);
  272. return p;
  273. }
  274. void operator delete (void *p)
  275. {
  276. fprintf (stderr, "delete count = %d\n", __count--);
  277. assert (p != NULL);
  278. PyObject_Free (p);
  279. }
  280. #endif
  281. #endif //DISABLE_SETUPUI
  282. #ifndef DISABLE_HELPER
  283. static PyObject *g_helper_mod = NULL;
  284. extern "C" unsigned int
  285. scim_helper_module_number_of_helpers (void)
  286. {
  287. PyObject *retval = NULL;
  288. int size = 0;
  289. if (g_helper_mod == NULL) {
  290. PyObject *name = PyString_FromString ("helper");
  291. g_helper_mod = PyImport_Import (name);
  292. Py_DECREF (name);
  293. }
  294. retval = Py_CallModuleFunction (g_helper_mod, "number_of_helpers", NULL);
  295. if (retval != NULL) {
  296. size = PyInt_AsLong (retval);
  297. Py_DECREF (retval);
  298. }
  299. return size;
  300. }
  301. extern "C" bool
  302. scim_helper_module_get_helper_info (unsigned int index, HelperInfo &info)
  303. {
  304. bool result = FALSE;
  305. PyObject *retval = NULL;
  306. PyObject *args = NULL;
  307. PyObject *helper_info = NULL;
  308. args = Py_BuildValue ("(I)", index);
  309. retval = Py_CallModuleFunction (g_helper_mod, "get_helper_info", args);
  310. Py_DECREF (args);
  311. if (retval == Py_None || retval == NULL) {
  312. result = FALSE;
  313. goto _out;
  314. }
  315. if (PyList_Check (retval)) {
  316. helper_info = PyList_AsTuple (retval);
  317. }
  318. else if (PyTuple_Check (args)) {
  319. helper_info = retval;
  320. Py_INCREF (retval);
  321. }
  322. if (helper_info != NULL && PyTuple_GET_SIZE (helper_info) == 5) {
  323. const char *uuid = PyString_AsString (PyTuple_GetItem (helper_info, 0));
  324. const char *name = PyString_AsString (PyTuple_GetItem (helper_info, 1));
  325. const char *icon = PyString_AsString (PyTuple_GetItem (helper_info, 2));
  326. const char *desc = PyString_AsString (PyTuple_GetItem (helper_info, 3));
  327. int opt = PyInt_AsLong (PyTuple_GetItem (helper_info, 4));
  328. info = HelperInfo (uuid, name, icon, desc, opt);
  329. result = TRUE;
  330. }
  331. _out:
  332. Py_XDECREF (args);
  333. Py_XDECREF (retval);
  334. Py_XDECREF (helper_info);
  335. return result;
  336. }
  337. extern "C" void
  338. scim_helper_module_run_helper (const String &uuid, const ConfigPointer &config,
  339. const String &display)
  340. {
  341. PyObject *retval = NULL;
  342. PyObject *args = NULL;
  343. args = Py_BuildValue ("(sOs)", uuid.c_str (), PyConfig_New (config), display.c_str ());
  344. retval = Py_CallModuleFunction (g_helper_mod, "run_helper", args);
  345. Py_XDECREF (args);
  346. Py_XDECREF (retval);
  347. }
  348. #endif //DISABLE_HELPER