/* vim:set noet ts=4: */ /** * scim-python * * Copyright (c) 2007-2008 Huang Peng * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * * $Id: $ */ #include "scim-python.h" #include using namespace scim; struct PyIMEngineFactoryObject { PyListObject list; /* Type-specific fields go here. */ PyIMEngineFactory factory; }; PyIMEngineFactory::PyIMEngineFactory (PyObject *self, PyObject *config) :self (self), config (config) { Py_INCREF (self); Py_INCREF (config); reload_signal_connection = PyConfig_from_pyobject (config)->signal_connect_reload (slot (this, &PyIMEngineFactory::reload_config)); }; PyIMEngineFactory::~PyIMEngineFactory () { PyObject *pFunc = NULL; PyObject *pArgs = NULL; PyObject *result = NULL; reload_signal_connection.disconnect (); if (!PyObject_HasAttrString (self, "destroy")) goto _success_out; pFunc = PyObject_GetAttrString (self, "destroy"); if (pFunc == NULL) { goto _failed_out; } pArgs = Py_BuildValue ("()"); result = PyObject_CallObject (pFunc, pArgs); if (result == NULL) goto _failed_out; goto _success_out; _failed_out: PyErr_Print (); _success_out: Py_XDECREF (result); Py_XDECREF (pArgs); Py_XDECREF (pFunc); Py_XDECREF (self); Py_XDECREF (config); } void PyIMEngineFactory::operator delete (void *p) { // do nothing } String PyIMEngineFactory::get_attr_string (char *name) const { PyObject *pValue; String result; pValue = PyObject_GetAttrString (self, name); if (pValue) { if (PyString_Check (pValue)) { char *str = PyString_AsString (pValue); result = str; } else if (PyUnicode_Check (pValue)) { gchar *str = NULL; #if Py_UNICODE_SIZE == 4 str = g_ucs4_to_utf8 ((gunichar *)PyUnicode_AS_UNICODE (pValue), PyUnicode_GET_SIZE (pValue), NULL, NULL, NULL); result = str; g_free (str); #else str = g_utf16_to_utf8 ((gunichar2 *)PyUnicode_AS_UNICODE (pValue), PyUnicode_GET_SIZE (pValue), NULL, NULL, NULL); result = str; g_free (str); #endif } Py_DECREF (pValue); } else { PyErr_Print (); } return result; } WideString PyIMEngineFactory::get_attr_unicode (char *name) const { PyObject *pValue; WideString result; pValue = PyObject_GetAttrString (self, name); if (pValue) { if (PyUnicode_Check (pValue)) { #if Py_UNICODE_SIZE == 4 result = (wchar_t *)PyUnicode_AS_UNICODE (pValue); #else gunichar *unistr = g_utf16_to_ucs4 (PyUnicode_AS_UNICODE (pValue), PyUnicode_GET_SIZE (pValue), NULL, NULL, NULL); result = (wchar_t *) unistr; g_free (unistr); #endif } else if (PyString_Check (pValue)) { gunichar *unistr = g_utf8_to_ucs4 (PyString_AsString (pValue), PyString_GET_SIZE (pValue), NULL, NULL, NULL); result = (wchar_t *)unistr; g_free (unistr); } Py_DECREF (pValue); } else { PyErr_Print (); } return result; } WideString PyIMEngineFactory::get_name () const { return get_attr_unicode ("name"); } String PyIMEngineFactory::get_uuid () const { return get_attr_string ("uuid"); } String PyIMEngineFactory::get_icon_file () const { return get_attr_string ("icon_file"); } WideString PyIMEngineFactory::get_authors () const { return get_attr_unicode ("authors"); } WideString PyIMEngineFactory::get_credits () const { return get_attr_unicode ("credits"); } WideString PyIMEngineFactory::get_help () const { return get_attr_unicode ("help"); } bool PyIMEngineFactory::validate_encoding (const String& encoding) { return true; } bool PyIMEngineFactory::validate_locale (const String& locale) { return true; } PyObject * PyIMEngineFactory::py_set_languages (PyIMEngineFactoryObject *self, PyObject *args) { char * languages; if (!PyArg_ParseTuple (args, "s:set_language", &languages)) return NULL; self->factory.set_languages (languages); Py_INCREF (Py_None); return Py_None; } IMEngineInstancePointer PyIMEngineFactory::create_instance (const String& encoding, int id) { PyObject *pFunc = NULL; PyObject *pEngine = NULL; PyObject *pArgs = NULL; IMEngineInstancePointer result (0); pFunc = PyObject_GetAttrString (self, "create_instance"); if (pFunc == NULL) goto _failed_out; pArgs = Py_BuildValue ("(si)", encoding.c_str (), id); pEngine = PyObject_CallObject (pFunc, pArgs); if (pEngine == NULL) { /* will create a dummy engine */ PyErr_Print (); extern PyTypeObject PyIMEngineType; pEngine = PyObject_New (PyObject, &PyIMEngineType); pEngine = PyObject_Init (pEngine, &PyIMEngineType); Py_XDECREF (pArgs); pArgs = Py_BuildValue ("(OOsi)", self, config, encoding.c_str (), id); PyIMEngineType.tp_init (pEngine, pArgs, NULL); } result = PyIMEngine::from_pyobject (pEngine); goto _success_out; _failed_out: PyErr_Print (); _success_out: Py_XDECREF (pArgs); Py_XDECREF (pFunc); Py_XDECREF (pEngine); return result; } void PyIMEngineFactory::reload_config (const ConfigPointer &config) { PyObject *pFunc = NULL; PyObject *pValue = NULL; PyObject *pArgs = NULL; pFunc = PyObject_GetAttrString (this->self, "reload_config"); if (pFunc == NULL) goto _failed_out; pArgs = Py_BuildValue ("(O)", this->config); if (pArgs == NULL) goto _failed_out; pValue = PyObject_CallObject (pFunc, pArgs); if (pValue == NULL) goto _failed_out; goto _success_out; _failed_out: PyErr_Print (); _success_out: Py_XDECREF (pArgs); Py_XDECREF (pFunc); Py_XDECREF (pValue); } PyMethodDef PyIMEngineFactory::py_methods[] = { { "set_languages", (PyCFunction)PyIMEngineFactory::py_set_languages, METH_VARARGS, "Set languages" }, { NULL } }; PyObject * PyIMEngineFactory::py_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { PyIMEngineFactoryObject *self; self = (PyIMEngineFactoryObject *)type->tp_alloc (type, 0); return (PyObject *)self; } int PyIMEngineFactory::py_init (PyIMEngineFactoryObject *self, PyObject *args, PyObject *kwds) { PyObject *config; if (!PyArg_ParseTuple (args, "O:__init__", &config)) return -1; new (&self->factory) PyIMEngineFactory ((PyObject *)self, config); return 0; } void PyIMEngineFactory::py_dealloc (PyIMEngineFactoryObject *self) { ((PyObject *) self)->ob_type->tp_free (self); } IMEngineFactoryBase * PyIMEngineFactory::from_pyobject (PyObject *object) { PyIMEngineFactoryObject *self = (PyIMEngineFactoryObject *) object; return (IMEngineFactoryBase *)&self->factory; } PyTypeObject PyIMEngineFactoryType = { PyObject_HEAD_INIT (NULL) 0, /*ob_size*/ "scim.IMEngineFactory", /*tp_name*/ sizeof (PyIMEngineFactoryObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ 0 /* (destructor)PyIMEngineFactory::py_dealloc */, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ "IMEngineInstanceBase objects", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ PyIMEngineFactory::py_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)PyIMEngineFactory::py_init, /* tp_init */ 0, /* tp_alloc */ PyIMEngineFactory::py_new, /* tp_new */ }; void init_factory (PyObject *module) { if (PyType_Ready (&PyIMEngineFactoryType) < 0) return; Py_INCREF (&PyIMEngineFactoryType); PyModule_AddObject (module, "IMEngineFactory", (PyObject *)&PyIMEngineFactoryType); }