patch-2.1.111 linux/drivers/video/fbcon.c
Next file: linux/drivers/video/fbcon.h
Previous file: linux/drivers/video/fbcon-vga.h
Back to the patch index
Back to the overall index
- Lines: 351
- Date:
Tue Jul 21 10:28:24 1998
- Orig file:
v2.1.110/linux/drivers/video/fbcon.c
- Orig date:
Tue Jul 21 00:15:32 1998
diff -u --recursive --new-file v2.1.110/linux/drivers/video/fbcon.c linux/drivers/video/fbcon.c
@@ -167,8 +167,7 @@
int height, int width);
static int fbcon_switch(struct vc_data *conp);
static int fbcon_blank(struct vc_data *conp, int blank);
-static int fbcon_get_font(struct vc_data *conp, int *w, int *h, char *data);
-static int fbcon_set_font(struct vc_data *conp, int w, int h, char *data);
+static int fbcon_font_op(struct vc_data *conp, struct console_font_op *op);
static int fbcon_set_palette(struct vc_data *conp, unsigned char *table);
static int fbcon_scrolldelta(struct vc_data *conp, int lines);
@@ -303,7 +302,7 @@
#endif /* CONFIG_MAC */
#if defined(__arm__) && defined(IRQ_VSYNCPULSE)
- irqres = request_irq(IRQ_VSYNCPULSE, fbcon_vbl_handler, 0,
+ irqres = request_irq(IRQ_VSYNCPULSE, fbcon_vbl_handler, SA_SHIRQ,
"console/cursor", fbcon_vbl_handler);
#endif
@@ -400,6 +399,7 @@
int logo_lines = 0;
/* Only if not module */
extern int initmem_freed;
+ struct fbcon_font_desc *font;
if (con != fg_console || initmem_freed || p->type == FB_TYPE_TEXT)
logo = 0;
@@ -407,11 +407,11 @@
p->var.xoffset = p->var.yoffset = p->yscroll = 0; /* reset wrap/pan */
if (!p->fb_info->fontname[0] ||
- !findsoftfont(p->fb_info->fontname, &p->fontwidth, &p->fontheight,
- &p->fontdata) || !fontwidthvalid(p,p->fontwidth))
- getdefaultfont(p->var.xres, p->var.yres, NULL, &p->fontwidth,
- &p->fontheight, &p->fontdata);
-
+ !(font = fbcon_find_font(p->fb_info->fontname)))
+ font = fbcon_get_default_font(p->var.xres, p->var.yres);
+ p->fontwidth = font->width;
+ p->fontheight = font->height;
+ p->fontdata = font->data;
fbcon_font_widths(p);
if (!fontwidthvalid(p,p->fontwidth)) {
#ifdef CONFIG_MAC
@@ -497,6 +497,9 @@
p->bgcol = 0;
if (!init) {
+ if (con == fg_console)
+ set_palette(); /* Unlike vgacon, we have to set palette before resize on directcolor,
+ so that it is drawn with correct colors */
vc_resize_con(nr_rows, nr_cols, con);
if (save) {
q = (unsigned short *)(conp->vc_origin + conp->vc_size_row * old_rows);
@@ -1103,6 +1106,8 @@
if (info && info->switch_con)
(*info->switch_con)(conp->vc_num, info);
+ if (p->dispsw && p->dispsw->clear_margins)
+ p->dispsw->clear_margins(conp, p);
return 1;
}
@@ -1145,21 +1150,17 @@
}
-static int fbcon_get_font(struct vc_data *conp, int *w, int *h, char *data)
+static inline int fbcon_get_font(int unit, struct console_font_op *op)
{
- int unit = conp->vc_num;
struct display *p = &fb_display[unit];
- int i, j, size, alloc;
-
- size = (p->fontwidth+7)/8 * p->fontheight * 256;
- alloc = (*w+7)/8 * *h * 256;
- *w = p->fontwidth;
- *h = p->fontheight;
-
- if (alloc < size)
- /* allocation length not sufficient */
- return -ENAMETOOLONG;
+ char *data = op->data;
+ int i, j;
+ if (p->fontwidth != 8) /* FIXME: Implement for wide fonts */
+ return -EINVAL;
+ op->width = p->fontwidth;
+ op->height = p->fontheight;
+ op->charcount = 256;
for (i = 0; i < 256; i++)
for (j = 0; j < p->fontheight; j++)
data[i*32+j] = p->fontdata[i*p->fontheight+j];
@@ -1170,85 +1171,30 @@
#define REFCOUNT(fd) (((int *)(fd))[-1])
#define FNTSIZE(fd) (((int *)(fd))[-2])
-static int fbcon_set_font(struct vc_data *conp, int w, int h, char *data)
+static int fbcon_do_set_font(int unit, struct console_font_op *op, u8 *data, int userfont)
{
- int unit = conp->vc_num;
struct display *p = &fb_display[unit];
- int i, j, size, userspace = 1, resize;
- char *old_data = NULL, *new_data;
-
- if (w < 0)
- w = p->fontwidth;
- if (h < 0)
- h = p->fontheight;
-
- if (w == 0) {
- /* engage predefined font, name in 'data' */
- unsigned short width, height;
- data[MAX_FONT_NAME] = 0;
-
- if (!findsoftfont( data, &width, &height, (u8 **)&data ))
- return -ENOENT;
- w = width; h = height;
- userspace = 0;
- } else if (w == 1) {
- /* copy font from some other console in 'h'*/
- struct display *op;
-
- if (h < 0 || !vc_cons_allocated( h ))
- return -ENOTTY;
- if (h == unit)
- return 0; /* nothing to do */
- op = &fb_display[h];
- if (op->fontdata == p->fontdata)
- return 0; /* already the same font... */
-
- resize = (op->fontwidth != p->fontwidth) ||
- (op->fontheight != p->fontheight);
- if (p->userfont)
- old_data = p->fontdata;
- p->fontdata = op->fontdata;
- w = p->fontwidth = op->fontwidth;
- h = p->fontheight = op->fontheight;
- p->fontwidthlog = op->fontwidthlog;
- p->fontheightlog = op->fontheightlog;
- if ((p->userfont = op->userfont))
- REFCOUNT(p->fontdata)++; /* increment usage counter */
- goto activate;
- }
-
- if (!fontwidthvalid(p,w))
- /* Currently only fontwidth == 8 supported */
+ int resize;
+ int w = op->width;
+ int h = op->height;
+ char *old_data = NULL;
+
+ if (!fontwidthvalid(p,w)) {
+ if (userfont)
+ kfree(data);
return -ENXIO;
+ }
resize = (w != p->fontwidth) || (h != p->fontheight);
- size = (w+7)/8 * h * 256;
-
if (p->userfont)
- old_data = p->fontdata;
-
- if (userspace) {
- if (!(new_data = kmalloc( 2*sizeof(int)+size, GFP_USER )))
- return -ENOMEM;
- new_data += 2*sizeof(int);
- FNTSIZE(new_data) = size;
- REFCOUNT(new_data) = 1; /* usage counter */
-
- for (i = 0; i < 256; i++)
- for (j = 0; j < h; j++)
- new_data[i*h+j] = data[i*32+j];
-
- p->fontdata = new_data;
- p->userfont = 1;
- } else {
- p->fontdata = data;
- p->userfont = 0;
- }
+ old_data = p->fontdata;
+ p->fontdata = data;
+ if ((p->userfont = userfont))
+ REFCOUNT(data)++;
p->fontwidth = w;
p->fontheight = h;
fbcon_font_widths(p);
-activate:
if (resize) {
/* reset wrap/pan */
p->var.xoffset = p->var.yoffset = p->yscroll = 0;
@@ -1269,6 +1215,82 @@
return 0;
}
+static inline int fbcon_copy_font(int unit, struct console_font_op *op)
+{
+ struct display *od, *p = &fb_display[unit];
+ int h = op->height;
+
+ if (h < 0 || !vc_cons_allocated( h ))
+ return -ENOTTY;
+ if (h == unit)
+ return 0; /* nothing to do */
+ od = &fb_display[h];
+ if (od->fontdata == p->fontdata)
+ return 0; /* already the same font... */
+ return fbcon_do_set_font(unit, op, od->fontdata, od->userfont);
+}
+
+static inline int fbcon_set_font(int unit, struct console_font_op *op)
+{
+ int w = op->width;
+ int h = op->height;
+ int size = (w+7)/8 * h * 256;
+ int i, j;
+ u8 *new_data, *data = op->data;
+
+ if (w != 8 || op->charcount != 256)
+ return -EINVAL;
+
+ if (!(new_data = kmalloc( 2*sizeof(int)+size, GFP_USER )))
+ return -ENOMEM;
+ new_data += 2*sizeof(int);
+ FNTSIZE(new_data) = size;
+ REFCOUNT(new_data) = 0; /* usage counter */
+ for (i = 0; i < 256; i++)
+ for (j = 0; j < h; j++)
+ new_data[i*h+j] = data[i*32+j];
+ return fbcon_do_set_font(unit, op, new_data, 1);
+}
+
+static inline int fbcon_set_def_font(int unit, struct console_font_op *op)
+{
+ char name[MAX_FONT_NAME];
+ struct fbcon_font_desc *f;
+ struct display *p = &fb_display[unit];
+
+ if (!op->data)
+ f = fbcon_get_default_font(p->var.xres, p->var.yres);
+ else if (strncpy_from_user(name, op->data, MAX_FONT_NAME-1) < 0)
+ return -EFAULT;
+ else {
+ name[MAX_FONT_NAME-1] = 0;
+ if (!(f = fbcon_find_font(name)))
+ return -ENOENT;
+ }
+ op->width = f->width;
+ op->height = f->height;
+ op->charcount = 256;
+ return fbcon_do_set_font(unit, op, f->data, 0);
+}
+
+static int fbcon_font_op(struct vc_data *conp, struct console_font_op *op)
+{
+ int unit = conp->vc_num;
+
+ switch (op->op) {
+ case KD_FONT_OP_SET:
+ return fbcon_set_font(unit, op);
+ case KD_FONT_OP_GET:
+ return fbcon_get_font(unit, op);
+ case KD_FONT_OP_SET_DEFAULT:
+ return fbcon_set_def_font(unit, op);
+ case KD_FONT_OP_COPY:
+ return fbcon_copy_font(unit, op);
+ default:
+ return -ENOSYS;
+ }
+}
+
static u16 palette_red[16];
static u16 palette_green[16];
static u16 palette_blue[16];
@@ -1299,6 +1321,7 @@
palette_cmap.len = 1<<p->var.bits_per_pixel;
else
palette_cmap.len = 16;
+ palette_cmap.start = 0;
return p->fb_info->fbops->fb_set_cmap(&palette_cmap, 1, unit, p->fb_info);
}
@@ -1307,8 +1330,6 @@
int unit, offset, limit, scrollback_old;
struct display *p;
- /* FIXME: Sync to new code, remember to set visible_origin */
-
if (!scrollback_phys_max)
return -ENOSYS;
@@ -1346,6 +1367,8 @@
p->var.xoffset = 0;
p->var.yoffset = offset*p->fontheight;
p->fb_info->updatevar(unit, p->fb_info);
+ if (!offset)
+ fbcon_cursor(conp, CM_DRAW);
return 0;
}
@@ -1375,7 +1398,6 @@
int first_col = use_256 ? 32 : depth > 4 ? 16 : 0;
int num_cols = use_256 ? LINUX_LOGO_COLORS : 16;
unsigned char *red, *green, *blue;
- int old_cmap_len;
if (use_256) {
red = linux_logo_red;
@@ -1388,11 +1410,6 @@
blue = linux_logo16_blue;
}
- /* dirty trick to avoid setcmap calling kmalloc which isn't
- * initialized yet... */
- old_cmap_len = fb_display[fg_console].cmap.len;
- fb_display[fg_console].cmap.len = 1 << (depth/(is_truecolor ? 3 : 1));
-
for( i = 0; i < num_cols; i += n ) {
n = num_cols - i;
if (n > 16)
@@ -1408,7 +1425,6 @@
p->fb_info->fbops->fb_set_cmap(&palette_cmap, 1, fg_console,
p->fb_info);
}
- fb_display[fg_console].cmap.len = old_cmap_len;
}
if (depth >= 8) {
@@ -1626,12 +1642,13 @@
con_bmove: fbcon_bmove,
con_switch: fbcon_switch,
con_blank: fbcon_blank,
- con_get_font: fbcon_get_font,
- con_set_font: fbcon_set_font,
+ con_font_op: fbcon_font_op,
con_set_palette: fbcon_set_palette,
con_scrolldelta: fbcon_scrolldelta,
con_set_origin: NULL,
con_save_screen: NULL,
+ con_build_attr: NULL,
+ con_invert_region: NULL,
};
@@ -1657,3 +1674,4 @@
*/
EXPORT_SYMBOL(fb_display);
+EXPORT_SYMBOL(fbcon_redraw_bmove);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov