/src/scim-python-engine.cpp

http://scim-python.googlecode.com/ · C++ · 1043 lines · 770 code · 201 blank · 72 comment · 50 complexity · 2763000dc776399f2aa316b4f1c03642 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. #if Py_UNICODE_SIZE == 2
  27. # include <glib.h>
  28. #endif
  29. extern PyTypeObject PyIMEngineType;
  30. struct PyIMEngineObject {
  31. PyListObject list;
  32. /* Type-specific fields go here. */
  33. PyIMEngine engine;
  34. };
  35. PyIMEngine::PyIMEngine (
  36. PyObject *self,
  37. PyObject *factory,
  38. PyObject *config,
  39. const String &encoding,
  40. int id)
  41. : IMEngineInstanceBase (PyIMEngineFactory::from_pyobject (factory),
  42. encoding, id),
  43. self (self),
  44. factory (factory),
  45. config (config)
  46. {
  47. Py_INCREF (self);
  48. Py_INCREF (factory);
  49. Py_INCREF (config);
  50. reload_signal_connection =
  51. PyConfig_from_pyobject (config)->signal_connect_reload (slot (this, &PyIMEngine::reload_config));
  52. }
  53. PyIMEngine::~PyIMEngine ()
  54. {
  55. reload_signal_connection.disconnect ();
  56. Py_XDECREF (config);
  57. Py_XDECREF (factory);
  58. Py_XDECREF (self);
  59. }
  60. void
  61. PyIMEngine::operator delete (void *p)
  62. {
  63. }
  64. #define PY_CALL(fun) ({ \
  65. PyObject *pValue = NULL; \
  66. PyObject *pFunc = NULL; \
  67. pFunc = PyObject_GetAttrString (this->self, fun);\
  68. if (pFunc != NULL) { \
  69. pValue = PyObject_CallObject (pFunc, NULL); \
  70. Py_DECREF (pFunc); \
  71. } \
  72. pValue;})
  73. #define PY_CALL_1(fun, arg1) ({ \
  74. PyObject *pValue = NULL; \
  75. PyObject *pFunc = NULL; \
  76. PyObject *pArgs = NULL; \
  77. pFunc = PyObject_GetAttrString (this->self, fun);\
  78. if (pFunc != NULL) { \
  79. pArgs = Py_BuildValue ("(O)", arg1); \
  80. pValue = PyObject_CallObject (pFunc, pArgs);\
  81. Py_DECREF (pFunc); \
  82. Py_DECREF (pArgs); \
  83. } \
  84. pValue;})
  85. #define PY_CHECK_RET(v) \
  86. if (v == NULL) { \
  87. PyErr_Print (); \
  88. return; \
  89. }
  90. #define PY_CHECK_RET_VAL(v, val) \
  91. if (v == NULL) { \
  92. PyErr_Print (); \
  93. return val; \
  94. }
  95. bool
  96. PyIMEngine::process_key_event (const KeyEvent &key)
  97. {
  98. PyObject *pValue;
  99. bool result = false;
  100. pValue = PY_CALL_1("process_key_event", PyKeyEvent_New (key));
  101. PY_CHECK_RET_VAL (pValue, false);
  102. result = (pValue == Py_True);
  103. Py_XDECREF (pValue);
  104. return result;
  105. }
  106. PyDoc_STRVAR (IMEngine_process_key_event__doc__,
  107. "process_key_event (key_event)\n\n"
  108. "This function will be called, when user press keyboard in client application.\n"
  109. "IM developer must implement it in sub class.\n");
  110. PyObject *
  111. PyIMEngine::py_process_key_event (PyIMEngineObject *self, PyObject *args)
  112. {
  113. PyErr_SetString (PyExc_NotImplementedError, "process_key_event is not implemented!");
  114. return NULL;
  115. }
  116. void
  117. PyIMEngine::move_preedit_caret (unsigned int pos)
  118. {
  119. PyObject *pValue = NULL;
  120. pValue = PY_CALL_1 ("move_preedit_caret", PyInt_FromLong ((unsigned long)pos));
  121. PY_CHECK_RET (pValue);
  122. Py_XDECREF (pValue);
  123. }
  124. PyDoc_STRVAR (IMEngine_move_preedit_caret__doc__,
  125. "move_preedit_caret (pos)\n\n"
  126. "This function will be called, when client move preedit caret.\n"
  127. "IM developer may override it in sub class.\n");
  128. PyObject *
  129. PyIMEngine::py_move_preedit_caret (PyIMEngineObject *self, PyObject *args)
  130. {
  131. unsigned int pos;
  132. if (!PyArg_ParseTuple (args, "I:move_preedit_caret", &pos))
  133. return NULL;
  134. self->engine.IMEngineInstanceBase::move_preedit_caret (pos);
  135. Py_INCREF (Py_None);
  136. return Py_None;
  137. }
  138. void
  139. PyIMEngine::select_candidate (unsigned int index)
  140. {
  141. PyObject *pValue = NULL;
  142. pValue = PY_CALL_1 ("select_candidate", PyInt_FromLong ((unsigned long)index));
  143. PY_CHECK_RET (pValue);
  144. Py_XDECREF (pValue);
  145. }
  146. PyDoc_STRVAR (IMEngine_select_candidate__doc__,
  147. "select_candidate (index)\n\n"
  148. "IM developer may override it in sub class.\n");
  149. PyObject *
  150. PyIMEngine::py_select_candidate (PyIMEngineObject *self, PyObject *args)
  151. {
  152. unsigned int index;
  153. if (!PyArg_ParseTuple (args, "I:select_candidate", &index))
  154. return NULL;
  155. self->engine.IMEngineInstanceBase::select_candidate (index);
  156. Py_INCREF (Py_None);
  157. return Py_None;
  158. }
  159. void
  160. PyIMEngine::update_lookup_table_page_size (unsigned int page_size)
  161. {
  162. PyObject *pValue = NULL;
  163. pValue = PY_CALL_1 ("update_lookup_table_page_size", PyInt_FromLong ((unsigned long)page_size));
  164. PY_CHECK_RET (pValue);
  165. Py_XDECREF (pValue);
  166. }
  167. PyDoc_STRVAR (IMEngine_update_lookup_table_page_size__doc__,
  168. "update_lookup_table_page_size (page_size)\n\n"
  169. "This function will be called, when page size of lookup table is changed.\n"
  170. "IM developer may override it in sub class.\n");
  171. PyObject *
  172. PyIMEngine::py_update_lookup_table_page_size (PyIMEngineObject *self, PyObject *args)
  173. {
  174. unsigned int page_size;
  175. if (!PyArg_ParseTuple (args, "I:update_lookup_table_page_size", &page_size))
  176. return NULL;
  177. self->engine.IMEngineInstanceBase::move_preedit_caret (page_size);
  178. Py_INCREF (Py_None);
  179. return Py_None;
  180. }
  181. void
  182. PyIMEngine::lookup_table_page_up ()
  183. {
  184. PyObject *pValue = NULL;
  185. pValue = PY_CALL ("lookup_table_page_up");
  186. PY_CHECK_RET (pValue);
  187. Py_XDECREF (pValue);
  188. }
  189. PyDoc_STRVAR (IMEngine_lookup_table_page_up__doc__,
  190. "lookup_table_page_up ()\n\n"
  191. "This function will be called, when user press page up button in candidate window.\n"
  192. "IM developer may override it in sub class.\n");
  193. PyObject *
  194. PyIMEngine::py_lookup_table_page_up (PyIMEngineObject *self)
  195. {
  196. self->engine.IMEngineInstanceBase::lookup_table_page_up ();
  197. Py_INCREF (Py_None);
  198. return Py_None;
  199. }
  200. void
  201. PyIMEngine::lookup_table_page_down ()
  202. {
  203. PyObject *pValue = NULL;
  204. pValue = PY_CALL ("lookup_table_page_down");
  205. PY_CHECK_RET (pValue);
  206. Py_XDECREF (pValue);
  207. }
  208. PyDoc_STRVAR (IMEngine_lookup_table_page_down__doc__,
  209. "lookup_table_page_down ()\n\n"
  210. "This function will be called, when user press page down button in candidate window.\n"
  211. "IM developer may override it in sub class.\n");
  212. PyObject *
  213. PyIMEngine::py_lookup_table_page_down (PyIMEngineObject *self)
  214. {
  215. self->engine.IMEngineInstanceBase::lookup_table_page_down ();
  216. Py_INCREF (Py_None);
  217. return Py_None;
  218. }
  219. void
  220. PyIMEngine::reset ()
  221. {
  222. PyObject *pValue = NULL;
  223. pValue = PY_CALL ("reset");
  224. PY_CHECK_RET (pValue);
  225. Py_XDECREF (pValue);
  226. }
  227. PyDoc_STRVAR (IMEngine_reset__doc__,
  228. "reset ()\n\n"
  229. "This function will be called, when im client request reseting engine.\n"
  230. "IM developer may override it in sub class.\n");
  231. PyObject *
  232. PyIMEngine::py_reset (PyIMEngineObject *self)
  233. {
  234. self->engine.IMEngineInstanceBase::reset ();
  235. Py_INCREF (Py_None);
  236. return Py_None;
  237. }
  238. void
  239. PyIMEngine::focus_in ()
  240. {
  241. PyObject *pValue = NULL;
  242. pValue = PY_CALL ("focus_in");
  243. PY_CHECK_RET (pValue);
  244. Py_XDECREF (pValue);
  245. }
  246. PyDoc_STRVAR (IMEngine_focus_in__doc__,
  247. "focus_in ()\n\n"
  248. "This function will be called, when engine is focused in.\n"
  249. "IM developer may override it in sub class.\n");
  250. PyObject *
  251. PyIMEngine::py_focus_in (PyIMEngineObject *self)
  252. {
  253. self->engine.IMEngineInstanceBase::focus_in ();
  254. Py_INCREF (Py_None);
  255. return Py_None;
  256. }
  257. void
  258. PyIMEngine::focus_out ()
  259. {
  260. PyObject *pValue = NULL;
  261. pValue = PY_CALL ("focus_out");
  262. PY_CHECK_RET (pValue);
  263. Py_XDECREF (pValue);
  264. }
  265. PyDoc_STRVAR (IMEngine_focus_out__doc__,
  266. "focus_out ()\n\n"
  267. "This function will be called, when engine is focused out.\n"
  268. "IM developer may override it in sub class.\n");
  269. PyObject *
  270. PyIMEngine::py_focus_out (PyIMEngineObject *self)
  271. {
  272. self->engine.IMEngineInstanceBase::focus_out ();
  273. Py_INCREF (Py_None);
  274. return Py_None;
  275. }
  276. void
  277. PyIMEngine::trigger_property (const String &property)
  278. {
  279. PyObject *pValue = NULL;
  280. pValue = PY_CALL_1 ("trigger_property", PyString_FromString (property.c_str ()));
  281. PY_CHECK_RET (pValue);
  282. Py_XDECREF (pValue);
  283. }
  284. PyDoc_STRVAR (IMEngine_trigger_property__doc__,
  285. "trigger_property (prop_name)\n\n"
  286. "This function will be called, when user presses property button on panel.\n"
  287. "IM developer may override it in sub class.\n");
  288. PyObject *
  289. PyIMEngine::py_trigger_property (PyIMEngineObject *self, PyObject *args)
  290. {
  291. char *property;
  292. if (!PyArg_ParseTuple (args, "s:trigger_property", &property))
  293. return NULL;
  294. self->engine.IMEngineInstanceBase::trigger_property (String (property));
  295. Py_INCREF (Py_None);
  296. return Py_None;
  297. }
  298. void
  299. PyIMEngine::process_helper_event (const String &helper_uuid, const Transaction &trans)
  300. {
  301. //IMEngineInstanceBase::process_helper_event (helper_uuid, trans);
  302. }
  303. PyDoc_STRVAR (IMEngine_process_helper_event__doc__,
  304. "process_helper (uuid, trans)\n\n"
  305. "This function will be called, when user ....\n"
  306. "IM developer may override it in sub class.\n");
  307. PyObject *
  308. PyIMEngine::py_process_helper_event (PyIMEngineObject *self, PyObject *args)
  309. {
  310. // TODO:
  311. char *helper_uuid;
  312. PyObject *trans;
  313. if (!PyArg_ParseTuple (args, "sO:process_helper_event", &helper_uuid, &trans))
  314. return NULL;
  315. //self->engine.IMEngineInstanceBase::update_client_capabilities (cap);
  316. Py_INCREF (Py_None);
  317. return Py_None;
  318. }
  319. void
  320. PyIMEngine::update_client_capabilities (unsigned int cap)
  321. {
  322. PyObject *pValue = NULL;
  323. pValue = PY_CALL_1 ("update_client_capabilities", PyInt_FromLong ((unsigned long)cap));
  324. PY_CHECK_RET (pValue);
  325. Py_XDECREF (pValue);
  326. }
  327. PyDoc_STRVAR (IMEngine_update_client_capabilities__doc__,
  328. "update_client_capabilities (cap)\n\n"
  329. "This function will be called, when im client request update client capabilities.\n"
  330. "IM developer may override it in sub class.\n");
  331. PyObject *
  332. PyIMEngine::py_update_client_capabilities (PyIMEngineObject *self, PyObject *args)
  333. {
  334. unsigned int cap;
  335. if (!PyArg_ParseTuple (args, "I:update_client_capabilities", &cap))
  336. return NULL;
  337. self->engine.IMEngineInstanceBase::update_client_capabilities (cap);
  338. Py_INCREF (Py_None);
  339. return Py_None;
  340. }
  341. void
  342. PyIMEngine::reload_config (const ConfigPointer &config)
  343. {
  344. PyObject *pFunc = NULL;
  345. PyObject *pValue = NULL;
  346. PyObject *pArgs = NULL;
  347. pFunc = PyObject_GetAttrString (this->self, "reload_config");
  348. if (pFunc == NULL)
  349. goto _failed_out;
  350. pArgs = Py_BuildValue ("(O)", this->config);
  351. if (pArgs == NULL)
  352. goto _failed_out;
  353. pValue = PyObject_CallObject (pFunc, pArgs);
  354. if (pValue == NULL)
  355. goto _failed_out;
  356. goto _success_out;
  357. _failed_out:
  358. PyErr_Print ();
  359. _success_out:
  360. Py_XDECREF (pArgs);
  361. Py_XDECREF (pFunc);
  362. Py_XDECREF (pValue);
  363. }
  364. IMEngineInstanceBase *
  365. PyIMEngine::from_pyobject (PyObject *object)
  366. {
  367. PyIMEngineObject *self = (PyIMEngineObject *)object;
  368. return (IMEngineInstanceBase *) &self->engine;
  369. }
  370. PyObject *
  371. PyIMEngine::py_new (PyTypeObject *type, PyObject *args, PyObject *kwds)
  372. {
  373. PyIMEngine *self;
  374. self = (PyIMEngine *)type->tp_alloc (type, 0);
  375. return (PyObject *)self;
  376. }
  377. int
  378. PyIMEngine::py_init (PyIMEngineObject *self, PyObject *args, PyObject *kwds)
  379. {
  380. PyObject *factory;
  381. PyObject *config;
  382. char *encoding;
  383. int id;
  384. if (!PyArg_ParseTuple (args, "OOsi:__init__", &factory, &config, &encoding, &id)) {
  385. PyErr_Print ();
  386. return -1;
  387. }
  388. new (&self->engine) PyIMEngine ((PyObject *)self,
  389. factory,
  390. config,
  391. String (encoding), id);
  392. return 0;
  393. }
  394. void
  395. PyIMEngine::py_dealloc (PyIMEngineObject *self)
  396. {
  397. ((PyObject *)self)->ob_type->tp_free (self);
  398. }
  399. PyDoc_STRVAR (IMEngine_show_preedit_string__doc__,
  400. "show_preedit_string ()\n\n"
  401. "Hide the preedit string.\n");
  402. PyObject *
  403. PyIMEngine::py_show_preedit_string (PyIMEngineObject *self)
  404. {
  405. self->engine.show_preedit_string ();
  406. Py_INCREF (Py_None);
  407. return Py_None;
  408. }
  409. PyDoc_STRVAR (IMEngine_show_aux_string__doc__,
  410. "show_aux_string ()\n\n"
  411. "Hide the aux string.\n");
  412. PyObject *
  413. PyIMEngine::py_show_aux_string (PyIMEngineObject *self)
  414. {
  415. self->engine.show_aux_string ();
  416. Py_INCREF (Py_None);
  417. return Py_None;
  418. }
  419. PyDoc_STRVAR (IMEngine_show_lookup_table__doc__,
  420. "show_lookup_table ()\n\n"
  421. "Hide the lookup table.\n");
  422. PyObject *
  423. PyIMEngine::py_show_lookup_table (PyIMEngineObject *self)
  424. {
  425. self->engine.show_lookup_table ();
  426. Py_INCREF (Py_None);
  427. return Py_None;
  428. }
  429. PyDoc_STRVAR (IMEngine_hide_preedit_string__doc__,
  430. "hide_preedit_string ()\n\n"
  431. "Hide the preedit string.\n");
  432. PyObject *
  433. PyIMEngine::py_hide_preedit_string (PyIMEngineObject *self)
  434. {
  435. self->engine.hide_preedit_string ();
  436. Py_INCREF (Py_None);
  437. return Py_None;
  438. }
  439. PyDoc_STRVAR (IMEngine_hide_aux_string__doc__,
  440. "hide_aux_string ()\n\n"
  441. "Hide the aux string.\n");
  442. PyObject *
  443. PyIMEngine::py_hide_aux_string (PyIMEngineObject *self)
  444. {
  445. self->engine.hide_aux_string ();
  446. Py_INCREF (Py_None);
  447. return Py_None;
  448. }
  449. PyDoc_STRVAR (IMEngine_hide_lookup_table__doc__,
  450. "hide_lookup_table ()\n\n"
  451. "Hide the lookup table.\n");
  452. PyObject *
  453. PyIMEngine::py_hide_lookup_table (PyIMEngineObject *self)
  454. {
  455. self->engine.hide_lookup_table ();
  456. Py_INCREF (Py_None);
  457. return Py_None;
  458. }
  459. PyDoc_STRVAR (IMEngine_update_preedit_caret__doc__,
  460. "update_preedit_caret (pos)\n\n"
  461. "Update the caret position of preedit string.\n");
  462. PyObject *
  463. PyIMEngine::py_update_preedit_caret (PyIMEngineObject *self, PyObject *args)
  464. {
  465. int caret;
  466. if (!PyArg_ParseTuple (args, "i:update_preedit_caret", &caret))
  467. return NULL;
  468. self->engine.update_preedit_caret (caret);
  469. Py_INCREF (Py_None);
  470. return Py_None;
  471. }
  472. /*
  473. void update_preedit_string (const WideString &str,
  474. const AttributeList &attrs = AttributeList ());
  475. */
  476. PyDoc_STRVAR (IMEngine_update_preedit_string__doc__,
  477. "update_preedit_string (text, attrs = None)\n\n"
  478. "Update preedit string with attrs.\n");
  479. PyObject *
  480. PyIMEngine::py_update_preedit_string (PyIMEngineObject *self, PyObject *args)
  481. {
  482. Py_UNICODE *str = NULL;
  483. PyObject *pAttrs = NULL;
  484. AttributeList attrs;
  485. #if Py_UNICODE_SIZE == 4
  486. if (!PyArg_ParseTuple (args, "u|O:update_preedit_string", &str, &pAttrs))
  487. return NULL;
  488. self->engine.update_preedit_string (WideString ((wchar_t *)str),
  489. Attributes_FromTupleOrList (pAttrs));
  490. #else
  491. gunichar *unistr = NULL;
  492. int size = 0;
  493. if (!PyArg_ParseTuple (args, "u#|O:update_preedit_string", &str, &size, &pAttrs))
  494. return NULL;
  495. unistr = g_utf16_to_ucs4 (str, size, NULL, NULL, NULL);
  496. self->engine.update_preedit_string (WideString ((wchar_t *)unistr),
  497. Attributes_FromTupleOrList (pAttrs));
  498. g_free (unistr);
  499. #endif
  500. Py_INCREF (Py_None);
  501. return Py_None;
  502. }
  503. /*
  504. * void update_aux_string (const WideString &str,
  505. * const AttributeList &attrs = AttributeList ());
  506. */
  507. PyDoc_STRVAR (IMEngine_update_aux_string__doc__,
  508. "update_aux_string (text, attrs = None)\n\n"
  509. "Update aux string with attrs.\n");
  510. PyObject *
  511. PyIMEngine::py_update_aux_string (PyIMEngineObject *self, PyObject *args)
  512. {
  513. Py_UNICODE *str = NULL;
  514. PyObject *pAttrs = NULL;
  515. AttributeList attrs;
  516. #if Py_UNICODE_SIZE == 4
  517. if (!PyArg_ParseTuple (args, "u|O:update_aux_string", &str, &pAttrs))
  518. return NULL;
  519. self->engine.update_aux_string (WideString ((wchar_t *)str),
  520. Attributes_FromTupleOrList (pAttrs));
  521. #else
  522. int size = 0;
  523. gunichar *unistr = NULL;
  524. if (!PyArg_ParseTuple (args, "u#|O:update_aux_string", &str, &size, &pAttrs))
  525. return NULL;
  526. unistr = g_utf16_to_ucs4 (str, size, NULL, NULL, NULL);
  527. self->engine.update_aux_string (WideString ((wchar_t *)unistr),
  528. Attributes_FromTupleOrList (pAttrs));
  529. g_free (unistr);
  530. #endif
  531. Py_INCREF (Py_None);
  532. return Py_None;
  533. }
  534. /*
  535. * void update_lookup_table (const LookupTable &table);
  536. */
  537. PyDoc_STRVAR (IMEngine_update_lookup_table__doc__,
  538. "update_lookup_table (lookup_table)\n\n"
  539. "Update the lookup table that contains candidates.\n");
  540. PyObject *
  541. PyIMEngine::py_update_lookup_table (PyIMEngineObject *self, PyObject *args)
  542. {
  543. PyObject *lookup_table = NULL;
  544. if (!PyArg_ParseTuple (args, "O:update_lookup_table", &lookup_table))
  545. return NULL;
  546. self->engine.update_lookup_table (PyLookupTable::from_pyobject (lookup_table));
  547. Py_INCREF (Py_None);
  548. return Py_None;
  549. }
  550. /*
  551. * void commit_string (const WideString &str);
  552. */
  553. PyDoc_STRVAR (IMEngine_commit_string__doc__,
  554. "commit_string (text)\n\n"
  555. "Commit text to im client.\n");
  556. PyObject *
  557. PyIMEngine::py_commit_string (PyIMEngineObject *self, PyObject *args)
  558. {
  559. Py_UNICODE *str = NULL;
  560. #if Py_UNICODE_SIZE == 4
  561. if (!PyArg_ParseTuple (args, "u:commit_string", &str))
  562. return NULL;
  563. self->engine.commit_string (WideString ((wchar_t *)str));
  564. #else
  565. int size = 0;
  566. gunichar *unistr = NULL;
  567. if (!PyArg_ParseTuple (args, "u#:commit_string", &str, &size))
  568. return NULL;
  569. unistr = g_utf16_to_ucs4 (str, size, NULL, NULL, NULL);
  570. self->engine.commit_string (WideString ((wchar_t *)unistr));
  571. g_free (unistr);
  572. #endif
  573. Py_INCREF (Py_None);
  574. return Py_None;
  575. }
  576. /*
  577. * void forward_key_event (const KeyEvent &key);
  578. */
  579. PyDoc_STRVAR (IMEngine_forward_key_event__doc__,
  580. "forward_key_event (key_event)\n\n"
  581. "Forward a key_event (scim.KeyEvent) to im client.\n");
  582. PyObject *
  583. PyIMEngine::py_forward_key_event (PyIMEngineObject *self, PyObject *args)
  584. {
  585. Py_INCREF (Py_None);
  586. return Py_None;
  587. }
  588. /*
  589. * void register_properties (const PropertyList &properties);
  590. */
  591. PyDoc_STRVAR (IMEngine_register_properties__doc__,
  592. "register_properties (props)\n\n"
  593. "Regitser props (a list of scim.Property) with IMEngine.\n");
  594. PyObject *
  595. PyIMEngine::py_register_properties (PyIMEngineObject *self, PyObject *args)
  596. {
  597. PyObject *props = NULL;
  598. PropertyList proplist;
  599. int i;
  600. if (!PyArg_ParseTuple (args, "O:register_properties", &props))
  601. return NULL;
  602. if (PyList_Check (props)) {
  603. for (i = 0; i < PyList_Size (props); i++) {
  604. PyObject *prop = PyList_GetItem (props, i);
  605. proplist.push_back (PyProperty_AsProperty (prop));
  606. }
  607. }
  608. else if (PyTuple_Check (props)) {
  609. for (i = 0; i < PyTuple_Size (props); i++) {
  610. PyObject *prop = PyTuple_GetItem (props, i);
  611. proplist.push_back (PyProperty_AsProperty (prop));
  612. }
  613. }
  614. else {
  615. PyErr_SetString (PyExc_TypeError, "the argument must be a list or a tuple that contains propertys");
  616. return NULL;
  617. }
  618. self->engine.register_properties (proplist);
  619. Py_INCREF (Py_None);
  620. return Py_None;
  621. }
  622. /*
  623. * void update_property (const Property &property);
  624. */
  625. PyDoc_STRVAR (IMEngine_update_property__doc__,
  626. "update_property (property)\n\n"
  627. "Update property (scim.Property) with IMEngine.\n");
  628. PyObject *
  629. PyIMEngine::py_update_property (PyIMEngineObject *self, PyObject *args)
  630. {
  631. PyObject *prop = NULL;
  632. if (!PyArg_ParseTuple (args, "O:update_property", &prop))
  633. return NULL;
  634. self->engine.update_property (PyProperty_AsProperty (prop));
  635. Py_INCREF (Py_None);
  636. return Py_None;
  637. }
  638. /*
  639. * void beep ();
  640. */
  641. PyDoc_STRVAR (IMEngine_beep__doc__,
  642. "beep ()\n\n"
  643. "Beep.\n");
  644. PyObject *
  645. PyIMEngine::py_beep (PyIMEngineObject *self)
  646. {
  647. self->engine.beep ();
  648. Py_INCREF (Py_None);
  649. return Py_None;
  650. }
  651. /*
  652. * void start_helper (const String &helper_uuid);
  653. */
  654. PyDoc_STRVAR (IMEngine_start_helper__doc__,
  655. "start_helper (helper_uuid)\n\n"
  656. "Start a helper specified with the uuid.\n");
  657. PyObject *
  658. PyIMEngine::py_start_helper (PyIMEngineObject *self, PyObject *args)
  659. {
  660. char *str = NULL;
  661. if (!PyArg_ParseTuple (args, "s:start_helper", &str))
  662. return NULL;
  663. self->engine.start_helper (String (str));
  664. Py_INCREF (Py_None);
  665. return Py_None;
  666. }
  667. /*
  668. * void stop_helper (const String &helper_uuid);
  669. */
  670. PyDoc_STRVAR (IMEngine_stop_helper__doc__,
  671. "stop_helper (helper_uuid)\n\n"
  672. "Stop a helper specified with the uuid.\n");
  673. PyObject *
  674. PyIMEngine::py_stop_helper (PyIMEngineObject *self, PyObject *args)
  675. {
  676. char *str = NULL;
  677. if (!PyArg_ParseTuple (args, "s:stop_helper", &str))
  678. return NULL;
  679. self->engine.stop_helper (String (str));
  680. Py_INCREF (Py_None);
  681. return Py_None;
  682. }
  683. /*
  684. * void send_helper_event (const String &helper_uuid, const Transaction &trans);
  685. */
  686. PyDoc_STRVAR (IMEngine_send_helper_event__doc__,
  687. "send_helper_event ()\n\n"
  688. "Do nothing.\n");
  689. PyObject *
  690. PyIMEngine::py_send_helper_event (PyIMEngineObject *self, PyObject *args)
  691. {
  692. char *str = NULL;
  693. if (!PyArg_ParseTuple (args, "s:send_helper_event", &str))
  694. return NULL;
  695. Py_INCREF (Py_None);
  696. return Py_None;
  697. }
  698. /*
  699. * bool get_surrounding_text (WideString &text,
  700. * int &cursor,
  701. * int maxlen_before = -1,
  702. * int maxlen_after = -1);
  703. */
  704. PyDoc_STRVAR (IMEngine_get_surrounding_text__doc__,
  705. "get_surrounding_text (maxlen_before = -1, maxlen_after = -1)\n\n"
  706. "Retrieves a tuple contains a text and cursor within the text.\n");
  707. PyObject *
  708. PyIMEngine::py_get_surrounding_text (PyIMEngineObject *self, PyObject *args)
  709. {
  710. PyObject *tuple;
  711. int maxlen_before = -1;
  712. int maxlen_after = -1;
  713. if (!PyArg_ParseTuple (args, "|ii:get_surrounding_text", &maxlen_before, &maxlen_after))
  714. return NULL;
  715. WideString text;
  716. int cursor;
  717. int provided = self->engine.get_surrounding_text(text, cursor, maxlen_before, maxlen_after);
  718. tuple = PyTuple_New (2);
  719. if (!provided) {
  720. text = L"";
  721. cursor = 0;
  722. }
  723. #if Py_UNICODE_SIZE == 4
  724. PyTuple_SET_ITEM (tuple, 0, PyUnicode_FromUnicode ((Py_UNICODE *)text.c_str(), text.length()));
  725. #else
  726. gunichar2 *utf16_str = g_ucs4_to_utf16 (text.c_str(), -1, NULL, NULL, NULL);
  727. PyTuple_SET_ITEM (tuple, 0, PyUnicode_FromUnicode ((Py_UNICODE *)utf16_str, text.length()));
  728. #endif
  729. PyTuple_SET_ITEM (tuple, 1, PyInt_FromLong ((long) cursor));
  730. return tuple;
  731. }
  732. /*
  733. * bool delete_surrounding_text (int offset, int len);
  734. */
  735. PyDoc_STRVAR (IMEngine_delete_surrounding_text__doc__,
  736. "delete_surrounding_text (offset, len)\n\n"
  737. "Do nothing.\n");
  738. PyObject *
  739. PyIMEngine::py_delete_surrounding_text (PyIMEngineObject *self, PyObject *args)
  740. {
  741. int offset;
  742. int len;
  743. if (!PyArg_ParseTuple (args, "ii:delete_surrounding_text", &offset, &len))
  744. return NULL;
  745. self->engine.delete_surrounding_text (offset, len);
  746. Py_INCREF (Py_None);
  747. return Py_None;
  748. }
  749. PyMethodDef
  750. PyIMEngine::py_methods[] = {
  751. #define ENTRY(name, type) \
  752. { \
  753. #name, \
  754. (PyCFunction)PyIMEngine::py_##name, \
  755. type, \
  756. IMEngine_##name##__doc__ \
  757. }
  758. ENTRY (show_preedit_string, METH_NOARGS),
  759. ENTRY (show_aux_string, METH_NOARGS),
  760. ENTRY (show_lookup_table, METH_NOARGS),
  761. ENTRY (hide_preedit_string, METH_NOARGS),
  762. ENTRY (hide_aux_string, METH_NOARGS),
  763. ENTRY (hide_lookup_table, METH_NOARGS),
  764. ENTRY (update_preedit_caret, METH_VARARGS),
  765. ENTRY (update_preedit_string, METH_VARARGS),
  766. ENTRY (update_aux_string, METH_VARARGS),
  767. ENTRY (update_lookup_table, METH_VARARGS),
  768. ENTRY (commit_string, METH_VARARGS),
  769. ENTRY (forward_key_event, METH_VARARGS),
  770. ENTRY (register_properties, METH_VARARGS),
  771. ENTRY (update_property, METH_VARARGS),
  772. ENTRY (beep, METH_NOARGS),
  773. ENTRY (start_helper, METH_VARARGS),
  774. ENTRY (stop_helper, METH_VARARGS),
  775. ENTRY (send_helper_event, METH_VARARGS),
  776. ENTRY (get_surrounding_text, METH_VARARGS),
  777. ENTRY (delete_surrounding_text, METH_VARARGS),
  778. ENTRY (process_key_event, METH_VARARGS),
  779. ENTRY (move_preedit_caret, METH_VARARGS),
  780. ENTRY (select_candidate, METH_VARARGS),
  781. ENTRY (update_lookup_table_page_size, METH_VARARGS),
  782. ENTRY (lookup_table_page_up, METH_NOARGS),
  783. ENTRY (lookup_table_page_down, METH_NOARGS),
  784. ENTRY (reset, METH_NOARGS),
  785. ENTRY (focus_in, METH_NOARGS),
  786. ENTRY (focus_out, METH_NOARGS),
  787. ENTRY (trigger_property, METH_VARARGS),
  788. ENTRY (process_helper_event, METH_VARARGS),
  789. ENTRY (update_client_capabilities, METH_VARARGS),
  790. #undef ENTRY
  791. { NULL }
  792. };
  793. PyTypeObject PyIMEngineType = {
  794. PyObject_HEAD_INIT (NULL)
  795. 0, /*ob_size*/
  796. "scim.IMEngine", /*tp_name*/
  797. sizeof (PyIMEngineObject), /*tp_basicsize*/
  798. 0, /*tp_itemsize*/
  799. (destructor)PyIMEngine::py_dealloc, /*tp_dealloc*/
  800. 0, /*tp_print*/
  801. 0, /*tp_getattr*/
  802. 0, /*tp_setattr*/
  803. 0, /*tp_compare*/
  804. 0, /*tp_repr*/
  805. 0, /*tp_as_number*/
  806. 0, /*tp_as_sequence*/
  807. 0, /*tp_as_mapping*/
  808. 0, /*tp_hash */
  809. 0, /*tp_call*/
  810. 0, /*tp_str*/
  811. 0, /*tp_getattro*/
  812. 0, /*tp_setattro*/
  813. 0, /*tp_as_buffer*/
  814. Py_TPFLAGS_DEFAULT |
  815. Py_TPFLAGS_BASETYPE, /*tp_flags*/
  816. "IMEngineInstanceBase objects", /* tp_doc */
  817. 0, /* tp_traverse */
  818. 0, /* tp_clear */
  819. 0, /* tp_richcompare */
  820. 0, /* tp_weaklistoffset */
  821. 0, /* tp_iter */
  822. 0, /* tp_iternext */
  823. PyIMEngine::py_methods, /* tp_methods */
  824. 0, /* tp_members */
  825. 0, /* tp_getset */
  826. 0, /* tp_base */
  827. 0, /* tp_dict */
  828. 0, /* tp_descr_get */
  829. 0, /* tp_descr_set */
  830. 0, /* tp_dictoffset */
  831. (initproc)PyIMEngine::py_init, /* tp_init */
  832. 0, /* tp_alloc */
  833. PyIMEngine::py_new, /* tp_new */
  834. PyObject_Del, /* tp_free */
  835. };
  836. void init_engine (PyObject *module)
  837. {
  838. if (PyType_Ready (&PyIMEngineType) < 0)
  839. return;
  840. Py_INCREF (&PyIMEngineType);
  841. PyModule_AddObject (module, "IMEngine", (PyObject *)&PyIMEngineType);
  842. }