+typedef struct {
+ unsigned int depth, red_mask, green_mask, blue_mask; /* when this... */
+ GLint type, format; /* ...use this. */
+} conversion_table;
+
+/* Abbreviate these so that the table entries all fit on one line...
+ */
+#define BYTE GL_UNSIGNED_BYTE
+#define BYTE_2_3_3_REV GL_UNSIGNED_BYTE_2_3_3_REV
+#define BYTE_3_3_2 GL_UNSIGNED_BYTE_3_3_2
+#define INT_10_10_10_2 GL_UNSIGNED_INT_10_10_10_2
+#define INT_2_10_10_10_REV GL_UNSIGNED_INT_2_10_10_10_REV
+#define INT_8_8_8_8 GL_UNSIGNED_INT_8_8_8_8
+#define INT_8_8_8_8_REV GL_UNSIGNED_INT_8_8_8_8_REV
+#define SHORT_1_5_5_5_REV GL_UNSIGNED_SHORT_1_5_5_5_REV
+#define SHORT_4_4_4_4 GL_UNSIGNED_SHORT_4_4_4_4
+#define SHORT_4_4_4_4_REV GL_UNSIGNED_SHORT_4_4_4_4_REV
+#define SHORT_5_5_5_1 GL_UNSIGNED_SHORT_5_5_5_1
+#define SHORT_5_6_5 GL_UNSIGNED_SHORT_5_6_5
+#define SHORT_5_6_5_REV GL_UNSIGNED_SHORT_5_6_5_REV
+
+static const conversion_table ctable[] = {
+ { 8, 0x000000E0, 0x0000001C, 0x00000003, BYTE_3_3_2, GL_RGB },
+ { 8, 0x00000007, 0x00000038, 0x000000C0, BYTE_2_3_3_REV, GL_RGB },
+ { 16, 0x0000F800, 0x000007E0, 0x0000001F, SHORT_5_6_5, GL_RGB },
+ { 16, 0x0000001F, 0x000007E0, 0x0000F800, SHORT_5_6_5_REV, GL_RGB },
+ { 16, 0x0000F000, 0x00000F00, 0x000000F0, SHORT_4_4_4_4, GL_RGBA },
+ { 16, 0x000000F0, 0x00000F00, 0x0000F000, SHORT_4_4_4_4, GL_BGRA },
+ { 16, 0x0000000F, 0x000000F0, 0x00000F00, SHORT_4_4_4_4, GL_ABGR_EXT },
+ { 16, 0x0000000F, 0x000000F0, 0x00000F00, SHORT_4_4_4_4_REV, GL_RGBA },
+ { 16, 0x00000F00, 0x000000F0, 0x0000000F, SHORT_4_4_4_4_REV, GL_BGRA },
+ { 16, 0x0000F800, 0x000007C0, 0x0000003E, SHORT_5_5_5_1, GL_RGBA },
+ { 16, 0x0000003E, 0x000007C0, 0x0000F800, SHORT_5_5_5_1, GL_BGRA },
+ { 16, 0x00000001, 0x0000003E, 0x000007C0, SHORT_5_5_5_1, GL_ABGR_EXT },
+ { 16, 0x0000001F, 0x000003E0, 0x00007C00, SHORT_1_5_5_5_REV, GL_RGBA },
+ { 16, 0x00007C00, 0x000003E0, 0x0000001F, SHORT_1_5_5_5_REV, GL_BGRA },
+ { 32, 0xFF000000, 0x00FF0000, 0x0000FF00, INT_8_8_8_8, GL_RGBA },
+ { 32, 0x0000FF00, 0x00FF0000, 0xFF000000, INT_8_8_8_8, GL_BGRA },
+ { 32, 0x000000FF, 0x0000FF00, 0x00FF0000, INT_8_8_8_8, GL_ABGR_EXT },
+ { 32, 0x000000FF, 0x0000FF00, 0x00FF0000, INT_8_8_8_8_REV, GL_RGBA },
+ { 32, 0x00FF0000, 0x0000FF00, 0x000000FF, INT_8_8_8_8_REV, GL_BGRA },
+ { 32, 0xFFC00000, 0x003FF000, 0x00000FFC, INT_10_10_10_2, GL_RGBA },
+ { 32, 0x00000FFC, 0x003FF000, 0xFFC00000, INT_10_10_10_2, GL_BGRA },
+ { 32, 0x00000003, 0x00000FFC, 0x003FF000, INT_10_10_10_2, GL_ABGR_EXT },
+ { 32, 0x000003FF, 0x000FFC00, 0x3FF00000, INT_2_10_10_10_REV, GL_RGBA },
+ { 32, 0x3FF00000, 0x000FFC00, 0x000003FF, INT_2_10_10_10_REV, GL_BGRA },
+ { 24, 0x000000FF, 0x0000FF00, 0x00FF0000, BYTE, GL_RGB },
+ { 24, 0x00FF0000, 0x0000FF00, 0x000000FF, BYTE, GL_BGR },
+};
+
+
+/* Given an XImage, returns the GL settings to use its data as a texture.
+ */
+static void
+gl_settings_for_ximage (XImage *image,
+ GLint *type_ret, GLint *format_ret, GLint *swap_ret)
+{
+ int i;
+ for (i = 0; i < countof(ctable); ++i)