8db9b1725be27ba0cd8d8b2c0f11be96ac7c5154
[platform/upstream/python-gobject.git] / gi / pyglib.c
1 /* -*- Mode: C; c-set-style: python; c-basic-offset: 4  -*-
2  * pyglib - Python bindings for GLib toolkit.
3  * Copyright (C) 1998-2003  James Henstridge
4  *               2004-2008  Johan Dahlin
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #  include <config.h>
22 #endif
23
24 #include <Python.h>
25 #include <pythread.h>
26 #include "pyglib.h"
27 #include "pyglib-private.h"
28 #include "pygoptioncontext.h"
29 #include "pygoptiongroup.h"
30
31
32 /**
33  * pyg_option_group_transfer_group:
34  * @group: a GOptionGroup wrapper
35  *
36  * This is used to transfer the GOptionGroup to a GOptionContext. After this
37  * is called, the calle must handle the release of the GOptionGroup.
38  *
39  * When #NULL is returned, the GOptionGroup was already transfered.
40  *
41  * Returns: Either #NULL or the wrapped GOptionGroup.
42  */
43 GOptionGroup *
44 pyglib_option_group_transfer_group(PyObject *obj)
45 {
46     PyGOptionGroup *self = (PyGOptionGroup*)obj;
47     
48     if (self->is_in_context)
49         return NULL;
50
51     self->is_in_context = TRUE;
52     
53     /* Here we increase the reference count of the PyGOptionGroup, because now
54      * the GOptionContext holds an reference to us (it is the userdata passed
55      * to g_option_group_new().
56      *
57      * The GOptionGroup is freed with the GOptionContext.
58      *
59      * We set it here because if we would do this in the init method we would
60      * hold two references and the PyGOptionGroup would never be freed.
61      */
62     Py_INCREF(self);
63     
64     return self->group;
65 }
66
67
68 /****** Private *****/
69
70 /**
71  * _pyglib_destroy_notify:
72  * @user_data: a PyObject pointer.
73  *
74  * A function that can be used as a GDestroyNotify callback that will
75  * call Py_DECREF on the data.
76  */
77 void
78 _pyglib_destroy_notify(gpointer user_data)
79 {
80     PyObject *obj = (PyObject *)user_data;
81     PyGILState_STATE state;
82
83     state = pyglib_gil_state_ensure();
84     Py_DECREF(obj);
85     pyglib_gil_state_release(state);
86 }
87
88 gboolean
89 _pyglib_handler_marshal(gpointer user_data)
90 {
91     PyObject *tuple, *ret;
92     gboolean res;
93     PyGILState_STATE state;
94
95     g_return_val_if_fail(user_data != NULL, FALSE);
96
97     state = pyglib_gil_state_ensure();
98
99     tuple = (PyObject *)user_data;
100     ret = PyObject_CallObject(PyTuple_GetItem(tuple, 0),
101                               PyTuple_GetItem(tuple, 1));
102     if (!ret) {
103         PyErr_Print();
104         res = FALSE;
105     } else {
106         res = PyObject_IsTrue(ret);
107         Py_DECREF(ret);
108     }
109     
110     pyglib_gil_state_release(state);
111
112     return res;
113 }
114
115 PyObject*
116 _pyglib_generic_ptr_richcompare(void* a, void *b, int op)
117 {
118     PyObject *res;
119
120     switch (op) {
121
122       case Py_EQ:
123         res = (a == b) ? Py_True : Py_False;
124         break;
125
126       case Py_NE:
127         res = (a != b) ? Py_True : Py_False;
128         break;
129
130       case Py_LT:
131         res = (a < b) ? Py_True : Py_False;
132         break;
133
134       case Py_LE:
135         res = (a <= b) ? Py_True : Py_False;
136         break;
137
138       case Py_GT:
139         res = (a > b) ? Py_True : Py_False;
140         break;
141
142       case Py_GE:
143         res = (a >= b) ? Py_True : Py_False;
144         break;
145
146       default:
147         res = Py_NotImplemented;
148         break;
149     }
150
151     Py_INCREF(res);
152     return res;
153 }
154
155 PyObject*
156 _pyglib_generic_long_richcompare(long a, long b, int op)
157 {
158     PyObject *res;
159
160     switch (op) {
161
162       case Py_EQ:
163         res = (a == b) ? Py_True : Py_False;
164         Py_INCREF(res);
165         break;
166
167       case Py_NE:
168         res = (a != b) ? Py_True : Py_False;
169         Py_INCREF(res);
170         break;
171
172
173       case Py_LT:
174         res = (a < b) ? Py_True : Py_False;
175         Py_INCREF(res);
176         break;
177
178       case Py_LE:
179         res = (a <= b) ? Py_True : Py_False;
180         Py_INCREF(res);
181         break;
182
183       case Py_GT:
184         res = (a > b) ? Py_True : Py_False;
185         Py_INCREF(res);
186         break;
187
188       case Py_GE:
189         res = (a >= b) ? Py_True : Py_False;
190         Py_INCREF(res);
191         break;
192
193       default:
194         res = Py_NotImplemented;
195         Py_INCREF(res);
196         break;
197     }
198
199     return res;
200 }
201