add idl4k kernel firmware version 1.13.0.105

This commit is contained in:
Jaroslav Kysela
2015-03-26 17:22:37 +01:00
parent 5194d2792e
commit e9070cdc77
31064 changed files with 12769984 additions and 0 deletions

View File

@@ -0,0 +1,242 @@
#
# Video configuration
#
menu "Console display driver support"
config VGA_CONSOLE
bool "VGA text console" if EMBEDDED || !X86
depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC && !M68K && !PARISC && !FRV && !ARCH_VERSATILE && !SUPERH && !BLACKFIN && !AVR32 && !MN10300
default y
help
Saying Y here will allow you to use Linux in text mode through a
display that complies with the generic VGA standard. Virtually
everyone wants that.
The program SVGATextMode can be used to utilize SVGA video cards to
their full potential in text mode. Download it from
<ftp://ibiblio.org/pub/Linux/utils/console/>.
Say Y.
config VGACON_SOFT_SCROLLBACK
bool "Enable Scrollback Buffer in System RAM"
depends on VGA_CONSOLE
default n
help
The scrollback buffer of the standard VGA console is located in
the VGA RAM. The size of this RAM is fixed and is quite small.
If you require a larger scrollback buffer, this can be placed in
System RAM which is dynamically allocated during initialization.
Placing the scrollback buffer in System RAM will slightly slow
down the console.
If you want this feature, say 'Y' here and enter the amount of
RAM to allocate for this buffer. If unsure, say 'N'.
config VGACON_SOFT_SCROLLBACK_SIZE
int "Scrollback Buffer Size (in KB)"
depends on VGACON_SOFT_SCROLLBACK
default "64"
help
Enter the amount of System RAM to allocate for the scrollback
buffer. Each 64KB will give you approximately 16 80x25
screenfuls of scrollback buffer
config MDA_CONSOLE
depends on !M68K && !PARISC && ISA
tristate "MDA text console (dual-headed) (EXPERIMENTAL)"
---help---
Say Y here if you have an old MDA or monochrome Hercules graphics
adapter in your system acting as a second head ( = video card). You
will then be able to use two monitors with your Linux system. Do not
say Y here if your MDA card is the primary card in your system; the
normal VGA driver will handle it.
To compile this driver as a module, choose M here: the
module will be called mdacon.
If unsure, say N.
config SGI_NEWPORT_CONSOLE
tristate "SGI Newport Console support"
depends on SGI_IP22
help
Say Y here if you want the console on the Newport aka XL graphics
card of your Indy. Most people say Y here.
# bool 'IODC console' CONFIG_IODC_CONSOLE
config DUMMY_CONSOLE
bool
depends on VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y
default y
config DUMMY_CONSOLE_COLUMNS
int "Initial number of console screen columns"
depends on PARISC && DUMMY_CONSOLE
default "160"
help
The default value is 160, which should fit a 1280x1024 monitor.
Select 80 if you use a 640x480 resolution by default.
config DUMMY_CONSOLE_ROWS
int "Initial number of console screen rows"
depends on PARISC && DUMMY_CONSOLE
default "64"
help
The default value is 64, which should fit a 1280x1024 monitor.
Select 25 if you use a 640x480 resolution by default.
config FRAMEBUFFER_CONSOLE
tristate "Framebuffer Console support"
depends on FB
select CRC32
help
Low-level framebuffer-based console driver.
config FRAMEBUFFER_CONSOLE_DETECT_PRIMARY
bool "Map the console to the primary display device"
depends on FRAMEBUFFER_CONSOLE
default n
---help---
If this option is selected, the framebuffer console will
automatically select the primary display device (if the architecture
supports this feature). Otherwise, the framebuffer console will
always select the first framebuffer driver that is loaded. The latter
is the default behavior.
You can always override the automatic selection of the primary device
by using the fbcon=map: boot option.
If unsure, select n.
config FRAMEBUFFER_CONSOLE_ROTATION
bool "Framebuffer Console Rotation"
depends on FRAMEBUFFER_CONSOLE
help
Enable display rotation for the framebuffer console. This is done
in software and may be significantly slower than a normally oriented
display. Note that the rotation is done at the console level only
such that other users of the framebuffer will remain normally
oriented.
config FB_CON_DECOR
bool "Support for the Framebuffer Console Decorations"
depends on FRAMEBUFFER_CONSOLE=y && !FB_TILEBLITTING
default n
help
This option enables support for framebuffer console decorations which
makes it possible to display images in the background of the system
consoles. Note that userspace utilities are necessary in order to take
advantage of these features. Refer to Documentation/fb/fbcondecor.txt
for more information.
If unsure, say N.
config STI_CONSOLE
bool "STI text console"
depends on PARISC
default y
help
The STI console is the builtin display/keyboard on HP-PARISC
machines. Say Y here to build support for it into your kernel.
The alternative is to use your primary serial port as a console.
config FONTS
bool "Select compiled-in fonts"
depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
help
Say Y here if you would like to use fonts other than the default
your frame buffer console usually use.
Note that the answer to this question won't directly affect the
kernel: saying N will just cause the configurator to skip all
the questions about foreign fonts.
If unsure, say N (the default choices are safe).
config FONT_8x8
bool "VGA 8x8 font" if FONTS
depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
default y if !SPARC && !FONTS
help
This is the "high resolution" font for the VGA frame buffer (the one
provided by the text console 80x50 (and higher) modes).
Note that this is a poor quality font. The VGA 8x16 font is quite a
lot more readable.
Given the resolution provided by the frame buffer device, answer N
here is safe.
config FONT_8x16
bool "VGA 8x16 font" if FONTS
depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE || STI_CONSOLE || USB_SISUSBVGA_CON
default y if !SPARC && !FONTS
help
This is the "high resolution" font for the VGA frame buffer (the one
provided by the VGA text console 80x25 mode.
If unsure, say Y.
config FONT_6x11
bool "Mac console 6x11 font (not supported by all drivers)" if FONTS
depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
default y if !SPARC && !FONTS && MAC
help
Small console font with Macintosh-style high-half glyphs. Some Mac
framebuffer drivers don't support this one at all.
config FONT_7x14
bool "console 7x14 font (not supported by all drivers)" if FONTS
depends on FRAMEBUFFER_CONSOLE
help
Console font with characters just a bit smaller than the default.
If the standard 8x16 font is a little too big for you, say Y.
Otherwise, say N.
config FONT_PEARL_8x8
bool "Pearl (old m68k) console 8x8 font" if FONTS
depends on FRAMEBUFFER_CONSOLE
default y if !SPARC && !FONTS && AMIGA
help
Small console font with PC-style control-character and high-half
glyphs.
config FONT_ACORN_8x8
bool "Acorn console 8x8 font" if FONTS
depends on FRAMEBUFFER_CONSOLE
default y if !SPARC && !FONTS && ARM && ARCH_ACORN
help
Small console font with PC-style control characters and high-half
glyphs.
config FONT_MINI_4x6
bool "Mini 4x6 font"
depends on !SPARC && FONTS
config FONT_SUN8x16
bool "Sparc console 8x16 font"
depends on FRAMEBUFFER_CONSOLE && (!SPARC && FONTS || SPARC)
help
This is the high resolution console font for Sun machines. Say Y.
config FONT_SUN12x22
bool "Sparc console 12x22 font (not supported by all drivers)"
depends on FRAMEBUFFER_CONSOLE && (!SPARC && FONTS || SPARC)
help
This is the high resolution console font for Sun machines with very
big letters (like the letters used in the SPARC PROM). If the
standard font is unreadable for you, say Y, otherwise say N.
config FONT_10x18
bool "console 10x18 font (not supported by all drivers)" if FONTS
depends on FRAMEBUFFER_CONSOLE
help
This is a high resolution console font for machines with very
big letters. It fits between the sun 12x22 and the normal 8x16 font.
If other fonts are too big or too small for you, say Y, otherwise say N.
endmenu

View File

@@ -0,0 +1,42 @@
# Makefile for the Linux graphics to console drivers.
# 5 Aug 1999, James Simmons, <mailto:jsimmons@users.sf.net>
# Rewritten to use lists instead of if-statements.
# Font handling
font-objs := fonts.o
font-objs-$(CONFIG_FONT_SUN8x16) += font_sun8x16.o
font-objs-$(CONFIG_FONT_SUN12x22) += font_sun12x22.o
font-objs-$(CONFIG_FONT_8x8) += font_8x8.o
font-objs-$(CONFIG_FONT_8x16) += font_8x16.o
font-objs-$(CONFIG_FONT_6x11) += font_6x11.o
font-objs-$(CONFIG_FONT_7x14) += font_7x14.o
font-objs-$(CONFIG_FONT_10x18) += font_10x18.o
font-objs-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o
font-objs-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o
font-objs-$(CONFIG_FONT_MINI_4x6) += font_mini_4x6.o
font-objs += $(font-objs-y)
# Each configuration option enables a list of files.
obj-$(CONFIG_DUMMY_CONSOLE) += dummycon.o
obj-$(CONFIG_SGI_NEWPORT_CONSOLE) += newport_con.o font.o
obj-$(CONFIG_STI_CONSOLE) += sticon.o sticore.o font.o
obj-$(CONFIG_VGA_CONSOLE) += vgacon.o
obj-$(CONFIG_MDA_CONSOLE) += mdacon.o
obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o bitblit.o font.o softcursor.o
ifeq ($(CONFIG_FB_TILEBLITTING),y)
obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += tileblit.o
endif
ifeq ($(CONFIG_FRAMEBUFFER_CONSOLE_ROTATION),y)
obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon_rotate.o fbcon_cw.o fbcon_ud.o \
fbcon_ccw.o
endif
obj-$(CONFIG_FB_CON_DECOR) += fbcondecor.o cfbcondecor.o
obj-$(CONFIG_FB_STI) += sticore.o font.o
ifeq ($(CONFIG_USB_SISUSBVGA_CON),y)
obj-$(CONFIG_USB_SISUSBVGA) += font.o
endif

View File

@@ -0,0 +1,433 @@
/*
* linux/drivers/video/console/bitblit.c -- BitBlitting Operation
*
* Originally from the 'accel_*' routines in drivers/video/console/fbcon.c
*
* Copyright (C) 2004 Antonino Daplas <adaplas @pol.net>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*/
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <linux/vt_kern.h>
#include <linux/console.h>
#include <asm/types.h>
#include "fbcon.h"
#include "fbcondecor.h"
/*
* Accelerated handlers.
*/
static inline void update_attr(u8 *dst, u8 *src, int attribute,
struct vc_data *vc)
{
int i, offset = (vc->vc_font.height < 10) ? 1 : 2;
int width = DIV_ROUND_UP(vc->vc_font.width, 8);
unsigned int cellsize = vc->vc_font.height * width;
u8 c;
offset = cellsize - (offset * width);
for (i = 0; i < cellsize; i++) {
c = src[i];
if (attribute & FBCON_ATTRIBUTE_UNDERLINE && i >= offset)
c = 0xff;
if (attribute & FBCON_ATTRIBUTE_BOLD)
c |= c >> 1;
if (attribute & FBCON_ATTRIBUTE_REVERSE)
c = ~c;
dst[i] = c;
}
}
static void bit_bmove(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int dy, int dx, int height, int width)
{
struct fb_copyarea area;
area.sx = sx * vc->vc_font.width;
area.sy = sy * vc->vc_font.height;
area.dx = dx * vc->vc_font.width;
area.dy = dy * vc->vc_font.height;
area.height = height * vc->vc_font.height;
area.width = width * vc->vc_font.width;
if (fbcon_decor_active(info, vc)) {
area.sx += vc->vc_decor.tx;
area.sy += vc->vc_decor.ty;
area.dx += vc->vc_decor.tx;
area.dy += vc->vc_decor.ty;
}
info->fbops->fb_copyarea(info, &area);
}
static void bit_clear(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int height, int width)
{
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
struct fb_fillrect region;
region.color = attr_bgcol_ec(bgshift, vc, info);
region.dx = sx * vc->vc_font.width;
region.dy = sy * vc->vc_font.height;
region.width = width * vc->vc_font.width;
region.height = height * vc->vc_font.height;
region.rop = ROP_COPY;
info->fbops->fb_fillrect(info, &region);
}
static inline void bit_putcs_aligned(struct vc_data *vc, struct fb_info *info,
const u16 *s, u32 attr, u32 cnt,
u32 d_pitch, u32 s_pitch, u32 cellsize,
struct fb_image *image, u8 *buf, u8 *dst)
{
u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
u32 idx = vc->vc_font.width >> 3;
u8 *src;
while (cnt--) {
src = vc->vc_font.data + (scr_readw(s++)&
charmask)*cellsize;
if (attr) {
update_attr(buf, src, attr, vc);
src = buf;
}
if (likely(idx == 1))
__fb_pad_aligned_buffer(dst, d_pitch, src, idx,
image->height);
else
fb_pad_aligned_buffer(dst, d_pitch, src, idx,
image->height);
dst += s_pitch;
}
info->fbops->fb_imageblit(info, image);
}
static inline void bit_putcs_unaligned(struct vc_data *vc,
struct fb_info *info, const u16 *s,
u32 attr, u32 cnt, u32 d_pitch,
u32 s_pitch, u32 cellsize,
struct fb_image *image, u8 *buf,
u8 *dst)
{
u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
u32 shift_low = 0, mod = vc->vc_font.width % 8;
u32 shift_high = 8;
u32 idx = vc->vc_font.width >> 3;
u8 *src;
while (cnt--) {
src = vc->vc_font.data + (scr_readw(s++)&
charmask)*cellsize;
if (attr) {
update_attr(buf, src, attr, vc);
src = buf;
}
fb_pad_unaligned_buffer(dst, d_pitch, src, idx,
image->height, shift_high,
shift_low, mod);
shift_low += mod;
dst += (shift_low >= 8) ? s_pitch : s_pitch - 1;
shift_low &= 7;
shift_high = 8 - shift_low;
}
info->fbops->fb_imageblit(info, image);
}
static void bit_putcs(struct vc_data *vc, struct fb_info *info,
const unsigned short *s, int count, int yy, int xx,
int fg, int bg)
{
struct fb_image image;
u32 width = DIV_ROUND_UP(vc->vc_font.width, 8);
u32 cellsize = width * vc->vc_font.height;
u32 maxcnt = info->pixmap.size/cellsize;
u32 scan_align = info->pixmap.scan_align - 1;
u32 buf_align = info->pixmap.buf_align - 1;
u32 mod = vc->vc_font.width % 8, cnt, pitch, size;
u32 attribute = get_attribute(info, scr_readw(s));
u8 *dst, *buf = NULL;
image.fg_color = fg;
image.bg_color = bg;
image.dx = xx * vc->vc_font.width;
image.dy = yy * vc->vc_font.height;
image.height = vc->vc_font.height;
image.depth = 1;
if (attribute) {
buf = kmalloc(cellsize, GFP_KERNEL);
if (!buf)
return;
}
while (count) {
if (count > maxcnt)
cnt = maxcnt;
else
cnt = count;
image.width = vc->vc_font.width * cnt;
pitch = DIV_ROUND_UP(image.width, 8) + scan_align;
pitch &= ~scan_align;
size = pitch * image.height + buf_align;
size &= ~buf_align;
dst = fb_get_buffer_offset(info, &info->pixmap, size);
image.data = dst;
if (!mod)
bit_putcs_aligned(vc, info, s, attribute, cnt, pitch,
width, cellsize, &image, buf, dst);
else
bit_putcs_unaligned(vc, info, s, attribute, cnt,
pitch, width, cellsize, &image,
buf, dst);
image.dx += cnt * vc->vc_font.width;
count -= cnt;
s += cnt;
}
/* buf is always NULL except when in monochrome mode, so in this case
it's a gain to check buf against NULL even though kfree() handles
NULL pointers just fine */
if (unlikely(buf))
kfree(buf);
}
static void bit_clear_margins(struct vc_data *vc, struct fb_info *info,
int bottom_only)
{
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
unsigned int cw = vc->vc_font.width;
unsigned int ch = vc->vc_font.height;
unsigned int rw = info->var.xres - (vc->vc_cols*cw);
unsigned int bh = info->var.yres - (vc->vc_rows*ch);
unsigned int rs = info->var.xres - rw;
unsigned int bs = info->var.yres - bh;
struct fb_fillrect region;
region.color = attr_bgcol_ec(bgshift, vc, info);
region.rop = ROP_COPY;
if (rw && !bottom_only) {
region.dx = info->var.xoffset + rs;
region.dy = 0;
region.width = rw;
region.height = info->var.yres_virtual;
info->fbops->fb_fillrect(info, &region);
}
if (bh) {
region.dx = info->var.xoffset;
region.dy = info->var.yoffset + bs;
region.width = rs;
region.height = bh;
info->fbops->fb_fillrect(info, &region);
}
}
static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
int softback_lines, int fg, int bg)
{
struct fb_cursor cursor;
struct fbcon_ops *ops = info->fbcon_par;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
int w = DIV_ROUND_UP(vc->vc_font.width, 8), c;
int y = real_y(ops->p, vc->vc_y);
int attribute, use_sw = (vc->vc_cursor_type & 0x10);
int err = 1;
char *src;
cursor.set = 0;
if (softback_lines) {
if (y + softback_lines >= vc->vc_rows) {
mode = CM_ERASE;
ops->cursor_flash = 0;
return;
} else
y += softback_lines;
}
c = scr_readw((u16 *) vc->vc_pos);
attribute = get_attribute(info, c);
src = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height));
if (ops->cursor_state.image.data != src ||
ops->cursor_reset) {
ops->cursor_state.image.data = src;
cursor.set |= FB_CUR_SETIMAGE;
}
if (attribute) {
u8 *dst;
dst = kmalloc(w * vc->vc_font.height, GFP_ATOMIC);
if (!dst)
return;
kfree(ops->cursor_data);
ops->cursor_data = dst;
update_attr(dst, src, attribute, vc);
src = dst;
}
if (ops->cursor_state.image.fg_color != fg ||
ops->cursor_state.image.bg_color != bg ||
ops->cursor_reset) {
ops->cursor_state.image.fg_color = fg;
ops->cursor_state.image.bg_color = bg;
cursor.set |= FB_CUR_SETCMAP;
}
if ((ops->cursor_state.image.dx != (vc->vc_font.width * vc->vc_x)) ||
(ops->cursor_state.image.dy != (vc->vc_font.height * y)) ||
ops->cursor_reset) {
ops->cursor_state.image.dx = vc->vc_font.width * vc->vc_x;
ops->cursor_state.image.dy = vc->vc_font.height * y;
cursor.set |= FB_CUR_SETPOS;
}
if (ops->cursor_state.image.height != vc->vc_font.height ||
ops->cursor_state.image.width != vc->vc_font.width ||
ops->cursor_reset) {
ops->cursor_state.image.height = vc->vc_font.height;
ops->cursor_state.image.width = vc->vc_font.width;
cursor.set |= FB_CUR_SETSIZE;
}
if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
ops->cursor_reset) {
ops->cursor_state.hot.x = cursor.hot.y = 0;
cursor.set |= FB_CUR_SETHOT;
}
if (cursor.set & FB_CUR_SETSIZE ||
vc->vc_cursor_type != ops->p->cursor_shape ||
ops->cursor_state.mask == NULL ||
ops->cursor_reset) {
char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC);
int cur_height, size, i = 0;
u8 msk = 0xff;
if (!mask)
return;
kfree(ops->cursor_state.mask);
ops->cursor_state.mask = mask;
ops->p->cursor_shape = vc->vc_cursor_type;
cursor.set |= FB_CUR_SETSHAPE;
switch (ops->p->cursor_shape & CUR_HWMASK) {
case CUR_NONE:
cur_height = 0;
break;
case CUR_UNDERLINE:
cur_height = (vc->vc_font.height < 10) ? 1 : 2;
break;
case CUR_LOWER_THIRD:
cur_height = vc->vc_font.height/3;
break;
case CUR_LOWER_HALF:
cur_height = vc->vc_font.height >> 1;
break;
case CUR_TWO_THIRDS:
cur_height = (vc->vc_font.height << 1)/3;
break;
case CUR_BLOCK:
default:
cur_height = vc->vc_font.height;
break;
}
size = (vc->vc_font.height - cur_height) * w;
while (size--)
mask[i++] = ~msk;
size = cur_height * w;
while (size--)
mask[i++] = msk;
}
switch (mode) {
case CM_ERASE:
ops->cursor_state.enable = 0;
break;
case CM_DRAW:
case CM_MOVE:
default:
ops->cursor_state.enable = (use_sw) ? 0 : 1;
break;
}
cursor.image.data = src;
cursor.image.fg_color = ops->cursor_state.image.fg_color;
cursor.image.bg_color = ops->cursor_state.image.bg_color;
cursor.image.dx = ops->cursor_state.image.dx;
cursor.image.dy = ops->cursor_state.image.dy;
cursor.image.height = ops->cursor_state.image.height;
cursor.image.width = ops->cursor_state.image.width;
cursor.hot.x = ops->cursor_state.hot.x;
cursor.hot.y = ops->cursor_state.hot.y;
cursor.mask = ops->cursor_state.mask;
cursor.enable = ops->cursor_state.enable;
cursor.image.depth = 1;
cursor.rop = ROP_XOR;
if (fbcon_decor_active(info, vc)) {
fbcon_decor_cursor(info, &cursor);
} else {
if (info->fbops->fb_cursor)
err = info->fbops->fb_cursor(info, &cursor);
if (err)
soft_cursor(info, &cursor);
}
ops->cursor_reset = 0;
}
static int bit_update_start(struct fb_info *info)
{
struct fbcon_ops *ops = info->fbcon_par;
int err;
err = fb_pan_display(info, &ops->var);
ops->var.xoffset = info->var.xoffset;
ops->var.yoffset = info->var.yoffset;
ops->var.vmode = info->var.vmode;
return err;
}
void fbcon_set_bitops(struct fbcon_ops *ops)
{
ops->bmove = bit_bmove;
ops->clear = bit_clear;
ops->putcs = bit_putcs;
ops->clear_margins = bit_clear_margins;
ops->cursor = bit_cursor;
ops->update_start = bit_update_start;
ops->rotate_font = NULL;
if (ops->rotate)
fbcon_set_rotate(ops);
}
EXPORT_SYMBOL(fbcon_set_bitops);
MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
MODULE_DESCRIPTION("Bit Blitting Operation");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,471 @@
/*
* linux/drivers/video/cfbcon_decor.c -- Framebuffer decor render functions
*
* Copyright (C) 2004 Michal Januszewski <spock@gentoo.org>
*
* Code based upon "Bootdecor" (C) 2001-2003
* Volker Poplawski <volker@poplawski.de>,
* Stefan Reinauer <stepan@suse.de>,
* Steffen Winterfeldt <snwint@suse.de>,
* Michael Schroeder <mls@suse.de>,
* Ken Wimer <wimer@suse.de>.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fb.h>
#include <linux/selection.h>
#include <linux/vt_kern.h>
#include <asm/irq.h>
#include <asm/system.h>
#include "fbcon.h"
#include "fbcondecor.h"
#define parse_pixel(shift,bpp,type) \
do { \
if (d & (0x80 >> (shift))) \
dd2[(shift)] = fgx; \
else \
dd2[(shift)] = transparent ? *(type *)decor_src : bgx; \
decor_src += (bpp); \
} while (0) \
extern int get_color(struct vc_data *vc, struct fb_info *info,
u16 c, int is_fg);
void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc)
{
int i, j, k;
int minlen = min(min(info->var.red.length, info->var.green.length),
info->var.blue.length);
u32 col;
for (j = i = 0; i < 16; i++) {
k = color_table[i];
col = ((vc->vc_palette[j++] >> (8-minlen))
<< info->var.red.offset);
col |= ((vc->vc_palette[j++] >> (8-minlen))
<< info->var.green.offset);
col |= ((vc->vc_palette[j++] >> (8-minlen))
<< info->var.blue.offset);
((u32 *)info->pseudo_palette)[k] = col;
}
}
void fbcon_decor_renderc(struct fb_info *info, int ypos, int xpos, int height,
int width, u8* src, u32 fgx, u32 bgx, u8 transparent)
{
unsigned int x, y;
u32 dd;
int bytespp = ((info->var.bits_per_pixel + 7) >> 3);
unsigned int d = ypos * info->fix.line_length + xpos * bytespp;
unsigned int ds = (ypos * info->var.xres + xpos) * bytespp;
u16 dd2[4];
u8* decor_src = (u8 *)(info->bgdecor.data + ds);
u8* dst = (u8 *)(info->screen_base + d);
if ((ypos + height) > info->var.yres || (xpos + width) > info->var.xres)
return;
for (y = 0; y < height; y++) {
switch (info->var.bits_per_pixel) {
case 32:
for (x = 0; x < width; x++) {
if ((x & 7) == 0)
d = *src++;
if (d & 0x80)
dd = fgx;
else
dd = transparent ?
*(u32 *)decor_src : bgx;
d <<= 1;
decor_src += 4;
fb_writel(dd, dst);
dst += 4;
}
break;
case 24:
for (x = 0; x < width; x++) {
if ((x & 7) == 0)
d = *src++;
if (d & 0x80)
dd = fgx;
else
dd = transparent ?
(*(u32 *)decor_src & 0xffffff) : bgx;
d <<= 1;
decor_src += 3;
#ifdef __LITTLE_ENDIAN
fb_writew(dd & 0xffff, dst);
dst += 2;
fb_writeb((dd >> 16), dst);
#else
fb_writew(dd >> 8, dst);
dst += 2;
fb_writeb(dd & 0xff, dst);
#endif
dst++;
}
break;
case 16:
for (x = 0; x < width; x += 2) {
if ((x & 7) == 0)
d = *src++;
parse_pixel(0, 2, u16);
parse_pixel(1, 2, u16);
#ifdef __LITTLE_ENDIAN
dd = dd2[0] | (dd2[1] << 16);
#else
dd = dd2[1] | (dd2[0] << 16);
#endif
d <<= 2;
fb_writel(dd, dst);
dst += 4;
}
break;
case 8:
for (x = 0; x < width; x += 4) {
if ((x & 7) == 0)
d = *src++;
parse_pixel(0, 1, u8);
parse_pixel(1, 1, u8);
parse_pixel(2, 1, u8);
parse_pixel(3, 1, u8);
#ifdef __LITTLE_ENDIAN
dd = dd2[0] | (dd2[1] << 8) | (dd2[2] << 16) | (dd2[3] << 24);
#else
dd = dd2[3] | (dd2[2] << 8) | (dd2[1] << 16) | (dd2[0] << 24);
#endif
d <<= 4;
fb_writel(dd, dst);
dst += 4;
}
}
dst += info->fix.line_length - width * bytespp;
decor_src += (info->var.xres - width) * bytespp;
}
}
#define cc2cx(a) \
((info->fix.visual == FB_VISUAL_TRUECOLOR || \
info->fix.visual == FB_VISUAL_DIRECTCOLOR) ? \
((u32*)info->pseudo_palette)[a] : a)
void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info,
const unsigned short *s, int count, int yy, int xx)
{
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
struct fbcon_ops *ops = info->fbcon_par;
int fg_color, bg_color, transparent;
u8 *src;
u32 bgx, fgx;
u16 c = scr_readw(s);
fg_color = get_color(vc, info, c, 1);
bg_color = get_color(vc, info, c, 0);
/* Don't paint the background image if console is blanked */
transparent = ops->blank_state ? 0 :
(vc->vc_decor.bg_color == bg_color);
xx = xx * vc->vc_font.width + vc->vc_decor.tx;
yy = yy * vc->vc_font.height + vc->vc_decor.ty;
fgx = cc2cx(fg_color);
bgx = cc2cx(bg_color);
while (count--) {
c = scr_readw(s++);
src = vc->vc_font.data + (c & charmask) * vc->vc_font.height *
((vc->vc_font.width + 7) >> 3);
fbcon_decor_renderc(info, yy, xx, vc->vc_font.height,
vc->vc_font.width, src, fgx, bgx, transparent);
xx += vc->vc_font.width;
}
}
void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
int i;
unsigned int dsize, s_pitch;
struct fbcon_ops *ops = info->fbcon_par;
struct vc_data* vc;
u8 *src;
/* we really don't need any cursors while the console is blanked */
if (info->state != FBINFO_STATE_RUNNING || ops->blank_state)
return;
vc = vc_cons[ops->currcon].d;
src = kmalloc(64 + sizeof(struct fb_image), GFP_ATOMIC);
if (!src)
return;
s_pitch = (cursor->image.width + 7) >> 3;
dsize = s_pitch * cursor->image.height;
if (cursor->enable) {
switch (cursor->rop) {
case ROP_XOR:
for (i = 0; i < dsize; i++)
src[i] = cursor->image.data[i] ^ cursor->mask[i];
break;
case ROP_COPY:
default:
for (i = 0; i < dsize; i++)
src[i] = cursor->image.data[i] & cursor->mask[i];
break;
}
} else
memcpy(src, cursor->image.data, dsize);
fbcon_decor_renderc(info,
cursor->image.dy + vc->vc_decor.ty,
cursor->image.dx + vc->vc_decor.tx,
cursor->image.height,
cursor->image.width,
(u8*)src,
cc2cx(cursor->image.fg_color),
cc2cx(cursor->image.bg_color),
cursor->image.bg_color == vc->vc_decor.bg_color);
kfree(src);
}
static void decorset(u8 *dst, int height, int width, int dstbytes,
u32 bgx, int bpp)
{
int i;
if (bpp == 8)
bgx |= bgx << 8;
if (bpp == 16 || bpp == 8)
bgx |= bgx << 16;
while (height-- > 0) {
u8 *p = dst;
switch (bpp) {
case 32:
for (i=0; i < width; i++) {
fb_writel(bgx, p); p += 4;
}
break;
case 24:
for (i=0; i < width; i++) {
#ifdef __LITTLE_ENDIAN
fb_writew((bgx & 0xffff),(u16*)p); p += 2;
fb_writeb((bgx >> 16),p++);
#else
fb_writew((bgx >> 8),(u16*)p); p += 2;
fb_writeb((bgx & 0xff),p++);
#endif
}
case 16:
for (i=0; i < width/4; i++) {
fb_writel(bgx,p); p += 4;
fb_writel(bgx,p); p += 4;
}
if (width & 2) {
fb_writel(bgx,p); p += 4;
}
if (width & 1)
fb_writew(bgx,(u16*)p);
break;
case 8:
for (i=0; i < width/4; i++) {
fb_writel(bgx,p); p += 4;
}
if (width & 2) {
fb_writew(bgx,p); p += 2;
}
if (width & 1)
fb_writeb(bgx,(u8*)p);
break;
}
dst += dstbytes;
}
}
void fbcon_decor_copy(u8 *dst, u8 *src, int height, int width, int linebytes,
int srclinebytes, int bpp)
{
int i;
while (height-- > 0) {
u32 *p = (u32 *)dst;
u32 *q = (u32 *)src;
switch (bpp) {
case 32:
for (i=0; i < width; i++)
fb_writel(*q++, p++);
break;
case 24:
for (i=0; i < (width*3/4); i++)
fb_writel(*q++, p++);
if ((width*3) % 4) {
if (width & 2) {
fb_writeb(*(u8*)q, (u8*)p);
} else if (width & 1) {
fb_writew(*(u16*)q, (u16*)p);
fb_writeb(*(u8*)((u16*)q+1),(u8*)((u16*)p+2));
}
}
break;
case 16:
for (i=0; i < width/4; i++) {
fb_writel(*q++, p++);
fb_writel(*q++, p++);
}
if (width & 2)
fb_writel(*q++, p++);
if (width & 1)
fb_writew(*(u16*)q, (u16*)p);
break;
case 8:
for (i=0; i < width/4; i++)
fb_writel(*q++, p++);
if (width & 2) {
fb_writew(*(u16*)q, (u16*)p);
q = (u32*) ((u16*)q + 1);
p = (u32*) ((u16*)p + 1);
}
if (width & 1)
fb_writeb(*(u8*)q, (u8*)p);
break;
}
dst += linebytes;
src += srclinebytes;
}
}
static void decorfill(struct fb_info *info, int sy, int sx, int height,
int width)
{
int bytespp = ((info->var.bits_per_pixel + 7) >> 3);
int d = sy * info->fix.line_length + sx * bytespp;
int ds = (sy * info->var.xres + sx) * bytespp;
fbcon_decor_copy((u8 *)(info->screen_base + d), (u8 *)(info->bgdecor.data + ds),
height, width, info->fix.line_length, info->var.xres * bytespp,
info->var.bits_per_pixel);
}
void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx,
int height, int width)
{
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
int bg_color = attr_bgcol_ec(bgshift, vc);
int transparent = vc->vc_decor.bg_color == bg_color;
struct fbcon_ops *ops = info->fbcon_par;
u8 *dst;
sy = sy * vc->vc_font.height + vc->vc_decor.ty;
sx = sx * vc->vc_font.width + vc->vc_decor.tx;
height *= vc->vc_font.height;
width *= vc->vc_font.width;
/* Don't paint the background image if console is blanked */
if (transparent && !ops->blank_state) {
decorfill(info, sy, sx, height, width);
} else {
dst = (u8 *)(info->screen_base + sy * info->fix.line_length +
sx * ((info->var.bits_per_pixel + 7) >> 3));
decorset(dst, height, width, info->fix.line_length, cc2cx(bg_color),
info->var.bits_per_pixel);
}
}
void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info,
int bottom_only)
{
unsigned int tw = vc->vc_cols*vc->vc_font.width;
unsigned int th = vc->vc_rows*vc->vc_font.height;
if (!bottom_only) {
/* top margin */
decorfill(info, 0, 0, vc->vc_decor.ty, info->var.xres);
/* left margin */
decorfill(info, vc->vc_decor.ty, 0, th, vc->vc_decor.tx);
/* right margin */
decorfill(info, vc->vc_decor.ty, vc->vc_decor.tx + tw, th,
info->var.xres - vc->vc_decor.tx - tw);
}
decorfill(info, vc->vc_decor.ty + th, 0,
info->var.yres - vc->vc_decor.ty - th, info->var.xres);
}
void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y,
int sx, int dx, int width)
{
u16 *d = (u16 *) (vc->vc_origin + vc->vc_size_row * y + dx * 2);
u16 *s = d + (dx - sx);
u16 *start = d;
u16 *ls = d;
u16 *le = d + width;
u16 c;
int x = dx;
u16 attr = 1;
do {
c = scr_readw(d);
if (attr != (c & 0xff00)) {
attr = c & 0xff00;
if (d > start) {
fbcon_decor_putcs(vc, info, start, d - start, y, x);
x += d - start;
start = d;
}
}
if (s >= ls && s < le && c == scr_readw(s)) {
if (d > start) {
fbcon_decor_putcs(vc, info, start, d - start, y, x);
x += d - start + 1;
start = d + 1;
} else {
x++;
start++;
}
}
s++;
d++;
} while (d < le);
if (d > start)
fbcon_decor_putcs(vc, info, start, d - start, y, x);
}
void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank)
{
if (blank) {
decorset((u8 *)info->screen_base, info->var.yres, info->var.xres,
info->fix.line_length, 0, info->var.bits_per_pixel);
} else {
update_screen(vc);
fbcon_decor_clear_margins(vc, info, 0);
}
}

View File

@@ -0,0 +1,79 @@
/*
* linux/drivers/video/dummycon.c -- A dummy console driver
*
* To be used if there's no other console driver (e.g. for plain VGA text)
* available, usually until fbcon takes console over.
*/
#include <linux/types.h>
#include <linux/kdev_t.h>
#include <linux/console.h>
#include <linux/vt_kern.h>
#include <linux/screen_info.h>
#include <linux/init.h>
#include <linux/module.h>
/*
* Dummy console driver
*/
#if defined(__arm__)
#define DUMMY_COLUMNS screen_info.orig_video_cols
#define DUMMY_ROWS screen_info.orig_video_lines
#elif defined(__hppa__)
/* set by Kconfig. Use 80x25 for 640x480 and 160x64 for 1280x1024 */
#define DUMMY_COLUMNS CONFIG_DUMMY_CONSOLE_COLUMNS
#define DUMMY_ROWS CONFIG_DUMMY_CONSOLE_ROWS
#else
#define DUMMY_COLUMNS 80
#define DUMMY_ROWS 25
#endif
static const char *dummycon_startup(void)
{
return "dummy device";
}
static void dummycon_init(struct vc_data *vc, int init)
{
vc->vc_can_do_color = 1;
if (init) {
vc->vc_cols = DUMMY_COLUMNS;
vc->vc_rows = DUMMY_ROWS;
} else
vc_resize(vc, DUMMY_COLUMNS, DUMMY_ROWS);
}
static int dummycon_dummy(void)
{
return 0;
}
#define DUMMY (void *)dummycon_dummy
/*
* The console `switch' structure for the dummy console
*
* Most of the operations are dummies.
*/
const struct consw dummy_con = {
.owner = THIS_MODULE,
.con_startup = dummycon_startup,
.con_init = dummycon_init,
.con_deinit = DUMMY,
.con_clear = DUMMY,
.con_putc = DUMMY,
.con_putcs = DUMMY,
.con_cursor = DUMMY,
.con_scroll = DUMMY,
.con_bmove = DUMMY,
.con_switch = DUMMY,
.con_blank = DUMMY,
.con_font_set = DUMMY,
.con_font_get = DUMMY,
.con_font_default = DUMMY,
.con_font_copy = DUMMY,
.con_set_palette = DUMMY,
.con_scrolldelta = DUMMY,
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,263 @@
/*
* linux/drivers/video/console/fbcon.h -- Low level frame buffer based console driver
*
* Copyright (C) 1997 Geert Uytterhoeven
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*/
#ifndef _VIDEO_FBCON_H
#define _VIDEO_FBCON_H
#include <linux/types.h>
#include <linux/vt_buffer.h>
#include <linux/vt_kern.h>
#include <asm/io.h>
#define FBCON_FLAGS_INIT 1
#define FBCON_FLAGS_CURSOR_TIMER 2
/*
* This is the interface between the low-level console driver and the
* low-level frame buffer device
*/
struct display {
/* Filled in by the low-level console driver */
const u_char *fontdata;
int userfont; /* != 0 if fontdata kmalloc()ed */
u_short scrollmode; /* Scroll Method */
u_short inverse; /* != 0 text black on white as default */
short yscroll; /* Hardware scrolling */
int vrows; /* number of virtual rows */
int cursor_shape;
int con_rotate;
u32 xres_virtual;
u32 yres_virtual;
u32 height;
u32 width;
u32 bits_per_pixel;
u32 grayscale;
u32 nonstd;
u32 accel_flags;
u32 rotate;
struct fb_bitfield red;
struct fb_bitfield green;
struct fb_bitfield blue;
struct fb_bitfield transp;
const struct fb_videomode *mode;
};
struct fbcon_ops {
void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int dy, int dx, int height, int width);
void (*clear)(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int height, int width);
void (*putcs)(struct vc_data *vc, struct fb_info *info,
const unsigned short *s, int count, int yy, int xx,
int fg, int bg);
void (*clear_margins)(struct vc_data *vc, struct fb_info *info,
int bottom_only);
void (*cursor)(struct vc_data *vc, struct fb_info *info, int mode,
int softback_lines, int fg, int bg);
int (*update_start)(struct fb_info *info);
int (*rotate_font)(struct fb_info *info, struct vc_data *vc);
struct fb_var_screeninfo var; /* copy of the current fb_var_screeninfo */
struct timer_list cursor_timer; /* Cursor timer */
struct fb_cursor cursor_state;
struct display *p;
int currcon; /* Current VC. */
int cursor_flash;
int cursor_reset;
int blank_state;
int graphics;
int flags;
int rotate;
int cur_rotate;
char *cursor_data;
u8 *fontbuffer;
u8 *fontdata;
u8 *cursor_src;
u32 cursor_size;
u32 fd_size;
};
/*
* Attribute Decoding
*/
/* Color */
#define attr_fgcol(fgshift,s) \
(((s) >> (fgshift)) & 0x0f)
#define attr_bgcol(bgshift,s) \
(((s) >> (bgshift)) & 0x0f)
/* Monochrome */
#define attr_bold(s) \
((s) & 0x200)
#define attr_reverse(s) \
((s) & 0x800)
#define attr_underline(s) \
((s) & 0x400)
#define attr_blink(s) \
((s) & 0x8000)
static inline int mono_col(const struct fb_info *info)
{
__u32 max_len;
max_len = max(info->var.green.length, info->var.red.length);
max_len = max(info->var.blue.length, max_len);
return (~(0xfff << max_len)) & 0xff;
}
static inline int attr_col_ec(int shift, struct vc_data *vc,
struct fb_info *info, int is_fg)
{
int is_mono01;
int col;
int fg;
int bg;
if (!vc)
return 0;
if (vc->vc_can_do_color)
return is_fg ? attr_fgcol(shift,vc->vc_video_erase_char)
: attr_bgcol(shift,vc->vc_video_erase_char);
if (!info)
return 0;
col = mono_col(info);
is_mono01 = info->fix.visual == FB_VISUAL_MONO01;
if (attr_reverse(vc->vc_video_erase_char)) {
fg = is_mono01 ? col : 0;
bg = is_mono01 ? 0 : col;
}
else {
fg = is_mono01 ? 0 : col;
bg = is_mono01 ? col : 0;
}
return is_fg ? fg : bg;
}
#define attr_bgcol_ec(bgshift, vc, info) attr_col_ec(bgshift, vc, info, 0)
#define attr_fgcol_ec(fgshift, vc, info) attr_col_ec(fgshift, vc, info, 1)
/* Font */
#define REFCOUNT(fd) (((int *)(fd))[-1])
#define FNTSIZE(fd) (((int *)(fd))[-2])
#define FNTCHARCNT(fd) (((int *)(fd))[-3])
#define FNTSUM(fd) (((int *)(fd))[-4])
#define FONT_EXTRA_WORDS 4
/*
* Scroll Method
*/
/* There are several methods fbcon can use to move text around the screen:
*
* Operation Pan Wrap
*---------------------------------------------
* SCROLL_MOVE copyarea No No
* SCROLL_PAN_MOVE copyarea Yes No
* SCROLL_WRAP_MOVE copyarea No Yes
* SCROLL_REDRAW imageblit No No
* SCROLL_PAN_REDRAW imageblit Yes No
* SCROLL_WRAP_REDRAW imageblit No Yes
*
* (SCROLL_WRAP_REDRAW is not implemented yet)
*
* In general, fbcon will choose the best scrolling
* method based on the rule below:
*
* Pan/Wrap > accel imageblit > accel copyarea >
* soft imageblit > (soft copyarea)
*
* Exception to the rule: Pan + accel copyarea is
* preferred over Pan + accel imageblit.
*
* The above is typical for PCI/AGP cards. Unless
* overridden, fbcon will never use soft copyarea.
*
* If you need to override the above rule, set the
* appropriate flags in fb_info->flags. For example,
* to prefer copyarea over imageblit, set
* FBINFO_READS_FAST.
*
* Other notes:
* + use the hardware engine to move the text
* (hw-accelerated copyarea() and fillrect())
* + use hardware-supported panning on a large virtual screen
* + amifb can not only pan, but also wrap the display by N lines
* (i.e. visible line i = physical line (i+N) % yres).
* + read what's already rendered on the screen and
* write it in a different place (this is cfb_copyarea())
* + re-render the text to the screen
*
* Whether to use wrapping or panning can only be figured out at
* runtime (when we know whether our font height is a multiple
* of the pan/wrap step)
*
*/
#define SCROLL_MOVE 0x001
#define SCROLL_PAN_MOVE 0x002
#define SCROLL_WRAP_MOVE 0x003
#define SCROLL_REDRAW 0x004
#define SCROLL_PAN_REDRAW 0x005
#ifdef CONFIG_FB_TILEBLITTING
extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info);
#endif
extern void fbcon_set_bitops(struct fbcon_ops *ops);
extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
#define FBCON_ATTRIBUTE_UNDERLINE 1
#define FBCON_ATTRIBUTE_REVERSE 2
#define FBCON_ATTRIBUTE_BOLD 4
static inline int real_y(struct display *p, int ypos)
{
int rows = p->vrows;
ypos += p->yscroll;
return ypos < rows ? ypos : ypos - rows;
}
static inline int get_attribute(struct fb_info *info, u16 c)
{
int attribute = 0;
if (fb_get_color_depth(&info->var, &info->fix) == 1) {
if (attr_underline(c))
attribute |= FBCON_ATTRIBUTE_UNDERLINE;
if (attr_reverse(c))
attribute |= FBCON_ATTRIBUTE_REVERSE;
if (attr_bold(c))
attribute |= FBCON_ATTRIBUTE_BOLD;
}
return attribute;
}
#define FBCON_SWAP(i,r,v) ({ \
typeof(r) _r = (r); \
typeof(v) _v = (v); \
(void) (&_r == &_v); \
(i == FB_ROTATE_UR || i == FB_ROTATE_UD) ? _r : _v; })
#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION
extern void fbcon_set_rotate(struct fbcon_ops *ops);
#else
#define fbcon_set_rotate(x) do {} while(0)
#endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */
#endif /* _VIDEO_FBCON_H */

View File

