aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Pfaff <tpfaff@pcs.com>2008-02-06 04:39:45 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-06 13:41:18 -0500
commit91c4313206e4409871e2ddd13c29508afe1c8834 (patch)
treea37ae47c38b3f1fa119f141d546c000f58502eb9
parente8973637bd49de225130f9c04ceb388d48969d98 (diff)
fbcon: fix color generation for monochrome framebuffer
The current attr_fgcol_ec / attr_bgcol_ec macros do a simple shift of bits to get the color from vc_video_erase_char. For a monochrome display however the attribute does not contain any color, only attribute bits. Furthermore the reverse bit is lost because it is shifted out, the resulting color is always 0. This can bee seen on a monochrome console either directly or by setting it to inverse mode via "setterm -inversescreen on" . Text is written with correct color, fb_fillrects from a bit_clear / bit_clear_margins will get wrong colors. Signed-off-by: Thomas Pfaff <tpfaff@pcs.com> Cc: "Antonino A. Daplas" <adaplas@pol.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/video/console/bitblit.c4
-rw-r--r--drivers/video/console/fbcon.c5
-rw-r--r--drivers/video/console/fbcon.h47
-rw-r--r--drivers/video/console/fbcon_ccw.c4
-rw-r--r--drivers/video/console/fbcon_cw.c4
-rw-r--r--drivers/video/console/fbcon_ud.c4
-rw-r--r--drivers/video/console/tileblit.c4
-rw-r--r--drivers/video/pmag-aa-fb.c2
8 files changed, 55 insertions, 19 deletions
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
index 308850df16fe..69864b1b3f9e 100644
--- a/drivers/video/console/bitblit.c
+++ b/drivers/video/console/bitblit.c
@@ -63,7 +63,7 @@ static void bit_clear(struct vc_data *vc, struct fb_info *info, int sy,
63 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; 63 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
64 struct fb_fillrect region; 64 struct fb_fillrect region;
65 65
66 region.color = attr_bgcol_ec(bgshift, vc); 66 region.color = attr_bgcol_ec(bgshift, vc, info);
67 region.dx = sx * vc->vc_font.width; 67 region.dx = sx * vc->vc_font.width;
68 region.dy = sy * vc->vc_font.height; 68 region.dy = sy * vc->vc_font.height;
69 region.width = width * vc->vc_font.width; 69 region.width = width * vc->vc_font.width;
@@ -213,7 +213,7 @@ static void bit_clear_margins(struct vc_data *vc, struct fb_info *info,
213 unsigned int bs = info->var.yres - bh; 213 unsigned int bs = info->var.yres - bh;
214 struct fb_fillrect region; 214 struct fb_fillrect region;
215 215
216 region.color = attr_bgcol_ec(bgshift, vc); 216 region.color = attr_bgcol_ec(bgshift, vc, info);
217 region.rop = ROP_COPY; 217 region.rop = ROP_COPY;
218 218
219 if (rw && !bottom_only) { 219 if (rw && !bottom_only) {
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index c6babb178c77..022282494d3f 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -334,10 +334,7 @@ static inline int get_color(struct vc_data *vc, struct fb_info *info,
334 switch (depth) { 334 switch (depth) {
335 case 1: 335 case 1:
336 { 336 {
337 int col = ~(0xfff << (max(info->var.green.length, 337 int col = mono_col(info);
338 max(info->var.red.length,
339 info->var.blue.length)))) & 0xff;
340
341 /* 0 or 1 */ 338 /* 0 or 1 */
342 int fg = (info->fix.visual != FB_VISUAL_MONO01) ? col : 0; 339 int fg = (info->fix.visual != FB_VISUAL_MONO01) ? col : 0;
343 int bg = (info->fix.visual != FB_VISUAL_MONO01) ? 0 : col; 340 int bg = (info->fix.visual != FB_VISUAL_MONO01) ? 0 : col;
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index 8e6ef4bc7a5c..3706307e70ed 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -93,10 +93,6 @@ struct fbcon_ops {
93 (((s) >> (fgshift)) & 0x0f) 93 (((s) >> (fgshift)) & 0x0f)
94#define attr_bgcol(bgshift,s) \ 94#define attr_bgcol(bgshift,s) \
95 (((s) >> (bgshift)) & 0x0f) 95 (((s) >> (bgshift)) & 0x0f)
96#define attr_bgcol_ec(bgshift,vc) \
97 ((vc) ? (((vc)->vc_video_erase_char >> (bgshift)) & 0x0f) : 0)
98#define attr_fgcol_ec(fgshift,vc) \
99 ((vc) ? (((vc)->vc_video_erase_char >> (fgshift)) & 0x0f) : 0)
100 96
101/* Monochrome */ 97/* Monochrome */
102#define attr_bold(s) \ 98#define attr_bold(s) \
@@ -108,6 +104,49 @@ struct fbcon_ops {
108#define attr_blink(s) \ 104#define attr_blink(s) \
109 ((s) & 0x8000) 105 ((s) & 0x8000)
110 106
107#define mono_col(info) \
108 (~(0xfff << (max((info)->var.green.length, \
109 max((info)->var.red.length, \
110 (info)->var.blue.length)))) & 0xff)
111
112static inline int attr_col_ec(int shift, struct vc_data *vc,
113 struct fb_info *info, int is_fg)
114{
115 int is_mono01;
116 int col;
117 int fg;
118 int bg;
119
120 if (!vc)
121 return 0;
122
123 if (vc->vc_can_do_color)
124 return is_fg ? attr_fgcol(shift,vc->vc_video_erase_char)
125 : attr_bgcol(shift,vc->vc_video_erase_char);
126
127 if (!info)
128 return 0;
129
130 col = mono_col(info);
131 is_mono01 = info->fix.visual == FB_VISUAL_MONO01;
132
133 if (attr_reverse(vc->vc_video_erase_char)) {
134 fg = is_mono01 ? col : 0;
135 bg = is_mono01 ? 0 : col;
136 }
137 else {
138 fg = is_mono01 ? 0 : col;
139 bg = is_mono01 ? col : 0;
140 }
141
142 return is_fg ? fg : bg;
143}
144
145#define attr_bgcol_ec(bgshift,vc,info) \
146 attr_col_ec(bgshift,vc,info,0);
147#define attr_fgcol_ec(fgshift,vc,info) \
148 attr_col_ec(fgshift,vc,info,1);
149
111/* Font */ 150/* Font */
112#define REFCOUNT(fd) (((int *)(fd))[-1]) 151#define REFCOUNT(fd) (((int *)(fd))[-1])
113#define FNTSIZE(fd) (((int *)(fd))[-2]) 152#define FNTSIZE(fd) (((int *)(fd))[-2])
diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c
index 825e6d6972a7..bdf913ecf001 100644
--- a/drivers/video/console/fbcon_ccw.c
+++ b/drivers/video/console/fbcon_ccw.c
@@ -84,7 +84,7 @@ static void ccw_clear(struct vc_data *vc, struct fb_info *info, int sy,
84 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; 84 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
85 u32 vyres = GETVYRES(ops->p->scrollmode, info); 85 u32 vyres = GETVYRES(ops->p->scrollmode, info);
86 86
87 region.color = attr_bgcol_ec(bgshift,vc); 87 region.color = attr_bgcol_ec(bgshift,vc,info);
88 region.dx = sy * vc->vc_font.height; 88 region.dx = sy * vc->vc_font.height;
89 region.dy = vyres - ((sx + width) * vc->vc_font.width); 89 region.dy = vyres - ((sx + width) * vc->vc_font.width);
90 region.height = width * vc->vc_font.width; 90 region.height = width * vc->vc_font.width;
@@ -198,7 +198,7 @@ static void ccw_clear_margins(struct vc_data *vc, struct fb_info *info,
198 struct fb_fillrect region; 198 struct fb_fillrect region;
199 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; 199 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
200 200
201 region.color = attr_bgcol_ec(bgshift,vc); 201 region.color = attr_bgcol_ec(bgshift,vc,info);
202 region.rop = ROP_COPY; 202 region.rop = ROP_COPY;
203 203
204 if (rw && !bottom_only) { 204 if (rw && !bottom_only) {
diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c
index c637e6318803..a6819b9d1770 100644
--- a/drivers/video/console/fbcon_cw.c
+++ b/drivers/video/console/fbcon_cw.c
@@ -70,7 +70,7 @@ static void cw_clear(struct vc_data *vc, struct fb_info *info, int sy,
70 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; 70 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
71 u32 vxres = GETVXRES(ops->p->scrollmode, info); 71 u32 vxres = GETVXRES(ops->p->scrollmode, info);
72 72
73 region.color = attr_bgcol_ec(bgshift,vc); 73 region.color = attr_bgcol_ec(bgshift,vc,info);
74 region.dx = vxres - ((sy + height) * vc->vc_font.height); 74 region.dx = vxres - ((sy + height) * vc->vc_font.height);
75 region.dy = sx * vc->vc_font.width; 75 region.dy = sx * vc->vc_font.width;
76 region.height = width * vc->vc_font.width; 76 region.height = width * vc->vc_font.width;
@@ -182,7 +182,7 @@ static void cw_clear_margins(struct vc_data *vc, struct fb_info *info,
182 struct fb_fillrect region; 182 struct fb_fillrect region;
183 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; 183 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
184 184
185 region.color = attr_bgcol_ec(bgshift,vc); 185 region.color = attr_bgcol_ec(bgshift,vc,info);
186 region.rop = ROP_COPY; 186 region.rop = ROP_COPY;
187 187
188 if (rw && !bottom_only) { 188 if (rw && !bottom_only) {
diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c
index 1473506df5d0..d9b5d6eb68a7 100644
--- a/drivers/video/console/fbcon_ud.c
+++ b/drivers/video/console/fbcon_ud.c
@@ -71,7 +71,7 @@ static void ud_clear(struct vc_data *vc, struct fb_info *info, int sy,
71 u32 vyres = GETVYRES(ops->p->scrollmode, info); 71 u32 vyres = GETVYRES(ops->p->scrollmode, info);
72 u32 vxres = GETVXRES(ops->p->scrollmode, info); 72 u32 vxres = GETVXRES(ops->p->scrollmode, info);
73 73
74 region.color = attr_bgcol_ec(bgshift,vc); 74 region.color = attr_bgcol_ec(bgshift,vc,info);
75 region.dy = vyres - ((sy + height) * vc->vc_font.height); 75 region.dy = vyres - ((sy + height) * vc->vc_font.height);
76 region.dx = vxres - ((sx + width) * vc->vc_font.width); 76 region.dx = vxres - ((sx + width) * vc->vc_font.width);
77 region.width = width * vc->vc_font.width; 77 region.width = width * vc->vc_font.width;
@@ -228,7 +228,7 @@ static void ud_clear_margins(struct vc_data *vc, struct fb_info *info,
228 struct fb_fillrect region; 228 struct fb_fillrect region;
229 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; 229 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
230 230
231 region.color = attr_bgcol_ec(bgshift,vc); 231 region.color = attr_bgcol_ec(bgshift,vc,info);
232 region.rop = ROP_COPY; 232 region.rop = ROP_COPY;
233 233
234 if (rw && !bottom_only) { 234 if (rw && !bottom_only) {
diff --git a/drivers/video/console/tileblit.c b/drivers/video/console/tileblit.c
index d981fe4d86c6..0056a41e5c35 100644
--- a/drivers/video/console/tileblit.c
+++ b/drivers/video/console/tileblit.c
@@ -40,8 +40,8 @@ static void tile_clear(struct vc_data *vc, struct fb_info *info, int sy,
40 40
41 rect.index = vc->vc_video_erase_char & 41 rect.index = vc->vc_video_erase_char &
42 ((vc->vc_hi_font_mask) ? 0x1ff : 0xff); 42 ((vc->vc_hi_font_mask) ? 0x1ff : 0xff);
43 rect.fg = attr_fgcol_ec(fgshift, vc); 43 rect.fg = attr_fgcol_ec(fgshift, vc, info);
44 rect.bg = attr_bgcol_ec(bgshift, vc); 44 rect.bg = attr_bgcol_ec(bgshift, vc, info);
45 rect.sx = sx; 45 rect.sx = sx;
46 rect.sy = sy; 46 rect.sy = sy;
47 rect.width = width; 47 rect.width = width;
diff --git a/drivers/video/pmag-aa-fb.c b/drivers/video/pmag-aa-fb.c
index a864438b6008..6515ec11c16b 100644
--- a/drivers/video/pmag-aa-fb.c
+++ b/drivers/video/pmag-aa-fb.c
@@ -150,7 +150,7 @@ static int aafbcon_set_font(struct display *disp, int width, int height)
150{ 150{
151 struct aafb_info *info = (struct aafb_info *)disp->fb_info; 151 struct aafb_info *info = (struct aafb_info *)disp->fb_info;
152 struct aafb_cursor *c = &info->cursor; 152 struct aafb_cursor *c = &info->cursor;
153 u8 fgc = ~attr_bgcol_ec(disp, disp->conp); 153 u8 fgc = ~attr_bgcol_ec(disp, disp->conp, &info->info);
154 154
155 if (width > 64 || height > 64 || width < 0 || height < 0) 155 if (width > 64 || height > 64 || width < 0 || height < 0)
156 return -EINVAL; 156 return -EINVAL;