diff --git a/uitoolkit/fb/ui.h b/uitoolkit/fb/ui.h index 8af39385..8f15bb60 100644 --- a/uitoolkit/fb/ui.h +++ b/uitoolkit/fb/ui.h @@ -64,9 +64,11 @@ typedef struct { unsigned int r_limit; unsigned int g_limit; unsigned int b_limit; + unsigned int a_limit; unsigned int r_offset; unsigned int g_offset; unsigned int b_offset; + unsigned int a_offset; } rgbinfo; @@ -109,6 +111,8 @@ typedef struct { ((((r) >> (rgbinfo).r_limit) << (rgbinfo).r_offset) | \ (((g) >> (rgbinfo).g_limit) << (rgbinfo).g_offset) | \ (((b) >> (rgbinfo).b_limit) << (rgbinfo).b_offset)) +#define ALPHA_TO_PIXEL(a, rgbinfo, depth) \ + ((depth) == 32 ? (((a) >> (rgbinfo).a_limit) << (rgbinfo).a_offset) : 0) typedef int XIC; /* dummy */ typedef void *XID; /* dummy */ diff --git a/uitoolkit/fb/ui_color.c b/uitoolkit/fb/ui_color.c index 341ae287..c477be64 100644 --- a/uitoolkit/fb/ui_color.c +++ b/uitoolkit/fb/ui_color.c @@ -68,7 +68,7 @@ int ui_load_rgb_xcolor(ui_display_t *disp, ui_color_t *xcolor, u_int8_t red, u_i #endif xcolor->pixel = RGB_TO_PIXEL(red, green, blue, disp->display->rgbinfo) | - (disp->depth == 32 ? (alpha << 24) : 0); + ALPHA_TO_PIXEL(alpha, disp->display->rgbinfo, disp->depth); } return 1; diff --git a/uitoolkit/fb/ui_display_freebsd.c b/uitoolkit/fb/ui_display_freebsd.c index 8765677b..2b1a2cf1 100644 --- a/uitoolkit/fb/ui_display_freebsd.c +++ b/uitoolkit/fb/ui_display_freebsd.c @@ -143,9 +143,11 @@ static int open_display(u_int depth) { _display.rgbinfo.r_limit = 8 - vinfo.vi_pixel_fsizes[0]; _display.rgbinfo.g_limit = 8 - vinfo.vi_pixel_fsizes[1]; _display.rgbinfo.b_limit = 8 - vinfo.vi_pixel_fsizes[2]; + _display.rgbinfo.a_limit = 8 - vinfo.vi_pixel_fsizes[3]; _display.rgbinfo.r_offset = vinfo.vi_pixel_fields[0]; _display.rgbinfo.g_offset = vinfo.vi_pixel_fields[1]; _display.rgbinfo.b_offset = vinfo.vi_pixel_fields[2]; + _display.rgbinfo.a_offset = vinfo.vi_pixel_fields[3]; tcgetattr(STDIN_FILENO, &tm); orig_tm = tm; diff --git a/uitoolkit/fb/ui_display_linux.c b/uitoolkit/fb/ui_display_linux.c index 1813c60e..8db347e5 100644 --- a/uitoolkit/fb/ui_display_linux.c +++ b/uitoolkit/fb/ui_display_linux.c @@ -429,9 +429,11 @@ static int open_display(u_int depth) { _display.rgbinfo.r_limit = 8 - vinfo.red.length; _display.rgbinfo.g_limit = 8 - vinfo.green.length; _display.rgbinfo.b_limit = 8 - vinfo.blue.length; + _display.rgbinfo.a_limit = 8 - vinfo.transp.length; _display.rgbinfo.r_offset = vinfo.red.offset; _display.rgbinfo.g_offset = vinfo.green.offset; _display.rgbinfo.b_offset = vinfo.blue.offset; + _display.rgbinfo.a_offset = vinfo.transp.offset; get_event_device_num(kbd_num, mouse_num); diff --git a/uitoolkit/fb/ui_display_wscons.c b/uitoolkit/fb/ui_display_wscons.c index 5a588f75..d31117b7 100644 --- a/uitoolkit/fb/ui_display_wscons.c +++ b/uitoolkit/fb/ui_display_wscons.c @@ -505,10 +505,38 @@ static int open_display(u_int depth /* used on luna68k alone. */ _display.rgbinfo.g_offset = vinfo2.fbi_subtype.fbi_rgbmasks.green_offset; _display.rgbinfo.b_offset = vinfo2.fbi_subtype.fbi_rgbmasks.blue_offset; + /* + * XXX + * wscons does not correctly set alpha size and offset. + * Therefore, we need to guess them below. + */ + { + int r = _display.rgbinfo.r_offset, + g = _display.rgbinfo.g_offset, + b = _display.rgbinfo.b_offset; + if (_display.rgbinfo.r_limit != 0 || + _display.rgbinfo.g_limit != 0 || + _display.rgbinfo.b_limit != 0 || + r % 8 != 0 || g % 8 != 0 || b % 8 != 0 || + r == g || g == b || b == r || + r > 24 || g > 24 || b > 24) { + _display.rgbinfo.a_limit = 8; + _display.rgbinfo.a_offset = 0; + } else { + int a, mask = (1 << (r / 8)) | (1 << (g / 8)) | (1 << (b / 8)); + for (a = 0; a < 4; a++) { + if ((mask & (1 << a)) == 0) + break; + } + _display.rgbinfo.a_limit = 0; + _display.rgbinfo.a_offset = a * 8; + } + } + #ifdef DEBUG - bl_debug_printf("FBINFO: (limit)r%d g%d b%d (offset)r%d g%d b%d\n", _display.rgbinfo.r_limit, - _display.rgbinfo.g_limit, _display.rgbinfo.b_limit, _display.rgbinfo.r_offset, - _display.rgbinfo.g_offset, _display.rgbinfo.b_offset); + bl_debug_printf("FBINFO: (limit)r%d g%d b%d a%d (offset)r%d g%d b%d a%d\n", + _display.rgbinfo.r_limit, _display.rgbinfo.g_limit, _display.rgbinfo.b_limit, _display.rgbinfo.a_limit, + _display.rgbinfo.r_offset, _display.rgbinfo.g_offset, _display.rgbinfo.b_offset, _display.rgbinfo.a_offset); #endif } #endif diff --git a/uitoolkit/fb/ui_imagelib.c b/uitoolkit/fb/ui_imagelib.c index 2955462c..8fd5cf43 100644 --- a/uitoolkit/fb/ui_imagelib.c +++ b/uitoolkit/fb/ui_imagelib.c @@ -140,7 +140,8 @@ static void modify_pixmap(Display *display, Pixmap pixmap, ui_picture_modifier_t *(dst++) = pixel; #endif } else { - pixel = RGB_TO_PIXEL(r, g, b, display->rgbinfo) | (depth == 32 ? (pixel & 0xff000000) : 0); + pixel = RGB_TO_PIXEL(r, g, b, display->rgbinfo) | + ALPHA_TO_PIXEL((pixel >> 24) & 0xff, display->rgbinfo, depth); if (display->bytes_per_pixel == 2) { *((u_int16_t *)dst) = pixel;