@@ -0,0 +1,424 @@
/*
* linux/drivers/video/console/fbcon_ccw.c -- Software Rotation - 270 degrees
*
* Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*/
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <linux/vt_kern.h>
#include <linux/console.h>
#include <asm/types.h>
#include "fbcon.h"
#include "fbcon_rotate.h"
/*
* Rotation 270 degrees
*/
static inline void ccw_update_attr(u8 *dst, u8 *src, int attribute,
struct vc_data *vc)
{
int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2;
int width = (vc->vc_font.height + 7) >> 3;
int mod = vc->vc_font.height % 8;
u8 c, msk = ~(0xff << offset), msk1 = 0;
if (mod)
msk <<= (8 - mod);
if (offset > mod)
msk1 |= 0x01;
for (i = 0; i < vc->vc_font.width; i++) {
for (j = 0; j < width; j++) {
c = *src;
if (attribute & FBCON_ATTRIBUTE_UNDERLINE) {
if (j == width - 1)
c |= msk;
if (msk1 && j == width - 2)
c |= msk1;
}
if (attribute & FBCON_ATTRIBUTE_BOLD && i)
*(dst - width) |= c;
if (attribute & FBCON_ATTRIBUTE_REVERSE)
c = ~c;
src++;
*dst++ = c;
}
}
}
static void ccw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int dy, int dx, int height, int width)
{
struct fbcon_ops *ops = info->fbcon_par;
struct fb_copyarea area;
u32 vyres = GETVYRES(ops->p->scrollmode, info);
area.sx = sy * vc->vc_font.height;
area.sy = vyres - ((sx + width) * vc->vc_font.width);
area.dx = dy * vc->vc_font.height;
area.dy = vyres - ((dx + width) * vc->vc_font.width);
area.width = height * vc->vc_font.height;
area.height = width * vc->vc_font.width;
info->fbops->fb_copyarea(info, &area);
}
static void ccw_clear(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int height, int width)
{
struct fbcon_ops *ops = info->fbcon_par;
struct fb_fillrect region;
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
u32 vyres = GETVYRES(ops->p->scrollmode, info);
region.color = attr_bgcol_ec(bgshift,vc,info);
region.dx = sy * vc->vc_font.height;
region.dy = vyres - ((sx + width) * vc->vc_font.width);
region.height = width * vc->vc_font.width;
region.width = height * vc->vc_font.height;
region.rop = ROP_COPY;
info->fbops->fb_fillrect(info, &region);
}
static inline void ccw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
const u16 *s, u32 attr, u32 cnt,
u32 d_pitch, u32 s_pitch, u32 cellsize,
struct fb_image *image, u8 *buf, u8 *dst)
{
struct fbcon_ops *ops = info->fbcon_par;
u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
u32 idx = (vc->vc_font.height + 7) >> 3;
u8 *src;
while (cnt--) {
src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
if (attr) {
ccw_update_attr(buf, src, attr, vc);
src = buf;
}
if (likely(idx == 1))
__fb_pad_aligned_buffer(dst, d_pitch, src, idx,
vc->vc_font.width);
else
fb_pad_aligned_buffer(dst, d_pitch, src, idx,
vc->vc_font.width);
dst += d_pitch * vc->vc_font.width;
}
info->fbops->fb_imageblit(info, image);
}
static void ccw_putcs(struct vc_data *vc, struct fb_info *info,
const unsigned short *s, int count, int yy, int xx,
int fg, int bg)
{
struct fb_image image;
struct fbcon_ops *ops = info->fbcon_par;
u32 width = (vc->vc_font.height + 7)/8;
u32 cellsize = width * vc->vc_font.width;
u32 maxcnt = info->pixmap.size/cellsize;
u32 scan_align = info->pixmap.scan_align - 1;
u32 buf_align = info->pixmap.buf_align - 1;
u32 cnt, pitch, size;
u32 attribute = get_attribute(info, scr_readw(s));
u8 *dst, *buf = NULL;
u32 vyres = GETVYRES(ops->p->scrollmode, info);
if (!ops->fontbuffer)
return;
image.fg_color = fg;
image.bg_color = bg;
image.dx = yy * vc->vc_font.height;
image.dy = vyres - ((xx + count) * vc->vc_font.width);
image.width = vc->vc_font.height;
image.depth = 1;
if (attribute) {
buf = kmalloc(cellsize, GFP_KERNEL);
if (!buf)
return;
}
s += count - 1;
while (count) {
if (count > maxcnt)
cnt = maxcnt;
else
cnt = count;
image.height = vc->vc_font.width * cnt;
pitch = ((image.width + 7) >> 3) + scan_align;
pitch &= ~scan_align;
size = pitch * image.height + buf_align;
size &= ~buf_align;
dst = fb_get_buffer_offset(info, &info->pixmap, size);
image.data = dst;
ccw_putcs_aligned(vc, info, s, attribute, cnt, pitch,
width, cellsize, &image, buf, dst);
image.dy += image.height;
count -= cnt;
s -= cnt;
}
/* buf is always NULL except when in monochrome mode, so in this case
it's a gain to check buf against NULL even though kfree() handles
NULL pointers just fine */
if (unlikely(buf))
kfree(buf);
}
static void ccw_clear_margins(struct vc_data *vc, struct fb_info *info,
int bottom_only)
{
unsigned int cw = vc->vc_font.width;
unsigned int ch = vc->vc_font.height;
unsigned int rw = info->var.yres - (vc->vc_cols*cw);
unsigned int bh = info->var.xres - (vc->vc_rows*ch);
unsigned int bs = vc->vc_rows*ch;
struct fb_fillrect region;
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
region.color = attr_bgcol_ec(bgshift,vc,info);
region.rop = ROP_COPY;
if (rw && !bottom_only) {
region.dx = 0;
region.dy = info->var.yoffset;
region.height = rw;
region.width = info->var.xres_virtual;
info->fbops->fb_fillrect(info, &region);
}
if (bh) {
region.dx = info->var.xoffset + bs;
region.dy = 0;
region.height = info->var.yres_virtual;
region.width = bh;
info->fbops->fb_fillrect(info, &region);
}
}
static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
int softback_lines, int fg, int bg)
{
struct fb_cursor cursor;
struct fbcon_ops *ops = info->fbcon_par;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
int w = (vc->vc_font.height + 7) >> 3, c;
int y = real_y(ops->p, vc->vc_y);
int attribute, use_sw = (vc->vc_cursor_type & 0x10);
int err = 1, dx, dy;
char *src;
u32 vyres = GETVYRES(ops->p->scrollmode, info);
if (!ops->fontbuffer)
return;
cursor.set = 0;
if (softback_lines) {
if (y + softback_lines >= vc->vc_rows) {
mode = CM_ERASE;
ops->cursor_flash = 0;
return;
} else
y += softback_lines;
}
c = scr_readw((u16 *) vc->vc_pos);
attribute = get_attribute(info, c);
src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
if (ops->cursor_state.image.data != src ||
ops->cursor_reset) {
ops->cursor_state.image.data = src;
cursor.set |= FB_CUR_SETIMAGE;
}
if (attribute) {
u8 *dst;
dst = kmalloc(w * vc->vc_font.width, GFP_ATOMIC);
if (!dst)
return;
kfree(ops->cursor_data);
ops->cursor_data = dst;
ccw_update_attr(dst, src, attribute, vc);
src = dst;
}
if (ops->cursor_state.image.fg_color != fg ||
ops->cursor_state.image.bg_color != bg ||
ops->cursor_reset) {
ops->cursor_state.image.fg_color = fg;
ops->cursor_state.image.bg_color = bg;
cursor.set |= FB_CUR_SETCMAP;
}
if (ops->cursor_state.image.height != vc->vc_font.width ||
ops->cursor_state.image.width != vc->vc_font.height ||
ops->cursor_reset) {
ops->cursor_state.image.height = vc->vc_font.width;
ops->cursor_state.image.width = vc->vc_font.height;
cursor.set |= FB_CUR_SETSIZE;
}
dx = y * vc->vc_font.height;
dy = vyres - ((vc->vc_x + 1) * vc->vc_font.width);
if (ops->cursor_state.image.dx != dx ||
ops->cursor_state.image.dy != dy ||
ops->cursor_reset) {
ops->cursor_state.image.dx = dx;
ops->cursor_state.image.dy = dy;
cursor.set |= FB_CUR_SETPOS;
}
if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
ops->cursor_reset) {
ops->cursor_state.hot.x = cursor.hot.y = 0;
cursor.set |= FB_CUR_SETHOT;
}
if (cursor.set & FB_CUR_SETSIZE ||
vc->vc_cursor_type != ops->p->cursor_shape ||
ops->cursor_state.mask == NULL ||
ops->cursor_reset) {
char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC);
int cur_height, size, i = 0;
int width = (vc->vc_font.width + 7)/8;
if (!mask)
return;
tmp = kmalloc(width * vc->vc_font.height, GFP_ATOMIC);
if (!tmp) {
kfree(mask);
return;
}
kfree(ops->cursor_state.mask);
ops->cursor_state.mask = mask;
ops->p->cursor_shape = vc->vc_cursor_type;
cursor.set |= FB_CUR_SETSHAPE;
switch (ops->p->cursor_shape & CUR_HWMASK) {
case CUR_NONE:
cur_height = 0;
break;
case CUR_UNDERLINE:
cur_height = (vc->vc_font.height < 10) ? 1 : 2;
break;
case CUR_LOWER_THIRD:
cur_height = vc->vc_font.height/3;
break;
case CUR_LOWER_HALF:
cur_height = vc->vc_font.height >> 1;
break;
case CUR_TWO_THIRDS:
cur_height = (vc->vc_font.height << 1)/3;
break;
case CUR_BLOCK:
default:
cur_height = vc->vc_font.height;
break;
}
size = (vc->vc_font.height - cur_height) * width;
while (size--)
tmp[i++] = 0;
size = cur_height * width;
while (size--)
tmp[i++] = 0xff;
memset(mask, 0, w * vc->vc_font.width);
rotate_ccw(tmp, mask, vc->vc_font.width, vc->vc_font.height);
kfree(tmp);
}
switch (mode) {
case CM_ERASE:
ops->cursor_state.enable = 0;
break;
case CM_DRAW:
case CM_MOVE:
default:
ops->cursor_state.enable = (use_sw) ? 0 : 1;
break;
}
cursor.image.data = src;
cursor.image.fg_color = ops->cursor_state.image.fg_color;
cursor.image.bg_color = ops->cursor_state.image.bg_color;
cursor.image.dx = ops->cursor_state.image.dx;
cursor.image.dy = ops->cursor_state.image.dy;
cursor.image.height = ops->cursor_state.image.height;
cursor.image.width = ops->cursor_state.image.width;
cursor.hot.x = ops->cursor_state.hot.x;
cursor.hot.y = ops->cursor_state.hot.y;
cursor.mask = ops->cursor_state.mask;
cursor.enable = ops->cursor_state.enable;
cursor.image.depth = 1;
cursor.rop = ROP_XOR;
if (info->fbops->fb_cursor)
err = info->fbops->fb_cursor(info, &cursor);
if (err)
soft_cursor(info, &cursor);
ops->cursor_reset = 0;
}
static int ccw_update_start(struct fb_info *info)
{
struct fbcon_ops *ops = info->fbcon_par;
u32 yoffset;
u32 vyres = GETVYRES(ops->p->scrollmode, info);
int err;
yoffset = (vyres - info->var.yres) - ops->var.xoffset;
ops->var.xoffset = ops->var.yoffset;
ops->var.yoffset = yoffset;
err = fb_pan_display(info, &ops->var);
ops->var.xoffset = info->var.xoffset;
ops->var.yoffset = info->var.yoffset;
ops->var.vmode = info->var.vmode;
return err;
}
void fbcon_rotate_ccw(struct fbcon_ops *ops)
{
ops->bmove = ccw_bmove;
ops->clear = ccw_clear;
ops->putcs = ccw_putcs;
ops->clear_margins = ccw_clear_margins;
ops->cursor = ccw_cursor;
ops->update_start = ccw_update_start;
}
EXPORT_SYMBOL(fbcon_rotate_ccw);
MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
MODULE_DESCRIPTION("Console Rotation (270 degrees) Support");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,408 @@
/*
* linux/drivers/video/console/fbcon_ud.c -- Software Rotation - 90 degrees
*
* Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*/
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <linux/vt_kern.h>
#include <linux/console.h>
#include <asm/types.h>
#include "fbcon.h"
#include "fbcon_rotate.h"
/*
* Rotation 90 degrees
*/
static inline void cw_update_attr(u8 *dst, u8 *src, int attribute,
struct vc_data *vc)
{
int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2;
int width = (vc->vc_font.height + 7) >> 3;
u8 c, t = 0, msk = ~(0xff >> offset);
for (i = 0; i < vc->vc_font.width; i++) {
for (j = 0; j < width; j++) {
c = *src;
if (attribute & FBCON_ATTRIBUTE_UNDERLINE && !j)
c |= msk;
if (attribute & FBCON_ATTRIBUTE_BOLD && i)
c |= *(src-width);
if (attribute & FBCON_ATTRIBUTE_REVERSE)
c = ~c;
src++;
*dst++ = c;
t = c;
}
}
}
static void cw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int dy, int dx, int height, int width)
{
struct fbcon_ops *ops = info->fbcon_par;
struct fb_copyarea area;
u32 vxres = GETVXRES(ops->p->scrollmode, info);
area.sx = vxres - ((sy + height) * vc->vc_font.height);
area.sy = sx * vc->vc_font.width;
area.dx = vxres - ((dy + height) * vc->vc_font.height);
area.dy = dx * vc->vc_font.width;
area.width = height * vc->vc_font.height;
area.height = width * vc->vc_font.width;
info->fbops->fb_copyarea(info, &area);
}
static void cw_clear(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int height, int width)
{
struct fbcon_ops *ops = info->fbcon_par;
struct fb_fillrect region;
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
u32 vxres = GETVXRES(ops->p->scrollmode, info);
region.color = attr_bgcol_ec(bgshift,vc,info);
region.dx = vxres - ((sy + height) * vc->vc_font.height);
region.dy = sx * vc->vc_font.width;
region.height = width * vc->vc_font.width;
region.width = height * vc->vc_font.height;
region.rop = ROP_COPY;
info->fbops->fb_fillrect(info, &region);
}
static inline void cw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
const u16 *s, u32 attr, u32 cnt,
u32 d_pitch, u32 s_pitch, u32 cellsize,
struct fb_image *image, u8 *buf, u8 *dst)
{
struct fbcon_ops *ops = info->fbcon_par;
u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
u32 idx = (vc->vc_font.height + 7) >> 3;
u8 *src;
while (cnt--) {
src = ops->fontbuffer + (scr_readw(s++) & charmask)*cellsize;
if (attr) {
cw_update_attr(buf, src, attr, vc);
src = buf;
}
if (likely(idx == 1))
__fb_pad_aligned_buffer(dst, d_pitch, src, idx,
vc->vc_font.width);
else
fb_pad_aligned_buffer(dst, d_pitch, src, idx,
vc->vc_font.width);
dst += d_pitch * vc->vc_font.width;
}
info->fbops->fb_imageblit(info, image);
}
static void cw_putcs(struct vc_data *vc, struct fb_info *info,
const unsigned short *s, int count, int yy, int xx,
int fg, int bg)
{
struct fb_image image;
struct fbcon_ops *ops = info->fbcon_par;
u32 width = (vc->vc_font.height + 7)/8;
u32 cellsize = width * vc->vc_font.width;
u32 maxcnt = info->pixmap.size/cellsize;
u32 scan_align = info->pixmap.scan_align - 1;
u32 buf_align = info->pixmap.buf_align - 1;
u32 cnt, pitch, size;
u32 attribute = get_attribute(info, scr_readw(s));
u8 *dst, *buf = NULL;
u32 vxres = GETVXRES(ops->p->scrollmode, info);
if (!ops->fontbuffer)
return;
image.fg_color = fg;
image.bg_color = bg;
image.dx = vxres - ((yy + 1) * vc->vc_font.height);
image.dy = xx * vc->vc_font.width;
image.width = vc->vc_font.height;
image.depth = 1;
if (attribute) {
buf = kmalloc(cellsize, GFP_KERNEL);
if (!buf)
return;
}
while (count) {
if (count > maxcnt)
cnt = maxcnt;
else
cnt = count;
image.height = vc->vc_font.width * cnt;
pitch = ((image.width + 7) >> 3) + scan_align;
pitch &= ~scan_align;
size = pitch * image.height + buf_align;
size &= ~buf_align;
dst = fb_get_buffer_offset(info, &info->pixmap, size);
image.data = dst;
cw_putcs_aligned(vc, info, s, attribute, cnt, pitch,
width, cellsize, &image, buf, dst);
image.dy += image.height;
count -= cnt;
s += cnt;
}
/* buf is always NULL except when in monochrome mode, so in this case
it's a gain to check buf against NULL even though kfree() handles
NULL pointers just fine */
if (unlikely(buf))
kfree(buf);
}
static void cw_clear_margins(struct vc_data *vc, struct fb_info *info,
int bottom_only)
{
unsigned int cw = vc->vc_font.width;
unsigned int ch = vc->vc_font.height;
unsigned int rw = info->var.yres - (vc->vc_cols*cw);
unsigned int bh = info->var.xres - (vc->vc_rows*ch);
unsigned int rs = info->var.yres - rw;
struct fb_fillrect region;
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
region.color = attr_bgcol_ec(bgshift,vc,info);
region.rop = ROP_COPY;
if (rw && !bottom_only) {
region.dx = 0;
region.dy = info->var.yoffset + rs;
region.height = rw;
region.width = info->var.xres_virtual;
info->fbops->fb_fillrect(info, &region);
}
if (bh) {
region.dx = info->var.xoffset;
region.dy = info->var.yoffset;
region.height = info->var.yres;
region.width = bh;
info->fbops->fb_fillrect(info, &region);
}
}
static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
int softback_lines, int fg, int bg)
{
struct fb_cursor cursor;
struct fbcon_ops *ops = info->fbcon_par;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
int w = (vc->vc_font.height + 7) >> 3, c;
int y = real_y(ops->p, vc->vc_y);
int attribute, use_sw = (vc->vc_cursor_type & 0x10);
int err = 1, dx, dy;
char *src;
u32 vxres = GETVXRES(ops->p->scrollmode, info);
if (!ops->fontbuffer)
return;
cursor.set = 0;
if (softback_lines) {
if (y + softback_lines >= vc->vc_rows) {
mode = CM_ERASE;
ops->cursor_flash = 0;
return;
} else
y += softback_lines;
}
c = scr_readw((u16 *) vc->vc_pos);
attribute = get_attribute(info, c);
src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
if (ops->cursor_state.image.data != src ||
ops->cursor_reset) {
ops->cursor_state.image.data = src;
cursor.set |= FB_CUR_SETIMAGE;
}
if (attribute) {
u8 *dst;
dst = kmalloc(w * vc->vc_font.width, GFP_ATOMIC);
if (!dst)
return;
kfree(ops->cursor_data);
ops->cursor_data = dst;
cw_update_attr(dst, src, attribute, vc);
src = dst;
}
if (ops->cursor_state.image.fg_color != fg ||
ops->cursor_state.image.bg_color != bg ||
ops->cursor_reset) {
ops->cursor_state.image.fg_color = fg;
ops->cursor_state.image.bg_color = bg;
cursor.set |= FB_CUR_SETCMAP;
}
if (ops->cursor_state.image.height != vc->vc_font.width ||
ops->cursor_state.image.width != vc->vc_font.height ||
ops->cursor_reset) {
ops->cursor_state.image.height = vc->vc_font.width;
ops->cursor_state.image.width = vc->vc_font.height;
cursor.set |= FB_CUR_SETSIZE;
}
dx = vxres - ((y * vc->vc_font.height) + vc->vc_font.height);
dy = vc->vc_x * vc->vc_font.width;
if (ops->cursor_state.image.dx != dx ||
ops->cursor_state.image.dy != dy ||
ops->cursor_reset) {
ops->cursor_state.image.dx = dx;
ops->cursor_state.image.dy = dy;
cursor.set |= FB_CUR_SETPOS;
}
if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
ops->cursor_reset) {
ops->cursor_state.hot.x = cursor.hot.y = 0;
cursor.set |= FB_CUR_SETHOT;
}
if (cursor.set & FB_CUR_SETSIZE ||
vc->vc_cursor_type != ops->p->cursor_shape ||
ops->cursor_state.mask == NULL ||
ops->cursor_reset) {
char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC);
int cur_height, size, i = 0;
int width = (vc->vc_font.width + 7)/8;
if (!mask)
return;
tmp = kmalloc(width * vc->vc_font.height, GFP_ATOMIC);
if (!tmp) {
kfree(mask);
return;
}
kfree(ops->cursor_state.mask);
ops->cursor_state.mask = mask;
ops->p->cursor_shape = vc->vc_cursor_type;
cursor.set |= FB_CUR_SETSHAPE;
switch (ops->p->cursor_shape & CUR_HWMASK) {
case CUR_NONE:
cur_height = 0;
break;
case CUR_UNDERLINE:
cur_height = (vc->vc_font.height < 10) ? 1 : 2;
break;
case CUR_LOWER_THIRD:
cur_height = vc->vc_font.height/3;
break;
case CUR_LOWER_HALF:
cur_height = vc->vc_font.height >> 1;
break;
case CUR_TWO_THIRDS:
cur_height = (vc->vc_font.height << 1)/3;
break;
case CUR_BLOCK:
default:
cur_height = vc->vc_font.height;
break;
}
size = (vc->vc_font.height - cur_height) * width;
while (size--)
tmp[i++] = 0;
size = cur_height * width;
while (size--)
tmp[i++] = 0xff;
memset(mask, 0, w * vc->vc_font.width);
rotate_cw(tmp, mask, vc->vc_font.width, vc->vc_font.height);
kfree(tmp);
}
switch (mode) {
case CM_ERASE:
ops->cursor_state.enable = 0;
break;
case CM_DRAW:
case CM_MOVE:
default:
ops->cursor_state.enable = (use_sw) ? 0 : 1;
break;
}
cursor.image.data = src;
cursor.image.fg_color = ops->cursor_state.image.fg_color;
cursor.image.bg_color = ops->cursor_state.image.bg_color;
cursor.image.dx = ops->cursor_state.image.dx;
cursor.image.dy = ops->cursor_state.image.dy;
cursor.image.height = ops->cursor_state.image.height;
cursor.image.width = ops->cursor_state.image.width;
cursor.hot.x = ops->cursor_state.hot.x;
cursor.hot.y = ops->cursor_state.hot.y;
cursor.mask = ops->cursor_state.mask;
cursor.enable = ops->cursor_state.enable;
cursor.image.depth = 1;
cursor.rop = ROP_XOR;
if (info->fbops->fb_cursor)
err = info->fbops->fb_cursor(info, &cursor);
if (err)
soft_cursor(info, &cursor);
ops->cursor_reset = 0;
}
static int cw_update_start(struct fb_info *info)
{
struct fbcon_ops *ops = info->fbcon_par;
u32 vxres = GETVXRES(ops->p->scrollmode, info);
u32 xoffset;
int err;
xoffset = vxres - (info->var.xres + ops->var.yoffset);
ops->var.yoffset = ops->var.xoffset;
ops->var.xoffset = xoffset;
err = fb_pan_display(info, &ops->var);
ops->var.xoffset = info->var.xoffset;
ops->var.yoffset = info->var.yoffset;
ops->var.vmode = info->var.vmode;
return err;
}
void fbcon_rotate_cw(struct fbcon_ops *ops)
{
ops->bmove = cw_bmove;
ops->clear = cw_clear;
ops->putcs = cw_putcs;
ops->clear_margins = cw_clear_margins;
ops->cursor = cw_cursor;
ops->update_start = cw_update_start;
}
EXPORT_SYMBOL(fbcon_rotate_cw);
MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
MODULE_DESCRIPTION("Console Rotation (90 degrees) Support");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,115 @@
/*
* linux/drivers/video/console/fbcon_rotate.c -- Software Rotation
*
* Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*/
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <linux/vt_kern.h>
#include <linux/console.h>
#include <asm/types.h>
#include "fbcon.h"
#include "fbcon_rotate.h"
static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc)
{
struct fbcon_ops *ops = info->fbcon_par;
int len, err = 0;
int s_cellsize, d_cellsize, i;
const u8 *src;
u8 *dst;
if (vc->vc_font.data == ops->fontdata &&
ops->p->con_rotate == ops->cur_rotate)
goto finished;
src = ops->fontdata = vc->vc_font.data;
ops->cur_rotate = ops->p->con_rotate;
len = (!ops->p->userfont) ? 256 : FNTCHARCNT(src);
s_cellsize = ((vc->vc_font.width + 7)/8) *
vc->vc_font.height;
d_cellsize = s_cellsize;
if (ops->rotate == FB_ROTATE_CW ||
ops->rotate == FB_ROTATE_CCW)
d_cellsize = ((vc->vc_font.height + 7)/8) *
vc->vc_font.width;
if (info->fbops->fb_sync)
info->fbops->fb_sync(info);
if (ops->fd_size < d_cellsize * len) {
dst = kmalloc(d_cellsize * len, GFP_KERNEL);
if (dst == NULL) {
err = -ENOMEM;
goto finished;
}
ops->fd_size = d_cellsize * len;
kfree(ops->fontbuffer);
ops->fontbuffer = dst;
}
dst = ops->fontbuffer;
memset(dst, 0, ops->fd_size);
switch (ops->rotate) {
case FB_ROTATE_UD:
for (i = len; i--; ) {
rotate_ud(src, dst, vc->vc_font.width,
vc->vc_font.height);
src += s_cellsize;
dst += d_cellsize;
}
break;
case FB_ROTATE_CW:
for (i = len; i--; ) {
rotate_cw(src, dst, vc->vc_font.width,
vc->vc_font.height);
src += s_cellsize;
dst += d_cellsize;
}
break;
case FB_ROTATE_CCW:
for (i = len; i--; ) {
rotate_ccw(src, dst, vc->vc_font.width,
vc->vc_font.height);
src += s_cellsize;
dst += d_cellsize;
}
break;
}
finished:
return err;
}
void fbcon_set_rotate(struct fbcon_ops *ops)
{
ops->rotate_font = fbcon_rotate_font;
switch(ops->rotate) {
case FB_ROTATE_CW:
fbcon_rotate_cw(ops);
break;
case FB_ROTATE_UD:
fbcon_rotate_ud(ops);
break;
case FB_ROTATE_CCW:
fbcon_rotate_ccw(ops);
break;
}
}
EXPORT_SYMBOL(fbcon_set_rotate);
MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
MODULE_DESCRIPTION("Console Rotation Support");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,96 @@
/*
* linux/drivers/video/console/fbcon_rotate.h -- Software Display Rotation
*
* Copyright (C) 2005 Antonino Daplas <adaplas@pol.net>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*/
#ifndef _FBCON_ROTATE_H
#define _FBCON_ROTATE_H
#define GETVYRES(s,i) ({ \
(s == SCROLL_REDRAW || s == SCROLL_MOVE) ? \
(i)->var.yres : (i)->var.yres_virtual; })
#define GETVXRES(s,i) ({ \
(s == SCROLL_REDRAW || s == SCROLL_MOVE || !(i)->fix.xpanstep) ? \
(i)->var.xres : (i)->var.xres_virtual; })
static inline int pattern_test_bit(u32 x, u32 y, u32 pitch, const char *pat)
{
u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8;
pat +=index;
return (*pat) & (0x80 >> bit);
}
static inline void pattern_set_bit(u32 x, u32 y, u32 pitch, char *pat)
{
u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8;
pat += index;
(*pat) |= 0x80 >> bit;
}
static inline void rotate_ud(const char *in, char *out, u32 width, u32 height)
{
int i, j;
int shift = (8 - (width % 8)) & 7;
width = (width + 7) & ~7;
for (i = 0; i < height; i++) {
for (j = 0; j < width - shift; j++) {
if (pattern_test_bit(j, i, width, in))
pattern_set_bit(width - (1 + j + shift),
height - (1 + i),
width, out);
}
}
}
static inline void rotate_cw(const char *in, char *out, u32 width, u32 height)
{
int i, j, h = height, w = width;
int shift = (8 - (height % 8)) & 7;
width = (width + 7) & ~7;
height = (height + 7) & ~7;
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
if (pattern_test_bit(j, i, width, in))
pattern_set_bit(height - 1 - i - shift, j,
height, out);
}
}
}
static inline void rotate_ccw(const char *in, char *out, u32 width, u32 height)
{
int i, j, h = height, w = width;
int shift = (8 - (width % 8)) & 7;
width = (width + 7) & ~7;
height = (height + 7) & ~7;
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
if (pattern_test_bit(j, i, width, in))
pattern_set_bit(i, width - 1 - j - shift,
height, out);
}
}
}
extern void fbcon_rotate_cw(struct fbcon_ops *ops);
extern void fbcon_rotate_ud(struct fbcon_ops *ops);
extern void fbcon_rotate_ccw(struct fbcon_ops *ops);
#endif

