commit d3079cd241329456462e5b9d1bce7ddcf658fe35
Author: bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Date:   Wed May 10 22:17:36 2006 +0000

    bgr32 pixel format support
    
    
    git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1912 c046a42c-6fe2-441c-8c8c-71466251a162

diff --git a/hw/vga.c b/hw/vga.c
index a712790..b4eacc3 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -808,6 +808,11 @@ static inline unsigned int rgb_to_pixel32(unsigned int r, unsigned int g, unsign
     return (r << 16) | (g << 8) | b;
 }
 
+static inline unsigned int rgb_to_pixel32bgr(unsigned int r, unsigned int g, unsigned b)
+{
+    return (b << 16) | (g << 8) | r;
+}
+
 #define DEPTH 8
 #include "vga_template.h"
 
@@ -820,6 +825,10 @@ static inline unsigned int rgb_to_pixel32(unsigned int r, unsigned int g, unsign
 #define DEPTH 32
 #include "vga_template.h"
 
+#define BGR_FORMAT
+#define DEPTH 32
+#include "vga_template.h"
+
 static unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g, unsigned b)
 {
     unsigned int col;
@@ -852,6 +861,13 @@ static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned
     return col;
 }
 
+static unsigned int rgb_to_pixel32bgr_dup(unsigned int r, unsigned int g, unsigned b)
+{
+    unsigned int col;
+    col = rgb_to_pixel32bgr(r, g, b);
+    return col;
+}
+
 /* return true if the palette was modified */
 static int update_palette16(VGAState *s)
 {
@@ -948,9 +964,11 @@ static int update_basic_params(VGAState *s)
     return full_update;
 }
 
-static inline int get_depth_index(int depth)
+#define NB_DEPTHS 5
+
+static inline int get_depth_index(DisplayState *s)
 {
-    switch(depth) {
+    switch(s->depth) {
     default:
     case 8:
         return 0;
@@ -959,29 +977,35 @@ static inline int get_depth_index(int depth)
     case 16:
         return 2;
     case 32:
-        return 3;
+        if (s->bgr)
+            return 4;
+        else
+            return 3;
     }
 }
 
-static vga_draw_glyph8_func *vga_draw_glyph8_table[4] = {
+static vga_draw_glyph8_func *vga_draw_glyph8_table[NB_DEPTHS] = {
     vga_draw_glyph8_8,
     vga_draw_glyph8_16,
     vga_draw_glyph8_16,
     vga_draw_glyph8_32,
+    vga_draw_glyph8_32,
 };
 
-static vga_draw_glyph8_func *vga_draw_glyph16_table[4] = {
+static vga_draw_glyph8_func *vga_draw_glyph16_table[NB_DEPTHS] = {
     vga_draw_glyph16_8,
     vga_draw_glyph16_16,
     vga_draw_glyph16_16,
     vga_draw_glyph16_32,
+    vga_draw_glyph16_32,
 };
 
-static vga_draw_glyph9_func *vga_draw_glyph9_table[4] = {
+static vga_draw_glyph9_func *vga_draw_glyph9_table[NB_DEPTHS] = {
     vga_draw_glyph9_8,
     vga_draw_glyph9_16,
     vga_draw_glyph9_16,
     vga_draw_glyph9_32,
+    vga_draw_glyph9_32,
 };
     
 static const uint8_t cursor_glyph[32 * 4] = {
@@ -1103,7 +1127,7 @@ static void vga_draw_text(VGAState *s, int full_update)
     }
     cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4;
     
-    depth_index = get_depth_index(s->ds->depth);
+    depth_index = get_depth_index(s->ds);
     if (cw == 16)
         vga_draw_glyph8 = vga_draw_glyph16_table[depth_index];
     else
@@ -1196,56 +1220,76 @@ enum {
     VGA_DRAW_LINE_NB,
 };
 
-static vga_draw_line_func *vga_draw_line_table[4 * VGA_DRAW_LINE_NB] = {
+static vga_draw_line_func *vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_NB] = {
     vga_draw_line2_8,
     vga_draw_line2_16,
     vga_draw_line2_16,
     vga_draw_line2_32,
+    vga_draw_line2_32,
 
     vga_draw_line2d2_8,
     vga_draw_line2d2_16,
     vga_draw_line2d2_16,
     vga_draw_line2d2_32,
+    vga_draw_line2d2_32,
 
     vga_draw_line4_8,
     vga_draw_line4_16,
     vga_draw_line4_16,
     vga_draw_line4_32,
+    vga_draw_line4_32,
 
     vga_draw_line4d2_8,
     vga_draw_line4d2_16,
     vga_draw_line4d2_16,
     vga_draw_line4d2_32,
+    vga_draw_line4d2_32,
 
     vga_draw_line8d2_8,
     vga_draw_line8d2_16,
     vga_draw_line8d2_16,
     vga_draw_line8d2_32,
+    vga_draw_line8d2_32,
 
     vga_draw_line8_8,
     vga_draw_line8_16,
     vga_draw_line8_16,
     vga_draw_line8_32,
+    vga_draw_line8_32,
 
     vga_draw_line15_8,
     vga_draw_line15_15,
     vga_draw_line15_16,
     vga_draw_line15_32,
+    vga_draw_line15_32bgr,
 
     vga_draw_line16_8,
     vga_draw_line16_15,
     vga_draw_line16_16,
     vga_draw_line16_32,
+    vga_draw_line16_32bgr,
 
     vga_draw_line24_8,
     vga_draw_line24_15,
     vga_draw_line24_16,
     vga_draw_line24_32,
+    vga_draw_line24_32bgr,
 
     vga_draw_line32_8,
     vga_draw_line32_15,
     vga_draw_line32_16,
     vga_draw_line32_32,
+    vga_draw_line32_32bgr,
+};
+
+typedef unsigned int rgb_to_pixel_dup_func(unsigned int r, unsigned int g, unsigned b);
+
+static rgb_to_pixel_dup_func *rgb_to_pixel_dup_table[NB_DEPTHS] = {
+    rgb_to_pixel8_dup,
+    rgb_to_pixel15_dup,
+    rgb_to_pixel16_dup,
+    rgb_to_pixel32_dup,
+    rgb_to_pixel32bgr_dup,
 };
 
 static int vga_get_bpp(VGAState *s)
@@ -1362,7 +1406,7 @@ static void vga_draw_graphic(VGAState *s, int full_update)
             break;
         }
     }
-    vga_draw_line = vga_draw_line_table[v * 4 + get_depth_index(s->ds->depth)];
+    vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)];
 
     if (disp_width != s->last_width ||
         height != s->last_height) {
@@ -1492,21 +1536,8 @@ static void vga_update_display(void *opaque)
     if (s->ds->depth == 0) {
         /* nothing to do */
     } else {
-        switch(s->ds->depth) {
-        case 8:
-            s->rgb_to_pixel = rgb_to_pixel8_dup;
-            break;
-        case 15:
-            s->rgb_to_pixel = rgb_to_pixel15_dup;
-            break;
-        default:
-        case 16:
-            s->rgb_to_pixel = rgb_to_pixel16_dup;
-            break;
-        case 32:
-            s->rgb_to_pixel = rgb_to_pixel32_dup;
-            break;
-        }
+        s->rgb_to_pixel = 
+            rgb_to_pixel_dup_table[get_depth_index(s->ds)];
         
         full_update = 0;
         if (!(s->ar_index & 0x20)) {
diff --git a/hw/vga_template.h b/hw/vga_template.h
index 909571e..4ea938e 100644
--- a/hw/vga_template.h
+++ b/hw/vga_template.h
@@ -35,7 +35,13 @@
 #error unsupport depth
 #endif
 
-#if DEPTH != 15
+#ifdef BGR_FORMAT
+#define PIXEL_NAME glue(DEPTH, bgr)
+#else
+#define PIXEL_NAME DEPTH
+#endif /* BGR_FORMAT */
+
+#if DEPTH != 15 && !defined(BGR_FORMAT)
 
 static inline void glue(vga_draw_glyph_line_, DEPTH)(uint8_t *d, 
                                                      uint32_t font_data,
@@ -334,6 +340,72 @@ static void glue(vga_draw_line8_, DEPTH)(VGAState *s1, uint8_t *d,
     }
 }
 
+void glue(vga_draw_cursor_line_, DEPTH)(uint8_t *d1, 
+                                        const uint8_t *src1, 
+                                        int poffset, int w,
+                                        unsigned int color0, 
+                                        unsigned int color1,
+                                        unsigned int color_xor)
+{
+    const uint8_t *plane0, *plane1;
+    int x, b0, b1;
+    uint8_t *d;
+
+    d = d1;
+    plane0 = src1;
+    plane1 = src1 + poffset;
+    for(x = 0; x < w; x++) {
+        b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1;
+        b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1;
+#if DEPTH == 8
+        switch(b0 | (b1 << 1)) {
+        case 0:
+            break;
+        case 1:
+            d[0] ^= color_xor;
+            break;
+        case 2:
+            d[0] = color0;
+            break;
+        case 3:
+            d[0] = color1;
+            break;
+        }
+#elif DEPTH == 16
+        switch(b0 | (b1 << 1)) {
+        case 0:
+            break;
+        case 1:
+            ((uint16_t *)d)[0] ^= color_xor;
+            break;
+        case 2:
+            ((uint16_t *)d)[0] = color0;
+            break;
+        case 3:
+            ((uint16_t *)d)[0] = color1;
+            break;
+        }
+#elif DEPTH == 32
+        switch(b0 | (b1 << 1)) {
+        case 0:
+            break;
+        case 1:
+            ((uint32_t *)d)[0] ^= color_xor;
+            break;
+        case 2:
+            ((uint32_t *)d)[0] = color0;
+            break;
+        case 3:
+            ((uint32_t *)d)[0] = color1;
+            break;
+        }
+#else
+#error unsupported depth
+#endif
+        d += BPP;
+    }
+}
+
 #endif /* DEPTH != 15 */
 
 
@@ -342,7 +414,7 @@ static void glue(vga_draw_line8_, DEPTH)(VGAState *s1, uint8_t *d,
 /* 
  * 15 bit color
  */
-static void glue(vga_draw_line15_, DEPTH)(VGAState *s1, uint8_t *d, 
+static void glue(vga_draw_line15_, PIXEL_NAME)(VGAState *s1, uint8_t *d, 
                                           const uint8_t *s, int width)
 {
 #if DEPTH == 15 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
@@ -357,7 +429,7 @@ static void glue(vga_draw_line15_, DEPTH)(VGAState *s1, uint8_t *d,
         r = (v >> 7) & 0xf8;
         g = (v >> 2) & 0xf8;
         b = (v << 3) & 0xf8;
-        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
+        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
         s += 2;
         d += BPP;
     } while (--w != 0);
@@ -367,7 +439,7 @@ static void glue(vga_draw_line15_, DEPTH)(VGAState *s1, uint8_t *d,
 /* 
  * 16 bit color
  */
-static void glue(vga_draw_line16_, DEPTH)(VGAState *s1, uint8_t *d, 
+static void glue(vga_draw_line16_, PIXEL_NAME)(VGAState *s1, uint8_t *d, 
                                           const uint8_t *s, int width)
 {
 #if DEPTH == 16 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
@@ -382,7 +454,7 @@ static void glue(vga_draw_line16_, DEPTH)(VGAState *s1, uint8_t *d,
         r = (v >> 8) & 0xf8;
         g = (v >> 3) & 0xfc;
         b = (v << 3) & 0xf8;
-        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
+        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
         s += 2;
         d += BPP;
     } while (--w != 0);
@@ -392,7 +464,7 @@ static void glue(vga_draw_line16_, DEPTH)(VGAState *s1, uint8_t *d,
 /* 
  * 24 bit color
  */
-static void glue(vga_draw_line24_, DEPTH)(VGAState *s1, uint8_t *d, 
+static void glue(vga_draw_line24_, PIXEL_NAME)(VGAState *s1, uint8_t *d, 
                                           const uint8_t *s, int width)
 {
     int w;
@@ -409,7 +481,7 @@ static void glue(vga_draw_line24_, DEPTH)(VGAState *s1, uint8_t *d,
         g = s[1];
         r = s[2];
 #endif
-        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
+        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
         s += 3;
         d += BPP;
     } while (--w != 0);
@@ -418,7 +490,7 @@ static void glue(vga_draw_line24_, DEPTH)(VGAState *s1, uint8_t *d,
 /* 
  * 32 bit color
  */
-static void glue(vga_draw_line32_, DEPTH)(VGAState *s1, uint8_t *d, 
+static void glue(vga_draw_line32_, PIXEL_NAME)(VGAState *s1, uint8_t *d, 
                                           const uint8_t *s, int width)
 {
 #if DEPTH == 32 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
@@ -438,82 +510,16 @@ static void glue(vga_draw_line32_, DEPTH)(VGAState *s1, uint8_t *d,
         g = s[1];
         r = s[2];
 #endif
-        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
+        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
         s += 4;
         d += BPP;
     } while (--w != 0);
 #endif
 }
 
-#if DEPTH != 15
-void glue(vga_draw_cursor_line_, DEPTH)(uint8_t *d1, 
-                                        const uint8_t *src1, 
-                                        int poffset, int w,
-                                        unsigned int color0, 
-                                        unsigned int color1,
-                                        unsigned int color_xor)
-{
-    const uint8_t *plane0, *plane1;
-    int x, b0, b1;
-    uint8_t *d;
-
-    d = d1;
-    plane0 = src1;
-    plane1 = src1 + poffset;
-    for(x = 0; x < w; x++) {
-        b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1;
-        b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1;
-#if DEPTH == 8
-        switch(b0 | (b1 << 1)) {
-        case 0:
-            break;
-        case 1:
-            d[0] ^= color_xor;
-            break;
-        case 2:
-            d[0] = color0;
-            break;
-        case 3:
-            d[0] = color1;
-            break;
-        }
-#elif DEPTH == 16
-        switch(b0 | (b1 << 1)) {
-        case 0:
-            break;
-        case 1:
-            ((uint16_t *)d)[0] ^= color_xor;
-            break;
-        case 2:
-            ((uint16_t *)d)[0] = color0;
-            break;
-        case 3:
-            ((uint16_t *)d)[0] = color1;
-            break;
-        }
-#elif DEPTH == 32
-        switch(b0 | (b1 << 1)) {
-        case 0:
-            break;
-        case 1:
-            ((uint32_t *)d)[0] ^= color_xor;
-            break;
-        case 2:
-            ((uint32_t *)d)[0] = color0;
-            break;
-        case 3:
-            ((uint32_t *)d)[0] = color1;
-            break;
-        }
-#else
-#error unsupported depth
-#endif
-        d += BPP;
-    }
-}
-#endif
-
 #undef PUT_PIXEL2
 #undef DEPTH
 #undef BPP
 #undef PIXEL_TYPE
+#undef PIXEL_NAME
+#undef BGR_FORMAT
diff --git a/sdl.c b/sdl.c
index 72a7080..ec4f93c 100644
--- a/sdl.c
+++ b/sdl.c
@@ -81,6 +81,11 @@ static void sdl_resize(DisplayState *ds, int w, int h)
     ds->data = screen->pixels;
     ds->linesize = screen->pitch;
     ds->depth = screen->format->BitsPerPixel;
+    if (ds->depth == 32 && screen->format->Rshift == 0) {
+        ds->bgr = 1;
+    } else {
+        ds->bgr = 0;
+    }
     ds->width = w;
     ds->height = h;
 }
diff --git a/vl.h b/vl.h
index 58a7877..7d51ff5 100644
--- a/vl.h
+++ b/vl.h
@@ -677,6 +677,7 @@ struct DisplayState {
     uint8_t *data;
     int linesize;
     int depth;
+    int bgr; /* BGR color order instead of RGB. Only valid for depth == 32 */
     int width;
     int height;
     void *opaque;
