608b8b12b852ab4ae425b6be9c7d90d744a07854
[platform/upstream/python-gobject.git] / tests / testhelpermodule.c
1 #include "pygobject.h"
2 #include <gobject/gmarshal.h>
3
4 #include "test-thread.h"
5 #include "test-unknown.h"
6 #include "test-floating.h"
7
8 #include <pyglib-python-compat.h>
9
10 static PyTypeObject *_PyGObject_Type;
11 #define PyGObject_Type (*_PyGObject_Type)
12
13 static PyObject * _wrap_TestInterface__do_iface_method(PyObject *cls,
14                                                        PyObject *args,
15                                                        PyObject *kwargs);
16
17 static GType
18 test_type_get_type(void)
19 {
20     static GType gtype = 0;
21     GType parent_type;
22     
23     if (gtype == 0)
24     {
25         GTypeInfo *type_info;
26         GTypeQuery query;
27         
28         parent_type = g_type_from_name("PyGObject");
29         if (parent_type == 0)
30              g_error("could not get PyGObject from testmodule");
31
32         type_info = (GTypeInfo *)g_new0(GTypeInfo, 1);
33         
34         g_type_query(parent_type, &query);
35         type_info->class_size = query.class_size;
36         type_info->instance_size = query.instance_size;
37         
38         gtype = g_type_register_static(parent_type,
39                                        "TestType", type_info, 0);
40         if (!gtype)
41              g_error("Could not register TestType");
42     }
43     
44     return gtype;
45 }
46
47 #define TYPE_TEST (test_type_get_type())
48
49 static PyObject *
50 _wrap_get_test_thread (PyObject * self)
51 {
52   GObject *obj;
53
54   test_thread_get_type();
55   g_assert (g_type_is_a (TEST_TYPE_THREAD, G_TYPE_OBJECT));
56   obj = g_object_new (TEST_TYPE_THREAD, NULL);
57   g_assert (obj != NULL);
58   
59   return pygobject_new(obj);
60 }
61
62 static PyObject *
63 _wrap_get_unknown (PyObject * self)
64 {
65   GObject *obj;
66   obj = g_object_new (TEST_TYPE_UNKNOWN, NULL);
67   return pygobject_new(obj);
68 }
69
70 static PyObject *
71 _wrap_create_test_type (PyObject * self)
72 {
73     GObject *obj;
74     PyObject *rv;
75     obj = g_object_new(TYPE_TEST, NULL);
76     rv = pygobject_new(obj);
77     g_object_unref(obj);
78     return rv;
79 }
80
81 static PyObject *
82 _wrap_test_g_object_new (PyObject * self)
83 {
84     GObject *obj;
85     PyObject *rv;
86
87     obj = g_object_new(g_type_from_name("PyGObject"), NULL);
88     rv = PYGLIB_PyLong_FromLong(obj->ref_count); /* should be == 2 at this point */
89     g_object_unref(obj);
90     return rv;
91 }
92
93 /* TestUnknown */
94 static PyObject *
95 _wrap_test_interface_iface_method(PyGObject *self, PyObject *args, PyObject *kwargs)
96 {
97     static char *kwlist[] = { NULL };
98
99     if (!PyArg_ParseTupleAndKeywords(args, kwargs,":", kwlist))
100         return NULL;
101     
102     test_interface_iface_method(TEST_INTERFACE(self->obj));
103     
104     Py_INCREF(Py_None);
105     return Py_None;
106 }
107
108 static const PyMethodDef _PyTestInterface_methods[] = {
109     { "iface_method", (PyCFunction)_wrap_test_interface_iface_method, METH_VARARGS|METH_KEYWORDS,
110       NULL },
111     { "do_iface_method", (PyCFunction)_wrap_TestInterface__do_iface_method, METH_VARARGS|METH_KEYWORDS|METH_CLASS,
112       NULL },
113     { NULL, NULL, 0, NULL }
114 };
115
116 /* TestInterface */
117 PYGLIB_DEFINE_TYPE("test.Interface", PyTestInterface_Type, PyObject);
118
119 static PyObject *
120 _wrap_TestInterface__do_iface_method(PyObject *cls, PyObject *args, PyObject *kwargs)
121 {
122   TestInterfaceIface *iface;
123   static char *kwlist[] = { "self", NULL };
124   PyGObject *self;
125
126   if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:TestInterface.iface_method", kwlist, &PyTestInterface_Type, &self))
127     return NULL;
128   
129   iface = g_type_interface_peek(g_type_class_peek(pyg_type_from_object(cls)),
130                                 TEST_TYPE_INTERFACE);
131   if (iface->iface_method)
132     iface->iface_method(TEST_INTERFACE(self->obj));
133   else {
134     PyErr_SetString(PyExc_NotImplementedError,
135                     "interface method TestInterface.iface_method not implemented");
136     return NULL;
137   }
138   Py_INCREF(Py_None);
139   return Py_None;
140 }
141
142 PYGLIB_DEFINE_TYPE("testhelper.Unknown", PyTestUnknown_Type, PyGObject);
143
144 static void
145 _wrap_TestInterface__proxy_do_iface_method(TestInterface *self)
146 {
147     PyGILState_STATE __py_state;
148     PyObject *py_self;
149     PyObject *py_retval;
150     PyObject *py_args;
151     PyObject *py_method;
152     
153     __py_state = pyg_gil_state_ensure();
154     py_self = pygobject_new((GObject *) self);
155     if (!py_self) {
156         if (PyErr_Occurred())
157             PyErr_Print();
158         pyg_gil_state_release(__py_state);
159         return;
160     }
161     py_args = PyTuple_New(0);
162     py_method = PyObject_GetAttrString(py_self, "do_iface_method");
163     if (!py_method) {
164         if (PyErr_Occurred())
165             PyErr_Print();
166         Py_DECREF(py_args);
167         Py_DECREF(py_self);
168         pyg_gil_state_release(__py_state);
169         return;
170     }
171     py_retval = PyObject_CallObject(py_method, py_args);
172     if (!py_retval) {
173         if (PyErr_Occurred())
174             PyErr_Print();
175         Py_DECREF(py_method);
176         Py_DECREF(py_args);
177         Py_DECREF(py_self);
178         pyg_gil_state_release(__py_state);
179         return;
180     }
181     if (py_retval != Py_None) {
182         if (PyErr_Occurred())
183             PyErr_Print();
184         PyErr_SetString(PyExc_TypeError, "retval should be None");
185         Py_DECREF(py_retval);
186         Py_DECREF(py_method);
187         Py_DECREF(py_args);
188         Py_DECREF(py_self);
189         pyg_gil_state_release(__py_state);
190         return;
191     }
192     
193     Py_DECREF(py_retval);
194     Py_DECREF(py_method);
195     Py_DECREF(py_args);
196     Py_DECREF(py_self);
197     pyg_gil_state_release(__py_state);
198 }
199
200 static void
201 __TestInterface__interface_init(TestInterfaceIface *iface,
202                                 PyTypeObject *pytype)
203 {
204     TestInterfaceIface *parent_iface = g_type_interface_peek_parent(iface);
205     PyObject *py_method;
206
207     py_method = pytype ? PyObject_GetAttrString((PyObject *) pytype,
208                                                 "do_iface_method") : NULL;
209
210     if (py_method && !PyObject_TypeCheck(py_method, &PyCFunction_Type)) {
211         iface->iface_method = _wrap_TestInterface__proxy_do_iface_method;
212     } else {
213         PyErr_Clear();
214         if (parent_iface) {
215             iface->iface_method = parent_iface->iface_method;
216         }
217         Py_XDECREF(py_method);
218     }
219 }
220
221 static const GInterfaceInfo __TestInterface__iinfo = {
222     (GInterfaceInitFunc) __TestInterface__interface_init,
223     NULL,
224     NULL
225 };
226
227 /* TestFloating */
228 PYGLIB_DEFINE_TYPE("testhelper.Floating", PyTestFloating_Type, PyGObject);
229
230 /* TestOwnedByLibrary */
231 PYGLIB_DEFINE_TYPE("testhelper.OwnedByLibrary", PyTestOwnedByLibrary_Type, PyGObject);
232
233 static PyObject *
234 _wrap_test_owned_by_library_release (PyGObject *self)
235 {
236     test_owned_by_library_release (TEST_OWNED_BY_LIBRARY (self->obj));
237     return Py_None;
238 }
239
240 static const PyMethodDef _PyTestOwnedByLibrary_methods[] = {
241     { "release", (PyCFunction)_wrap_test_owned_by_library_release, METH_NOARGS, NULL },
242     { NULL, NULL, 0, NULL }
243 };
244
245 /* TestFloatingAndSunk */
246 PYGLIB_DEFINE_TYPE("testhelper.FloatingAndSunk", PyTestFloatingAndSunk_Type, PyGObject);
247
248 static PyObject *
249 _wrap_test_floating_and_sunk_release (PyGObject *self)
250 {
251     test_floating_and_sunk_release (TEST_FLOATING_AND_SUNK (self->obj));
252     return Py_None;
253 }
254
255 static const PyMethodDef _PyTestFloatingAndSunk_methods[] = {
256     { "release", (PyCFunction)_wrap_test_floating_and_sunk_release, METH_NOARGS, NULL },
257     { NULL, NULL, 0, NULL }
258 };
259
260
261 #include <string.h>
262 #include <glib-object.h>
263
264 static void
265 test1_callback (GObject *object, char *data)
266 {
267   g_return_if_fail (G_IS_OBJECT (object));
268   g_return_if_fail (!strcmp (data, "user-data"));
269 }
270
271 static void
272 test1_callback_swapped (char *data, GObject *object)
273 {
274   g_return_if_fail (G_IS_OBJECT (object));
275   g_return_if_fail (!strcmp (data, "user-data"));
276 }
277
278 static void
279 test2_callback (GObject *object, char *string)
280 {
281   g_return_if_fail (G_IS_OBJECT (object));
282   g_return_if_fail (!strcmp (string, "string"));
283 }
284
285 static int
286 test3_callback (GObject *object, double d)
287 {
288   g_return_val_if_fail (G_IS_OBJECT (object), -1);
289   g_return_val_if_fail (d == 42.0, -1);
290
291   return 20;
292 }
293
294 static void
295 test4_callback (GObject *object,
296                 gboolean b, long l, float f, double d, guint uint, gulong ulong,
297                 gpointer user_data)
298 {
299   g_return_if_fail (b == TRUE);
300   g_return_if_fail (l == 10L);
301   g_return_if_fail (f <= 3.14001 && f >= 3.13999);
302   g_return_if_fail (d <= 1.78001 && d >= 1.77999);
303   g_return_if_fail (uint == 20);
304   g_return_if_fail (ulong == 30L);
305 }
306
307 static float
308 test_float_callback (GObject *object, float f)
309 {
310   g_return_val_if_fail (G_IS_OBJECT (object), -1);
311   g_return_val_if_fail (f <= 1.234001 && f >= 1.123999, -1);
312
313   return f;
314 }
315
316 static double
317 test_double_callback (GObject *object, double d)
318 {
319   g_return_val_if_fail (G_IS_OBJECT (object), -1);
320   g_return_val_if_fail (d <= 1.234001 && d >= 1.123999, -1);
321
322   return d;
323 }
324
325 static gint64 *
326 test_int64_callback (GObject *object, gint64 i)
327 {
328   g_return_val_if_fail (G_IS_OBJECT (object), -1);
329
330   if (i == G_MAXINT64)
331       return i-1;
332   return i;
333 }
334
335 static char *
336 test_string_callback (GObject *object, char *s)
337 {
338   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
339   g_return_val_if_fail (!strcmp(s, "str"), NULL);
340
341   return g_strdup (s);
342 }
343
344 static GObject *
345 test_object_callback (GObject *object, GObject *o)
346 {
347   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
348
349   return o;
350 }
351
352 static GParamSpec *
353 test_paramspec_callback (GObject *object)
354 {
355   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
356
357   return g_param_spec_boolean ("test-param", "test", "test boolean", TRUE, G_PARAM_READABLE);
358 }
359
360 static GValue *
361 test_gvalue_callback (GObject *object, const GValue *v)
362 {
363   GValue *ret = g_malloc0 (sizeof (GValue));
364
365   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
366   g_return_val_if_fail (G_IS_VALUE (v), NULL);
367
368   g_value_init (ret, G_VALUE_TYPE (v));
369   g_value_copy (v, ret);
370   return ret;
371 }
372
373 static GValue *
374 test_gvalue_ret_callback (GObject *object, GType type)
375 {
376   GValue *ret = g_malloc0 (sizeof (GValue));
377
378   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
379
380   g_value_init (ret, type);
381
382   switch (type) {
383     case G_TYPE_INT:
384       g_value_set_int(ret, G_MAXINT);
385       break;
386     case G_TYPE_INT64:
387       g_value_set_int64(ret, G_MAXINT64);
388       break;
389     case G_TYPE_UINT:
390       g_value_set_uint(ret, G_MAXUINT);
391       break;
392     case G_TYPE_UINT64:
393       g_value_set_uint64(ret, G_MAXUINT64);
394       break;
395     case G_TYPE_STRING:
396       g_value_set_string(ret, "hello");
397       break;
398     default:
399       g_critical ("test_gvalue_ret_callback() does not support type %s", g_type_name (type));
400   }
401
402   return ret;
403 }
404
405 static void
406 connectcallbacks (GObject *object)
407 {
408
409   gchar *data = "user-data";
410   
411   g_signal_connect (G_OBJECT (object),
412                     "test1",
413                     G_CALLBACK (test1_callback), 
414                     data);
415   g_signal_connect_swapped (G_OBJECT (object),
416                     "test1",
417                     G_CALLBACK (test1_callback_swapped), 
418                     data);
419   g_signal_connect (G_OBJECT (object),
420                     "test2",
421                     G_CALLBACK (test2_callback), 
422                     NULL);
423   g_signal_connect (G_OBJECT (object),
424                     "test3",
425                     G_CALLBACK (test3_callback), 
426                     NULL);
427   g_signal_connect (G_OBJECT (object),
428                     "test4",
429                     G_CALLBACK (test4_callback), 
430                     NULL);
431   g_signal_connect (G_OBJECT (object),
432                     "test_float",
433                     G_CALLBACK (test_float_callback), 
434                     NULL);
435   g_signal_connect (G_OBJECT (object),
436                     "test_double",
437                     G_CALLBACK (test_double_callback), 
438                     NULL);
439   g_signal_connect (G_OBJECT (object),
440                     "test_int64",
441                     G_CALLBACK (test_int64_callback), 
442                     NULL);
443   g_signal_connect (G_OBJECT (object),
444                     "test_string",
445                     G_CALLBACK (test_string_callback), 
446                     NULL);
447   g_signal_connect (G_OBJECT (object),
448                     "test_object",
449                     G_CALLBACK (test_object_callback), 
450                     NULL);
451   g_signal_connect (G_OBJECT (object),
452                     "test_paramspec",
453                     G_CALLBACK (test_paramspec_callback), 
454                     NULL);
455   g_signal_connect (G_OBJECT (object),
456                     "test_gvalue",
457                     G_CALLBACK (test_gvalue_callback), 
458                     NULL);
459   g_signal_connect (G_OBJECT (object),
460                     "test_gvalue_ret",
461                     G_CALLBACK (test_gvalue_ret_callback), 
462                     NULL);
463 }
464
465 static PyObject *
466 _wrap_connectcallbacks(PyObject * self, PyObject *args)
467 {
468     PyGObject *obj;
469
470     if (!PyArg_ParseTuple(args, "O", &obj))
471       return NULL;
472
473     connectcallbacks (G_OBJECT (obj->obj));
474
475     Py_INCREF(Py_None);
476     return Py_None;
477 }
478
479 static PyObject *
480 _wrap_test_value(PyObject *self, PyObject *args)
481 {
482   GValue tvalue = {0,}, *value = &tvalue;
483   PyObject *obj;
484
485   if (!PyArg_ParseTuple(args, "O", &obj))
486     return NULL;
487
488   g_value_init(value, G_TYPE_VALUE);
489   if (pyg_value_from_pyobject(value, obj)) {
490     PyErr_SetString(PyExc_TypeError, "Could not convert to GValue");
491     return NULL;
492   }
493   
494   return pyg_value_as_pyobject(value, FALSE);
495 }
496
497 static PyObject *
498 _wrap_test_value_array(PyObject *self, PyObject *args)
499 {
500   GValue tvalue = {0,}, *value = &tvalue;
501   PyObject *obj;
502
503   if (!PyArg_ParseTuple(args, "O", &obj))
504     return NULL;
505
506   g_value_init(value, G_TYPE_VALUE_ARRAY);
507   if (pyg_value_from_pyobject(value, obj)) {
508     PyErr_SetString(PyExc_TypeError, "Could not convert to GValueArray");
509     return NULL;
510   }
511   
512   return pyg_value_as_pyobject(value, FALSE);
513 }
514
515 static PyObject *
516 _wrap_test_gerror_exception(PyObject *self, PyObject *args)
517 {
518     PyObject *py_method;
519     PyObject *py_args;
520     PyObject *py_ret;
521     GError *err = NULL;
522
523     if (!PyArg_ParseTuple(args, "O", &py_method))
524         return NULL;
525
526     py_args = PyTuple_New(0);
527     py_ret = PyObject_CallObject(py_method, py_args);
528     if (pyg_gerror_exception_check(&err)) {
529         pyg_error_check(&err);
530         return NULL;
531     }       
532
533     Py_DECREF(py_method);
534     Py_DECREF(py_args);
535     Py_DECREF(py_ret);
536
537     Py_INCREF(Py_None);
538     return Py_None;
539 }
540
541 static PyObject *
542 _wrap_test_owned_by_library_get_instance_list (PyObject *self)
543 {
544     PyObject *py_list, *py_obj;
545     GSList *list, *tmp;
546
547     list = test_owned_by_library_get_instance_list ();
548
549     if ((py_list = PyList_New (0)) == NULL) {
550         return NULL;
551     }
552     for (tmp = list; tmp != NULL; tmp = tmp->next) {
553         py_obj = pygobject_new (G_OBJECT (tmp->data));
554         if (py_obj == NULL) {
555             Py_DECREF (py_list);
556             return NULL;
557         }
558         PyList_Append (py_list, py_obj);
559         Py_DECREF (py_obj);
560     }
561     return py_list;
562 }
563
564 static PyObject *
565 _wrap_test_floating_and_sunk_get_instance_list (PyObject *self)
566 {
567     PyObject *py_list, *py_obj;
568     GSList *list, *tmp;
569
570     list = test_floating_and_sunk_get_instance_list ();
571
572     if ((py_list = PyList_New (0)) == NULL) {
573        return NULL;
574     }
575     for (tmp = list; tmp != NULL; tmp = tmp->next) {
576        py_obj = pygobject_new (G_OBJECT (tmp->data));
577        if (py_obj == NULL) {
578            Py_DECREF (py_list);
579            return NULL;
580        }
581        PyList_Append (py_list, py_obj);
582        Py_DECREF (py_obj);
583     }
584     return py_list;
585 }
586
587 static PyMethodDef testhelper_functions[] = {
588     { "get_test_thread", (PyCFunction)_wrap_get_test_thread, METH_NOARGS },
589     { "get_unknown", (PyCFunction)_wrap_get_unknown, METH_NOARGS },
590     { "create_test_type", (PyCFunction)_wrap_create_test_type, METH_NOARGS },
591     { "test_g_object_new", (PyCFunction)_wrap_test_g_object_new, METH_NOARGS },
592     { "connectcallbacks", (PyCFunction)_wrap_connectcallbacks, METH_VARARGS },
593     { "test_value", (PyCFunction)_wrap_test_value, METH_VARARGS },      
594     { "test_value_array", (PyCFunction)_wrap_test_value_array, METH_VARARGS },
595     { "test_gerror_exception", (PyCFunction)_wrap_test_gerror_exception, METH_VARARGS },
596     { "owned_by_library_get_instance_list", (PyCFunction)_wrap_test_owned_by_library_get_instance_list, METH_NOARGS },
597     { "floating_and_sunk_get_instance_list", (PyCFunction)_wrap_test_floating_and_sunk_get_instance_list, METH_NOARGS },
598     { NULL, NULL }
599 };
600
601 PYGLIB_MODULE_START(testhelper, "testhelper")
602 {
603   PyObject *m, *d;
604   
605   g_thread_init(NULL);
606   pygobject_init(-1, -1, -1);
607
608   d = PyModule_GetDict(module);
609
610   if ((m = PyImport_ImportModule("gi._gobject")) != NULL) {
611     PyObject *moddict = PyModule_GetDict(m);
612     
613     _PyGObject_Type = (PyTypeObject *)PyDict_GetItemString(moddict, "GObject");
614     if (_PyGObject_Type == NULL) {
615       PyErr_SetString(PyExc_ImportError,
616                       "cannot import name GObject from gobject");
617       return PYGLIB_MODULE_ERROR_RETURN;
618     }
619   } else {
620     PyErr_SetString(PyExc_ImportError,
621                     "could not import gobject");
622     return PYGLIB_MODULE_ERROR_RETURN;
623   }
624
625   /* TestInterface */
626   PyTestInterface_Type.tp_methods = (struct PyMethodDef*)_PyTestInterface_methods;
627   PyTestInterface_Type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE);  
628   pyg_register_interface(d, "Interface", TEST_TYPE_INTERFACE,
629                          &PyTestInterface_Type);
630   pyg_register_interface_info(TEST_TYPE_INTERFACE, &__TestInterface__iinfo);
631
632
633   /* TestUnknown */
634   PyTestUnknown_Type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE);
635   PyTestUnknown_Type.tp_weaklistoffset = offsetof(PyGObject, weakreflist);
636   PyTestUnknown_Type.tp_dictoffset = offsetof(PyGObject, inst_dict);
637   pygobject_register_class(d, "Unknown", TEST_TYPE_UNKNOWN,
638                            &PyTestUnknown_Type,
639                            Py_BuildValue("(O)",
640                            &PyGObject_Type,
641                            &PyTestInterface_Type));
642
643   /* TestFloating */
644   PyTestFloating_Type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE);
645   PyTestFloating_Type.tp_weaklistoffset = offsetof(PyGObject, weakreflist);
646   PyTestFloating_Type.tp_dictoffset = offsetof(PyGObject, inst_dict);
647   pygobject_register_class(d, "Floating", TEST_TYPE_FLOATING,
648                            &PyTestFloating_Type,
649                            Py_BuildValue("(O)",
650                            &PyGObject_Type));
651
652   /* TestOwnedByLibrary */
653   PyTestOwnedByLibrary_Type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE);
654   PyTestOwnedByLibrary_Type.tp_methods = (struct PyMethodDef*)_PyTestOwnedByLibrary_methods;
655   PyTestOwnedByLibrary_Type.tp_weaklistoffset = offsetof(PyGObject, weakreflist);
656   PyTestOwnedByLibrary_Type.tp_dictoffset = offsetof(PyGObject, inst_dict);
657   pygobject_register_class(d, "OwnedByLibrary", TEST_TYPE_OWNED_BY_LIBRARY,
658                            &PyTestOwnedByLibrary_Type,
659                            Py_BuildValue("(O)",
660                            &PyGObject_Type));
661
662   /* TestFloatingAndSunk */
663   PyTestFloatingAndSunk_Type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE);
664   PyTestFloatingAndSunk_Type.tp_methods = (struct PyMethodDef*)_PyTestFloatingAndSunk_methods;
665   PyTestFloatingAndSunk_Type.tp_weaklistoffset = offsetof(PyGObject, weakreflist);
666   PyTestFloatingAndSunk_Type.tp_dictoffset = offsetof(PyGObject, inst_dict);
667   pygobject_register_class(d, "FloatingAndSunk", TEST_TYPE_FLOATING_AND_SUNK,
668                            &PyTestFloatingAndSunk_Type,
669                            Py_BuildValue("(O)",
670                            &PyGObject_Type));
671 }
672 PYGLIB_MODULE_END
673