View File

@@ -0,0 +1,452 @@
/*
* linux/drivers/video/console/fbcon_ud.c -- Software Rotation - 180 degrees
*
* Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*/
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <linux/vt_kern.h>
#include <linux/console.h>
#include <asm/types.h>
#include "fbcon.h"
#include "fbcon_rotate.h"
/*
* Rotation 180 degrees
*/
static inline void ud_update_attr(u8 *dst, u8 *src, int attribute,
struct vc_data *vc)
{
int i, offset = (vc->vc_font.height < 10) ? 1 : 2;
int width = (vc->vc_font.width + 7) >> 3;
unsigned int cellsize = vc->vc_font.height * width;
u8 c;
offset = offset * width;
for (i = 0; i < cellsize; i++) {
c = src[i];
if (attribute & FBCON_ATTRIBUTE_UNDERLINE && i < offset)
c = 0xff;
if (attribute & FBCON_ATTRIBUTE_BOLD)
c |= c << 1;
if (attribute & FBCON_ATTRIBUTE_REVERSE)
c = ~c;
dst[i] = c;
}
}
static void ud_bmove(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int dy, int dx, int height, int width)
{
struct fbcon_ops *ops = info->fbcon_par;
struct fb_copyarea area;
u32 vyres = GETVYRES(ops->p->scrollmode, info);
u32 vxres = GETVXRES(ops->p->scrollmode, info);
area.sy = vyres - ((sy + height) * vc->vc_font.height);
area.sx = vxres - ((sx + width) * vc->vc_font.width);
area.dy = vyres - ((dy + height) * vc->vc_font.height);
area.dx = vxres - ((dx + width) * vc->vc_font.width);
area.height = height * vc->vc_font.height;
area.width = width * vc->vc_font.width;
info->fbops->fb_copyarea(info, &area);
}
static void ud_clear(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int height, int width)
{
struct fbcon_ops *ops = info->fbcon_par;
struct fb_fillrect region;
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
u32 vyres = GETVYRES(ops->p->scrollmode, info);
u32 vxres = GETVXRES(ops->p->scrollmode, info);
region.color = attr_bgcol_ec(bgshift,vc,info);
region.dy = vyres - ((sy + height) * vc->vc_font.height);
region.dx = vxres - ((sx + width) * vc->vc_font.width);
region.width = width * vc->vc_font.width;
region.height = height * vc->vc_font.height;
region.rop = ROP_COPY;
info->fbops->fb_fillrect(info, &region);
}
static inline void ud_putcs_aligned(struct vc_data *vc, struct fb_info *info,
const u16 *s, u32 attr, u32 cnt,
u32 d_pitch, u32 s_pitch, u32 cellsize,
struct fb_image *image, u8 *buf, u8 *dst)
{
struct fbcon_ops *ops = info->fbcon_par;
u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
u32 idx = vc->vc_font.width >> 3;
u8 *src;
while (cnt--) {
src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
if (attr) {
ud_update_attr(buf, src, attr, vc);
src = buf;
}
if (likely(idx == 1))
__fb_pad_aligned_buffer(dst, d_pitch, src, idx,
image->height);
else
fb_pad_aligned_buffer(dst, d_pitch, src, idx,
image->height);
dst += s_pitch;
}
info->fbops->fb_imageblit(info, image);
}
static inline void ud_putcs_unaligned(struct vc_data *vc,
struct fb_info *info, const u16 *s,
u32 attr, u32 cnt, u32 d_pitch,
u32 s_pitch, u32 cellsize,
struct fb_image *image, u8 *buf,
u8 *dst)
{
struct fbcon_ops *ops = info->fbcon_par;
u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
u32 shift_low = 0, mod = vc->vc_font.width % 8;
u32 shift_high = 8;
u32 idx = vc->vc_font.width >> 3;
u8 *src;
while (cnt--) {
src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
if (attr) {
ud_update_attr(buf, src, attr, vc);
src = buf;
}
fb_pad_unaligned_buffer(dst, d_pitch, src, idx,
image->height, shift_high,
shift_low, mod);
shift_low += mod;
dst += (shift_low >= 8) ? s_pitch : s_pitch - 1;
shift_low &= 7;
shift_high = 8 - shift_low;
}
info->fbops->fb_imageblit(info, image);
}
static void ud_putcs(struct vc_data *vc, struct fb_info *info,
const unsigned short *s, int count, int yy, int xx,
int fg, int bg)
{
struct fb_image image;
struct fbcon_ops *ops = info->fbcon_par;
u32 width = (vc->vc_font.width + 7)/8;
u32 cellsize = width * vc->vc_font.height;
u32 maxcnt = info->pixmap.size/cellsize;
u32 scan_align = info->pixmap.scan_align - 1;
u32 buf_align = info->pixmap.buf_align - 1;
u32 mod = vc->vc_font.width % 8, cnt, pitch, size;
u32 attribute = get_attribute(info, scr_readw(s));
u8 *dst, *buf = NULL;
u32 vyres = GETVYRES(ops->p->scrollmode, info);
u32 vxres = GETVXRES(ops->p->scrollmode, info);
if (!ops->fontbuffer)
return;
image.fg_color = fg;
image.bg_color = bg;
image.dy = vyres - ((yy * vc->vc_font.height) + vc->vc_font.height);
image.dx = vxres - ((xx + count) * vc->vc_font.width);
image.height = vc->vc_font.height;
image.depth = 1;
if (attribute) {
buf = kmalloc(cellsize, GFP_KERNEL);
if (!buf)
return;
}
s += count - 1;
while (count) {
if (count > maxcnt)
cnt = maxcnt;
else
cnt = count;
image.width = vc->vc_font.width * cnt;
pitch = ((image.width + 7) >> 3) + scan_align;
pitch &= ~scan_align;
size = pitch * image.height + buf_align;
size &= ~buf_align;
dst = fb_get_buffer_offset(info, &info->pixmap, size);
image.data = dst;
if (!mod)
ud_putcs_aligned(vc, info, s, attribute, cnt, pitch,
width, cellsize, &image, buf, dst);
else
ud_putcs_unaligned(vc, info, s, attribute, cnt, pitch,
width, cellsize, &image,
buf, dst);
image.dx += image.width;
count -= cnt;
s -= cnt;
xx += cnt;
}
/* buf is always NULL except when in monochrome mode, so in this case
it's a gain to check buf against NULL even though kfree() handles
NULL pointers just fine */
if (unlikely(buf))
kfree(buf);
}
static void ud_clear_margins(struct vc_data *vc, struct fb_info *info,
int bottom_only)
{
unsigned int cw = vc->vc_font.width;
unsigned int ch = vc->vc_font.height;
unsigned int rw = info->var.xres - (vc->vc_cols*cw);
unsigned int bh = info->var.yres - (vc->vc_rows*ch);
struct fb_fillrect region;
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
region.color = attr_bgcol_ec(bgshift,vc,info);
region.rop = ROP_COPY;
if (rw && !bottom_only) {
region.dy = 0;
region.dx = info->var.xoffset;
region.width = rw;
region.height = info->var.yres_virtual;
info->fbops->fb_fillrect(info, &region);
}
if (bh) {
region.dy = info->var.yoffset;
region.dx = info->var.xoffset;
region.height = bh;
region.width = info->var.xres;
info->fbops->fb_fillrect(info, &region);
}
}
static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode,
int softback_lines, int fg, int bg)
{
struct fb_cursor cursor;
struct fbcon_ops *ops = info->fbcon_par;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
int w = (vc->vc_font.width + 7) >> 3, c;
int y = real_y(ops->p, vc->vc_y);
int attribute, use_sw = (vc->vc_cursor_type & 0x10);
int err = 1, dx, dy;
char *src;
u32 vyres = GETVYRES(ops->p->scrollmode, info);
u32 vxres = GETVXRES(ops->p->scrollmode, info);
if (!ops->fontbuffer)
return;
cursor.set = 0;
if (softback_lines) {
if (y + softback_lines >= vc->vc_rows) {
mode = CM_ERASE;
ops->cursor_flash = 0;
return;
} else
y += softback_lines;
}
c = scr_readw((u16 *) vc->vc_pos);
attribute = get_attribute(info, c);
src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.height));
if (ops->cursor_state.image.data != src ||
ops->cursor_reset) {
ops->cursor_state.image.data = src;
cursor.set |= FB_CUR_SETIMAGE;
}
if (attribute) {
u8 *dst;
dst = kmalloc(w * vc->vc_font.height, GFP_ATOMIC);
if (!dst)
return;
kfree(ops->cursor_data);
ops->cursor_data = dst;
ud_update_attr(dst, src, attribute, vc);
src = dst;
}
if (ops->cursor_state.image.fg_color != fg ||
ops->cursor_state.image.bg_color != bg ||
ops->cursor_reset) {
ops->cursor_state.image.fg_color = fg;
ops->cursor_state.image.bg_color = bg;
cursor.set |= FB_CUR_SETCMAP;
}
if (ops->cursor_state.image.height != vc->vc_font.height ||
ops->cursor_state.image.width != vc->vc_font.width ||
ops->cursor_reset) {
ops->cursor_state.image.height = vc->vc_font.height;
ops->cursor_state.image.width = vc->vc_font.width;
cursor.set |= FB_CUR_SETSIZE;
}
dy = vyres - ((y * vc->vc_font.height) + vc->vc_font.height);
dx = vxres - ((vc->vc_x * vc->vc_font.width) + vc->vc_font.width);
if (ops->cursor_state.image.dx != dx ||
ops->cursor_state.image.dy != dy ||
ops->cursor_reset) {
ops->cursor_state.image.dx = dx;
ops->cursor_state.image.dy = dy;
cursor.set |= FB_CUR_SETPOS;
}
if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
ops->cursor_reset) {
ops->cursor_state.hot.x = cursor.hot.y = 0;
cursor.set |= FB_CUR_SETHOT;
}
if (cursor.set & FB_CUR_SETSIZE ||
vc->vc_cursor_type != ops->p->cursor_shape ||
ops->cursor_state.mask == NULL ||
ops->cursor_reset) {
char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC);
int cur_height, size, i = 0;
u8 msk = 0xff;
if (!mask)
return;
kfree(ops->cursor_state.mask);
ops->cursor_state.mask = mask;
ops->p->cursor_shape = vc->vc_cursor_type;
cursor.set |= FB_CUR_SETSHAPE;
switch (ops->p->cursor_shape & CUR_HWMASK) {
case CUR_NONE:
cur_height = 0;
break;
case CUR_UNDERLINE:
cur_height = (vc->vc_font.height < 10) ? 1 : 2;
break;
case CUR_LOWER_THIRD:
cur_height = vc->vc_font.height/3;
break;
case CUR_LOWER_HALF:
cur_height = vc->vc_font.height >> 1;
break;
case CUR_TWO_THIRDS:
cur_height = (vc->vc_font.height << 1)/3;
break;
case CUR_BLOCK:
default:
cur_height = vc->vc_font.height;
break;
}
size = cur_height * w;
while (size--)
mask[i++] = msk;
size = (vc->vc_font.height - cur_height) * w;
while (size--)
mask[i++] = ~msk;
}
switch (mode) {
case CM_ERASE:
ops->cursor_state.enable = 0;
break;
case CM_DRAW:
case CM_MOVE:
default:
ops->cursor_state.enable = (use_sw) ? 0 : 1;
break;
}
cursor.image.data = src;
cursor.image.fg_color = ops->cursor_state.image.fg_color;
cursor.image.bg_color = ops->cursor_state.image.bg_color;
cursor.image.dx = ops->cursor_state.image.dx;
cursor.image.dy = ops->cursor_state.image.dy;
cursor.image.height = ops->cursor_state.image.height;
cursor.image.width = ops->cursor_state.image.width;
cursor.hot.x = ops->cursor_state.hot.x;
cursor.hot.y = ops->cursor_state.hot.y;
cursor.mask = ops->cursor_state.mask;
cursor.enable = ops->cursor_state.enable;
cursor.image.depth = 1;
cursor.rop = ROP_XOR;
if (info->fbops->fb_cursor)
err = info->fbops->fb_cursor(info, &cursor);
if (err)
soft_cursor(info, &cursor);
ops->cursor_reset = 0;
}
static int ud_update_start(struct fb_info *info)
{
struct fbcon_ops *ops = info->fbcon_par;
int xoffset, yoffset;
u32 vyres = GETVYRES(ops->p->scrollmode, info);
u32 vxres = GETVXRES(ops->p->scrollmode, info);
int err;
xoffset = vxres - info->var.xres - ops->var.xoffset;
yoffset = vyres - info->var.yres - ops->var.yoffset;
if (yoffset < 0)
yoffset += vyres;
ops->var.xoffset = xoffset;
ops->var.yoffset = yoffset;
err = fb_pan_display(info, &ops->var);
ops->var.xoffset = info->var.xoffset;
ops->var.yoffset = info->var.yoffset;
ops->var.vmode = info->var.vmode;
return err;
}
void fbcon_rotate_ud(struct fbcon_ops *ops)
{
ops->bmove = ud_bmove;
ops->clear = ud_clear;
ops->putcs = ud_putcs;
ops->clear_margins = ud_clear_margins;
ops->cursor = ud_cursor;
ops->update_start = ud_update_start;
}
EXPORT_SYMBOL(fbcon_rotate_ud);
MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
MODULE_DESCRIPTION("Console Rotation (180 degrees) Support");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,418 @@
/*
* linux/drivers/video/console/fbcondecor.c -- Framebuffer console decorations+ *
* Copyright (C) 2004 Michal Januszewski <spock@gentoo.org>
*
* Code based upon "Bootsplash" (C) 2001-2003
* Volker Poplawski <volker@poplawski.de>,
* Stefan Reinauer <stepan@suse.de>,
* Steffen Winterfeldt <snwint@suse.de>,
* Michael Schroeder <mls@suse.de>,
* Ken Wimer <wimer@suse.de>.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/fb.h>
#include <linux/vt_kern.h>
#include <linux/vmalloc.h>
#include <linux/unistd.h>
#include <linux/syscalls.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/workqueue.h>
#include <linux/kmod.h>
#include <linux/miscdevice.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/system.h>
#include "fbcon.h"
#include "fbcondecor.h"
extern signed char con2fb_map[];
static int fbcon_decor_enable(struct vc_data *vc);
char fbcon_decor_path[KMOD_PATH_LEN] = "/sbin/fbcondecor_helper";
static int initialized = 0;
int fbcon_decor_call_helper(char* cmd, unsigned short vc)
{
char *envp[] = {
"HOME=/",
"PATH=/sbin:/bin",
NULL
};
char tfb[5];
char tcons[5];
unsigned char fb = (int) con2fb_map[vc];
char *argv[] = {
fbcon_decor_path,
"2",
cmd,
tcons,
tfb,
vc_cons[vc].d->vc_decor.theme,
NULL
};
snprintf(tfb,5,"%d",fb);
snprintf(tcons,5,"%d",vc);
return call_usermodehelper(fbcon_decor_path, argv, envp, 1);
}
/* Disables fbcondecor on a virtual console; called with console sem held. */
int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw)
{
struct fb_info* info;
if (!vc->vc_decor.state)
return -EINVAL;
info = registered_fb[(int) con2fb_map[vc->vc_num]];
if (info == NULL)
return -EINVAL;
vc->vc_decor.state = 0;
vc_resize(vc, info->var.xres / vc->vc_font.width,
info->var.yres / vc->vc_font.height);
if (fg_console == vc->vc_num && redraw) {
redraw_screen(vc, 0);
update_region(vc, vc->vc_origin +
vc->vc_size_row * vc->vc_top,
vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
}
printk(KERN_INFO "fbcondecor: switched decor state to 'off' on console %d\n",
vc->vc_num);
return 0;
}
/* Enables fbcondecor on a virtual console; called with console sem held. */
static int fbcon_decor_enable(struct vc_data *vc)
{
struct fb_info* info;
info = registered_fb[(int) con2fb_map[vc->vc_num]];
if (vc->vc_decor.twidth == 0 || vc->vc_decor.theight == 0 ||
info == NULL || vc->vc_decor.state || (!info->bgdecor.data &&
vc->vc_num == fg_console))
return -EINVAL;
vc->vc_decor.state = 1;
vc_resize(vc, vc->vc_decor.twidth / vc->vc_font.width,
vc->vc_decor.theight / vc->vc_font.height);
if (fg_console == vc->vc_num) {
redraw_screen(vc, 0);
update_region(vc, vc->vc_origin +
vc->vc_size_row * vc->vc_top,
vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
fbcon_decor_clear_margins(vc, info, 0);
}
printk(KERN_INFO "fbcondecor: switched decor state to 'on' on console %d\n",
vc->vc_num);
return 0;
}
static inline int fbcon_decor_ioctl_dosetstate(struct vc_data *vc, unsigned int __user* state, unsigned char origin)
{
int tmp, ret;
if (get_user(tmp, state))
return -EFAULT;
if (origin == FBCON_DECOR_IO_ORIG_USER)
acquire_console_sem();
if (!tmp)
ret = fbcon_decor_disable(vc, 1);
else
ret = fbcon_decor_enable(vc);
if (origin == FBCON_DECOR_IO_ORIG_USER)
release_console_sem();
return ret;
}
static inline int fbcon_decor_ioctl_dogetstate(struct vc_data *vc, unsigned int __user *state)
{
return put_user(vc->vc_decor.state, (unsigned int __user*) state);
}
static int fbcon_decor_ioctl_dosetcfg(struct vc_data *vc, struct vc_decor __user *arg, unsigned char origin)
{
struct vc_decor cfg;
struct fb_info *info;
int len;
char *tmp;
info = registered_fb[(int) con2fb_map[vc->vc_num]];
if (copy_from_user(&cfg, arg, sizeof(struct vc_decor)))
return -EFAULT;
if (info == NULL || !cfg.twidth || !cfg.theight ||
cfg.tx + cfg.twidth > info->var.xres ||
cfg.ty + cfg.theight > info->var.yres)
return -EINVAL;
len = strlen_user(cfg.theme);
if (!len || len > FBCON_DECOR_THEME_LEN)
return -EINVAL;
tmp = kmalloc(len, GFP_KERNEL);
if (!tmp)
return -ENOMEM;
if (copy_from_user(tmp, (void __user *)cfg.theme, len))
return -EFAULT;
cfg.theme = tmp;
cfg.state = 0;
/* If this ioctl is a response to a request from kernel, the console sem
* is already held; we also don't need to disable decor because either the
* new config and background picture will be successfully loaded, and the
* decor will stay on, or in case of a failure it'll be turned off in fbcon. */
if (origin == FBCON_DECOR_IO_ORIG_USER) {
acquire_console_sem();
if (vc->vc_decor.state)
fbcon_decor_disable(vc, 1);
}
if (vc->vc_decor.theme)
kfree(vc->vc_decor.theme);
vc->vc_decor = cfg;
if (origin == FBCON_DECOR_IO_ORIG_USER)
release_console_sem();
printk(KERN_INFO "fbcondecor: console %d using theme '%s'\n",
vc->vc_num, vc->vc_decor.theme);
return 0;
}
static int fbcon_decor_ioctl_dogetcfg(struct vc_data *vc, struct vc_decor __user *arg)
{
struct vc_decor decor;
char __user *tmp;
if (get_user(tmp, &arg->theme))
return -EFAULT;
decor = vc->vc_decor;
decor.theme = tmp;
if (vc->vc_decor.theme) {
if (copy_to_user(tmp, vc->vc_decor.theme, strlen(vc->vc_decor.theme) + 1))
return -EFAULT;
} else
if (put_user(0, tmp))
return -EFAULT;
if (copy_to_user(arg, &decor, sizeof(struct vc_decor)))
return -EFAULT;
return 0;
}
static int fbcon_decor_ioctl_dosetpic(struct vc_data *vc, struct fb_image __user *arg, unsigned char origin)
{
struct fb_image img;
struct fb_info *info;
int len;
u8 *tmp;
if (vc->vc_num != fg_console)
return -EINVAL;
info = registered_fb[(int) con2fb_map[vc->vc_num]];
if (info == NULL)
return -EINVAL;
if (copy_from_user(&img, arg, sizeof(struct fb_image)))
return -EFAULT;
if (img.width != info->var.xres || img.height != info->var.yres) {
printk(KERN_ERR "fbcondecor: picture dimensions mismatch\n");
return -EINVAL;
}
if (img.depth != info->var.bits_per_pixel) {
printk(KERN_ERR "fbcondecor: picture depth mismatch\n");
return -EINVAL;
}
if (img.depth == 8) {
if (!img.cmap.len || !img.cmap.red || !img.cmap.green ||
!img.cmap.blue)
return -EINVAL;
tmp = vmalloc(img.cmap.len * 3 * 2);
if (!tmp)
return -ENOMEM;
if (copy_from_user(tmp, (void __user*)img.cmap.red, img.cmap.len * 2) ||
copy_from_user(tmp + (img.cmap.len << 1),
(void __user*)img.cmap.green, (img.cmap.len << 1)) ||
copy_from_user(tmp + (img.cmap.len << 2),
(void __user*)img.cmap.blue, (img.cmap.len << 1))) {
vfree(tmp);
return -EFAULT;
}
img.cmap.transp = NULL;
img.cmap.red = (u16*)tmp;
img.cmap.green = img.cmap.red + img.cmap.len;
img.cmap.blue = img.cmap.green + img.cmap.len;
} else {
img.cmap.red = NULL;
}
len = ((img.depth + 7) >> 3) * img.width * img.height;
tmp = vmalloc(len);
if (!tmp)
goto out;
if (copy_from_user(tmp, (void __user*)img.data, len))
goto out;
img.data = tmp;
/* If this ioctl is a response to a request from kernel, the console sem
* is already held. */
if (origin == FBCON_DECOR_IO_ORIG_USER)
acquire_console_sem();
if (info->bgdecor.data)
vfree((u8*)info->bgdecor.data);
if (info->bgdecor.cmap.red)
vfree(info->bgdecor.cmap.red);
info->bgdecor = img;
if (origin == FBCON_DECOR_IO_ORIG_USER)
release_console_sem();
return 0;
out: if (img.cmap.red)
vfree(img.cmap.red);
if (tmp)
vfree(tmp);
return -ENOMEM;
}
static int fbcon_decor_ioctl(struct inode * inode, struct file *filp, u_int cmd,
u_long arg)
{
struct fbcon_decor_iowrapper __user *wrapper = (void __user*) arg;
struct vc_data *vc = NULL;
unsigned short vc_num = 0;
unsigned char origin = 0;
void __user *data = NULL;
if (!access_ok(VERIFY_READ, wrapper,
sizeof(struct fbcon_decor_iowrapper)))
return -EFAULT;
__get_user(vc_num, &wrapper->vc);
__get_user(origin, &wrapper->origin);
__get_user(data, &wrapper->data);
if (!vc_cons_allocated(vc_num))
return -EINVAL;
vc = vc_cons[vc_num].d;
switch (cmd) {
case FBIOCONDECOR_SETPIC:
return fbcon_decor_ioctl_dosetpic(vc, (struct fb_image __user*)data, origin);
case FBIOCONDECOR_SETCFG:
return fbcon_decor_ioctl_dosetcfg(vc, (struct vc_decor*)data, origin);
case FBIOCONDECOR_GETCFG:
return fbcon_decor_ioctl_dogetcfg(vc, (struct vc_decor*)data);
case FBIOCONDECOR_SETSTATE:
return fbcon_decor_ioctl_dosetstate(vc, (unsigned int *)data, origin);
case FBIOCONDECOR_GETSTATE:
return fbcon_decor_ioctl_dogetstate(vc, (unsigned int *)data);
default:
return -ENOIOCTLCMD;
}
}
static struct file_operations fbcon_decor_ops = {
.owner = THIS_MODULE,
.ioctl = fbcon_decor_ioctl
};
static struct miscdevice fbcon_decor_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = "fbcondecor",
.fops = &fbcon_decor_ops
};
void fbcon_decor_reset(void)
{
struct fb_info *info;
struct vc_data *vc;
int i;
vc = vc_cons[0].d;
info = registered_fb[0];
for (i = 0; i < num_registered_fb; i++) {
registered_fb[i]->bgdecor.data = NULL;
registered_fb[i]->bgdecor.cmap.red = NULL;
}
for (i = 0; i < MAX_NR_CONSOLES && vc_cons[i].d; i++) {
vc_cons[i].d->vc_decor.state = vc_cons[i].d->vc_decor.twidth =
vc_cons[i].d->vc_decor.theight = 0;
vc_cons[i].d->vc_decor.theme = NULL;
}
return;
}
int fbcon_decor_init(void)
{
int i;
fbcon_decor_reset();
if (initialized)
return 0;
i = misc_register(&fbcon_decor_dev);
if (i) {
printk(KERN_ERR "fbcondecor: failed to register device\n");
return i;
}
fbcon_decor_call_helper("init", 0);
initialized = 1;
return 0;
}
int fbcon_decor_exit(void)
{
fbcon_decor_reset();
return 0;
}
EXPORT_SYMBOL(fbcon_decor_path);

View File

@@ -0,0 +1,78 @@
/*
* linux/drivers/video/console/fbcondecor.h -- Framebuffer Console Decoration headers
*
* Copyright (C) 2004 Michal Januszewski <spock@gentoo.org>
*
*/
#ifndef __FBCON_DECOR_H
#define __FBCON_DECOR_H
#ifndef _LINUX_FB_H
#include <linux/fb.h>
#endif
/* This is needed for vc_cons in fbcmap.c */
#include <linux/vt_kern.h>
struct fb_cursor;
struct fb_info;
struct vc_data;
#ifdef CONFIG_FB_CON_DECOR
/* fbcondecor.c */
int fbcon_decor_init(void);
int fbcon_decor_exit(void);
int fbcon_decor_call_helper(char* cmd, unsigned short cons);
int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw);
/* cfbcondecor.c */
void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx);
void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor);
void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width);
void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only);
void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank);
void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width);
void fbcon_decor_copy(u8 *dst, u8 *src, int height, int width, int linebytes, int srclinesbytes, int bpp);
void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc);
/* vt.c */
void acquire_console_sem(void);
void release_console_sem(void);
void do_unblank_screen(int entering_gfx);
/* struct vc_data *y */
#define fbcon_decor_active_vc(y) (y->vc_decor.state && y->vc_decor.theme)
/* struct fb_info *x, struct vc_data *y */
#define fbcon_decor_active_nores(x,y) (x->bgdecor.data && fbcon_decor_active_vc(y))
/* struct fb_info *x, struct vc_data *y */
#define fbcon_decor_active(x,y) (fbcon_decor_active_nores(x,y) && \
x->bgdecor.width == x->var.xres && \
x->bgdecor.height == x->var.yres && \
x->bgdecor.depth == x->var.bits_per_pixel)
#else /* CONFIG_FB_CON_DECOR */
static inline void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx) {}
static inline void fbcon_decor_putc(struct vc_data *vc, struct fb_info *info, int c, int ypos, int xpos) {}
static inline void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor) {}
static inline void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width) {}
static inline void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only) {}
static inline void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank) {}
static inline void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width) {}
static inline void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc) {}
static inline int fbcon_decor_call_helper(char* cmd, unsigned short cons) { return 0; }
static inline int fbcon_decor_init(void) { return 0; }
static inline int fbcon_decor_exit(void) { return 0; }
static inline int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw) { return 0; }
#define fbcon_decor_active_vc(y) (0)
#define fbcon_decor_active_nores(x,y) (0)
#define fbcon_decor_active(x,y) (0)
#endif /* CONFIG_FB_CON_DECOR */
#endif /* __FBCON_DECOR_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,275 @@
/* Acorn-like font definition, with PC graphics characters */
#include <linux/font.h>
static const unsigned char acorndata_8x8[] = {
/* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ^@ */
/* 01 */ 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, /* ^A */
/* 02 */ 0x7e, 0xff, 0xbd, 0xff, 0xc3, 0xe7, 0xff, 0x7e, /* ^B */
/* 03 */ 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, /* ^C */
/* 04 */ 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, /* ^D */
/* 05 */ 0x00, 0x18, 0x3c, 0xe7, 0xe7, 0x3c, 0x18, 0x00, /* ^E */
/* 06 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* 07 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* 08 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* 09 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* 0A */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* 0B */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* 0C */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* 0D */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* 0E */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* 0F */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* 10 */ 0x00, 0x60, 0x78, 0x7e, 0x7e, 0x78, 0x60, 0x00, /* |> */
/* 11 */ 0x00, 0x06, 0x1e, 0x7e, 0x7e, 0x1e, 0x06, 0x00, /* <| */
/* 12 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* 13 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* 14 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* 15 */ 0x3c, 0x60, 0x3c, 0x66, 0x3c, 0x06, 0x3c, 0x00,
/* 16 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* 17 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* 18 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* 19 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* 1A */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* 1B */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* 1C */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* 1D */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* 1E */ 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x7e, 0x7e, 0x00, /* /\ */
/* 1F */ 0x00, 0x7e, 0x7e, 0x3c, 0x3c, 0x18, 0x18, 0x00, /* \/ */
/* 20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* */
/* 21 */ 0x18, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x00, /* ! */
/* 22 */ 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, /* " */
/* 23 */ 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00, /* # */
/* 24 */ 0x0C, 0x3F, 0x68, 0x3E, 0x0B, 0x7E, 0x18, 0x00, /* $ */
/* 25 */ 0x60, 0x66, 0x0C, 0x18, 0x30, 0x66, 0x06, 0x00, /* % */
/* 26 */ 0x38, 0x6C, 0x6C, 0x38, 0x6D, 0x66, 0x3B, 0x00, /* & */
/* 27 */ 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, /* ' */
/* 28 */ 0x0C, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x00, /* ( */
/* 29 */ 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00, /* ) */
/* 2A */ 0x00, 0x18, 0x7E, 0x3C, 0x7E, 0x18, 0x00, 0x00, /* * */
/* 2B */ 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, /* + */
/* 2C */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, /* , */
/* 2D */ 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, /* - */
/* 2E */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, /* . */
/* 2F */ 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, /* / */
/* 30 */ 0x3C, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x3C, 0x00, /* 0 */
/* 31 */ 0x18, 0x38, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, /* 1 */
/* 32 */ 0x3C, 0x66, 0x06, 0x0C, 0x18, 0x30, 0x7E, 0x00, /* 2 */
/* 33 */ 0x3C, 0x66, 0x06, 0x1C, 0x06, 0x66, 0x3C, 0x00, /* 3 */
/* 34 */ 0x0C, 0x1C, 0x3C, 0x6C, 0x7E, 0x0C, 0x0C, 0x00, /* 4 */
/* 35 */ 0x7E, 0x60, 0x7C, 0x06, 0x06, 0x66, 0x3C, 0x00, /* 5 */
/* 36 */ 0x1C, 0x30, 0x60, 0x7C, 0x66, 0x66, 0x3C, 0x00, /* 6 */
/* 37 */ 0x7E, 0x06, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00, /* 7 */
/* 38 */ 0x3C, 0x66, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00, /* 8 */
/* 39 */ 0x3C, 0x66, 0x66, 0x3E, 0x06, 0x0C, 0x38, 0x00, /* 9 */
/* 3A */ 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, /* : */
/* 3B */ 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x30, /* ; */
/* 3C */ 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x00, /* < */
/* 3D */ 0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00, /* = */
/* 3E */ 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x00, /* > */
/* 3F */ 0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00, /* ? */
/* 40 */ 0x3C, 0x66, 0x6E, 0x6A, 0x6E, 0x60, 0x3C, 0x00, /* @ */
/* 41 */ 0x3C, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, /* A */
/* 42 */ 0x7C, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x7C, 0x00, /* B */
/* 43 */ 0x3C, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3C, 0x00, /* C */
/* 44 */ 0x78, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0x78, 0x00, /* D */
/* 45 */ 0x7E, 0x60, 0x60, 0x7C, 0x60, 0x60, 0x7E, 0x00, /* E */
/* 46 */ 0x7E, 0x60, 0x60, 0x7C, 0x60, 0x60, 0x60, 0x00, /* F */
/* 47 */ 0x3C, 0x66, 0x60, 0x6E, 0x66, 0x66, 0x3C, 0x00, /* G */
/* 48 */ 0x66, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, /* H */
/* 49 */ 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, /* I */
/* 4A */ 0x3E, 0x0C, 0x0C, 0x0C, 0x0C, 0x6C, 0x38, 0x00, /* J */
/* 4B */ 0x66, 0x6C, 0x78, 0x70, 0x78, 0x6C, 0x66, 0x00, /* K */
/* 4C */ 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7E, 0x00, /* L */
/* 4D */ 0x63, 0x77, 0x7F, 0x6B, 0x6B, 0x63, 0x63, 0x00, /* M */
/* 4E */ 0x66, 0x66, 0x76, 0x7E, 0x6E, 0x66, 0x66, 0x00, /* N */
/* 4F */ 0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, /* O */
/* 50 */ 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0x00, /* P */
/* 51 */ 0x3C, 0x66, 0x66, 0x66, 0x6A, 0x6C, 0x36, 0x00, /* Q */
/* 52 */ 0x7C, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0x66, 0x00, /* R */
/* 53 */ 0x3C, 0x66, 0x60, 0x3C, 0x06, 0x66, 0x3C, 0x00, /* S */
/* 54 */ 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, /* T */
/* 55 */ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, /* U */
/* 56 */ 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, /* V */
/* 57 */ 0x63, 0x63, 0x6B, 0x6B, 0x7F, 0x77, 0x63, 0x00, /* W */
/* 58 */ 0x66, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00, /* X */
/* 59 */ 0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00, /* Y */
/* 5A */ 0x7E, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x7E, 0x00, /* Z */
/* 5B */ 0x7C, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7C, 0x00, /* [ */
/* 5C */ 0x00, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00, 0x00, /* \ */
/* 5D */ 0x3E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3E, 0x00, /* ] */
/* 5E */ 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ^ */
/* 5F */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, /* _ */
/* 60 */ 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ` */
/* 61 */ 0x00, 0x00, 0x3C, 0x06, 0x3E, 0x66, 0x3E, 0x00, /* a */
/* 62 */ 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x7C, 0x00, /* b */
/* 63 */ 0x00, 0x00, 0x3C, 0x66, 0x60, 0x66, 0x3C, 0x00, /* c */
/* 64 */ 0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x3E, 0x00, /* d */
/* 65 */ 0x00, 0x00, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00, /* e */
/* 66 */ 0x1C, 0x30, 0x30, 0x7C, 0x30, 0x30, 0x30, 0x00, /* f */
/* 67 */ 0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x3C, /* g */
/* 68 */ 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x00, /* h */
/* 69 */ 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00, /* i */
/* 6A */ 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x70, /* j */
/* 6B */ 0x60, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0x00, /* k */
/* 6C */ 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, /* l */
/* 6D */ 0x00, 0x00, 0x36, 0x7F, 0x6B, 0x6B, 0x63, 0x00, /* m */
/* 6E */ 0x00, 0x00, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x00, /* n */
/* 6F */ 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00, /* o */
/* 70 */ 0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60, /* p */
/* 71 */ 0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x07, /* q */
/* 72 */ 0x00, 0x00, 0x6C, 0x76, 0x60, 0x60, 0x60, 0x00, /* r */
/* 73 */ 0x00, 0x00, 0x3E, 0x60, 0x3C, 0x06, 0x7C, 0x00, /* s */
/* 74 */ 0x30, 0x30, 0x7C, 0x30, 0x30, 0x30, 0x1C, 0x00, /* t */
/* 75 */ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x00, /* u */
/* 76 */ 0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, /* v */
/* 77 */ 0x00, 0x00, 0x63, 0x6B, 0x6B, 0x7F, 0x36, 0x00, /* w */
/* 78 */ 0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00, /* x */
/* 79 */ 0x00, 0x00, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x3C, /* y */
/* 7A */ 0x00, 0x00, 0x7E, 0x0C, 0x18, 0x30, 0x7E, 0x00, /* z */
/* 7B */ 0x0C, 0x18, 0x18, 0x70, 0x18, 0x18, 0x0C, 0x00, /* { */
/* 7C */ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, /* | */
/* 7D */ 0x30, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x30, 0x00, /* } */
/* 7E */ 0x31, 0x6B, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, /* ~ */
/* 7F */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /*  */
/* 80 */ 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x30, 0x60,
/* 81 */ 0x66, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,
/* 82 */ 0x0c, 0x18, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
/* 83 */ 0x18, 0x66, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
/* 84 */ 0x66, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
/* 85 */ 0x30, 0x18, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
/* 86 */ 0x3c, 0x66, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
/* 87 */ 0x00, 0x00, 0x3c, 0x66, 0x60, 0x66, 0x3c, 0x60,
/* 88 */ 0x3c, 0x66, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
/* 89 */ 0x66, 0x00, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
/* 8A */ 0x30, 0x18, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
/* 8B */ 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
/* 8C */ 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
/* 8D */ 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
/* 8E */ 0x66, 0x66, 0x00, 0x3c, 0x66, 0x7e, 0x66, 0x00,
/* 8F */ 0x18, 0x66, 0x00, 0x3c, 0x66, 0x7e, 0x66, 0x00,
/* 90 */ 0x0c, 0x18, 0x7e, 0x60, 0x7c, 0x60, 0x7e, 0x00,
/* 91 */ 0x00, 0x00, 0x3f, 0x0d, 0x3f, 0x6c, 0x3f, 0x00,
/* 92 */ 0x3f, 0x66, 0x66, 0x7f, 0x66, 0x66, 0x67, 0x00,
/* 93 */ 0x3c, 0x66, 0x00, 0x3c, 0x66, 0x66, 0x3c, 0x00,
/* 94 */ 0x66, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x3c, 0x00,
/* 95 */ 0x30, 0x18, 0x00, 0x3c, 0x66, 0x66, 0x3c, 0x00,
/* 96 */ 0x3c, 0x66, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x00,
/* 97 */ 0x30, 0x18, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x00,
/* 98 */ 0x66, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x3c,
/* 99 */ 0x66, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00,
/* 9A */ 0x66, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
/* 9B */ 0x08, 0x3e, 0x6b, 0x68, 0x6b, 0x3e, 0x08, 0x00,
/* 9C */ 0x1c, 0x36, 0x30, 0x7c, 0x30, 0x30, 0x7e, 0x00,
/* 9D */ 0x66, 0x3c, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00,
/* 9E */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* 9F */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* A0 */ 0x0c, 0x18, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
/* A1 */ 0x0c, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
/* A2 */ 0x0c, 0x18, 0x00, 0x3c, 0x66, 0x66, 0x3c, 0x00,
/* A3 */ 0x0c, 0x18, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x00,
/* A4 */ 0x36, 0x6c, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x00,
/* A5 */ 0x36, 0x6c, 0x00, 0x66, 0x76, 0x6e, 0x66, 0x00,
/* A6 */ 0x1c, 0x06, 0x1e, 0x36, 0x1e, 0x00, 0x3e, 0x00,
/* A7 */ 0x1c, 0x36, 0x36, 0x36, 0x1c, 0x00, 0x3e, 0x00,
/* A8 */ 0x18, 0x00, 0x18, 0x18, 0x30, 0x66, 0x3c, 0x00,
/* A9 */ 0x7e, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* AA */ 0x7e, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* AB */ 0x40, 0xc0, 0x40, 0x4f, 0x41, 0x0f, 0x08, 0x0f,
/* AC */ 0x40, 0xc0, 0x40, 0x48, 0x48, 0x0a, 0x0f, 0x02,
/* AD */ 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00,
/* AE */ 0x00, 0x33, 0x66, 0xcc, 0xcc, 0x66, 0x33, 0x00,
/* AF */ 0x00, 0xcc, 0x66, 0x33, 0x33, 0x66, 0xcc, 0x00,
/* B0 */ 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88,
/* B1 */ 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
/* B2 */ 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
/* B3 */ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
/* B4 */ 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18,
/* B5 */ 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18,
/* B6 */ 0x66, 0x66, 0x66, 0xe6, 0x66, 0x66, 0x66, 0x66,
/* B7 */ 0x00, 0x00, 0x00, 0xfe, 0x66, 0x66, 0x66, 0x66,
/* B8 */ 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18,
/* B9 */ 0x66, 0x66, 0xe6, 0x06, 0xe6, 0x66, 0x66, 0x66,
/* BA */ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
/* BB */ 0x00, 0x00, 0xfe, 0x06, 0xe6, 0x66, 0x66, 0x66,
/* BC */ 0x66, 0x66, 0xe6, 0x06, 0xfe, 0x00, 0x00, 0x00,
/* BD */ 0x66, 0x66, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
/* BE */ 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00,
/* BF */ 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18,
/* C0 */ 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00,
/* C1 */ 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00,
/* C2 */ 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18,
/* C3 */ 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
/* C4 */ 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
/* C5 */ 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18,
/* C6 */ 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18,
/* C7 */ 0x66, 0x66, 0x66, 0x67, 0x66, 0x66, 0x66, 0x66,
/* C8 */ 0x66, 0x66, 0x67, 0x60, 0x7f, 0x00, 0x00, 0x00,
/* C9 */ 0x00, 0x00, 0x7f, 0x60, 0x67, 0x66, 0x66, 0x66,
/* CA */ 0x66, 0x66, 0xe7, 0x00, 0xff, 0x00, 0x00, 0x00,
/* CB */ 0x00, 0x00, 0xff, 0x00, 0xe7, 0x66, 0x66, 0x66,
/* CC */ 0x66, 0x66, 0x67, 0x60, 0x67, 0x66, 0x66, 0x66,
/* CD */ 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
/* CE */ 0x66, 0x66, 0xe7, 0x00, 0xe7, 0x66, 0x66, 0x66,
/* CF */ 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
/* D0 */ 0x66, 0x66, 0x66, 0xff, 0x00, 0x00, 0x00, 0x00,
/* D1 */ 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18,
/* D2 */ 0x00, 0x00, 0x00, 0xff, 0x66, 0x66, 0x66, 0x66,
/* D3 */ 0x66, 0x66, 0x66, 0x7f, 0x00, 0x00, 0x00, 0x00,
/* D4 */ 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00,
/* D5 */ 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18,
/* D6 */ 0x00, 0x00, 0x00, 0x7f, 0x66, 0x66, 0x66, 0x66,
/* D7 */ 0x66, 0x66, 0x66, 0xff, 0x66, 0x66, 0x66, 0x66,
/* D8 */ 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18,
/* D9 */ 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00,
/* DA */ 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18,
/* DB */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
/* DC */ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
/* DD */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
/* DE */ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
/* DF */ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
/* E0 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* E1 */ 0x3c, 0x66, 0x66, 0x6c, 0x66, 0x66, 0x6c, 0xc0,
/* E2 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* E3 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* E4 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* E5 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* E6 */ 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x3e, 0x60,
/* E7 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* E8 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* E9 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* EA */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* EB */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* EC */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* ED */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* EE */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* EF */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* F0 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* F1 */ 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x7e, 0x00,
/* F2 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* F3 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* F4 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* F5 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* F6 */ 0x00, 0x18, 0x00, 0xff, 0x00, 0x18, 0x00, 0x00,
/* F7 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* F8 */ 0x3c, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,
/* F9 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* FA */ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
/* FB */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* FC */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* FD */ 0x38, 0x04, 0x18, 0x20, 0x3c, 0x00, 0x00, 0x00,
/* FE */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
/* FF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const struct font_desc font_acorn_8x8 = {
.idx = ACORN8x8_IDX,
.name = "Acorn8x8",
.width = 8,
.height = 8,
.data = acorndata_8x8,
#ifdef CONFIG_ARCH_ACORN
.pref = 20,
#else
.pref = 0,
#endif
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,275 @@
#include <linux/font.h>
#define FONTDATAMAX 4096
static const unsigned char fontdata_sun8x16[FONTDATAMAX] = {
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x7e,0x81,0xa5,0x81,0x81,0xbd,0x99,0x81,0x81,0x7e,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x7e,0xff,0xdb,0xff,0xff,0xc3,0xe7,0xff,0xff,0x7e,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x6c,0xfe,0xfe,0xfe,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x10,0x38,0x7c,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x18,0x3c,0x3c,0xe7,0xe7,0xe7,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x18,0x3c,0x7e,0xff,0xff,0x7e,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0xff,0xff,0xff,0xff,0xff,0xff,0xe7,0xc3,0xc3,0xe7,0xff,0xff,0xff,0xff,0xff,0xff,
/* */ 0x00,0x00,0x00,0x00,0x00,0x3c,0x66,0x42,0x42,0x66,0x3c,0x00,0x00,0x00,0x00,0x00,
/* */ 0xff,0xff,0xff,0xff,0xff,0xc3,0x99,0xbd,0xbd,0x99,0xc3,0xff,0xff,0xff,0xff,0xff,
/* */ 0x00,0x00,0x1e,0x0e,0x1a,0x32,0x78,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x3c,0x66,0x66,0x66,0x66,0x3c,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x3f,0x33,0x3f,0x30,0x30,0x30,0x30,0x70,0xf0,0xe0,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x7f,0x63,0x7f,0x63,0x63,0x63,0x63,0x67,0xe7,0xe6,0xc0,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x18,0x18,0xdb,0x3c,0xe7,0x3c,0xdb,0x18,0x18,0x00,0x00,0x00,0x00,
/* */ 0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfe,0xf8,0xf0,0xe0,0xc0,0x80,0x00,0x00,0x00,0x00,
/* */ 0x00,0x02,0x06,0x0e,0x1e,0x3e,0xfe,0x3e,0x1e,0x0e,0x06,0x02,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x66,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x7f,0xdb,0xdb,0xdb,0x7b,0x1b,0x1b,0x1b,0x1b,0x1b,0x00,0x00,0x00,0x00,
/* */ 0x00,0x7c,0xc6,0x60,0x38,0x6c,0xc6,0xc6,0x6c,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xfe,0xfe,0xfe,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x18,0x0c,0xfe,0x0c,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xfe,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xc0,0xc0,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x24,0x66,0xff,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7c,0x7c,0xfe,0xfe,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0xfe,0xfe,0x7c,0x7c,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*!*/ 0x00,0x00,0x18,0x3c,0x3c,0x3c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
/*"*/ 0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*#*/ 0x00,0x00,0x00,0x6c,0x6c,0xfe,0x6c,0x6c,0x6c,0xfe,0x6c,0x6c,0x00,0x00,0x00,0x00,
/*$*/ 0x18,0x18,0x7c,0xc6,0xc2,0xc0,0x7c,0x06,0x06,0x86,0xc6,0x7c,0x18,0x18,0x00,0x00,
/*%*/ 0x00,0x00,0x00,0x00,0xc2,0xc6,0x0c,0x18,0x30,0x60,0xc6,0x86,0x00,0x00,0x00,0x00,
/*&*/ 0x00,0x00,0x38,0x6c,0x6c,0x38,0x76,0xdc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/*'*/ 0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*(*/ 0x00,0x00,0x0c,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0c,0x00,0x00,0x00,0x00,
/*)*/ 0x00,0x00,0x30,0x18,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x18,0x30,0x00,0x00,0x00,0x00,
/***/ 0x00,0x00,0x00,0x00,0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00,0x00,0x00,0x00,0x00,
/*+*/ 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
/*,*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00,
/*-*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*.*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x02,0x06,0x0c,0x18,0x30,0x60,0xc0,0x80,0x00,0x00,0x00,0x00,
/*0*/ 0x00,0x00,0x7c,0xc6,0xc6,0xce,0xde,0xf6,0xe6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*1*/ 0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x00,0x00,0x00,0x00,
/*2*/ 0x00,0x00,0x7c,0xc6,0x06,0x0c,0x18,0x30,0x60,0xc0,0xc6,0xfe,0x00,0x00,0x00,0x00,
/*3*/ 0x00,0x00,0x7c,0xc6,0x06,0x06,0x3c,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*4*/ 0x00,0x00,0x0c,0x1c,0x3c,0x6c,0xcc,0xfe,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00,
/*5*/ 0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xfc,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*6*/ 0x00,0x00,0x38,0x60,0xc0,0xc0,0xfc,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*7*/ 0x00,0x00,0xfe,0xc6,0x06,0x06,0x0c,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00,
/*8*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7c,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*9*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7e,0x06,0x06,0x06,0x0c,0x78,0x00,0x00,0x00,0x00,
/*:*/ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
/*;*/ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00,
/*<*/ 0x00,0x00,0x00,0x06,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x06,0x00,0x00,0x00,0x00,
/*=*/ 0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*>*/ 0x00,0x00,0x00,0x60,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x60,0x00,0x00,0x00,0x00,
/*?*/ 0x00,0x00,0x7c,0xc6,0xc6,0x0c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
/*@*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xde,0xde,0xde,0xdc,0xc0,0x7c,0x00,0x00,0x00,0x00,
/*A*/ 0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
/*B*/ 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x66,0x66,0x66,0x66,0xfc,0x00,0x00,0x00,0x00,
/*C*/ 0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x00,0x00,0x00,0x00,
/*D*/ 0x00,0x00,0xf8,0x6c,0x66,0x66,0x66,0x66,0x66,0x66,0x6c,0xf8,0x00,0x00,0x00,0x00,
/*E*/ 0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00,
/*F*/ 0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
/*G*/ 0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xde,0xc6,0xc6,0x66,0x3a,0x00,0x00,0x00,0x00,
/*H*/ 0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
/*I*/ 0x00,0x00,0x3c,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
/*J*/ 0x00,0x00,0x1e,0x0c,0x0c,0x0c,0x0c,0x0c,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00,
/*K*/ 0x00,0x00,0xe6,0x66,0x66,0x6c,0x78,0x78,0x6c,0x66,0x66,0xe6,0x00,0x00,0x00,0x00,
/*L*/ 0x00,0x00,0xf0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00,
/*M*/ 0x00,0x00,0xc3,0xe7,0xff,0xff,0xdb,0xc3,0xc3,0xc3,0xc3,0xc3,0x00,0x00,0x00,0x00,
/*N*/ 0x00,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
/*O*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*P*/ 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
/*Q*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xd6,0xde,0x7c,0x0c,0x0e,0x00,0x00,
/*R*/ 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x6c,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00,
/*S*/ 0x00,0x00,0x7c,0xc6,0xc6,0x60,0x38,0x0c,0x06,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*T*/ 0x00,0x00,0xff,0xdb,0x99,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
/*U*/ 0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*V*/ 0x00,0x00,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x00,0x00,0x00,0x00,
/*W*/ 0x00,0x00,0xc3,0xc3,0xc3,0xc3,0xc3,0xdb,0xdb,0xff,0x66,0x66,0x00,0x00,0x00,0x00,
/*X*/ 0x00,0x00,0xc3,0xc3,0x66,0x3c,0x18,0x18,0x3c,0x66,0xc3,0xc3,0x00,0x00,0x00,0x00,
/*Y*/ 0x00,0x00,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
/*Z*/ 0x00,0x00,0xff,0xc3,0x86,0x0c,0x18,0x30,0x60,0xc1,0xc3,0xff,0x00,0x00,0x00,0x00,
/*[*/ 0x00,0x00,0x3c,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3c,0x00,0x00,0x00,0x00,
/*\*/ 0x00,0x00,0x00,0x80,0xc0,0xe0,0x70,0x38,0x1c,0x0e,0x06,0x02,0x00,0x00,0x00,0x00,
/*]*/ 0x00,0x00,0x3c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3c,0x00,0x00,0x00,0x00,
/*^*/ 0x10,0x38,0x6c,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*_*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,
/*`*/ 0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*a*/ 0x00,0x00,0x00,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/*b*/ 0x00,0x00,0xe0,0x60,0x60,0x78,0x6c,0x66,0x66,0x66,0x66,0x7c,0x00,0x00,0x00,0x00,
/*c*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc0,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*d*/ 0x00,0x00,0x1c,0x0c,0x0c,0x3c,0x6c,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/*e*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*f*/ 0x00,0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
/*g*/ 0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0xcc,0x78,0x00,
/*h*/ 0x00,0x00,0xe0,0x60,0x60,0x6c,0x76,0x66,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00,
/*i*/ 0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
/*j*/ 0x00,0x00,0x06,0x06,0x00,0x0e,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3c,0x00,
/*k*/ 0x00,0x00,0xe0,0x60,0x60,0x66,0x6c,0x78,0x78,0x6c,0x66,0xe6,0x00,0x00,0x00,0x00,
/*l*/ 0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
/*m*/ 0x00,0x00,0x00,0x00,0x00,0xe6,0xff,0xdb,0xdb,0xdb,0xdb,0xdb,0x00,0x00,0x00,0x00,
/*n*/ 0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
/*o*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*p*/ 0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xf0,0x00,
/*q*/ 0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x0c,0x1e,0x00,
/*r*/ 0x00,0x00,0x00,0x00,0x00,0xdc,0x76,0x66,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
/*s*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0x60,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*t*/ 0x00,0x00,0x10,0x30,0x30,0xfc,0x30,0x30,0x30,0x30,0x36,0x1c,0x00,0x00,0x00,0x00,
/*u*/ 0x00,0x00,0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/*v*/ 0x00,0x00,0x00,0x00,0x00,0xc3,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x00,0x00,0x00,0x00,
/*w*/ 0x00,0x00,0x00,0x00,0x00,0xc3,0xc3,0xc3,0xdb,0xdb,0xff,0x66,0x00,0x00,0x00,0x00,
/*x*/ 0x00,0x00,0x00,0x00,0x00,0xc3,0x66,0x3c,0x18,0x3c,0x66,0xc3,0x00,0x00,0x00,0x00,
/*y*/ 0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0xf8,0x00,
/*z*/ 0x00,0x00,0x00,0x00,0x00,0xfe,0xcc,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00,
/*{*/ 0x00,0x00,0x0e,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0e,0x00,0x00,0x00,0x00,
/*|*/ 0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
/*}*/ 0x00,0x00,0x70,0x18,0x18,0x18,0x0e,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00,
/*~*/ 0x00,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xc6,0xfe,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x0c,0x06,0x7c,0x00,0x00,
/* */ 0x00,0x00,0xcc,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/* */ 0x00,0x0c,0x18,0x30,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x10,0x38,0x6c,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0xcc,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/* */ 0x00,0x60,0x30,0x18,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/* */ 0x00,0x38,0x6c,0x38,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x3c,0x66,0x60,0x60,0x66,0x3c,0x0c,0x06,0x3c,0x00,0x00,0x00,
/* */ 0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x66,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x18,0x3c,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
/* */ 0x00,0xc6,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
/* */ 0x38,0x6c,0x38,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
/* */ 0x18,0x30,0x60,0x00,0xfe,0x66,0x60,0x7c,0x60,0x60,0x66,0xfe,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x6e,0x3b,0x1b,0x7e,0xd8,0xdc,0x77,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x3e,0x6c,0xcc,0xcc,0xfe,0xcc,0xcc,0xcc,0xcc,0xce,0x00,0x00,0x00,0x00,
/* */ 0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x30,0x78,0xcc,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/* */ 0x00,0x60,0x30,0x18,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0xc6,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0x78,0x00,
/* */ 0x00,0xc6,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/* */ 0x00,0xc6,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x18,0x18,0x7e,0xc3,0xc0,0xc0,0xc0,0xc3,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,
/* */ 0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xe6,0xfc,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0xc3,0x66,0x3c,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
/* */ 0x00,0xfc,0x66,0x66,0x7c,0x62,0x66,0x6f,0x66,0x66,0x66,0xf3,0x00,0x00,0x00,0x00,
/* */ 0x00,0x0e,0x1b,0x18,0x18,0x18,0x7e,0x18,0x18,0x18,0x18,0x18,0xd8,0x70,0x00,0x00,
/* */ 0x00,0x18,0x30,0x60,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/* */ 0x00,0x0c,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x18,0x30,0x60,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x18,0x30,0x60,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x76,0xdc,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
/* */ 0x76,0xdc,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
/* */ 0x00,0x3c,0x6c,0x6c,0x3e,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x38,0x6c,0x6c,0x38,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0xc0,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x60,0xce,0x9b,0x06,0x0c,0x1f,0x00,0x00,
/* */ 0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x66,0xce,0x96,0x3e,0x06,0x06,0x00,0x00,
/* */ 0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x3c,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x36,0x6c,0xd8,0x6c,0x36,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0xd8,0x6c,0x36,0x6c,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,
/* */ 0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,
/* */ 0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,
/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x3f,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x18,0x18,0x18,0x18,0x18,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x18,0x18,0x18,0x18,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
/* */ 0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,
/* */ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
/* */ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0xd8,0xd8,0xd8,0xdc,0x76,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x78,0xcc,0xcc,0xcc,0xd8,0xcc,0xc6,0xc6,0xc6,0xcc,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0xfe,0xc6,0xc6,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0xfe,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0xfe,0xc6,0x60,0x30,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x7e,0xd8,0xd8,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xc0,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x76,0xdc,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x7e,0x18,0x3c,0x66,0x66,0x66,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0x6c,0x38,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x38,0x6c,0xc6,0xc6,0xc6,0x6c,0x6c,0x6c,0x6c,0xee,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x1e,0x30,0x18,0x0c,0x3e,0x66,0x66,0x66,0x66,0x3c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x7e,0xdb,0xdb,0xdb,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x03,0x06,0x7e,0xdb,0xdb,0xf3,0x7e,0x60,0xc0,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x1c,0x30,0x60,0x60,0x7c,0x60,0x60,0x60,0x30,0x1c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0xff,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x00,0x7e,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x00,0x7e,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x0e,0x1b,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x7e,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x38,0x6c,0x6c,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x0f,0x0c,0x0c,0x0c,0x0c,0x0c,0xec,0x6c,0x6c,0x3c,0x1c,0x00,0x00,0x00,0x00,
/* */ 0x00,0xd8,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x70,0xd8,0x30,0x60,0xc8,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
const struct font_desc font_sun_8x16 = {
.idx = SUN8x16_IDX,
.name = "SUN8x16",
.width = 8,
.height = 16,
.data = fontdata_sun8x16,
#ifdef __sparc__
.pref = 10,
#else
.pref = -1,
#endif
};

View File

@@ -0,0 +1,153 @@
/*
* linux/drivers/video/fonts.c -- `Soft' font definitions
*
* Created 1995 by Geert Uytterhoeven
* Rewritten 1998 by Martin Mares <mj@ucw.cz>
*
* 2001 - Documented with DocBook
* - Brad Douglas <brad@neruo.com>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/string.h>
#if defined(__mc68000__)
#include <asm/setup.h>
#endif
#include <linux/font.h>
#define NO_FONTS
static const struct font_desc *fonts[] = {
#ifdef CONFIG_FONT_8x8
#undef NO_FONTS
&font_vga_8x8,
#endif
#ifdef CONFIG_FONT_8x16
#undef NO_FONTS
&font_vga_8x16,
#endif
#ifdef CONFIG_FONT_6x11
#undef NO_FONTS
&font_vga_6x11,
#endif
#ifdef CONFIG_FONT_7x14
#undef NO_FONTS
&font_7x14,
#endif
#ifdef CONFIG_FONT_SUN8x16
#undef NO_FONTS
&font_sun_8x16,
#endif
#ifdef CONFIG_FONT_SUN12x22
#undef NO_FONTS
&font_sun_12x22,
#endif
#ifdef CONFIG_FONT_10x18
#undef NO_FONTS
&font_10x18,
#endif
#ifdef CONFIG_FONT_ACORN_8x8
#undef NO_FONTS
&font_acorn_8x8,
#endif
#ifdef CONFIG_FONT_PEARL_8x8
#undef NO_FONTS
&font_pearl_8x8,
#endif
#ifdef CONFIG_FONT_MINI_4x6
#undef NO_FONTS
&font_mini_4x6,
#endif
};
#define num_fonts ARRAY_SIZE(fonts)
#ifdef NO_FONTS
#error No fonts configured.
#endif
/**
* find_font - find a font
* @name: string name of a font
*
* Find a specified font with string name @name.
*
* Returns %NULL if no font found, or a pointer to the
* specified font.
*
*/
const struct font_desc *find_font(const char *name)
{
unsigned int i;
for (i = 0; i < num_fonts; i++)
if (!strcmp(fonts[i]->name, name))
return fonts[i];
return NULL;
}
/**
* get_default_font - get default font
* @xres: screen size of X
* @yres: screen size of Y
* @font_w: bit array of supported widths (1 - 32)
* @font_h: bit array of supported heights (1 - 32)
*
* Get the default font for a specified screen size.
* Dimensions are in pixels.
*
* Returns %NULL if no font is found, or a pointer to the
* chosen font.
*
*/
const struct font_desc *get_default_font(int xres, int yres, u32 font_w,
u32 font_h)
{
int i, c, cc;
const struct font_desc *f, *g;
g = NULL;
cc = -10000;
for(i=0; i<num_fonts; i++) {
f = fonts[i];
c = f->pref;
#if defined(__mc68000__)
#ifdef CONFIG_FONT_PEARL_8x8
if (MACH_IS_AMIGA && f->idx == PEARL8x8_IDX)
c = 100;
#endif
#ifdef CONFIG_FONT_6x11
if (MACH_IS_MAC && xres < 640 && f->idx == VGA6x11_IDX)
c = 100;
#endif
#endif
if ((yres < 400) == (f->height <= 8))
c += 1000;
if ((font_w & (1 << (f->width - 1))) &&
(font_h & (1 << (f->height - 1))))
c += 1000;
if (c > cc) {
cc = c;
g = f;
}
}
return g;
}
EXPORT_SYMBOL(find_font);
EXPORT_SYMBOL(get_default_font);
MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
MODULE_DESCRIPTION("Console Fonts");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,604 @@
/*
* linux/drivers/video/mdacon.c -- Low level MDA based console driver
*
* (c) 1998 Andrew Apted <ajapted@netspace.net.au>
*
* including portions (c) 1995-1998 Patrick Caulfield.
*
* slight improvements (c) 2000 Edward Betts <edward@debian.org>
*
* This file is based on the VGA console driver (vgacon.c):
*
* Created 28 Sep 1997 by Geert Uytterhoeven
*
* Rewritten by Martin Mares <mj@ucw.cz>, July 1998
*
* and on the old console.c, vga.c and vesa_blank.c drivers:
*
* Copyright (C) 1991, 1992 Linus Torvalds
* 1995 Jay Estabrook
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*
* Changelog:
* Paul G. (03/2001) Fix mdacon= boot prompt to use __setup().
*/
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/console.h>
#include <linux/string.h>
#include <linux/kd.h>
#include <linux/slab.h>
#include <linux/vt_kern.h>
#include <linux/vt_buffer.h>
#include <linux/selection.h>
#include <linux/spinlock.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <asm/io.h>
#include <asm/vga.h>
static DEFINE_SPINLOCK(mda_lock);
/* description of the hardware layout */
static unsigned long mda_vram_base; /* Base of video memory */
static unsigned long mda_vram_len; /* Size of video memory */
static unsigned int mda_num_columns; /* Number of text columns */
static unsigned int mda_num_lines; /* Number of text lines */
static unsigned int mda_index_port; /* Register select port */
static unsigned int mda_value_port; /* Register value port */
static unsigned int mda_mode_port; /* Mode control port */
static unsigned int mda_status_port; /* Status and Config port */
static unsigned int mda_gfx_port; /* Graphics control port */
/* current hardware state */
static int mda_cursor_loc=-1;
static int mda_cursor_size_from=-1;
static int mda_cursor_size_to=-1;
static enum { TYPE_MDA, TYPE_HERC, TYPE_HERCPLUS, TYPE_HERCCOLOR } mda_type;
static char *mda_type_name;
/* console information */
static int mda_first_vc = 13;
static int mda_last_vc = 16;
static struct vc_data *mda_display_fg = NULL;
module_param(mda_first_vc, int, 0);
MODULE_PARM_DESC(mda_first_vc, "First virtual console. Default: 13");
module_param(mda_last_vc, int, 0);
MODULE_PARM_DESC(mda_last_vc, "Last virtual console. Default: 16");
/* MDA register values
*/
#define MDA_CURSOR_BLINKING 0x00
#define MDA_CURSOR_OFF 0x20
#define MDA_CURSOR_SLOWBLINK 0x60
#define MDA_MODE_GRAPHICS 0x02
#define MDA_MODE_VIDEO_EN 0x08
#define MDA_MODE_BLINK_EN 0x20
#define MDA_MODE_GFX_PAGE1 0x80
#define MDA_STATUS_HSYNC 0x01
#define MDA_STATUS_VSYNC 0x80
#define MDA_STATUS_VIDEO 0x08
#define MDA_CONFIG_COL132 0x08
#define MDA_GFX_MODE_EN 0x01
#define MDA_GFX_PAGE_EN 0x02
/*
* MDA could easily be classified as "pre-dinosaur hardware".
*/
static void write_mda_b(unsigned int val, unsigned char reg)
{
unsigned long flags;
spin_lock_irqsave(&mda_lock, flags);
outb_p(reg, mda_index_port);
outb_p(val, mda_value_port);
spin_unlock_irqrestore(&mda_lock, flags);
}
static void write_mda_w(unsigned int val, unsigned char reg)
{
unsigned long flags;
spin_lock_irqsave(&mda_lock, flags);
outb_p(reg, mda_index_port); outb_p(val >> 8, mda_value_port);
outb_p(reg+1, mda_index_port); outb_p(val & 0xff, mda_value_port);
spin_unlock_irqrestore(&mda_lock, flags);
}
#ifdef TEST_MDA_B
static int test_mda_b(unsigned char val, unsigned char reg)
{
unsigned long flags;
spin_lock_irqsave(&mda_lock, flags);
outb_p(reg, mda_index_port);
outb (val, mda_value_port);
udelay(20); val = (inb_p(mda_value_port) == val);
spin_unlock_irqrestore(&mda_lock, flags);
return val;
}
#endif
static inline void mda_set_cursor(unsigned int location)
{
if (mda_cursor_loc == location)
return;
write_mda_w(location >> 1, 0x0e);
mda_cursor_loc = location;
}
static inline void mda_set_cursor_size(int from, int to)
{
if (mda_cursor_size_from==from && mda_cursor_size_to==to)
return;
if (from > to) {
write_mda_b(MDA_CURSOR_OFF, 0x0a); /* disable cursor */
} else {
write_mda_b(from, 0x0a); /* cursor start */
write_mda_b(to, 0x0b); /* cursor end */
}
mda_cursor_size_from = from;
mda_cursor_size_to = to;
}
#ifndef MODULE
static int __init mdacon_setup(char *str)
{
/* command line format: mdacon=<first>,<last> */
int ints[3];
str = get_options(str, ARRAY_SIZE(ints), ints);
if (ints[0] < 2)
return 0;
if (ints[1] < 1 || ints[1] > MAX_NR_CONSOLES ||
ints[2] < 1 || ints[2] > MAX_NR_CONSOLES)
return 0;
mda_first_vc = ints[1];
mda_last_vc = ints[2];
return 1;
}
__setup("mdacon=", mdacon_setup);
#endif
static int mda_detect(void)
{
int count=0;
u16 *p, p_save;
u16 *q, q_save;
/* do a memory check */
p = (u16 *) mda_vram_base;
q = (u16 *) (mda_vram_base + 0x01000);
p_save = scr_readw(p); q_save = scr_readw(q);
scr_writew(0xAA55, p); if (scr_readw(p) == 0xAA55) count++;
scr_writew(0x55AA, p); if (scr_readw(p) == 0x55AA) count++;
scr_writew(p_save, p);
if (count != 2) {
return 0;
}
/* check if we have 4K or 8K */
scr_writew(0xA55A, q); scr_writew(0x0000, p);
if (scr_readw(q) == 0xA55A) count++;
scr_writew(0x5AA5, q); scr_writew(0x0000, p);
if (scr_readw(q) == 0x5AA5) count++;
scr_writew(p_save, p); scr_writew(q_save, q);
if (count == 4) {
mda_vram_len = 0x02000;
}
/* Ok, there is definitely a card registering at the correct
* memory location, so now we do an I/O port test.
*/
#ifdef TEST_MDA_B
/* Edward: These two mess `tests' mess up my cursor on bootup */
/* cursor low register */
if (! test_mda_b(0x66, 0x0f)) {
return 0;
}
/* cursor low register */
if (! test_mda_b(0x99, 0x0f)) {
return 0;
}
#endif
/* See if the card is a Hercules, by checking whether the vsync
* bit of the status register is changing. This test lasts for
* approximately 1/10th of a second.
*/
p_save = q_save = inb_p(mda_status_port) & MDA_STATUS_VSYNC;
for (count=0; count < 50000 && p_save == q_save; count++) {
q_save = inb(mda_status_port) & MDA_STATUS_VSYNC;
udelay(2);
}
if (p_save != q_save) {
switch (inb_p(mda_status_port) & 0x70) {
case 0x10:
mda_type = TYPE_HERCPLUS;
mda_type_name = "HerculesPlus";
break;
case 0x50:
mda_type = TYPE_HERCCOLOR;
mda_type_name = "HerculesColor";
break;
default:
mda_type = TYPE_HERC;
mda_type_name = "Hercules";
break;
}
}
return 1;
}
static void mda_initialize(void)
{
write_mda_b(97, 0x00); /* horizontal total */
write_mda_b(80, 0x01); /* horizontal displayed */
write_mda_b(82, 0x02); /* horizontal sync pos */
write_mda_b(15, 0x03); /* horizontal sync width */
write_mda_b(25, 0x04); /* vertical total */
write_mda_b(6, 0x05); /* vertical total adjust */
write_mda_b(25, 0x06); /* vertical displayed */
write_mda_b(25, 0x07); /* vertical sync pos */
write_mda_b(2, 0x08); /* interlace mode */
write_mda_b(13, 0x09); /* maximum scanline */
write_mda_b(12, 0x0a); /* cursor start */
write_mda_b(13, 0x0b); /* cursor end */
write_mda_w(0x0000, 0x0c); /* start address */
write_mda_w(0x0000, 0x0e); /* cursor location */
outb_p(MDA_MODE_VIDEO_EN | MDA_MODE_BLINK_EN, mda_mode_port);
outb_p(0x00, mda_status_port);
outb_p(0x00, mda_gfx_port);
}
static const char *mdacon_startup(void)
{
mda_num_columns = 80;
mda_num_lines = 25;
mda_vram_len = 0x01000;
mda_vram_base = VGA_MAP_MEM(0xb0000, mda_vram_len);
mda_index_port = 0x3b4;
mda_value_port = 0x3b5;
mda_mode_port = 0x3b8;
mda_status_port = 0x3ba;
mda_gfx_port = 0x3bf;
mda_type = TYPE_MDA;
mda_type_name = "MDA";
if (! mda_detect()) {
printk("mdacon: MDA card not detected.\n");
return NULL;
}
if (mda_type != TYPE_MDA) {
mda_initialize();
}
/* cursor looks ugly during boot-up, so turn it off */
mda_set_cursor(mda_vram_len - 1);
printk("mdacon: %s with %ldK of memory detected.\n",
mda_type_name, mda_vram_len/1024);
return "MDA-2";
}
static void mdacon_init(struct vc_data *c, int init)
{
c->vc_complement_mask = 0x0800; /* reverse video */
c->vc_display_fg = &mda_display_fg;
if (init) {
c->vc_cols = mda_num_columns;
c->vc_rows = mda_num_lines;
} else
vc_resize(c, mda_num_columns, mda_num_lines);
/* make the first MDA console visible */
if (mda_display_fg == NULL)
mda_display_fg = c;
}
static void mdacon_deinit(struct vc_data *c)
{
/* con_set_default_unimap(c->vc_num); */
if (mda_display_fg == c)
mda_display_fg = NULL;
}
static inline u16 mda_convert_attr(u16 ch)
{
u16 attr = 0x0700;
/* Underline and reverse-video are mutually exclusive on MDA.
* Since reverse-video is used for cursors and selected areas,
* it takes precedence.
*/
if (ch & 0x0800) attr = 0x7000; /* reverse */
else if (ch & 0x0400) attr = 0x0100; /* underline */
return ((ch & 0x0200) << 2) | /* intensity */
(ch & 0x8000) | /* blink */
(ch & 0x00ff) | attr;
}
static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
u8 blink, u8 underline, u8 reverse, u8 italic)
{
/* The attribute is just a bit vector:
*
* Bit 0..1 : intensity (0..2)
* Bit 2 : underline
* Bit 3 : reverse
* Bit 7 : blink
*/
return (intensity & 3) |
((underline & 1) << 2) |
((reverse & 1) << 3) |
(!!italic << 4) |
((blink & 1) << 7);
}
static void mdacon_invert_region(struct vc_data *c, u16 *p, int count)
{
for (; count > 0; count--) {
scr_writew(scr_readw(p) ^ 0x0800, p);
p++;
}
}
#define MDA_ADDR(x,y) ((u16 *) mda_vram_base + (y)*mda_num_columns + (x))
static void mdacon_putc(struct vc_data *c, int ch, int y, int x)
{
scr_writew(mda_convert_attr(ch), MDA_ADDR(x, y));
}
static void mdacon_putcs(struct vc_data *c, const unsigned short *s,
int count, int y, int x)
{
u16 *dest = MDA_ADDR(x, y);
for (; count > 0; count--) {
scr_writew(mda_convert_attr(scr_readw(s++)), dest++);
}
}
static void mdacon_clear(struct vc_data *c, int y, int x,
int height, int width)
{
u16 *dest = MDA_ADDR(x, y);
u16 eattr = mda_convert_attr(c->vc_video_erase_char);
if (width <= 0 || height <= 0)
return;
if (x==0 && width==mda_num_columns) {
scr_memsetw(dest, eattr, height*width*2);
} else {
for (; height > 0; height--, dest+=mda_num_columns)
scr_memsetw(dest, eattr, width*2);
}
}
static void mdacon_bmove(struct vc_data *c, int sy, int sx,
int dy, int dx, int height, int width)
{
u16 *src, *dest;
if (width <= 0 || height <= 0)
return;
if (sx==0 && dx==0 && width==mda_num_columns) {
scr_memmovew(MDA_ADDR(0,dy), MDA_ADDR(0,sy), height*width*2);
} else if (dy < sy || (dy == sy && dx < sx)) {
src = MDA_ADDR(sx, sy);
dest = MDA_ADDR(dx, dy);
for (; height > 0; height--) {
scr_memmovew(dest, src, width*2);
src += mda_num_columns;
dest += mda_num_columns;
}
} else {
src = MDA_ADDR(sx, sy+height-1);
dest = MDA_ADDR(dx, dy+height-1);
for (; height > 0; height--) {
scr_memmovew(dest, src, width*2);
src -= mda_num_columns;
dest -= mda_num_columns;
}
}
}
static int mdacon_switch(struct vc_data *c)
{
return 1; /* redrawing needed */
}
static int mdacon_set_palette(struct vc_data *c, unsigned char *table)
{
return -EINVAL;
}
static int mdacon_blank(struct vc_data *c, int blank, int mode_switch)
{
if (mda_type == TYPE_MDA) {
if (blank)
scr_memsetw((void *)mda_vram_base,
mda_convert_attr(c->vc_video_erase_char),
c->vc_screenbuf_size);
/* Tell console.c that it has to restore the screen itself */
return 1;
} else {
if (blank)
outb_p(0x00, mda_mode_port); /* disable video */
else
outb_p(MDA_MODE_VIDEO_EN | MDA_MODE_BLINK_EN,
mda_mode_port);
return 0;
}
}
static int mdacon_scrolldelta(struct vc_data *c, int lines)
{
return 0;
}
static void mdacon_cursor(struct vc_data *c, int mode)
{
if (mode == CM_ERASE) {
mda_set_cursor(mda_vram_len - 1);
return;
}
mda_set_cursor(c->vc_y*mda_num_columns*2 + c->vc_x*2);
switch (c->vc_cursor_type & 0x0f) {
case CUR_LOWER_THIRD: mda_set_cursor_size(10, 13); break;
case CUR_LOWER_HALF: mda_set_cursor_size(7, 13); break;
case CUR_TWO_THIRDS: mda_set_cursor_size(4, 13); break;
case CUR_BLOCK: mda_set_cursor_size(1, 13); break;
case CUR_NONE: mda_set_cursor_size(14, 13); break;
default: mda_set_cursor_size(12, 13); break;
}
}
static int mdacon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
{
u16 eattr = mda_convert_attr(c->vc_video_erase_char);
if (!lines)
return 0;
if (lines > c->vc_rows) /* maximum realistic size */
lines = c->vc_rows;
switch (dir) {
case SM_UP:
scr_memmovew(MDA_ADDR(0,t), MDA_ADDR(0,t+lines),
(b-t-lines)*mda_num_columns*2);
scr_memsetw(MDA_ADDR(0,b-lines), eattr,
lines*mda_num_columns*2);
break;
case SM_DOWN:
scr_memmovew(MDA_ADDR(0,t+lines), MDA_ADDR(0,t),
(b-t-lines)*mda_num_columns*2);
scr_memsetw(MDA_ADDR(0,t), eattr, lines*mda_num_columns*2);
break;
}
return 0;
}
/*
* The console `switch' structure for the MDA based console
*/
static const struct consw mda_con = {
.owner = THIS_MODULE,
.con_startup = mdacon_startup,
.con_init = mdacon_init,
.con_deinit = mdacon_deinit,
.con_clear = mdacon_clear,
.con_putc = mdacon_putc,
.con_putcs = mdacon_putcs,
.con_cursor = mdacon_cursor,
.con_scroll = mdacon_scroll,
.con_bmove = mdacon_bmove,
.con_switch = mdacon_switch,
.con_blank = mdacon_blank,
.con_set_palette = mdacon_set_palette,
.con_scrolldelta = mdacon_scrolldelta,
.con_build_attr = mdacon_build_attr,
.con_invert_region = mdacon_invert_region,
};
int __init mda_console_init(void)
{
if (mda_first_vc > mda_last_vc)
return 1;
return take_over_console(&mda_con, mda_first_vc-1, mda_last_vc-1, 0);
}
static void __exit mda_console_exit(void)
{
give_up_console(&mda_con);
}
module_init(mda_console_init);
module_exit(mda_console_exit);
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,768 @@
/*
* newport_con.c: Abscon for newport hardware
*
* (C) 1998 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
* (C) 1999 Ulf Carlsson (ulfc@thepuffingruop.com)
*
* This driver is based on sgicons.c and cons_newport.
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
* Copyright (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx)
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/kd.h>
#include <linux/selection.h>
#include <linux/console.h>
#include <linux/vt_kern.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <video/newport.h>
#include <linux/linux_logo.h>
#include <linux/font.h>
extern unsigned long sgi_gfxaddr;
#define FONT_DATA ((unsigned char *)font_vga_8x16.data)
/* borrowed from fbcon.c */
#define REFCOUNT(fd) (((int *)(fd))[-1])
#define FNTSIZE(fd) (((int *)(fd))[-2])
#define FNTCHARCNT(fd) (((int *)(fd))[-3])
#define FONT_EXTRA_WORDS 3
static unsigned char *font_data[MAX_NR_CONSOLES];
static struct newport_regs *npregs;
static int logo_active;
static int topscan;
static int xcurs_correction = 29;
static int newport_xsize;
static int newport_ysize;
static int newport_has_init;
static int newport_set_def_font(int unit, struct console_font *op);
#define BMASK(c) (c << 24)
#define RENDER(regs, cp) do { \
(regs)->go.zpattern = BMASK((cp)[0x0]); (regs)->go.zpattern = BMASK((cp)[0x1]); \
(regs)->go.zpattern = BMASK((cp)[0x2]); (regs)->go.zpattern = BMASK((cp)[0x3]); \
(regs)->go.zpattern = BMASK((cp)[0x4]); (regs)->go.zpattern = BMASK((cp)[0x5]); \
(regs)->go.zpattern = BMASK((cp)[0x6]); (regs)->go.zpattern = BMASK((cp)[0x7]); \
(regs)->go.zpattern = BMASK((cp)[0x8]); (regs)->go.zpattern = BMASK((cp)[0x9]); \
(regs)->go.zpattern = BMASK((cp)[0xa]); (regs)->go.zpattern = BMASK((cp)[0xb]); \
(regs)->go.zpattern = BMASK((cp)[0xc]); (regs)->go.zpattern = BMASK((cp)[0xd]); \
(regs)->go.zpattern = BMASK((cp)[0xe]); (regs)->go.zpattern = BMASK((cp)[0xf]); \
} while(0)
#define TESTVAL 0xdeadbeef
#define XSTI_TO_FXSTART(val) (((val) & 0xffff) << 11)
static inline void newport_render_background(int xstart, int ystart,
int xend, int yend, int ci)
{
newport_wait(npregs);
npregs->set.wrmask = 0xffffffff;
npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
| NPORT_DMODE0_STOPY);
npregs->set.colori = ci;
npregs->set.xystarti =
(xstart << 16) | ((ystart + topscan) & 0x3ff);
npregs->go.xyendi =
((xend + 7) << 16) | ((yend + topscan + 15) & 0x3ff);
}
static inline void newport_init_cmap(void)
{
unsigned short i;
for (i = 0; i < 16; i++) {
newport_bfwait(npregs);
newport_cmap_setaddr(npregs, color_table[i]);
newport_cmap_setrgb(npregs,
default_red[i],
default_grn[i], default_blu[i]);
}
}
static const struct linux_logo *newport_show_logo(void)
{
#ifdef CONFIG_LOGO_SGI_CLUT224
const struct linux_logo *logo = fb_find_logo(8);
const unsigned char *clut;
const unsigned char *data;
unsigned long i;
if (!logo)
return NULL;
clut = logo->clut;
data = logo->data;
for (i = 0; i < logo->clutsize; i++) {
newport_bfwait(npregs);
newport_cmap_setaddr(npregs, i + 0x20);
newport_cmap_setrgb(npregs, clut[0], clut[1], clut[2]);
clut += 3;
}
newport_wait(npregs);
npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
NPORT_DMODE0_CHOST);
npregs->set.xystarti = ((newport_xsize - logo->width) << 16) | (0);
npregs->set.xyendi = ((newport_xsize - 1) << 16);
newport_wait(npregs);
for (i = 0; i < logo->width*logo->height; i++)
npregs->go.hostrw0 = *data++ << 24;
return logo;
#endif /* CONFIG_LOGO_SGI_CLUT224 */
}
static inline void newport_clear_screen(int xstart, int ystart, int xend,
int yend, int ci)
{
if (logo_active)
return;
newport_wait(npregs);
npregs->set.wrmask = 0xffffffff;
npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
| NPORT_DMODE0_STOPY);
npregs->set.colori = ci;
npregs->set.xystarti = (xstart << 16) | ystart;
npregs->go.xyendi = (xend << 16) | yend;
}
static inline void newport_clear_lines(int ystart, int yend, int ci)
{
ystart = ((ystart << 4) + topscan) & 0x3ff;
yend = ((yend << 4) + topscan + 15) & 0x3ff;
newport_clear_screen(0, ystart, 1280 + 63, yend, ci);
}
static void newport_reset(void)
{
unsigned short treg;
int i;
newport_wait(npregs);
treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
newport_vc2_set(npregs, VC2_IREG_CONTROL,
(treg | VC2_CTRL_EVIDEO));
treg = newport_vc2_get(npregs, VC2_IREG_CENTRY);
newport_vc2_set(npregs, VC2_IREG_RADDR, treg);
npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
NPORT_DMODE_W2 | VC2_PROTOCOL);
for (i = 0; i < 128; i++) {
newport_bfwait(npregs);
if (i == 92 || i == 94)
npregs->set.dcbdata0.byshort.s1 = 0xff00;
else
npregs->set.dcbdata0.byshort.s1 = 0x0000;
}
newport_init_cmap();
/* turn off popup plane */
npregs->set.dcbmode = (DCB_XMAP0 | R_DCB_XMAP9_PROTOCOL |
XM9_CRS_CONFIG | NPORT_DMODE_W1);
npregs->set.dcbdata0.bybytes.b3 &= ~XM9_PUPMODE;
npregs->set.dcbmode = (DCB_XMAP1 | R_DCB_XMAP9_PROTOCOL |
XM9_CRS_CONFIG | NPORT_DMODE_W1);
npregs->set.dcbdata0.bybytes.b3 &= ~XM9_PUPMODE;
topscan = 0;
npregs->cset.topscan = 0x3ff;
npregs->cset.xywin = (4096 << 16) | 4096;
/* Clear the screen. */
newport_clear_screen(0, 0, 1280 + 63, 1024, 0);
}
/*
* calculate the actual screen size by reading
* the video timing out of the VC2
*/
static void newport_get_screensize(void)
{
int i, cols;
unsigned short ventry, treg;
unsigned short linetable[128]; /* should be enough */
ventry = newport_vc2_get(npregs, VC2_IREG_VENTRY);
newport_vc2_set(npregs, VC2_IREG_RADDR, ventry);
npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
NPORT_DMODE_W2 | VC2_PROTOCOL);
for (i = 0; i < 128; i++) {
newport_bfwait(npregs);
linetable[i] = npregs->set.dcbdata0.byshort.s1;
}
newport_xsize = newport_ysize = 0;
for (i = 0; i < ARRAY_SIZE(linetable) - 1 && linetable[i + 1]; i += 2) {
cols = 0;
newport_vc2_set(npregs, VC2_IREG_RADDR, linetable[i]);
npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
NPORT_DMODE_W2 | VC2_PROTOCOL);
do {
newport_bfwait(npregs);
treg = npregs->set.dcbdata0.byshort.s1;
if ((treg & 1) == 0)
cols += (treg >> 7) & 0xfe;
if ((treg & 0x80) == 0) {
newport_bfwait(npregs);
treg = npregs->set.dcbdata0.byshort.s1;
}
} while ((treg & 0x8000) == 0);
if (cols) {
if (cols > newport_xsize)
newport_xsize = cols;
newport_ysize += linetable[i + 1];
}
}
printk("NG1: Screensize %dx%d\n", newport_xsize, newport_ysize);
}
static void newport_get_revisions(void)
{
unsigned int tmp;
unsigned int board_rev;
unsigned int rex3_rev;
unsigned int vc2_rev;
unsigned int cmap_rev;
unsigned int xmap9_rev;
unsigned int bt445_rev;
unsigned int bitplanes;
rex3_rev = npregs->cset.status & NPORT_STAT_VERS;
npregs->set.dcbmode = (DCB_CMAP0 | NCMAP_PROTOCOL |
NCMAP_REGADDR_RREG | NPORT_DMODE_W1);
tmp = npregs->set.dcbdata0.bybytes.b3;
cmap_rev = tmp & 7;
board_rev = (tmp >> 4) & 7;
bitplanes = ((board_rev > 1) && (tmp & 0x80)) ? 8 : 24;
npregs->set.dcbmode = (DCB_CMAP1 | NCMAP_PROTOCOL |
NCMAP_REGADDR_RREG | NPORT_DMODE_W1);
tmp = npregs->set.dcbdata0.bybytes.b3;
if ((tmp & 7) < cmap_rev)
cmap_rev = (tmp & 7);
vc2_rev = (newport_vc2_get(npregs, VC2_IREG_CONFIG) >> 5) & 7;
npregs->set.dcbmode = (DCB_XMAP0 | R_DCB_XMAP9_PROTOCOL |
XM9_CRS_REVISION | NPORT_DMODE_W1);
xmap9_rev = npregs->set.dcbdata0.bybytes.b3 & 7;
npregs->set.dcbmode = (DCB_BT445 | BT445_PROTOCOL |
BT445_CSR_ADDR_REG | NPORT_DMODE_W1);
npregs->set.dcbdata0.bybytes.b3 = BT445_REVISION_REG;
npregs->set.dcbmode = (DCB_BT445 | BT445_PROTOCOL |
BT445_CSR_REVISION | NPORT_DMODE_W1);
bt445_rev = (npregs->set.dcbdata0.bybytes.b3 >> 4) - 0x0a;
#define L(a) (char)('A'+(a))
printk
("NG1: Revision %d, %d bitplanes, REX3 revision %c, VC2 revision %c, xmap9 revision %c, cmap revision %c, bt445 revision %c\n",
board_rev, bitplanes, L(rex3_rev), L(vc2_rev), L(xmap9_rev),
L(cmap_rev ? (cmap_rev + 1) : 0), L(bt445_rev));
#undef L
if (board_rev == 3) /* I don't know all affected revisions */
xcurs_correction = 21;
}
static void newport_exit(void)
{
int i;
/* free memory used by user font */
for (i = 0; i < MAX_NR_CONSOLES; i++)
newport_set_def_font(i, NULL);
}
/* Can't be __init, take_over_console may call it later */
static const char *newport_startup(void)
{
int i;
if (!sgi_gfxaddr)
return NULL;
if (!npregs)
npregs = (struct newport_regs *)/* ioremap cannot fail */
ioremap(sgi_gfxaddr, sizeof(struct newport_regs));
npregs->cset.config = NPORT_CFG_GD0;
if (newport_wait(npregs))
goto out_unmap;
npregs->set.xstarti = TESTVAL;
if (npregs->set._xstart.word != XSTI_TO_FXSTART(TESTVAL))
goto out_unmap;
for (i = 0; i < MAX_NR_CONSOLES; i++)
font_data[i] = FONT_DATA;
newport_reset();
newport_get_revisions();
newport_get_screensize();
newport_has_init = 1;
return "SGI Newport";
out_unmap:
return NULL;
}
static void newport_init(struct vc_data *vc, int init)
{
vc->vc_cols = newport_xsize / 8;
vc->vc_rows = newport_ysize / 16;
vc->vc_can_do_color = 1;
}
static void newport_deinit(struct vc_data *c)
{
if (!con_is_bound(&newport_con) && newport_has_init) {
newport_exit();
newport_has_init = 0;
}
}
static void newport_clear(struct vc_data *vc, int sy, int sx, int height,
int width)
{
int xend = ((sx + width) << 3) - 1;
int ystart = ((sy << 4) + topscan) & 0x3ff;
int yend = (((sy + height) << 4) + topscan - 1) & 0x3ff;
if (logo_active)
return;
if (ystart < yend) {
newport_clear_screen(sx << 3, ystart, xend, yend,
(vc->vc_color & 0xf0) >> 4);
} else {
newport_clear_screen(sx << 3, ystart, xend, 1023,
(vc->vc_color & 0xf0) >> 4);
newport_clear_screen(sx << 3, 0, xend, yend,
(vc->vc_color & 0xf0) >> 4);
}
}
static void newport_putc(struct vc_data *vc, int charattr, int ypos,
int xpos)
{
unsigned char *p;
p = &font_data[vc->vc_num][(charattr & 0xff) << 4];
charattr = (charattr >> 8) & 0xff;
xpos <<= 3;
ypos <<= 4;
newport_render_background(xpos, ypos, xpos, ypos,
(charattr & 0xf0) >> 4);
/* Set the color and drawing mode. */
newport_wait(npregs);
npregs->set.colori = charattr & 0xf;
npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
NPORT_DMODE0_STOPX | NPORT_DMODE0_ZPENAB |
NPORT_DMODE0_L32);
/* Set coordinates for bitmap operation. */
npregs->set.xystarti = (xpos << 16) | ((ypos + topscan) & 0x3ff);
npregs->set.xyendi = ((xpos + 7) << 16);
newport_wait(npregs);
/* Go, baby, go... */
RENDER(npregs, p);
}
static void newport_putcs(struct vc_data *vc, const unsigned short *s,
int count, int ypos, int xpos)
{
int i;
int charattr;
unsigned char *p;
charattr = (scr_readw(s) >> 8) & 0xff;
xpos <<= 3;
ypos <<= 4;
if (!logo_active)
/* Clear the area behing the string */
newport_render_background(xpos, ypos,
xpos + ((count - 1) << 3), ypos,
(charattr & 0xf0) >> 4);
newport_wait(npregs);
/* Set the color and drawing mode. */
npregs->set.colori = charattr & 0xf;
npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
NPORT_DMODE0_STOPX | NPORT_DMODE0_ZPENAB |
NPORT_DMODE0_L32);
for (i = 0; i < count; i++, xpos += 8) {
p = &font_data[vc->vc_num][(scr_readw(s++) & 0xff) << 4];
newport_wait(npregs);
/* Set coordinates for bitmap operation. */
npregs->set.xystarti =
(xpos << 16) | ((ypos + topscan) & 0x3ff);
npregs->set.xyendi = ((xpos + 7) << 16);
/* Go, baby, go... */
RENDER(npregs, p);
}
}
static void newport_cursor(struct vc_data *vc, int mode)
{
unsigned short treg;
int xcurs, ycurs;
switch (mode) {
case CM_ERASE:
treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
newport_vc2_set(npregs, VC2_IREG_CONTROL,
(treg & ~(VC2_CTRL_ECDISP)));
break;
case CM_MOVE:
case CM_DRAW:
treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
newport_vc2_set(npregs, VC2_IREG_CONTROL,
(treg | VC2_CTRL_ECDISP));
xcurs = (vc->vc_pos - vc->vc_visible_origin) / 2;
ycurs = ((xcurs / vc->vc_cols) << 4) + 31;
xcurs = ((xcurs % vc->vc_cols) << 3) + xcurs_correction;
newport_vc2_set(npregs, VC2_IREG_CURSX, xcurs);
newport_vc2_set(npregs, VC2_IREG_CURSY, ycurs);
}
}
static int newport_switch(struct vc_data *vc)
{
static int logo_drawn = 0;
topscan = 0;
npregs->cset.topscan = 0x3ff;
if (!logo_drawn) {
if (newport_show_logo()) {
logo_drawn = 1;
logo_active = 1;
}
}
return 1;
}
static int newport_blank(struct vc_data *c, int blank, int mode_switch)
{
unsigned short treg;
if (blank == 0) {
/* unblank console */
treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
newport_vc2_set(npregs, VC2_IREG_CONTROL,
(treg | VC2_CTRL_EDISP));
} else {
/* blank console */
treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
newport_vc2_set(npregs, VC2_IREG_CONTROL,
(treg & ~(VC2_CTRL_EDISP)));
}
return 1;
}
static int newport_set_font(int unit, struct console_font *op)
{
int w = op->width;
int h = op->height;
int size = h * op->charcount;
int i;
unsigned char *new_data, *data = op->data, *p;
/* ladis: when I grow up, there will be a day... and more sizes will
* be supported ;-) */
if ((w != 8) || (h != 16)
|| (op->charcount != 256 && op->charcount != 512))
return -EINVAL;
if (!(new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size,
GFP_USER))) return -ENOMEM;
new_data += FONT_EXTRA_WORDS * sizeof(int);
FNTSIZE(new_data) = size;
FNTCHARCNT(new_data) = op->charcount;
REFCOUNT(new_data) = 0; /* usage counter */
p = new_data;
for (i = 0; i < op->charcount; i++) {
memcpy(p, data, h);
data += 32;
p += h;
}
/* check if font is already used by other console */
for (i = 0; i < MAX_NR_CONSOLES; i++) {
if (font_data[i] != FONT_DATA
&& FNTSIZE(font_data[i]) == size
&& !memcmp(font_data[i], new_data, size)) {
kfree(new_data - FONT_EXTRA_WORDS * sizeof(int));
/* current font is the same as the new one */
if (i == unit)
return 0;
new_data = font_data[i];
break;
}
}
/* old font is user font */
if (font_data[unit] != FONT_DATA) {
if (--REFCOUNT(font_data[unit]) == 0)
kfree(font_data[unit] -
FONT_EXTRA_WORDS * sizeof(int));
}
REFCOUNT(new_data)++;
font_data[unit] = new_data;
return 0;
}
static int newport_set_def_font(int unit, struct console_font *op)
{
if (font_data[unit] != FONT_DATA) {
if (--REFCOUNT(font_data[unit]) == 0)
kfree(font_data[unit] -
FONT_EXTRA_WORDS * sizeof(int));
font_data[unit] = FONT_DATA;
}
return 0;
}
static int newport_font_default(struct vc_data *vc, struct console_font *op, char *name)
{
return newport_set_def_font(vc->vc_num, op);
}
static int newport_font_set(struct vc_data *vc, struct console_font *font, unsigned flags)
{
return newport_set_font(vc->vc_num, font);
}
static int newport_set_palette(struct vc_data *vc, unsigned char *table)
{
return -EINVAL;
}
static int newport_scrolldelta(struct vc_data *vc, int lines)
{
/* there is (nearly) no off-screen memory, so we can't scroll back */
return 0;
}
static int newport_scroll(struct vc_data *vc, int t, int b, int dir,
int lines)
{
int count, x, y;
unsigned short *s, *d;
unsigned short chattr;
logo_active = 0; /* it's time to disable the logo now.. */
if (t == 0 && b == vc->vc_rows) {
if (dir == SM_UP) {
topscan = (topscan + (lines << 4)) & 0x3ff;
newport_clear_lines(vc->vc_rows - lines,
vc->vc_rows - 1,
(vc->vc_color & 0xf0) >> 4);
} else {
topscan = (topscan + (-lines << 4)) & 0x3ff;
newport_clear_lines(0, lines - 1,
(vc->vc_color & 0xf0) >> 4);
}
npregs->cset.topscan = (topscan - 1) & 0x3ff;
return 0;
}
count = (b - t - lines) * vc->vc_cols;
if (dir == SM_UP) {
x = 0;
y = t;
s = (unsigned short *) (vc->vc_origin +
vc->vc_size_row * (t + lines));
d = (unsigned short *) (vc->vc_origin +
vc->vc_size_row * t);
while (count--) {
chattr = scr_readw(s++);
if (chattr != scr_readw(d)) {
newport_putc(vc, chattr, y, x);
scr_writew(chattr, d);
}
d++;
if (++x == vc->vc_cols) {
x = 0;
y++;
}
}
d = (unsigned short *) (vc->vc_origin +
vc->vc_size_row * (b - lines));
x = 0;
y = b - lines;
for (count = 0; count < (lines * vc->vc_cols); count++) {
if (scr_readw(d) != vc->vc_video_erase_char) {
newport_putc(vc, vc->vc_video_erase_char,
y, x);
scr_writew(vc->vc_video_erase_char, d);
}
d++;
if (++x == vc->vc_cols) {
x = 0;
y++;
}
}
} else {
x = vc->vc_cols - 1;
y = b - 1;
s = (unsigned short *) (vc->vc_origin +
vc->vc_size_row * (b - lines) - 2);
d = (unsigned short *) (vc->vc_origin +
vc->vc_size_row * b - 2);
while (count--) {
chattr = scr_readw(s--);
if (chattr != scr_readw(d)) {
newport_putc(vc, chattr, y, x);
scr_writew(chattr, d);
}
d--;
if (x-- == 0) {
x = vc->vc_cols - 1;
y--;
}
}
d = (unsigned short *) (vc->vc_origin +
vc->vc_size_row * t);
x = 0;
y = t;
for (count = 0; count < (lines * vc->vc_cols); count++) {
if (scr_readw(d) != vc->vc_video_erase_char) {
newport_putc(vc, vc->vc_video_erase_char,
y, x);
scr_writew(vc->vc_video_erase_char, d);
}
d++;
if (++x == vc->vc_cols) {
x = 0;
y++;
}
}
}
return 1;
}
static void newport_bmove(struct vc_data *vc, int sy, int sx, int dy,
int dx, int h, int w)
{
short xs, ys, xe, ye, xoffs, yoffs, tmp;
xs = sx << 3;
xe = ((sx + w) << 3) - 1;
/*
* as bmove is only used to move stuff around in the same line
* (h == 1), we don't care about wrap arounds caused by topscan != 0
*/
ys = ((sy << 4) + topscan) & 0x3ff;
ye = (((sy + h) << 4) - 1 + topscan) & 0x3ff;
xoffs = (dx - sx) << 3;
yoffs = (dy - sy) << 4;
if (xoffs > 0) {
/* move to the right, exchange starting points */
tmp = xe;
xe = xs;
xs = tmp;
}
newport_wait(npregs);
npregs->set.drawmode0 = (NPORT_DMODE0_S2S | NPORT_DMODE0_BLOCK |
NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
| NPORT_DMODE0_STOPY);
npregs->set.xystarti = (xs << 16) | ys;
npregs->set.xyendi = (xe << 16) | ye;
npregs->go.xymove = (xoffs << 16) | yoffs;
}
static int newport_dummy(struct vc_data *c)
{
return 0;
}
#define DUMMY (void *) newport_dummy
const struct consw newport_con = {
.owner = THIS_MODULE,
.con_startup = newport_startup,
.con_init = newport_init,
.con_deinit = newport_deinit,
.con_clear = newport_clear,
.con_putc = newport_putc,
.con_putcs = newport_putcs,
.con_cursor = newport_cursor,
.con_scroll = newport_scroll,
.con_bmove = newport_bmove,
.con_switch = newport_switch,
.con_blank = newport_blank,
.con_font_set = newport_font_set,
.con_font_default = newport_font_default,
.con_set_palette = newport_set_palette,
.con_scrolldelta = newport_scrolldelta,
.con_set_origin = DUMMY,
.con_save_screen = DUMMY
};
#ifdef MODULE
static int __init newport_console_init(void)
{
if (!sgi_gfxaddr)
return 0;
if (!npregs)
npregs = (struct newport_regs *)/* ioremap cannot fail */
ioremap(sgi_gfxaddr, sizeof(struct newport_regs));
return take_over_console(&newport_con, 0, MAX_NR_CONSOLES - 1, 1);
}
module_init(newport_console_init);
static void __exit newport_console_exit(void)
{
give_up_console(&newport_con);
iounmap((void *)npregs);
}
module_exit(newport_console_exit);
#endif
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,83 @@
/*
* linux/drivers/video/console/softcursor.c
*
* Generic software cursor for frame buffer devices
*
* Created 14 Nov 2002 by James Simmons
*
* This file is subject to the terms and conditions of the GNU General
* Public License. See the file COPYING in the main directory of this
* archive for more details.
*/
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <linux/slab.h>
#include <asm/io.h>
#include "fbcon.h"
int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
struct fbcon_ops *ops = info->fbcon_par;
unsigned int scan_align = info->pixmap.scan_align - 1;
unsigned int buf_align = info->pixmap.buf_align - 1;
unsigned int i, size, dsize, s_pitch, d_pitch;
struct fb_image *image;
u8 *src, *dst;
if (info->state != FBINFO_STATE_RUNNING)
return 0;
s_pitch = (cursor->image.width + 7) >> 3;
dsize = s_pitch * cursor->image.height;
if (dsize + sizeof(struct fb_image) != ops->cursor_size) {
if (ops->cursor_src != NULL)
kfree(ops->cursor_src);
ops->cursor_size = dsize + sizeof(struct fb_image);
ops->cursor_src = kmalloc(ops->cursor_size, GFP_ATOMIC);
if (!ops->cursor_src) {
ops->cursor_size = 0;
return -ENOMEM;
}
}
src = ops->cursor_src + sizeof(struct fb_image);
image = (struct fb_image *)ops->cursor_src;
*image = cursor->image;
d_pitch = (s_pitch + scan_align) & ~scan_align;
size = d_pitch * image->height + buf_align;
size &= ~buf_align;
dst = fb_get_buffer_offset(info, &info->pixmap, size);
if (cursor->enable) {
switch (cursor->rop) {
case ROP_XOR:
for (i = 0; i < dsize; i++)
src[i] = image->data[i] ^ cursor->mask[i];
break;
case ROP_COPY:
default:
for (i = 0; i < dsize; i++)
src[i] = image->data[i] & cursor->mask[i];
break;
}
} else
memcpy(src, image->data, dsize);
fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, image->height);
image->data = dst;
info->fbops->fb_imageblit(info, image);
return 0;
}
EXPORT_SYMBOL(soft_cursor);
MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
MODULE_DESCRIPTION("Generic software cursor");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,391 @@
/*
* linux/drivers/video/console/sticon.c - console driver using HP's STI firmware
*
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
* Copyright (C) 2002 Helge Deller <deller@gmx.de>
*
* Based on linux/drivers/video/vgacon.c and linux/drivers/video/fbcon.c,
* which were
*
* Created 28 Sep 1997 by Geert Uytterhoeven
* Rewritten by Martin Mares <mj@ucw.cz>, July 1998
* Copyright (C) 1991, 1992 Linus Torvalds
* 1995 Jay Estabrook
* Copyright (C) 1995 Geert Uytterhoeven
* Copyright (C) 1993 Bjoern Brauel
* Roman Hodek
* Copyright (C) 1993 Hamish Macdonald
* Greg Harp
* Copyright (C) 1994 David Carter [carter@compsci.bristol.ac.uk]
*
* with work by William Rucklidge (wjr@cs.cornell.edu)
* Geert Uytterhoeven
* Jes Sorensen (jds@kom.auc.dk)
* Martin Apel
* with work by Guenther Kelleter
* Martin Schaller
* Andreas Schwab
* Emmanuel Marty (core@ggi-project.org)
* Jakub Jelinek (jj@ultra.linux.cz)
* Martin Mares <mj@ucw.cz>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/console.h>
#include <linux/errno.h>
#include <linux/vt_kern.h>
#include <linux/kd.h>
#include <linux/selection.h>
#include <linux/module.h>
#include <asm/io.h>
#include "../sticore.h"
/* switching to graphics mode */
#define BLANK 0
static int vga_is_gfx;
/* this is the sti_struct used for this console */
static struct sti_struct *sticon_sti;
/* Software scrollback */
static unsigned long softback_buf, softback_curr;
static unsigned long softback_in;
static unsigned long /* softback_top, */ softback_end;
static int softback_lines;
/* software cursor */
static int cursor_drawn;
#define CURSOR_DRAW_DELAY (1)
#define DEFAULT_CURSOR_BLINK_RATE (20)
static int vbl_cursor_cnt;
static inline void cursor_undrawn(void)
{
vbl_cursor_cnt = 0;
cursor_drawn = 0;
}
static const char *sticon_startup(void)
{
return "STI console";
}
static int sticon_set_palette(struct vc_data *c, unsigned char *table)
{
return -EINVAL;
}
static void sticon_putc(struct vc_data *conp, int c, int ypos, int xpos)
{
int redraw_cursor = 0;
if (vga_is_gfx || console_blanked)
return;
if (conp->vc_mode != KD_TEXT)
return;
#if 0
if ((p->cursor_x == xpos) && (p->cursor_y == ypos)) {
cursor_undrawn();
redraw_cursor = 1;
}
#endif
sti_putc(sticon_sti, c, ypos, xpos);
if (redraw_cursor)
vbl_cursor_cnt = CURSOR_DRAW_DELAY;
}
static void sticon_putcs(struct vc_data *conp, const unsigned short *s,
int count, int ypos, int xpos)
{
int redraw_cursor = 0;
if (vga_is_gfx || console_blanked)
return;
if (conp->vc_mode != KD_TEXT)
return;
#if 0
if ((p->cursor_y == ypos) && (xpos <= p->cursor_x) &&
(p->cursor_x < (xpos + count))) {
cursor_undrawn();
redraw_cursor = 1;
}
#endif
while (count--) {
sti_putc(sticon_sti, scr_readw(s++), ypos, xpos++);
}
if (redraw_cursor)
vbl_cursor_cnt = CURSOR_DRAW_DELAY;
}
static void sticon_cursor(struct vc_data *conp, int mode)
{
unsigned short car1;
car1 = conp->vc_screenbuf[conp->vc_x + conp->vc_y * conp->vc_cols];
switch (mode) {
case CM_ERASE:
sti_putc(sticon_sti, car1, conp->vc_y, conp->vc_x);
break;
case CM_MOVE:
case CM_DRAW:
switch (conp->vc_cursor_type & 0x0f) {
case CUR_UNDERLINE:
case CUR_LOWER_THIRD:
case CUR_LOWER_HALF:
case CUR_TWO_THIRDS:
case CUR_BLOCK:
sti_putc(sticon_sti, (car1 & 255) + (0 << 8) + (7 << 11),
conp->vc_y, conp->vc_x);
break;
}
break;
}
}
static int sticon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
{
struct sti_struct *sti = sticon_sti;
if (vga_is_gfx)
return 0;
sticon_cursor(conp, CM_ERASE);
switch (dir) {
case SM_UP:
sti_bmove(sti, t + count, 0, t, 0, b - t - count, conp->vc_cols);
sti_clear(sti, b - count, 0, count, conp->vc_cols, conp->vc_video_erase_char);
break;
case SM_DOWN:
sti_bmove(sti, t, 0, t + count, 0, b - t - count, conp->vc_cols);
sti_clear(sti, t, 0, count, conp->vc_cols, conp->vc_video_erase_char);
break;
}
return 0;
}
static void sticon_bmove(struct vc_data *conp, int sy, int sx,
int dy, int dx, int height, int width)
{
if (!width || !height)
return;
#if 0
if (((sy <= p->cursor_y) && (p->cursor_y < sy+height) &&
(sx <= p->cursor_x) && (p->cursor_x < sx+width)) ||
((dy <= p->cursor_y) && (p->cursor_y < dy+height) &&
(dx <= p->cursor_x) && (p->cursor_x < dx+width)))
sticon_cursor(p, CM_ERASE /*|CM_SOFTBACK*/);
#endif
sti_bmove(sticon_sti, sy, sx, dy, dx, height, width);
}
static void sticon_init(struct vc_data *c, int init)
{
struct sti_struct *sti = sticon_sti;
int vc_cols, vc_rows;
sti_set(sti, 0, 0, sti_onscreen_y(sti), sti_onscreen_x(sti), 0);
vc_cols = sti_onscreen_x(sti) / sti->font_width;
vc_rows = sti_onscreen_y(sti) / sti->font_height;
c->vc_can_do_color = 1;
if (init) {
c->vc_cols = vc_cols;
c->vc_rows = vc_rows;
} else {
/* vc_rows = (c->vc_rows > vc_rows) ? vc_rows : c->vc_rows; */
/* vc_cols = (c->vc_cols > vc_cols) ? vc_cols : c->vc_cols; */
vc_resize(c, vc_cols, vc_rows);
/* vc_resize_con(vc_rows, vc_cols, c->vc_num); */
}
}
static void sticon_deinit(struct vc_data *c)
{
}
static void sticon_clear(struct vc_data *conp, int sy, int sx, int height,
int width)
{
if (!height || !width)
return;
sti_clear(sticon_sti, sy, sx, height, width, conp->vc_video_erase_char);
}
static int sticon_switch(struct vc_data *conp)
{
return 1; /* needs refreshing */
}
static int sticon_set_origin(struct vc_data *conp)
{
return 0;
}
static int sticon_blank(struct vc_data *c, int blank, int mode_switch)
{
if (blank == 0) {
if (mode_switch)
vga_is_gfx = 0;
return 1;
}
sticon_set_origin(c);
sti_clear(sticon_sti, 0,0, c->vc_rows, c->vc_cols, BLANK);
if (mode_switch)
vga_is_gfx = 1;
return 1;
}
static int sticon_scrolldelta(struct vc_data *conp, int lines)
{
return 0;
}
static u16 *sticon_screen_pos(struct vc_data *conp, int offset)
{
int line;
unsigned long p;
if (conp->vc_num != fg_console || !softback_lines)
return (u16 *)(conp->vc_origin + offset);
line = offset / conp->vc_size_row;
if (line >= softback_lines)
return (u16 *)(conp->vc_origin + offset - softback_lines * conp->vc_size_row);
p = softback_curr + offset;
if (p >= softback_end)
p += softback_buf - softback_end;
return (u16 *)p;
}
static unsigned long sticon_getxy(struct vc_data *conp, unsigned long pos,
int *px, int *py)
{
int x, y;
unsigned long ret;
if (pos >= conp->vc_origin && pos < conp->vc_scr_end) {
unsigned long offset = (pos - conp->vc_origin) / 2;
x = offset % conp->vc_cols;
y = offset / conp->vc_cols;
if (conp->vc_num == fg_console)
y += softback_lines;
ret = pos + (conp->vc_cols - x) * 2;
} else if (conp->vc_num == fg_console && softback_lines) {
unsigned long offset = pos - softback_curr;
if (pos < softback_curr)
offset += softback_end - softback_buf;
offset /= 2;
x = offset % conp->vc_cols;
y = offset / conp->vc_cols;
ret = pos + (conp->vc_cols - x) * 2;
if (ret == softback_end)
ret = softback_buf;
if (ret == softback_in)
ret = conp->vc_origin;
} else {
/* Should not happen */
x = y = 0;
ret = conp->vc_origin;
}
if (px) *px = x;
if (py) *py = y;
return ret;
}
static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens,
u8 blink, u8 underline, u8 reverse, u8 italic)
{
u8 attr = ((color & 0x70) >> 1) | ((color & 7));
if (reverse) {
color = ((color >> 3) & 0x7) | ((color & 0x7) << 3);
}
return attr;
}
static void sticon_invert_region(struct vc_data *conp, u16 *p, int count)
{
int col = 1; /* vga_can_do_color; */
while (count--) {
u16 a = scr_readw(p);
if (col)
a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4);
else
a = ((a & 0x0700) == 0x0100) ? 0x7000 : 0x7700;
scr_writew(a, p++);
}
}
static void sticon_save_screen(struct vc_data *conp)
{
}
static const struct consw sti_con = {
.owner = THIS_MODULE,
.con_startup = sticon_startup,
.con_init = sticon_init,
.con_deinit = sticon_deinit,
.con_clear = sticon_clear,
.con_putc = sticon_putc,
.con_putcs = sticon_putcs,
.con_cursor = sticon_cursor,
.con_scroll = sticon_scroll,
.con_bmove = sticon_bmove,
.con_switch = sticon_switch,
.con_blank = sticon_blank,
.con_set_palette = sticon_set_palette,
.con_scrolldelta = sticon_scrolldelta,
.con_set_origin = sticon_set_origin,
.con_save_screen = sticon_save_screen,
.con_build_attr = sticon_build_attr,
.con_invert_region = sticon_invert_region,
.con_screen_pos = sticon_screen_pos,
.con_getxy = sticon_getxy,
};
static int __init sticonsole_init(void)
{
/* already initialized ? */
if (sticon_sti)
return 0;
sticon_sti = sti_get_rom(0);
if (!sticon_sti)
return -ENODEV;
if (conswitchp == &dummy_con) {
printk(KERN_INFO "sticon: Initializing STI text console.\n");
return take_over_console(&sti_con, 0, MAX_NR_CONSOLES - 1, 1);
}
return 0;
}
module_init(sticonsole_init);
MODULE_LICENSE("GPL");

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,159 @@
/*
* linux/drivers/video/console/tileblit.c -- Tile Blitting Operation
*
* Copyright (C) 2004 Antonino Daplas <adaplas @pol.net>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*/
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <linux/vt_kern.h>
#include <linux/console.h>
#include <asm/types.h>
#include "fbcon.h"
static void tile_bmove(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int dy, int dx, int height, int width)
{
struct fb_tilearea area;
area.sx = sx;
area.sy = sy;
area.dx = dx;
area.dy = dy;
area.height = height;
area.width = width;
info->tileops->fb_tilecopy(info, &area);
}
static void tile_clear(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int height, int width)
{
struct fb_tilerect rect;
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
rect.index = vc->vc_video_erase_char &
((vc->vc_hi_font_mask) ? 0x1ff : 0xff);
rect.fg = attr_fgcol_ec(fgshift, vc, info);
rect.bg = attr_bgcol_ec(bgshift, vc, info);
rect.sx = sx;
rect.sy = sy;
rect.width = width;
rect.height = height;
rect.rop = ROP_COPY;
info->tileops->fb_tilefill(info, &rect);
}
static void tile_putcs(struct vc_data *vc, struct fb_info *info,
const unsigned short *s, int count, int yy, int xx,
int fg, int bg)
{
struct fb_tileblit blit;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
int size = sizeof(u32) * count, i;
blit.sx = xx;
blit.sy = yy;
blit.width = count;
blit.height = 1;
blit.fg = fg;
blit.bg = bg;
blit.length = count;
blit.indices = (u32 *) fb_get_buffer_offset(info, &info->pixmap, size);
for (i = 0; i < count; i++)
blit.indices[i] = (u32)(scr_readw(s++) & charmask);
info->tileops->fb_tileblit(info, &blit);
}
static void tile_clear_margins(struct vc_data *vc, struct fb_info *info,
int bottom_only)
{
return;
}
static void tile_cursor(struct vc_data *vc, struct fb_info *info, int mode,
int softback_lines, int fg, int bg)
{
struct fb_tilecursor cursor;
int use_sw = (vc->vc_cursor_type & 0x10);
cursor.sx = vc->vc_x;
cursor.sy = vc->vc_y;
cursor.mode = (mode == CM_ERASE || use_sw) ? 0 : 1;
cursor.fg = fg;
cursor.bg = bg;
switch (vc->vc_cursor_type & 0x0f) {
case CUR_NONE:
cursor.shape = FB_TILE_CURSOR_NONE;
break;
case CUR_UNDERLINE:
cursor.shape = FB_TILE_CURSOR_UNDERLINE;
break;
case CUR_LOWER_THIRD:
cursor.shape = FB_TILE_CURSOR_LOWER_THIRD;
break;
case CUR_LOWER_HALF:
cursor.shape = FB_TILE_CURSOR_LOWER_HALF;
break;
case CUR_TWO_THIRDS:
cursor.shape = FB_TILE_CURSOR_TWO_THIRDS;
break;
case CUR_BLOCK:
default:
cursor.shape = FB_TILE_CURSOR_BLOCK;
break;
}
info->tileops->fb_tilecursor(info, &cursor);
}
static int tile_update_start(struct fb_info *info)
{
struct fbcon_ops *ops = info->fbcon_par;
int err;
err = fb_pan_display(info, &ops->var);
ops->var.xoffset = info->var.xoffset;
ops->var.yoffset = info->var.yoffset;
ops->var.vmode = info->var.vmode;
return err;
}
void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info)
{
struct fb_tilemap map;
struct fbcon_ops *ops = info->fbcon_par;
ops->bmove = tile_bmove;
ops->clear = tile_clear;
ops->putcs = tile_putcs;
ops->clear_margins = tile_clear_margins;
ops->cursor = tile_cursor;
ops->update_start = tile_update_start;
if (ops->p) {
map.width = vc->vc_font.width;
map.height = vc->vc_font.height;
map.depth = 1;
map.length = (ops->p->userfont) ?
FNTCHARCNT(ops->p->fontdata) : 256;
map.data = ops->p->fontdata;
info->tileops->fb_settile(info, &map);
}
}
EXPORT_SYMBOL(fbcon_set_tileops);
MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
MODULE_DESCRIPTION("Tile Blitting Operation");
MODULE_LICENSE("GPL");

File diff suppressed because it is too large Load Diff