patch-2.1.110 linux/drivers/video/sbusfb.c
Next file: linux/drivers/video/sbusfb.h
Previous file: linux/drivers/video/retz3fb.c
Back to the patch index
Back to the overall index
- Lines: 307
- Date:
Sat Jul 18 13:55:46 1998
- Orig file:
v2.1.109/linux/drivers/video/sbusfb.c
- Orig date:
Thu Jul 16 18:09:27 1998
diff -u --recursive --new-file v2.1.109/linux/drivers/video/sbusfb.c linux/drivers/video/sbusfb.c
@@ -51,12 +51,14 @@
void sbusfb_setup(char *options, int *ints);
static int currcon;
-static int nomargins __initdata = 0;
+static int defx_margin = -1, defy_margin = -1;
+static int disable __initdata = 0;
+static char fontname[40] __initdata = { 0 };
static struct {
int depth;
int xres, yres;
int x_margin, y_margin;
-} def_margins [] __initdata = {
+} def_margins [] = {
{ 8, 1280, 1024, 64, 80 },
{ 8, 1152, 1024, 64, 80 },
{ 8, 1152, 900, 64, 18 },
@@ -145,6 +147,8 @@
if (fb->mmaped)
sbusfb_clear_margin(&fb_display[fb->vtconsole], 0);
}
+ if (fb->reset)
+ fb->reset(fb);
fb->open = 0;
} else
fb->consolecnt--;
@@ -337,39 +341,7 @@
static int sbusfb_set_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
{
-#if 1
return -EINVAL;
-#else
- struct display *display;
- int oldbpp = -1, err;
- int activate = var->activate;
- struct fb_info_sbusfb *fb = sbusfbinfo(info);
-
- if (con >= 0)
- display = &fb_display[con];
- else
- display = &fb->disp; /* used during initialization */
-
- if (var->xres > fb->var.xres || var->yres > fb->var.yres ||
- var->xres_virtual > fb->var.xres_virtual ||
- var->yres_virtual > fb->var.yres_virtual ||
- var->bits_per_pixel > fb->var.bits_per_pixel ||
- var->nonstd ||
- (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
- return -EINVAL;
- memcpy(var, &fb->var, sizeof(struct fb_var_screeninfo));
-
- if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
- oldbpp = display->var.bits_per_pixel;
- display->var = *var;
- }
- if (oldbpp != var->bits_per_pixel) {
- if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
- return err;
- do_install_cmap(con, info);
- }
- return 0;
-#endif
}
/*
@@ -487,9 +459,12 @@
(*fb->setcurshape) (fb);
fb->hw_cursor_shown = 1;
}
- fb->cursor.cpos.fbx = (x << 3) + fb->x_margin; /* x * p->fontwidth */
- if (p->fontheight == 16)
- fb->cursor.cpos.fby = (y << 4) + fb->y_margin;
+ if (p->fontwidthlog)
+ fb->cursor.cpos.fbx = (x << p->fontwidthlog) + fb->x_margin;
+ else
+ fb->cursor.cpos.fbx = (x * p->fontwidth) + fb->x_margin;
+ if (p->fontheightlog)
+ fb->cursor.cpos.fby = (y << p->fontheightlog) + fb->y_margin;
else
fb->cursor.cpos.fby = (y * p->fontheight) + fb->y_margin;
(*fb->setcursor)(fb);
@@ -591,7 +566,7 @@
case FBIOGVIDEO:
put_user_ret(fb->blanked, (int *) arg, -EFAULT);
break;
- case FBIOGETCMAP: {
+ case FBIOGETCMAP_SPARC: {
char *rp, *gp, *bp;
int end, count, index;
struct fbcmap *cmap;
@@ -623,7 +598,7 @@
(*fb->loadcmap)(fb, index, count);
break;
}
- case FBIOPUTCMAP: { /* load color map entries */
+ case FBIOPUTCMAP_SPARC: { /* load color map entries */
char *rp, *gp, *bp;
int end, count, index;
struct fbcmap *cmap;
@@ -696,19 +671,63 @@
* Setup: parse used options
*/
-void sbusfb_setup(char *options, int *ints)
+__initfunc(void sbusfb_setup(char *options, int *ints))
{
- if (!strncmp(options, "nomargins", 9))
- nomargins = 1;
+ char *p;
+
+ for (p = options;;) {
+ if (!strncmp(p, "nomargins", 9)) {
+ defx_margin = 0; defy_margin = 0;
+ } else if (!strncmp(p, "margins=", 8)) {
+ int i, j;
+ char *q;
+
+ i = simple_strtoul(p+8,&q,10);
+ if (i >= 0 && *q == 'x') {
+ j = simple_strtoul(q+1,&q,10);
+ if (j >= 0 && (*q == ' ' || !*q)) {
+ defx_margin = i; defy_margin = j;
+ }
+ }
+ } else if (!strncmp(p, "disable", 7))
+ disable = 1;
+ else if (!strncmp(p, "font=", 5)) {
+ int i;
+
+ for (i = 0; i < sizeof(fontname) - 1; i++)
+ if (p[i+5] == ' ' || !p[i+5])
+ break;
+ memcpy(fontname, p+5, i);
+ fontname[i] = 0;
+ }
+ while (*p && *p != ' ' && *p != ',') p++;
+ if (*p != ',') break;
+ p++;
+ }
}
static int sbusfbcon_switch(int con, struct fb_info *info)
{
+ int x_margin, y_margin;
+ struct fb_info_sbusfb *fb = sbusfbinfo(info);
+
/* Do we have to save the colormap? */
if (fb_display[currcon].cmap.len)
fb_get_cmap(&fb_display[currcon].cmap, &fb_display[currcon].var, 1, sbusfb_getcolreg, info);
- sbusfbinfo(info)->lastconsole = con;
+ if (fb->lastconsole != con &&
+ (fb_display[fb->lastconsole].fontwidth != fb_display[con].fontwidth ||
+ fb_display[fb->lastconsole].fontheight != fb_display[con].fontheight))
+ fb->hw_cursor_shown = 0;
+ fb->lastconsole = con;
+ x_margin = (fb_display[con].var.xres_virtual - fb_display[con].var.xres) / 2;
+ y_margin = (fb_display[con].var.yres_virtual - fb_display[con].var.yres) / 2;
+ if (fb->margins)
+ fb->margins(fb, &fb_display[con], x_margin, y_margin);
+ if (fb->x_margin != x_margin || fb->y_margin != y_margin) {
+ fb->x_margin = x_margin; fb->y_margin = y_margin;
+ sbusfb_clear_margin(&fb_display[con], 0);
+ }
currcon = con;
/* Install new colormap */
do_install_cmap(con, info);
@@ -731,23 +750,12 @@
static void sbusfbcon_blank(int blank, struct fb_info *info)
{
-#if 0
struct fb_info_sbusfb *fb = sbusfbinfo(info);
- int i, j;
-
- if (!fb->cmap_adr)
- return;
-
- if (blank)
- for (i = 0; i < 256; i++) {
- *fb->cmap_adr = i;
- for (j = 0; j < 3; j++) {
- *fb->cmap_data = 0;
- }
- }
- else
- do_install_cmap(currcon, info);
-#endif
+
+ if (blank && fb->blank)
+ return fb->blank(fb);
+ else if (!blank && fb->unblank)
+ return fb->unblank(fb);
}
/*
@@ -805,6 +813,48 @@
(*fb->loadcmap)(fb, 0, 256);
}
+static int sbusfb_set_font(struct display *p, int width, int height)
+{
+ int margin;
+ int w = p->var.xres_virtual, h = p->var.yres_virtual;
+ int depth = p->var.bits_per_pixel;
+ struct fb_info_sbusfb *fb = sbusfbinfod(p);
+ int x_margin, y_margin;
+
+ if (depth > 8) depth = 8;
+ x_margin = 0;
+ y_margin = 0;
+ if (defx_margin < 0 || defy_margin < 0) {
+ for (margin = 0; def_margins[margin].depth; margin++)
+ if (w == def_margins[margin].xres &&
+ h == def_margins[margin].yres &&
+ depth == def_margins[margin].depth) {
+ x_margin = def_margins[margin].x_margin;
+ y_margin = def_margins[margin].y_margin;
+ break;
+ }
+ } else {
+ x_margin = defx_margin;
+ y_margin = defy_margin;
+ }
+ x_margin += ((w - 2*x_margin) % width) / 2;
+ y_margin += ((h - 2*y_margin) % height) / 2;
+
+ p->var.xres = w - 2*x_margin;
+ p->var.yres = h - 2*y_margin;
+
+ fb->hw_cursor_shown = 0;
+
+ if (fb->margins)
+ fb->margins(fb, p, x_margin, y_margin);
+ if (fb->x_margin != x_margin || fb->y_margin != y_margin) {
+ fb->x_margin = x_margin; fb->y_margin = y_margin;
+ sbusfb_clear_margin(p, 0);
+ }
+
+ return 1;
+}
+
/*
* Initialisation
*/
@@ -852,7 +902,7 @@
linebytes = prom_getintdefault(node, "linebytes", w * depth / 8);
type->fb_size = PAGE_ALIGN((linebytes) * h);
- if (!nomargins)
+ if (defx_margin < 0 || defy_margin < 0) {
for (margin = 0; def_margins[margin].depth; margin++)
if (w == def_margins[margin].xres &&
h == def_margins[margin].yres &&
@@ -861,7 +911,11 @@
fb->y_margin = def_margins[margin].y_margin;
break;
}
- fb->x_margin += ((w - 2*fb->x_margin) & 15) / 2;
+ } else {
+ fb->x_margin = defx_margin;
+ fb->y_margin = defy_margin;
+ }
+ fb->x_margin += ((w - 2*fb->x_margin) & 7) / 2;
fb->y_margin += ((h - 2*fb->y_margin) & 15) / 2;
var->xres_virtual = w;
@@ -883,7 +937,7 @@
fb->info.node = -1;
fb->info.fbops = &sbusfb_ops;
fb->info.disp = disp;
- fb->info.fontname[0] = '\0';
+ strcpy(fb->info.fontname, fontname);
fb->info.changevar = NULL;
fb->info.switch_con = &sbusfbcon_switch;
fb->info.updatevar = &sbusfbcon_updatevar;
@@ -934,6 +988,7 @@
disp->dispsw = &fb->dispsw;
if (fb->setcursor)
fb->dispsw.cursor = sbusfb_cursor;
+ fb->dispsw.set_font = sbusfb_set_font;
fb->setup = fb->dispsw.setup;
fb->dispsw.setup = sbusfb_disp_setup;
@@ -942,6 +997,9 @@
disp->type = fix->type;
disp->type_aux = fix->type_aux;
disp->line_length = fix->line_length;
+
+ if (fb->blank)
+ disp->can_soft_blank = 1;
sbusfb_set_var(var, -1, &fb->info);
@@ -978,7 +1036,10 @@
struct linux_sbus_device *sbdp;
struct linux_sbus *sbus;
char prom_name[40];
-
+ extern int con_is_present(void);
+
+ if (!con_is_present() || disable) return;
+
#ifdef CONFIG_FB_CREATOR
root = prom_getchild(prom_root_node);
for (node = prom_searchsiblings(root, "SUNW,ffb"); node;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov