aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntonino A. Daplas <adaplas@gmail.com>2005-09-09 16:04:37 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 16:58:00 -0400
commitb8c909454f046b59065c6997b651fe20cd90c0f4 (patch)
tree2a8e03fe69c1b02dc610f57208d693e05b95969c
parent094bb659f53b6d90aab6067268d6d14f1f352d30 (diff)
[PATCH] fbdev: Fix greater than 1 bit monochrome color handling
Currently, fbcon assumes that the visual FB_VISUAL_MONO* is always 1 bit. According to Geert, there are old hardware where it's possible to have monochrome at 8-bit, but has only 2 colors, black - 0x00 and white - 0xff. Fix color handlers (fb_get_color_depth, and get_color) for this special case. Signed-off-by: Antonino Daplas <adaplas@pol.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/video/console/bitblit.c2
-rw-r--r--drivers/video/console/fbcon.c26
-rw-r--r--drivers/video/fbmem.c41
-rw-r--r--drivers/video/nvidia/nvidia.c8
-rw-r--r--include/linux/fb.h3
5 files changed, 52 insertions, 28 deletions
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
index 3c731577fed6..12eaf0aa87e6 100644
--- a/drivers/video/console/bitblit.c
+++ b/drivers/video/console/bitblit.c
@@ -39,7 +39,7 @@ static inline int get_attribute(struct fb_info *info, u16 c)
39{ 39{
40 int attribute = 0; 40 int attribute = 0;
41 41
42 if (fb_get_color_depth(&info->var) == 1) { 42 if (fb_get_color_depth(&info->var, &info->fix) == 1) {
43 if (attr_underline(c)) 43 if (attr_underline(c))
44 attribute |= FBCON_ATTRIBUTE_UNDERLINE; 44 attribute |= FBCON_ATTRIBUTE_UNDERLINE;
45 if (attr_reverse(c)) 45 if (attr_reverse(c))
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 751890a5f5f3..88bd8ef56fde 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -214,7 +214,7 @@ static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info)
214static inline int get_color(struct vc_data *vc, struct fb_info *info, 214static inline int get_color(struct vc_data *vc, struct fb_info *info,
215 u16 c, int is_fg) 215 u16 c, int is_fg)
216{ 216{
217 int depth = fb_get_color_depth(&info->var); 217 int depth = fb_get_color_depth(&info->var, &info->fix);
218 int color = 0; 218 int color = 0;
219 219
220 if (console_blanked) { 220 if (console_blanked) {
@@ -230,9 +230,13 @@ static inline int get_color(struct vc_data *vc, struct fb_info *info,
230 switch (depth) { 230 switch (depth) {
231 case 1: 231 case 1:
232 { 232 {
233 int col = ~(0xfff << (max(info->var.green.length,
234 max(info->var.red.length,
235 info->var.blue.length)))) & 0xff;
236
233 /* 0 or 1 */ 237 /* 0 or 1 */
234 int fg = (info->fix.visual != FB_VISUAL_MONO01) ? 1 : 0; 238 int fg = (info->fix.visual != FB_VISUAL_MONO01) ? col : 0;
235 int bg = (info->fix.visual != FB_VISUAL_MONO01) ? 0 : 1; 239 int bg = (info->fix.visual != FB_VISUAL_MONO01) ? 0 : col;
236 240
237 if (console_blanked) 241 if (console_blanked)
238 fg = bg; 242 fg = bg;
@@ -246,7 +250,6 @@ static inline int get_color(struct vc_data *vc, struct fb_info *info,
246 * is grayscale. 250 * is grayscale.
247 */ 251 */
248 color /= 4; 252 color /= 4;
249 break;
250 case 3: 253 case 3:
251 /* 254 /*
252 * Last 8 entries of default 16-color palette is a more intense 255 * Last 8 entries of default 16-color palette is a more intense
@@ -426,7 +429,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
426 * remove underline attribute from erase character 429 * remove underline attribute from erase character
427 * if black and white framebuffer. 430 * if black and white framebuffer.
428 */ 431 */
429 if (fb_get_color_depth(&info->var) == 1) 432 if (fb_get_color_depth(&info->var, &info->fix) == 1)
430 erase &= ~0x400; 433 erase &= ~0x400;
431 logo_height = fb_prepare_logo(info); 434 logo_height = fb_prepare_logo(info);
432 logo_lines = (logo_height + vc->vc_font.height - 1) / 435 logo_lines = (logo_height + vc->vc_font.height - 1) /
@@ -930,7 +933,7 @@ static void fbcon_init(struct vc_data *vc, int init)
930 } 933 }
931 if (p->userfont) 934 if (p->userfont)
932 charcnt = FNTCHARCNT(p->fontdata); 935 charcnt = FNTCHARCNT(p->fontdata);
933 vc->vc_can_do_color = (fb_get_color_depth(&info->var) != 1); 936 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
934 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; 937 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
935 if (charcnt == 256) { 938 if (charcnt == 256) {
936 vc->vc_hi_font_mask = 0; 939 vc->vc_hi_font_mask = 0;
@@ -1178,7 +1181,12 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1178 if (p->userfont) 1181 if (p->userfont)
1179 charcnt = FNTCHARCNT(p->fontdata); 1182 charcnt = FNTCHARCNT(p->fontdata);
1180 1183
1181 vc->vc_can_do_color = (fb_get_color_depth(var) != 1); 1184 var->activate = FB_ACTIVATE_NOW;
1185 info->var.activate = var->activate;
1186 info->var.yoffset = info->var.xoffset = 0;
1187 fb_set_var(info, var);
1188
1189 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
1182 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; 1190 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
1183 if (charcnt == 256) { 1191 if (charcnt == 256) {
1184 vc->vc_hi_font_mask = 0; 1192 vc->vc_hi_font_mask = 0;
@@ -1967,7 +1975,7 @@ static int fbcon_switch(struct vc_data *vc)
1967 set_blitting_type(vc, info, p); 1975 set_blitting_type(vc, info, p);
1968 ((struct fbcon_ops *)info->fbcon_par)->cursor_reset = 1; 1976 ((struct fbcon_ops *)info->fbcon_par)->cursor_reset = 1;
1969 1977
1970 vc->vc_can_do_color = (fb_get_color_depth(&info->var) != 1); 1978 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
1971 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; 1979 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
1972 updatescrollmode(p, info, vc); 1980 updatescrollmode(p, info, vc);
1973 1981
@@ -2332,7 +2340,7 @@ static int fbcon_set_palette(struct vc_data *vc, unsigned char *table)
2332 if (!CON_IS_VISIBLE(vc)) 2340 if (!CON_IS_VISIBLE(vc))
2333 return 0; 2341 return 0;
2334 2342
2335 depth = fb_get_color_depth(&info->var); 2343 depth = fb_get_color_depth(&info->var, &info->fix);
2336 if (depth > 3) { 2344 if (depth > 3) {
2337 for (i = j = 0; i < 16; i++) { 2345 for (i = j = 0; i < 16; i++) {
2338 k = table[i]; 2346 k = table[i];
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index a8eee79e117d..a815f5e2fcb5 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -62,16 +62,26 @@ int num_registered_fb;
62 * Helpers 62 * Helpers
63 */ 63 */
64 64
65int fb_get_color_depth(struct fb_var_screeninfo *var) 65int fb_get_color_depth(struct fb_var_screeninfo *var,
66 struct fb_fix_screeninfo *fix)
66{ 67{
67 if (var->green.length == var->blue.length && 68 int depth = 0;
68 var->green.length == var->red.length && 69
69 !var->green.offset && !var->blue.offset && 70 if (fix->visual == FB_VISUAL_MONO01 ||
70 !var->red.offset) 71 fix->visual == FB_VISUAL_MONO10)
71 return var->green.length; 72 depth = 1;
72 else 73 else {
73 return (var->green.length + var->red.length + 74 if (var->green.length == var->blue.length &&
74 var->blue.length); 75 var->green.length == var->red.length &&
76 var->green.offset == var->blue.offset &&
77 var->green.offset == var->red.offset)
78 depth = var->green.length;
79 else
80 depth = var->green.length + var->red.length +
81 var->blue.length;
82 }
83
84 return depth;
75} 85}
76EXPORT_SYMBOL(fb_get_color_depth); 86EXPORT_SYMBOL(fb_get_color_depth);
77 87
@@ -249,13 +259,18 @@ static void fb_set_logo(struct fb_info *info,
249 const struct linux_logo *logo, u8 *dst, 259 const struct linux_logo *logo, u8 *dst,
250 int depth) 260 int depth)
251{ 261{
252 int i, j, k, fg = 1; 262 int i, j, k;
253 const u8 *src = logo->data; 263 const u8 *src = logo->data;
254 u8 d, xor = (info->fix.visual == FB_VISUAL_MONO01) ? 0xff : 0; 264 u8 xor = (info->fix.visual == FB_VISUAL_MONO01) ? 0xff : 0;
265 u8 fg = 1, d;
255 266
256 if (fb_get_color_depth(&info->var) == 3) 267 if (fb_get_color_depth(&info->var, &info->fix) == 3)
257 fg = 7; 268 fg = 7;
258 269
270 if (info->fix.visual == FB_VISUAL_MONO01 ||
271 info->fix.visual == FB_VISUAL_MONO10)
272 fg = ~((u8) (0xfff << info->var.green.length));
273
259 switch (depth) { 274 switch (depth) {
260 case 4: 275 case 4:
261 for (i = 0; i < logo->height; i++) 276 for (i = 0; i < logo->height; i++)
@@ -318,7 +333,7 @@ static struct logo_data {
318 333
319int fb_prepare_logo(struct fb_info *info) 334int fb_prepare_logo(struct fb_info *info)
320{ 335{
321 int depth = fb_get_color_depth(&info->var); 336 int depth = fb_get_color_depth(&info->var, &info->fix);
322 337
323 memset(&fb_logo, 0, sizeof(struct logo_data)); 338 memset(&fb_logo, 0, sizeof(struct logo_data));
324 339
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index af99ea96012e..32952204ce33 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -658,7 +658,7 @@ static int nvidia_calc_regs(struct fb_info *info)
658{ 658{
659 struct nvidia_par *par = info->par; 659 struct nvidia_par *par = info->par;
660 struct _riva_hw_state *state = &par->ModeReg; 660 struct _riva_hw_state *state = &par->ModeReg;
661 int i, depth = fb_get_color_depth(&info->var); 661 int i, depth = fb_get_color_depth(&info->var, &info->fix);
662 int h_display = info->var.xres / 8 - 1; 662 int h_display = info->var.xres / 8 - 1;
663 int h_start = (info->var.xres + info->var.right_margin) / 8 - 1; 663 int h_start = (info->var.xres + info->var.right_margin) / 8 - 1;
664 int h_end = (info->var.xres + info->var.right_margin + 664 int h_end = (info->var.xres + info->var.right_margin +
@@ -978,6 +978,9 @@ static int nvidiafb_set_par(struct fb_info *info)
978 !par->twoHeads) 978 !par->twoHeads)
979 par->FPDither = 0; 979 par->FPDither = 0;
980 980
981 info->fix.visual = (info->var.bits_per_pixel == 8) ?
982 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
983
981 nvidia_init_vga(info); 984 nvidia_init_vga(info);
982 nvidia_calc_regs(info); 985 nvidia_calc_regs(info);
983 nvidia_write_regs(par); 986 nvidia_write_regs(par);
@@ -992,9 +995,6 @@ static int nvidiafb_set_par(struct fb_info *info)
992 NVWriteCrtc(par, 0x11, 0x00); 995 NVWriteCrtc(par, 0x11, 0x00);
993 info->fix.line_length = (info->var.xres_virtual * 996 info->fix.line_length = (info->var.xres_virtual *
994 info->var.bits_per_pixel) >> 3; 997 info->var.bits_per_pixel) >> 3;
995 info->fix.visual = (info->var.bits_per_pixel == 8) ?
996 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
997
998 if (info->var.accel_flags) { 998 if (info->var.accel_flags) {
999 info->fbops->fb_imageblit = nvidiafb_imageblit; 999 info->fbops->fb_imageblit = nvidiafb_imageblit;
1000 info->fbops->fb_fillrect = nvidiafb_fillrect; 1000 info->fbops->fb_fillrect = nvidiafb_fillrect;
diff --git a/include/linux/fb.h b/include/linux/fb.h
index e3e16f43b1bb..c71a7162e098 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -823,7 +823,8 @@ extern void fb_pad_unaligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 idx,
823 u32 height, u32 shift_high, u32 shift_low, u32 mod); 823 u32 height, u32 shift_high, u32 shift_low, u32 mod);
824extern void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height); 824extern void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height);
825extern void fb_set_suspend(struct fb_info *info, int state); 825extern void fb_set_suspend(struct fb_info *info, int state);
826extern int fb_get_color_depth(struct fb_var_screeninfo *var); 826extern int fb_get_color_depth(struct fb_var_screeninfo *var,
827 struct fb_fix_screeninfo *fix);
827extern int fb_get_options(char *name, char **option); 828extern int fb_get_options(char *name, char **option);
828extern int fb_new_modelist(struct fb_info *info); 829extern int fb_new_modelist(struct fb_info *info);
829 830