--- /dev/null
+From: Simon McVittie <smcv@debian.org>
+Date: Mon, 30 Aug 2021 10:13:33 +0100
+Subject: compose: Generate endian-dependent compact Compose data
+
+The GtkComposeTable cache is always in big-endian format and is
+byteswapped on load for the more common little-endian CPUs, but
+init_builtin_table() in GtkIMContextSimple can't byteswap the built-in
+data without copying it, which is undesirable. Pregenerate both big-
+and little-endian compose data, and compile the correct flavour into
+each build of GTK. This fixes failure of the composetable test when
+building for a big-endian architecture such as s390x and (traditional,
+big-endian) powerpc.
+
+Resolves: https://gitlab.gnome.org/GNOME/gtk/-/issues/4217
+Signed-off-by: Simon McVittie <smcv@debian.org>
+Forwarded: https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/3902
+---
+ gtk/compose/compose-parse.c | 30 +++++++++++++++++++++++++-----
+ gtk/gen-gtk-gresources-xml.py | 9 +++++----
+ gtk/meson.build | 1 +
+ 3 files changed, 31 insertions(+), 9 deletions(-)
+
+diff --git a/gtk/compose/compose-parse.c b/gtk/compose/compose-parse.c
+index 7a3d511..a1ec09d 100644
+--- a/gtk/compose/compose-parse.c
++++ b/gtk/compose/compose-parse.c
+@@ -7,7 +7,7 @@
+ * character data, and definitions for the builtin compose table of GTK.
+ * Run it like this:
+ *
+- * compose-parse Compose sequences chars gtkcomposedata.h
++ * compose-parse Compose sequences-little-endian sequences-big-endian chars gtkcomposedata.h
+ *
+ * The GTK build expects the output files to be in the source tree, in
+ * the gtk/compose directory.
+@@ -15,15 +15,19 @@
+ int
+ main (int argc, char *argv[])
+ {
++ const guint16 *sequences_le;
++ const guint16 *sequences_be;
++ guint16 *other_sequences;
+ GtkComposeTable *table;
+ GError *error = NULL;
+ GString *str;
++ gsize i;
+
+ setlocale (LC_ALL, "");
+
+ if (argc < 5)
+ {
+- g_print ("Usage: compose-parse INPUT OUTPUT1 OUTPUT2 OUTPUT3\n");
++ g_print ("Usage: compose-parse INPUT SEQUENCES-LE SEQUENCES-BE CHARS HEADER\n");
+ exit (1);
+ }
+
+@@ -31,11 +35,26 @@ main (int argc, char *argv[])
+ if (!table)
+ g_error ("Failed to parse %s", argv[1]);
+
++#if G_BYTE_ORDER == G_BIG_ENDIAN
++ sequences_le = other_sequences = g_new0 (guint16, table->data_size);
++ sequences_be = (const guint16 *) table->data;
++#else
++ sequences_le = (const guint16 *) table->data;
++ sequences_be = other_sequences = g_new0 (guint16, table->data_size);
++#endif
++
++ for (i = 0; i < table->data_size; i++)
++ other_sequences[i] = GUINT16_SWAP_LE_BE (table->data[i]);
++
++ /* data_size is the size in guint16 */
++ if (!g_file_set_contents (argv[2], (char *) sequences_le, 2 * table->data_size, &error))
++ g_error ("%s", error->message);
++
+ /* data_size is the size in guint16 */
+- if (!g_file_set_contents (argv[2], (char *)table->data, 2 * table->data_size, &error))
++ if (!g_file_set_contents (argv[3], (char *) sequences_be, 2 * table->data_size, &error))
+ g_error ("%s", error->message);
+
+- if (!g_file_set_contents (argv[3], table->char_data, table->n_chars + 1, &error))
++ if (!g_file_set_contents (argv[4], table->char_data, table->n_chars + 1, &error))
+ g_error ("%s", error->message);
+
+ str = g_string_new ("");
+@@ -55,10 +74,11 @@ main (int argc, char *argv[])
+ "\n"
+ "#endif\n");
+
+- if (!g_file_set_contents (argv[4], str->str, str->len, &error))
++ if (!g_file_set_contents (argv[5], str->str, str->len, &error))
+ g_error ("%s", error->message);
+
+ g_string_free (str, TRUE);
++ g_free (other_sequences);
+
+ return 0;
+ }
+diff --git a/gtk/gen-gtk-gresources-xml.py b/gtk/gen-gtk-gresources-xml.py
+index 8a8da42..81c0663 100644
+--- a/gtk/gen-gtk-gresources-xml.py
++++ b/gtk/gen-gtk-gresources-xml.py
+@@ -21,6 +21,7 @@ def replace_if_changed(new, old):
+ os.remove(new)
+
+ srcdir = sys.argv[1]
++endian = sys.argv[2]
+
+ xml = '''<?xml version='1.0' encoding='UTF-8'?>
+ <gresources>
+@@ -84,13 +85,13 @@ for f in get_files('inspector', '.ui'):
+ xml += '''
+ <file>inspector/inspector.css</file>
+ <file>emoji/en.data</file>
+- <file>compose/sequences</file>
++ <file alias="compose/sequences">compose/sequences-{0}-endian</file>
+ <file>compose/chars</file>
+ </gresource>
+-</gresources>'''
++</gresources>'''.format(endian)
+
+-if len(sys.argv) > 2:
+- outfile = sys.argv[2]
++if len(sys.argv) > 3:
++ outfile = sys.argv[3]
+ tmpfile = outfile + '~'
+ with open(tmpfile, 'w') as f:
+ f.write(xml)
+diff --git a/gtk/meson.build b/gtk/meson.build
+index 18fbe6a..b123e06 100644
+--- a/gtk/meson.build
++++ b/gtk/meson.build
+@@ -835,6 +835,7 @@ gtk_gresources_xml = configure_file(output: 'gtk.gresources.xml',
+ command: [
+ gen_gtk_gresources_xml,
+ meson.current_source_dir(),
++ host_machine.endian(),
+ '@OUTPUT@'
+ ],
+ )