1 /* -*- Mode: C; c-basic-offset: 4 -*-
2  * pygtk- Python bindings for the GTK toolkit.
3  * Copyright (C) 1998-2006  James Henstridge
4  *
5  *   gtkobject-support.c: some helper routines for the GTK module.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
20  * USA
21  */
22 
23 /* this module provides some of the base functionality of the GtkObject
24  * wrapper system */
25 
26 #include "pygtk-private.h"
27 
28 /* ------------------- object support */
29 
30 void
pygtk_custom_destroy_notify(gpointer user_data)31 pygtk_custom_destroy_notify(gpointer user_data)
32 {
33     PyGtkCustomNotify *cunote = user_data;
34     PyGILState_STATE state;
35 
36     g_return_if_fail(user_data);
37     state = pyg_gil_state_ensure();
38     Py_XDECREF(cunote->func);
39     Py_XDECREF(cunote->data);
40     pyg_gil_state_release(state);
41 
42     g_free(cunote);
43 }
44 
45 GdkAtom*
pygdk_atom_vector_from_sequence(PyObject * py_targets,gint * n_targets)46 pygdk_atom_vector_from_sequence(PyObject *py_targets, gint *n_targets)
47 {
48     gint i;
49     GdkAtom *targets;
50 
51     if (!(py_targets = PySequence_Fast(py_targets,
52                                        "targets must be a sequence")))
53         return NULL;
54 
55     *n_targets = PySequence_Fast_GET_SIZE(py_targets);
56     targets = g_new(GdkAtom, *n_targets);
57     for (i = 0; i < *n_targets; i++) {
58         PyObject *trgt = PySequence_Fast_GET_ITEM(py_targets, i);
59         targets[i] = pygdk_atom_from_pyobject(trgt);
60         if (PyErr_Occurred()) {
61             PyErr_Clear();
62             PyErr_SetString(PyExc_TypeError,
63                             "each 'targets' item must be a GdkAtom or string");
64             g_free(targets);
65             Py_DECREF(py_targets);
66             return NULL;
67         }
68     }
69     Py_DECREF(py_targets);
70     return targets;
71 }
72 
73 GtkTargetList *
pygtk_target_list_from_sequence(PyObject * py_targets)74 pygtk_target_list_from_sequence(PyObject *py_targets)
75 {
76     gint n_targets, i;
77     GtkTargetEntry *targets;
78     GtkTargetList *target_list;
79 
80     if (!(py_targets = PySequence_Fast(py_targets,
81                                        "target list must be a sequence")))
82 	return NULL;
83     n_targets = PySequence_Fast_GET_SIZE(py_targets);
84     targets = g_new(GtkTargetEntry, n_targets);
85     for (i = 0; i < n_targets; i++) {
86         PyObject *item = PySequence_Fast_GET_ITEM(py_targets, i);
87         if (!PyArg_ParseTuple(item, "sii", &targets[i].target,
88                               &targets[i].flags, &targets[i].info)) {
89             PyErr_Clear();
90             PyErr_SetString(PyExc_TypeError,
91                             "target list items should be of form (string,int,int)");
92             g_free(targets);
93 	    Py_DECREF(py_targets);
94             return NULL;
95         }
96     }
97     target_list = gtk_target_list_new(targets, n_targets);
98     g_free(targets);
99     Py_DECREF(py_targets);
100     return target_list;
101 }
102 
103 PyObject *
pygtk_target_list_to_list(GtkTargetList * targets)104 pygtk_target_list_to_list(GtkTargetList *targets)
105 {
106     GList *tmp;
107     PyObject *list = PyList_New(0);
108 
109     for (tmp = targets->list; tmp != NULL; tmp = tmp->next) {
110         GtkTargetPair *pair = tmp->data;
111         PyObject *item;
112         gchar * name = gdk_atom_name(pair->target);
113         item = Py_BuildValue("(Nii)",
114                              PyString_FromString(name),
115                              pair->flags, pair->info);
116         PyList_Append(list, item);
117         g_free(name);
118         Py_DECREF(item);
119     }
120     return list;
121 }
122 
123 void
pygtk_boxed_unref_shared(PyObject * boxed)124 pygtk_boxed_unref_shared(PyObject *boxed)
125 {
126     if (boxed == Py_None) {
127         Py_DECREF(Py_None);
128         return;
129     }
130     PyGBoxed *pyboxed;
131     g_return_if_fail(boxed != NULL && PyObject_TypeCheck(boxed, &PyGBoxed_Type));
132     pyboxed = (PyGBoxed *) boxed;
133     if (pyboxed->ob_refcnt != 1) {
134         if (!pyboxed->free_on_dealloc) {
135             pyboxed->boxed = g_boxed_copy(pyboxed->gtype,
136                                           pyboxed->boxed);
137             pyboxed->free_on_dealloc = TRUE;
138         }
139     }
140     Py_DECREF(boxed);
141 }
142 
143