PageRenderTime 51ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 1ms

/src/scim-python-helper.cpp

http://scim-python.googlecode.com/
C++ | 516 lines | 405 code | 85 blank | 26 comment | 27 complexity | dfe01fdafeae6ce53b402ed80c498e4c 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 "scim-python.h"
  26. #include <glib.h>
  27. using namespace scim;
  28. struct PyHelperAgentObject {
  29. PyListObject list;
  30. /* Type-specific fields go here. */
  31. PyHelperAgent helper_agent;
  32. };
  33. PyHelperAgent::PyHelperAgent (PyObject *self)
  34. :self ((PyHelperAgentObject *)self)
  35. {
  36. Py_INCREF (self);
  37. exit_signal_connection =
  38. signal_connect_exit (slot (this, &PyHelperAgent::slot_exit));
  39. attach_input_context_signal_connection =
  40. signal_connect_attach_input_context (slot (this, &PyHelperAgent::slot_attach_input_context));
  41. detach_input_context_signal_connection =
  42. signal_connect_detach_input_context (slot (this, &PyHelperAgent::slot_detach_input_context));
  43. reload_config_signal_connection =
  44. signal_connect_reload_config (slot (this, &PyHelperAgent::slot_reload_config));
  45. update_screen_signal_connection =
  46. signal_connect_update_screen (slot (this, &PyHelperAgent::slot_update_screen));
  47. update_spot_location_signal_connection =
  48. signal_connect_update_spot_location (slot (this, &PyHelperAgent::slot_update_spot_location));
  49. trigger_property_connection =
  50. signal_connect_trigger_property (slot (this, &PyHelperAgent::slot_trigger_property));
  51. process_imengine_event_connection =
  52. signal_connect_process_imengine_event (slot (this, &PyHelperAgent::slot_process_imengine_event));
  53. };
  54. PyHelperAgent::~PyHelperAgent ()
  55. {
  56. exit_signal_connection.disconnect ();
  57. attach_input_context_signal_connection.disconnect ();
  58. detach_input_context_signal_connection.disconnect ();
  59. reload_config_signal_connection.disconnect ();
  60. update_screen_signal_connection.disconnect ();
  61. update_spot_location_signal_connection.disconnect ();
  62. trigger_property_connection.disconnect ();
  63. process_imengine_event_connection.disconnect ();
  64. Py_XDECREF ((PyObject *)self);
  65. }
  66. void
  67. PyHelperAgent::operator delete (void *p)
  68. {
  69. // do nothing
  70. }
  71. PyObject *
  72. PyHelperAgent::py_open_connection (PyHelperAgentObject *self, PyObject *args)
  73. {
  74. char *uuid = NULL;
  75. char *name = NULL;
  76. char *icon = NULL;
  77. char *desc = NULL;
  78. int opt = 0;
  79. char *display;
  80. int retval;
  81. if (!PyArg_ParseTuple (args, "(ssssi)s:open_connection", &uuid, &name, &icon, &desc, &opt, &display))
  82. return NULL;
  83. retval = self->helper_agent.open_connection (HelperInfo (uuid, name, icon, desc, opt), display);
  84. return PyInt_FromLong (retval);
  85. }
  86. PyObject *
  87. PyHelperAgent::py_close_connection (PyHelperAgentObject *self, PyObject *args)
  88. {
  89. self->helper_agent.close_connection ();
  90. Py_INCREF (Py_None);
  91. return Py_None;
  92. }
  93. PyObject *
  94. PyHelperAgent::py_get_connection_number (PyHelperAgentObject *self, PyObject *args)
  95. {
  96. int retval;
  97. retval = self->helper_agent.get_connection_number ();
  98. return PyInt_FromLong (retval);
  99. }
  100. PyObject *
  101. PyHelperAgent::py_is_connected (PyHelperAgentObject *self, PyObject *args)
  102. {
  103. PyObject *result = NULL;
  104. bool retval;
  105. retval = self->helper_agent.is_connected ();
  106. if (retval) {
  107. result = Py_True;
  108. }
  109. else {
  110. result = Py_False;
  111. }
  112. Py_INCREF (result);
  113. return result;
  114. }
  115. PyObject *
  116. PyHelperAgent::py_has_pending_event (PyHelperAgentObject *self, PyObject *args)
  117. {
  118. PyObject *result = NULL;
  119. bool retval;
  120. retval = self->helper_agent.has_pending_event ();
  121. if (retval) {
  122. result = Py_True;
  123. }
  124. else {
  125. result = Py_False;
  126. }
  127. Py_INCREF (result);
  128. return result;
  129. }
  130. PyObject *
  131. PyHelperAgent::py_filter_event (PyHelperAgentObject *self, PyObject *args)
  132. {
  133. PyObject *result = NULL;
  134. bool retval;
  135. retval = self->helper_agent.filter_event ();
  136. if (retval) {
  137. result = Py_True;
  138. }
  139. else {
  140. result = Py_False;
  141. }
  142. Py_INCREF (result);
  143. return result;
  144. }
  145. PyObject *
  146. PyHelperAgent::py_reload_config (PyHelperAgentObject *self, PyObject *args)
  147. {
  148. self->helper_agent.reload_config ();
  149. Py_INCREF (Py_None);
  150. return Py_None;
  151. }
  152. PyObject *
  153. PyHelperAgent::py_register_properties (PyHelperAgentObject *self, PyObject *args)
  154. {
  155. PyObject *props = NULL;
  156. PropertyList proplist;
  157. int i;
  158. if (!PyArg_ParseTuple (args, "O:register_properties", &props))
  159. return NULL;
  160. if (PyList_Check (props)) {
  161. for (i = 0; i < PyList_Size (props); i++) {
  162. PyObject *prop = PyList_GetItem (props, i);
  163. proplist.push_back (PyProperty_AsProperty (prop));
  164. }
  165. }
  166. else if (PyTuple_Check (props)) {
  167. for (i = 0; i < PyTuple_Size (props); i++) {
  168. PyObject *prop = PyTuple_GetItem (props, i);
  169. proplist.push_back (PyProperty_AsProperty (prop));
  170. }
  171. }
  172. else {
  173. PyErr_SetString (PyExc_TypeError, "the argument must be a list or a tuple that contains propertys");
  174. return NULL;
  175. }
  176. self->helper_agent.register_properties (proplist);
  177. Py_INCREF (Py_None);
  178. return Py_None;
  179. }
  180. PyObject *
  181. PyHelperAgent::py_update_property (PyHelperAgentObject *self, PyObject *args)
  182. {
  183. PyObject *prop = NULL;
  184. if (!PyArg_ParseTuple (args, "O:update_property", &prop))
  185. return NULL;
  186. self->helper_agent.update_property (PyProperty_AsProperty (prop));
  187. Py_INCREF (Py_None);
  188. return Py_None;
  189. }
  190. PyObject *
  191. PyHelperAgent::py_send_imengine_event (PyHelperAgentObject *self, PyObject *args)
  192. {
  193. int ic;
  194. char *ic_uuid = NULL;
  195. char *buf = NULL;
  196. int len = 0;
  197. Transaction trans;
  198. if (!PyArg_ParseTuple (args, "isst#:send_imengine_event", &ic, &ic_uuid, &buf, &len)) {
  199. return NULL;
  200. }
  201. trans.read_from_buffer (buf, len);
  202. self->helper_agent.send_imengine_event (ic, String (ic_uuid), trans);
  203. Py_INCREF (Py_None);
  204. return Py_None;
  205. Py_INCREF (Py_None);
  206. return Py_None;
  207. }
  208. PyObject *
  209. PyHelperAgent::py_send_key_event (PyHelperAgentObject *self, PyObject *args)
  210. {
  211. int ic;
  212. char *ic_uuid = NULL;
  213. int code, mask, layout;
  214. if (!PyArg_ParseTuple (args, "isiii:send_key_event", &ic, &ic_uuid, &code, &mask, &layout)) {
  215. return NULL;
  216. }
  217. self->helper_agent.send_key_event (ic, String (ic_uuid), KeyEvent (code, mask, layout));
  218. Py_INCREF (Py_None);
  219. return Py_None;
  220. }
  221. PyObject *
  222. PyHelperAgent::py_forward_key_event (PyHelperAgentObject *self, PyObject *args)
  223. {
  224. int ic;
  225. char *ic_uuid = NULL;
  226. int code, mask, layout;
  227. if (!PyArg_ParseTuple (args, "isiii:forward_key_event", &ic, &ic_uuid, &code, &mask, &layout)) {
  228. return NULL;
  229. }
  230. self->helper_agent.forward_key_event (ic, String (ic_uuid), KeyEvent (code, mask, layout));
  231. Py_INCREF (Py_None);
  232. return Py_None;
  233. }
  234. PyObject *
  235. PyHelperAgent::py_commit_string (PyHelperAgentObject *self, PyObject *args)
  236. {
  237. int ic;
  238. char *ic_uuid = NULL;
  239. char *str = NULL;
  240. if (!PyArg_ParseTuple (args, "iss:commit_string", &ic, &ic_uuid, &str)) {
  241. return NULL;
  242. }
  243. self->helper_agent.commit_string (ic, String (ic_uuid), utf8_mbstowcs (str));
  244. Py_INCREF (Py_None);
  245. return Py_None;
  246. }
  247. #define PY_CALL(fun, args) ({ \
  248. PyObject *pValue = NULL; \
  249. PyObject *pFunc = NULL; \
  250. pFunc = PyObject_GetAttrString ((PyObject *)this->self, fun);\
  251. if (pFunc != NULL) { \
  252. pValue = PyObject_CallObject (pFunc, args); \
  253. Py_DECREF (pFunc); \
  254. } \
  255. pValue;})
  256. #define PY_CHECK_RET(v) \
  257. if (v == NULL) { \
  258. PyErr_Print (); \
  259. return; \
  260. }
  261. void
  262. PyHelperAgent::slot_exit (const HelperAgent *helper, int ic, const String &ic_uuid)
  263. {
  264. }
  265. void
  266. PyHelperAgent::slot_attach_input_context (const HelperAgent *helper, int ic, const String &ic_uuid)
  267. {
  268. }
  269. void
  270. PyHelperAgent::slot_detach_input_context (const HelperAgent *helper, int ic, const String &ic_uuid)
  271. {
  272. }
  273. void
  274. PyHelperAgent::slot_reload_config (const HelperAgent *helper, int ic, const String &ic_uuid)
  275. {
  276. }
  277. void
  278. PyHelperAgent::slot_update_screen (const HelperAgent *helper, int ic, const String &ic_uuid, int screen_number)
  279. {
  280. }
  281. void
  282. PyHelperAgent::slot_update_spot_location (const HelperAgent *helper, int ic, const String &ic_uuid, int x, int y)
  283. {
  284. }
  285. void
  286. PyHelperAgent::slot_trigger_property (const HelperAgent *helper, int ic, const String &ic_uuid, const String &property)
  287. {
  288. PyObject *pValue = NULL;
  289. PyObject *pArgs = NULL;
  290. pArgs = Py_BuildValue ("(iss)", ic, ic_uuid.c_str (), property.c_str ());
  291. pValue = PY_CALL ("trigger_property", pArgs);
  292. PY_CHECK_RET (pValue);
  293. Py_XDECREF (pArgs);
  294. Py_XDECREF (pValue);
  295. }
  296. void
  297. PyHelperAgent::slot_process_imengine_event (const HelperAgent *helper, int ic, const String &ic_uuid, const Transaction &transaction)
  298. {
  299. }
  300. PyMethodDef
  301. PyHelperAgent::py_methods[] = {
  302. { "open_connection", (PyCFunction)PyHelperAgent::py_open_connection, METH_VARARGS,
  303. "open a connection"
  304. },
  305. { "get_connection_number", (PyCFunction)PyHelperAgent::py_get_connection_number, METH_NOARGS,
  306. "return id, that was returned by open_connection previously."
  307. },
  308. { "close_connection", (PyCFunction)PyHelperAgent::py_close_connection, METH_NOARGS,
  309. "close the connection"
  310. },
  311. { "is_connected", (PyCFunction)PyHelperAgent::py_is_connected, METH_NOARGS,
  312. "If agent is connected, the function returns True"
  313. },
  314. { "has_pending_event", (PyCFunction)PyHelperAgent::py_has_pending_event, METH_NOARGS,
  315. "If agent has pending event, the function returns True"
  316. },
  317. { "filter_event", (PyCFunction)PyHelperAgent::py_filter_event, METH_NOARGS,
  318. "filter events"
  319. },
  320. { "reload_config", (PyCFunction)PyHelperAgent::py_reload_config, METH_NOARGS,
  321. "This function will cause all IM engines to reload config"
  322. },
  323. { "register_properties", (PyCFunction)PyHelperAgent::py_register_properties, METH_VARARGS,
  324. "Register properties"
  325. },
  326. { "update_property", (PyCFunction)PyHelperAgent::py_update_property, METH_VARARGS,
  327. "Update a property"
  328. },
  329. { "send_imengine_event", (PyCFunction)PyHelperAgent::py_send_imengine_event, METH_VARARGS,
  330. "Send a event to IMEngine"
  331. },
  332. { "send_key_event", (PyCFunction)PyHelperAgent::py_send_key_event, METH_VARARGS,
  333. "Send a keyevent"
  334. },
  335. { "forward_key_event", (PyCFunction)PyHelperAgent::py_forward_key_event, METH_VARARGS,
  336. "Forward a keyevent"
  337. },
  338. { "commit_string", (PyCFunction)PyHelperAgent::py_commit_string, METH_VARARGS,
  339. "Commit a string to IC"
  340. },
  341. { NULL }
  342. };
  343. PyObject *
  344. PyHelperAgent::py_new (PyTypeObject *type, PyObject *args, PyObject *kwds)
  345. {
  346. PyHelperAgentObject *self;
  347. self = (PyHelperAgentObject *)type->tp_alloc (type, 0);
  348. return (PyObject *)self;
  349. }
  350. int
  351. PyHelperAgent::py_init (PyHelperAgentObject *self, PyObject *args, PyObject *kwds)
  352. {
  353. new (&self->helper_agent) PyHelperAgent ((PyObject *)self);
  354. return 0;
  355. }
  356. void
  357. PyHelperAgent::py_dealloc (PyHelperAgentObject *self)
  358. {
  359. self->helper_agent.~PyHelperAgent ();
  360. ((PyObject *) self)->ob_type->tp_free (self);
  361. }
  362. HelperAgent *
  363. PyHelperAgent::from_pyobject (PyObject *object)
  364. {
  365. PyHelperAgentObject *self = (PyHelperAgentObject *) object;
  366. return (HelperAgent *)&self->helper_agent;
  367. }
  368. PyTypeObject PyHelperAgentType = {
  369. PyObject_HEAD_INIT (NULL)
  370. 0, /*ob_size*/
  371. "scim.HelperAgent", /*tp_name*/
  372. sizeof (PyHelperAgentObject), /*tp_basicsize*/
  373. 0, /*tp_itemsize*/
  374. (destructor)PyHelperAgent::py_dealloc, /*tp_dealloc*/
  375. 0, /*tp_print*/
  376. 0, /*tp_getattr*/
  377. 0, /*tp_setattr*/
  378. 0, /*tp_compare*/
  379. 0, /*tp_repr*/
  380. 0, /*tp_as_number*/
  381. 0, /*tp_as_sequence*/
  382. 0, /*tp_as_mapping*/
  383. 0, /*tp_hash */
  384. 0, /*tp_call*/
  385. 0, /*tp_str*/
  386. 0, /*tp_getattro*/
  387. 0, /*tp_setattro*/
  388. 0, /*tp_as_buffer*/
  389. Py_TPFLAGS_DEFAULT |
  390. Py_TPFLAGS_BASETYPE, /*tp_flags*/
  391. "HelperAgent objects", /* tp_doc */
  392. 0, /* tp_traverse */
  393. 0, /* tp_clear */
  394. 0, /* tp_richcompare */
  395. 0, /* tp_weaklistoffset */
  396. 0, /* tp_iter */
  397. 0, /* tp_iternext */
  398. PyHelperAgent::py_methods, /* tp_methods */
  399. 0, /* tp_members */
  400. 0, /* tp_getset */
  401. 0, /* tp_base */
  402. 0, /* tp_dict */
  403. 0, /* tp_descr_get */
  404. 0, /* tp_descr_set */
  405. 0, /* tp_dictoffset */
  406. (initproc)PyHelperAgent::py_init, /* tp_init */
  407. 0, /* tp_alloc */
  408. PyHelperAgent::py_new, /* tp_new */
  409. };
  410. static void
  411. setint (PyObject *d, const char *name, long value)
  412. {
  413. PyObject *o = PyInt_FromLong (value);
  414. if (o && PyDict_SetItemString (d, name, o) == 0) {
  415. Py_DECREF (o);
  416. }
  417. }
  418. void init_helper (PyObject *module)
  419. {
  420. PyObject *dict = NULL;
  421. if (PyType_Ready (&PyHelperAgentType) < 0)
  422. return;
  423. Py_INCREF (&PyHelperAgentType);
  424. PyModule_AddObject (module, "HelperAgent", (PyObject *)&PyHelperAgentType);
  425. dict = PyModule_GetDict (module);
  426. setint (dict, "SCIM_HELPER_STAND_ALONE", SCIM_HELPER_STAND_ALONE);
  427. setint (dict, "SCIM_HELPER_AUTO_START", SCIM_HELPER_AUTO_START);
  428. setint (dict, "SCIM_HELPER_AUTO_RESTART", SCIM_HELPER_AUTO_RESTART);
  429. setint (dict, "SCIM_HELPER_NEED_SCREEN_INFO", SCIM_HELPER_NEED_SCREEN_INFO);
  430. setint (dict, "SCIM_HELPER_NEED_SPOT_LOCATION_INFO", SCIM_HELPER_NEED_SPOT_LOCATION_INFO);
  431. }