patch-2.1.124 linux/drivers/video/sbusfb.c
Next file: linux/drivers/video/sbusfb.h
Previous file: linux/drivers/video/s3blit.h
Back to the patch index
Back to the overall index
- Lines: 353
- Date:
Sat Oct 3 11:29:30 1998
- Orig file:
v2.1.123/linux/drivers/video/sbusfb.c
- Orig date:
Tue Jul 28 14:21:09 1998
diff -u --recursive --new-file v2.1.123/linux/drivers/video/sbusfb.c linux/drivers/video/sbusfb.c
@@ -40,8 +40,11 @@
#include <linux/vt_kern.h>
#include <asm/uaccess.h>
+#include <asm/pgtable.h> /* io_remap_page_range() */
-#include "sbusfb.h"
+#include <video/sbusfb.h>
+
+#define DEFAULT_CURSOR_BLINK_RATE (2*HZ/5)
/*
* Interface used by the world
@@ -53,6 +56,7 @@
static int currcon;
static int defx_margin = -1, defy_margin = -1;
static char fontname[40] __initdata = { 0 };
+static int curblink __initdata = 1;
static struct {
int depth;
int xres, yres;
@@ -88,8 +92,6 @@
u_long arg, int con, struct fb_info *info);
static void sbusfb_cursor(struct display *p, int mode, int x, int y);
static void sbusfb_clear_margin(struct display *p, int s);
-extern int io_remap_page_range(unsigned long from, unsigned long offset,
- unsigned long size, pgprot_t prot, int space);
/*
@@ -143,8 +145,10 @@
if (user) {
if (fb->vtconsole != -1) {
vt_cons[fb->vtconsole]->vc_mode = KD_TEXT;
- if (fb->mmaped)
+ if (fb->mmaped) {
+ fb->graphmode--;
sbusfb_clear_margin(&fb_display[fb->vtconsole], 0);
+ }
}
if (fb->reset)
fb->reset(fb);
@@ -247,7 +251,9 @@
fb->mmaped = 1;
if (fb->consolecnt && fb_display[lastconsole].fb_info == info) {
fb->vtconsole = lastconsole;
+ fb->graphmode++;
vt_cons [lastconsole]->vc_mode = KD_GRAPHICS;
+ vc_cons[lastconsole].d->vc_sw->con_cursor(vc_cons[lastconsole].d,CM_ERASE);
} else if (fb->unblank && !fb->blanked)
(*fb->unblank)(fb);
}
@@ -258,6 +264,8 @@
{
struct fb_info_sbusfb *fb = sbusfbinfod(p);
+ if (fb->switch_from_graph)
+ (*fb->switch_from_graph)(fb);
if (fb->fill) {
unsigned short rects [16];
@@ -289,13 +297,13 @@
fb_base -= (skip_bytes + fb->x_margin) / 8;
skip_bytes /= 8;
scr_size /= 8;
- memset (fb_base, ~0, skip_bytes - fb->x_margin / 8);
- memset (fb_base + scr_size - skip_bytes + fb->x_margin / 8, ~0, skip_bytes - fb->x_margin / 8);
+ mymemset (fb_base, skip_bytes - fb->x_margin / 8);
+ mymemset (fb_base + scr_size - skip_bytes + fb->x_margin / 8, skip_bytes - fb->x_margin / 8);
incr = fb->var.xres_virtual / 8;
size = fb->x_margin / 8 * 2;
for (q = fb_base + skip_bytes - fb->x_margin / 8, h = 0;
h <= he; q += incr, h++)
- memset (q, ~0, size);
+ mymemset (q, size);
} else {
fb_base -= (skip_bytes + fb->x_margin);
memset (fb_base, attr_bgcol(p,s), skip_bytes - fb->x_margin);
@@ -307,8 +315,6 @@
memset (q, attr_bgcol(p,s), size);
}
}
- if (fb->switch_from_graph)
- (*fb->switch_from_graph)(fb);
}
static void sbusfb_disp_setup(struct display *p)
@@ -414,13 +420,13 @@
copy_from_user (fb->cursor.bits [1], f.image, bytes))
return -EFAULT;
if (f.size.fbx <= 32) {
- u = ~(0xffffffff >> f.size.fbx);
+ u = 0xffffffff << (32 - f.size.fbx);
for (i = fb->cursor.size.fby - 1; i >= 0; i--) {
fb->cursor.bits [0][i] &= u;
fb->cursor.bits [1][i] &= fb->cursor.bits [0][i];
}
} else {
- u = ~(0xffffffff >> (f.size.fbx - 32));
+ u = 0xffffffff << (64 - f.size.fbx);
for (i = fb->cursor.size.fby - 1; i >= 0; i--) {
fb->cursor.bits [0][2*i+1] &= u;
fb->cursor.bits [1][2*i] &= fb->cursor.bits [0][2*i];
@@ -443,42 +449,58 @@
static unsigned char hw_cursor_cmap[2] = { 0, 0xff };
+static void
+sbusfb_cursor_timer_handler(unsigned long dev_addr)
+{
+ struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)dev_addr;
+
+ if (!fb->setcursor) return;
+
+ if (fb->cursor.mode != 2) {
+ fb->cursor.enable ^= 1;
+ fb->setcursor(fb);
+ }
+
+ fb->cursor.timer.expires = jiffies + fb->cursor.blink_rate;
+ add_timer(&fb->cursor.timer);
+}
+
static void sbusfb_cursor(struct display *p, int mode, int x, int y)
{
struct fb_info_sbusfb *fb = sbusfbinfod(p);
switch (mode) {
case CM_ERASE:
+ fb->cursor.mode = 2;
fb->cursor.enable = 0;
(*fb->setcursor)(fb);
- fb->hw_cursor_shown = 0;
break;
case CM_MOVE:
case CM_DRAW:
- if (!fb->hw_cursor_shown) {
- fb->cursor.size.fbx = p->fontwidth;
- fb->cursor.size.fby = p->fontheight;
+ if (fb->cursor.mode) {
+ fb->cursor.size.fbx = fontwidth(p);
+ fb->cursor.size.fby = fontheight(p);
fb->cursor.chot.fbx = 0;
fb->cursor.chot.fby = 0;
fb->cursor.enable = 1;
memset (fb->cursor.bits, 0, sizeof (fb->cursor.bits));
- fb->cursor.bits[0][p->fontheight - 2] = (0xffffffff << (32 - p->fontwidth));
- fb->cursor.bits[1][p->fontheight - 2] = (0xffffffff << (32 - p->fontwidth));
- fb->cursor.bits[0][p->fontheight - 1] = (0xffffffff << (32 - p->fontwidth));
- fb->cursor.bits[1][p->fontheight - 1] = (0xffffffff << (32 - p->fontwidth));
+ fb->cursor.bits[0][fontheight(p) - 2] = (0xffffffff << (32 - fontwidth(p)));
+ fb->cursor.bits[1][fontheight(p) - 2] = (0xffffffff << (32 - fontwidth(p)));
+ fb->cursor.bits[0][fontheight(p) - 1] = (0xffffffff << (32 - fontwidth(p)));
+ fb->cursor.bits[1][fontheight(p) - 1] = (0xffffffff << (32 - fontwidth(p)));
(*fb->setcursormap) (fb, hw_cursor_cmap, hw_cursor_cmap, hw_cursor_cmap);
(*fb->setcurshape) (fb);
- fb->hw_cursor_shown = 1;
+ fb->cursor.mode = 0;
}
- if (p->fontwidthlog)
- fb->cursor.cpos.fbx = (x << p->fontwidthlog) + fb->x_margin;
+ if (fontwidthlog(p))
+ fb->cursor.cpos.fbx = (x << fontwidthlog(p)) + 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;
+ fb->cursor.cpos.fbx = (x * fontwidth(p)) + fb->x_margin;
+ if (fontheightlog(p))
+ fb->cursor.cpos.fby = (y << fontheightlog(p)) + fb->y_margin;
else
- fb->cursor.cpos.fby = (y * p->fontheight) + fb->y_margin;
+ fb->cursor.cpos.fby = (y * fontheight(p)) + fb->y_margin;
(*fb->setcursor)(fb);
break;
}
@@ -492,7 +514,7 @@
struct fb_info *info)
{
if (con == currcon) /* current console? */
- return fb_get_cmap(cmap, &fb_display[con].var, kspc, sbusfb_getcolreg, info);
+ return fb_get_cmap(cmap, kspc, sbusfb_getcolreg, info);
else if (fb_display[con].cmap.len) /* non default colormap? */
fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
else
@@ -514,12 +536,12 @@
return err;
}
if (con == currcon) { /* current console? */
- err = fb_set_cmap(cmap, &fb_display[con].var, kspc, sbusfb_setcolreg, info);
+ err = fb_set_cmap(cmap, kspc, sbusfb_setcolreg, info);
if (!err) {
struct fb_info_sbusfb *fb = sbusfbinfo(info);
if (fb->loadcmap)
- (*fb->loadcmap)(fb, cmap->start, cmap->len);
+ (*fb->loadcmap)(fb, &fb_display[con], cmap->start, cmap->len);
}
return err;
} else
@@ -610,7 +632,7 @@
__put_user_ret(fb->color_map CM(i,2), bp, -EFAULT);
rp++; gp++; bp++;
}
- (*fb->loadcmap)(fb, index, count);
+ (*fb->loadcmap)(fb, NULL, index, count);
break;
}
case FBIOPUTCMAP_SPARC: { /* load color map entries */
@@ -643,7 +665,7 @@
__get_user_ret(fb->color_map CM(i,2), bp, -EFAULT);
rp++; gp++; bp++;
}
- (*fb->loadcmap)(fb, index, count);
+ (*fb->loadcmap)(fb, NULL, index, count);
break;
}
case FBIOGCURMAX: {
@@ -661,7 +683,7 @@
lastconsole = info->display_fg->vc_num;
if (vt_cons[lastconsole]->vc_mode == KD_TEXT)
return -EINVAL; /* Don't let graphics programs hide our nice text cursor */
- fb->hw_cursor_shown = 0; /* Forget state of our text cursor */
+ fb->cursor.mode = 2; /* Forget state of our text cursor */
}
return sbus_hw_scursor ((struct fbcursor *) arg, fb);
@@ -678,7 +700,8 @@
(*fb->setcursor) (fb);
break;
default:
- /* FIXME: Call here possible fb specific ioctl */
+ if (fb->ioctl)
+ return fb->ioctl(fb, cmd, arg);
return -EINVAL;
}
return 0;
@@ -714,7 +737,8 @@
break;
memcpy(fontname, p+5, i);
fontname[i] = 0;
- }
+ } else if (!strncmp(p, "noblink", 7))
+ curblink = 0;
while (*p && *p != ' ' && *p != ',') p++;
if (*p != ',') break;
p++;
@@ -729,18 +753,20 @@
/* 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);
+ fb_get_cmap(&fb_display[currcon].cmap, 1, sbusfb_getcolreg, info);
- lastconsole = info->display_fg->vc_num;
- if (lastconsole != con &&
- (fb_display[lastconsole].fontwidth != fb_display[con].fontwidth ||
- fb_display[lastconsole].fontheight != fb_display[con].fontheight))
- fb->hw_cursor_shown = 0;
+ if (info->display_fg) {
+ lastconsole = info->display_fg->vc_num;
+ if (lastconsole != con &&
+ (fontwidth(&fb_display[lastconsole]) != fontwidth(&fb_display[con]) ||
+ fontheight(&fb_display[lastconsole]) != fontheight(&fb_display[con])))
+ fb->cursor.mode = 1;
+ }
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) {
+ if (fb->graphmode || 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);
}
@@ -786,9 +812,10 @@
if (!fb->color_map || regno > 255)
return 1;
- *red = fb->color_map CM(regno, 0);
- *green = fb->color_map CM(regno, 1);
- *blue = fb->color_map CM(regno, 2);
+ *red = (fb->color_map CM(regno, 0)<<8) | fb->color_map CM(regno, 0);
+ *green = (fb->color_map CM(regno, 1)<<8) | fb->color_map CM(regno, 1);
+ *blue = (fb->color_map CM(regno, 2)<<8) | fb->color_map CM(regno, 2);
+ *transp = 0;
return 0;
}
@@ -806,6 +833,9 @@
if (!fb->color_map || regno > 255)
return 1;
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
fb->color_map CM(regno, 0) = red;
fb->color_map CM(regno, 1) = green;
fb->color_map CM(regno, 2) = blue;
@@ -820,13 +850,12 @@
if (con != currcon)
return;
if (fb_display[con].cmap.len)
- fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
- sbusfb_setcolreg, info);
+ fb_set_cmap(&fb_display[con].cmap, 1, sbusfb_setcolreg, info);
else
fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
- &fb_display[con].var, 1, sbusfb_setcolreg, info);
+ 1, sbusfb_setcolreg, info);
if (fb->loadcmap)
- (*fb->loadcmap)(fb, 0, 256);
+ (*fb->loadcmap)(fb, &fb_display[con], 0, 256);
}
static int sbusfb_set_font(struct display *p, int width, int height)
@@ -859,7 +888,7 @@
p->var.xres = w - 2*x_margin;
p->var.yres = h - 2*y_margin;
- fb->hw_cursor_shown = 0;
+ fb->cursor.mode = 1;
if (fb->margins)
fb->margins(fb, p, x_margin, y_margin);
@@ -987,6 +1016,7 @@
fb->info.switch_con = &sbusfbcon_switch;
fb->info.updatevar = &sbusfbcon_updatevar;
fb->info.blank = &sbusfbcon_blank;
+ fb->info.flags = FBINFO_FLAG_DEFAULT;
fb->cursor.hwsize.fbx = 32;
fb->cursor.hwsize.fby = 32;
@@ -1034,8 +1064,17 @@
goto sizechange;
disp->dispsw = &fb->dispsw;
- if (fb->setcursor)
+ if (fb->setcursor) {
fb->dispsw.cursor = sbusfb_cursor;
+ if (curblink) {
+ fb->cursor.blink_rate = DEFAULT_CURSOR_BLINK_RATE;
+ init_timer(&fb->cursor.timer);
+ fb->cursor.timer.expires = jiffies + fb->cursor.blink_rate;
+ fb->cursor.timer.data = (unsigned long)fb;
+ fb->cursor.timer.function = sbusfb_cursor_timer_handler;
+ add_timer(&fb->cursor.timer);
+ }
+ }
fb->dispsw.set_font = sbusfb_set_font;
fb->setup = fb->dispsw.setup;
fb->dispsw.setup = sbusfb_disp_setup;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov