[pygobject] Add special case for Gdk.Atom array entries from Python



commit 8ee21619b3cfc179cf114813478470d9aa3f6fb8
Author: Martin Pitt <martinpitt gnome org>
Date:   Mon Apr 23 12:33:09 2012 +0200

    Add special case for Gdk.Atom array entries from Python
    
    Gdk.Atom pretends to be a struct pointer, but is really just an int wrapped
    into a pointer. So we must not dereference it directly, nor free it, but
    instead just copy the pointer value.
    
    Also add a few other test cases for "single Atom return", "single Atom argument
    in", and Atom GList return", which already work fine.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=661709

 gi/pygi-marshal-from-py.c |   18 ++++++++++++++----
 tests/Makefile.am         |    1 +
 tests/test_atoms.py       |   41 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+), 4 deletions(-)
---
diff --git a/gi/pygi-marshal-from-py.c b/gi/pygi-marshal-from-py.c
index c789d1d..adb7152 100644
--- a/gi/pygi-marshal-from-py.c
+++ b/gi/pygi-marshal-from-py.c
@@ -855,10 +855,20 @@ _pygi_marshal_from_py_array (PyGIInvokeState   *state,
                             item_arg_cache->from_py_cleanup = NULL;
                         }
                     } else if (!is_boxed) {
-                        memcpy (array_->data + (i * item_size), item.v_pointer, item_size);
-
-                        if (from_py_cleanup)
-                            from_py_cleanup (state, item_arg_cache, item.v_pointer, TRUE);
+                        /* HACK: Gdk.Atom is merely an integer wrapped in a pointer,
+                         * so we must not dereference it; just copy the pointer
+                         * value, and don't attempt to free it. TODO: find out
+                         * if there are other data types with similar behaviour
+                         * and generalize. */
+                        if (g_strcmp0 (item_iface_cache->type_name, "Gdk.Atom") == 0) {
+                            g_assert (item_size == sizeof (item.v_pointer));
+                            memcpy (array_->data + (i * item_size), &item.v_pointer, item_size);
+                        } else {
+                            memcpy (array_->data + (i * item_size), item.v_pointer, item_size);
+
+                            if (from_py_cleanup)
+                                from_py_cleanup (state, item_arg_cache, item.v_pointer, TRUE);
+                        }
                     } else {
                         g_array_insert_val (array_, i, item);
                     }
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 9ed6179..0036ec8 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -89,6 +89,7 @@ EXTRA_DIST = \
 	test_gi.py \
 	test_gdbus.py \
 	test_overrides.py \
+	test_atoms.py \
 	test_pygtkcompat.py
 
 clean-local:
diff --git a/tests/test_atoms.py b/tests/test_atoms.py
new file mode 100644
index 0000000..851368f
--- /dev/null
+++ b/tests/test_atoms.py
@@ -0,0 +1,41 @@
+import unittest
+
+from gi.repository import Gdk, Gtk
+
+
+class TestGdkAtom(unittest.TestCase):
+    def test_create(self):
+        atom = Gdk.Atom.intern('my_string', False)
+        self.assertEqual(atom.name(), 'my_string')
+
+    def test_in_single(self):
+        a_selection = Gdk.Atom.intern('test_clipboard', False)
+        clipboard = Gtk.Clipboard.get(a_selection)
+        clipboard.set_text('hello', 5)
+
+        # needs a Gdk.Atom, not a string
+        self.assertRaises(TypeError, Gtk.Clipboard.get, 'CLIPBOARD')
+
+    def test_in_array(self):
+        a_plain = Gdk.Atom.intern('text/plain', False)
+        a_html = Gdk.Atom.intern('text/html', False)
+        a_jpeg = Gdk.Atom.intern('image/jpeg', False)
+
+        self.assertFalse(Gtk.targets_include_text([]))
+        self.assertTrue(Gtk.targets_include_text([a_plain, a_html]))
+        self.assertFalse(Gtk.targets_include_text([a_jpeg]))
+        self.assertTrue(Gtk.targets_include_text([a_jpeg, a_plain]))
+
+        self.assertFalse(Gtk.targets_include_image([], False))
+        self.assertFalse(Gtk.targets_include_image([a_plain, a_html], False))
+        self.assertTrue(Gtk.targets_include_image([a_jpeg], False))
+        self.assertTrue(Gtk.targets_include_image([a_jpeg, a_plain], False))
+
+    def test_out_glist(self):
+        display = Gdk.Display.get_default()
+        dm = display.get_device_manager()
+        device = dm.get_client_pointer()
+        axes = device.list_axes()
+        axes_names = [atom.name() for atom in axes]
+        self.assertNotEqual(axes_names, [])
+        self.assertTrue('Rel X' in axes_names)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]