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