/*
|
/*
|
* linux/arch/arm/drivers/char/console.c
|
* linux/arch/arm/drivers/char/console.c
|
*
|
*
|
* Modifications (C) 1995, 1996 Russell King
|
* Modifications (C) 1995, 1996 Russell King
|
*/
|
*/
|
|
|
/*
|
/*
|
* This module exports the console io functions:
|
* This module exports the console io functions:
|
*
|
*
|
* 'int vcd_init (struct vt *vt, int kmallocok, unsigned long *kmem)'
|
* 'int vcd_init (struct vt *vt, int kmallocok, unsigned long *kmem)'
|
* 'unsigned long vcd_pre_init (unsigned long kmem, struct vt *vt)'
|
* 'unsigned long vcd_pre_init (unsigned long kmem, struct vt *vt)'
|
* 'void vcd_disallocate (struct vt *vt)'
|
* 'void vcd_disallocate (struct vt *vt)'
|
* 'int vcd_resize (unsigned long lines, unsigned long cols)'
|
* 'int vcd_resize (unsigned long lines, unsigned long cols)'
|
* 'void vcd_blankscreen (int nopowersave)'
|
* 'void vcd_blankscreen (int nopowersave)'
|
* 'void vcd_unblankscreen (void)'
|
* 'void vcd_unblankscreen (void)'
|
* 'void vcd_savestate (const struct vt *vt, int blanked)'
|
* 'void vcd_savestate (const struct vt *vt, int blanked)'
|
* 'void vcd_restorestate (const struct vt *vt)'
|
* 'void vcd_restorestate (const struct vt *vt)'
|
* 'void vcd_setup_graphics (const struct vt *vt)'
|
* 'void vcd_setup_graphics (const struct vt *vt)'
|
* 'int vcd_write (const struct vt *vt, int from_user, const unsigned char *buf, int count)'
|
* 'int vcd_write (const struct vt *vt, int from_user, const unsigned char *buf, int count)'
|
* 'int vcd_ioctl (const struct vt *vt, int cmd, unsigned long arg)'
|
* 'int vcd_ioctl (const struct vt *vt, int cmd, unsigned long arg)'
|
*
|
*
|
*
|
*
|
* 'unsigned long con_init(unsigned long)'
|
* 'unsigned long con_init(unsigned long)'
|
* S 'int con_open(struct tty_struct *tty,struct file *filp)'
|
* S 'int con_open(struct tty_struct *tty,struct file *filp)'
|
* S 'void con_write(struct tty_struct *tty)'
|
* S 'void con_write(struct tty_struct *tty)'
|
* S 'void console_print(const char *b)'
|
* S 'void console_print(const char *b)'
|
*
|
*
|
* 'void unblank_screen(void)'
|
* 'void unblank_screen(void)'
|
* 'void scrollback(int lines)' *
|
* 'void scrollback(int lines)' *
|
* 'void scrollfront(int lines)' *
|
* 'void scrollfront(int lines)' *
|
* 'int do_screendump(int arg)'
|
* 'int do_screendump(int arg)'
|
*
|
*
|
* 'int con_get_font(char *)'
|
* 'int con_get_font(char *)'
|
* 'int con_set_font(char *)'
|
* 'int con_set_font(char *)'
|
* 'int con_get_trans(char *)'
|
* 'int con_get_trans(char *)'
|
* 'int con_set_trans(char *)'
|
* 'int con_set_trans(char *)'
|
*
|
*
|
* 'int mouse_reporting(void)'
|
* 'int mouse_reporting(void)'
|
*/
|
*/
|
|
|
#define BLANK 0x0020
|
#define BLANK 0x0020
|
|
|
/* A bitmap for codes <32. A bit of 1 indicates that the code
|
/* A bitmap for codes <32. A bit of 1 indicates that the code
|
* corresponding to that bit number invokes a special action
|
* corresponding to that bit number invokes a special action
|
* (such as cursor movement) and should not be displayed as a
|
* (such as cursor movement) and should not be displayed as a
|
* glyph unless the disp_ctrl mode is explicitly enabled.
|
* glyph unless the disp_ctrl mode is explicitly enabled.
|
*/
|
*/
|
#define CTRL_ACTION 0x0d00ff81
|
#define CTRL_ACTION 0x0d00ff81
|
#define CTRL_ALWAYS 0x0800f501 /* Cannot be overriden by disp_ctrl */
|
#define CTRL_ALWAYS 0x0800f501 /* Cannot be overriden by disp_ctrl */
|
|
|
/*
|
/*
|
* Here is the default bell parameters: 750HZ, 1/8th of a second
|
* Here is the default bell parameters: 750HZ, 1/8th of a second
|
*/
|
*/
|
#define DEFAULT_BELL_PITCH 750
|
#define DEFAULT_BELL_PITCH 750
|
#define DEFAULT_BELL_DURATION (HZ/8)
|
#define DEFAULT_BELL_DURATION (HZ/8)
|
|
|
/*
|
/*
|
* NOTE!!! We sometimes disable and enable interrupts for a short while
|
* NOTE!!! We sometimes disable and enable interrupts for a short while
|
* (to put a word in video IO), but this will work even for keyboard
|
* (to put a word in video IO), but this will work even for keyboard
|
* interrupts. We know interrupts aren't enabled when getting a keyboard
|
* interrupts. We know interrupts aren't enabled when getting a keyboard
|
* interrupt, as we use trap-gates. Hopefully all is well.
|
* interrupt, as we use trap-gates. Hopefully all is well.
|
*/
|
*/
|
|
|
#include <linux/config.h>
|
#include <linux/config.h>
|
#include <linux/sched.h>
|
#include <linux/sched.h>
|
#include <linux/timer.h>
|
#include <linux/timer.h>
|
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
#include <linux/tty.h>
|
#include <linux/tty.h>
|
#include <linux/tty_flip.h>
|
#include <linux/tty_flip.h>
|
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
#include <linux/errno.h>
|
#include <linux/errno.h>
|
#include <linux/kd.h>
|
#include <linux/kd.h>
|
#include <linux/major.h>
|
#include <linux/major.h>
|
#include <linux/malloc.h>
|
#include <linux/malloc.h>
|
#include <linux/mm.h>
|
#include <linux/mm.h>
|
|
|
#include <asm/io.h>
|
#include <asm/io.h>
|
#include <asm/segment.h>
|
#include <asm/segment.h>
|
#include <asm/irq.h>
|
#include <asm/irq.h>
|
#include <asm/hardware.h>
|
#include <asm/hardware.h>
|
|
|
#define DEBUG
|
#define DEBUG
|
|
|
#include "kbd_kern.h"
|
#include "kbd_kern.h"
|
#include "consolemap.h"
|
#include "consolemap.h"
|
#include "vt_kern.h"
|
#include "vt_kern.h"
|
#include "selection.h"
|
#include "selection.h"
|
|
|
#define set_kbd(x) set_vc_kbd_mode (vt->kbd, x)
|
#define set_kbd(x) set_vc_kbd_mode (vt->kbd, x)
|
#define clr_kbd(x) clr_vc_kbd_mode (vt->kbd, x)
|
#define clr_kbd(x) clr_vc_kbd_mode (vt->kbd, x)
|
#define is_kbd(x) vc_kbd_mode (vt->kbd, x)
|
#define is_kbd(x) vc_kbd_mode (vt->kbd, x)
|
|
|
#define decarm VC_REPEAT
|
#define decarm VC_REPEAT
|
#define decckm VC_CKMODE
|
#define decckm VC_CKMODE
|
#define kbdapplic VC_APPLIC
|
#define kbdapplic VC_APPLIC
|
#define lnm VC_CRLF
|
#define lnm VC_CRLF
|
|
|
/*
|
/*
|
* this is what the terminal answers to a ESC-Z or csi0c query.
|
* this is what the terminal answers to a ESC-Z or csi0c query.
|
*/
|
*/
|
#define VT100ID "\033[?1;2c"
|
#define VT100ID "\033[?1;2c"
|
#define VT102ID "\033[?6c"
|
#define VT102ID "\033[?6c"
|
|
|
extern int setup_arm_irq(int, struct irqaction *);
|
extern int setup_arm_irq(int, struct irqaction *);
|
|
|
/*
|
/*
|
* routines to load custom translation table, EGA/VGA font and
|
* routines to load custom translation table, EGA/VGA font and
|
* VGA colour palette from console.c
|
* VGA colour palette from console.c
|
*/
|
*/
|
extern int con_set_trans_old(unsigned char * table);
|
extern int con_set_trans_old(unsigned char * table);
|
extern int con_get_trans_old(unsigned char * table);
|
extern int con_get_trans_old(unsigned char * table);
|
extern int con_set_trans_new(unsigned short * table);
|
extern int con_set_trans_new(unsigned short * table);
|
extern int con_get_trans_new(unsigned short * table);
|
extern int con_get_trans_new(unsigned short * table);
|
extern void con_clear_unimap(struct unimapinit *ui);
|
extern void con_clear_unimap(struct unimapinit *ui);
|
extern int con_set_unimap(ushort ct, struct unipair *list);
|
extern int con_set_unimap(ushort ct, struct unipair *list);
|
extern int con_get_unimap(ushort ct, ushort *uct, struct unipair *list);
|
extern int con_get_unimap(ushort ct, ushort *uct, struct unipair *list);
|
extern void con_set_default_unimap(void);
|
extern void con_set_default_unimap(void);
|
extern int con_set_font(char * fontmap);
|
extern int con_set_font(char * fontmap);
|
extern int con_get_font(char * fontmap);
|
extern int con_get_font(char * fontmap);
|
|
|
|
|
/* ARM Extensions */
|
/* ARM Extensions */
|
#if defined(HAS_VIDC)
|
#if defined(HAS_VIDC)
|
|
|
extern void memc_write (int reg, int val);
|
extern void memc_write (int reg, int val);
|
extern void vidc_write (int reg, int val);
|
extern void vidc_write (int reg, int val);
|
static int __r;
|
static int __r;
|
#define palette_setpixel(p) __r = p
|
#define palette_setpixel(p) __r = p
|
#define palette_write(v) \
|
#define palette_write(v) \
|
{ \
|
{ \
|
int rr = __r++, red, green, blue, vv = (v); \
|
int rr = __r++, red, green, blue, vv = (v); \
|
red = (vv >> 4) & 0x00f; \
|
red = (vv >> 4) & 0x00f; \
|
green = (vv >> 8) & 0x0f0; \
|
green = (vv >> 8) & 0x0f0; \
|
blue = (vv >> 12) & 0xf00; \
|
blue = (vv >> 12) & 0xf00; \
|
outl((rr<<26)|red|green|blue, IO_VIDC_BASE); \
|
outl((rr<<26)|red|green|blue, IO_VIDC_BASE); \
|
}
|
}
|
|
|
#define MAX_PIX 16
|
#define MAX_PIX 16
|
|
|
#elif defined(HAS_VIDC20)
|
#elif defined(HAS_VIDC20)
|
#define palette_setpixel(p) outl(0x10000000|((p) & 255), IO_VIDC_BASE)
|
#define palette_setpixel(p) outl(0x10000000|((p) & 255), IO_VIDC_BASE)
|
#define palette_write(v) outl(0x00000000|((v) & 0x00ffffff), IO_VIDC_BASE)
|
#define palette_write(v) outl(0x00000000|((v) & 0x00ffffff), IO_VIDC_BASE)
|
#define MAX_PIX 256
|
#define MAX_PIX 256
|
#endif
|
#endif
|
|
|
/*
|
/*
|
* from ll_wr_char.S
|
* from ll_wr_char.S
|
*/
|
*/
|
int bytes_per_char_h, bytes_per_char_v, video_size_row;
|
int bytes_per_char_h, bytes_per_char_v, video_size_row;
|
extern void ll_write_char(unsigned long ps, unsigned long chinfo);
|
extern void ll_write_char(unsigned long ps, unsigned long chinfo);
|
extern unsigned long con_charconvtable[256];
|
extern unsigned long con_charconvtable[256];
|
extern unsigned long map_screen_mem (unsigned long vid_base, unsigned long kmem, int remap);
|
extern unsigned long map_screen_mem (unsigned long vid_base, unsigned long kmem, int remap);
|
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
|
|
extern struct console_driver screen_driver, buffer_driver;
|
extern struct console_driver screen_driver, buffer_driver;
|
|
|
#ifndef MIN
|
#ifndef MIN
|
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
#endif
|
#endif
|
|
|
static void gotoxy (struct con_struct *vcd, int new_x, int new_y);
|
static void gotoxy (struct con_struct *vcd, int new_x, int new_y);
|
static inline void set_cursor (const struct vt * const vt);
|
static inline void set_cursor (const struct vt * const vt);
|
extern void reset_vc(const struct vt * const vt);
|
extern void reset_vc(const struct vt * const vt);
|
extern void register_console(void (*proc)(const char *));
|
extern void register_console(void (*proc)(const char *));
|
extern void compute_shiftstate(void);
|
extern void compute_shiftstate(void);
|
extern void con_reset_palette (const struct vt * const vt);
|
extern void con_reset_palette (const struct vt * const vt);
|
extern void con_set_palette (const struct vt * const vt);
|
extern void con_set_palette (const struct vt * const vt);
|
|
|
static int printable; /* Is console ready for printing? */
|
static int printable; /* Is console ready for printing? */
|
|
|
#define console_charmask 0xff
|
#define console_charmask 0xff
|
#ifndef console_charmask
|
#ifndef console_charmask
|
static unsigned short console_charmask = 0x0ff;
|
static unsigned short console_charmask = 0x0ff;
|
#endif
|
#endif
|
|
|
#include "font.h"
|
#include "font.h"
|
|
|
static const unsigned long palette_1[MAX_PIX] = {
|
static const unsigned long palette_1[MAX_PIX] = {
|
0x00000000, /* Black */
|
0x00000000, /* Black */
|
0x00ffffff, /* White */
|
0x00ffffff, /* White */
|
0x00000000 /* Black */
|
0x00000000 /* Black */
|
};
|
};
|
|
|
static const unsigned long palette_4[MAX_PIX] = {
|
static const unsigned long palette_4[MAX_PIX] = {
|
0x00000000, /* Black */
|
0x00000000, /* Black */
|
0x000000cc, /* Red */
|
0x000000cc, /* Red */
|
0x0000cc00, /* Green */
|
0x0000cc00, /* Green */
|
0x0000cccc, /* Yellow */
|
0x0000cccc, /* Yellow */
|
0x00cc0000, /* Blue */
|
0x00cc0000, /* Blue */
|
0x00cc00cc, /* Magenta */
|
0x00cc00cc, /* Magenta */
|
0x00cccc00, /* Cyan */
|
0x00cccc00, /* Cyan */
|
0x00cccccc, /* White */
|
0x00cccccc, /* White */
|
0x00000000,
|
0x00000000,
|
0x000000ff,
|
0x000000ff,
|
0x0000ff00,
|
0x0000ff00,
|
0x0000ffff,
|
0x0000ffff,
|
0x00ff0000,
|
0x00ff0000,
|
0x00ff00ff,
|
0x00ff00ff,
|
0x00ffff00,
|
0x00ffff00,
|
0x00ffffff
|
0x00ffffff
|
};
|
};
|
|
|
#if defined(HAS_VIDC)
|
#if defined(HAS_VIDC)
|
static const unsigned long palette_8[MAX_PIX] = {
|
static const unsigned long palette_8[MAX_PIX] = {
|
0x00000000,
|
0x00000000,
|
0x00111111,
|
0x00111111,
|
0x00222222,
|
0x00222222,
|
0x00333333,
|
0x00333333,
|
0x00440000,
|
0x00440000,
|
0x00551111,
|
0x00551111,
|
0x00662222,
|
0x00662222,
|
0x00773333,
|
0x00773333,
|
0x00000044,
|
0x00000044,
|
0x00111155,
|
0x00111155,
|
0x00222266,
|
0x00222266,
|
0x00333377,
|
0x00333377,
|
0x00440044,
|
0x00440044,
|
0x00551155,
|
0x00551155,
|
0x00662266,
|
0x00662266,
|
0x00773377
|
0x00773377
|
};
|
};
|
#elif defined(HAS_VIDC20)
|
#elif defined(HAS_VIDC20)
|
#define palette_8 palette_4
|
#define palette_8 palette_4
|
#endif
|
#endif
|
|
|
static const unsigned long *default_palette_entries = palette_4;
|
static const unsigned long *default_palette_entries = palette_4;
|
|
|
static const unsigned char color_1[] = {0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 };
|
static const unsigned char color_1[] = {0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 };
|
static const unsigned char color_4[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 };
|
static const unsigned char color_4[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 };
|
#if defined(HAS_VIDC)
|
#if defined(HAS_VIDC)
|
static const unsigned char color_8[] = {0x00, 0x18, 0x60, 0x78, 0x84, 0x9C, 0xE4, 0xFC,
|
static const unsigned char color_8[] = {0x00, 0x18, 0x60, 0x78, 0x84, 0x9C, 0xE4, 0xFC,
|
0x00, 0x1B, 0x63, 0x7B, 0x87, 0x9F, 0xE7, 0xFF};
|
0x00, 0x1B, 0x63, 0x7B, 0x87, 0x9F, 0xE7, 0xFF};
|
#elif defined(HAS_VIDC20)
|
#elif defined(HAS_VIDC20)
|
static const unsigned char color_8[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 };
|
static const unsigned char color_8[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 };
|
#endif
|
#endif
|
static const unsigned char *color_table = color_4;
|
static const unsigned char *color_table = color_4;
|
|
|
/*===================================================================================*/
|
/*===================================================================================*/
|
|
|
#ifdef CONFIG_SERIAL_ECHO
|
#ifdef CONFIG_SERIAL_ECHO
|
#include "serialecho.c"
|
#include "serialecho.c"
|
#endif
|
#endif
|
|
|
/*
|
/*
|
* functions to handle /dev/fb
|
* functions to handle /dev/fb
|
*/
|
*/
|
int con_fb_read(char *buf, unsigned long pos, int count)
|
int con_fb_read(char *buf, unsigned long pos, int count)
|
{
|
{
|
return -EIO;
|
return -EIO;
|
}
|
}
|
|
|
int con_fb_write(const char *buf, unsigned long pos, int count)
|
int con_fb_write(const char *buf, unsigned long pos, int count)
|
{
|
{
|
return -EIO;
|
return -EIO;
|
}
|
}
|
|
|
int con_fb_mmap(unsigned long vma_start, unsigned long vma_offset,
|
int con_fb_mmap(unsigned long vma_start, unsigned long vma_offset,
|
unsigned long vma_end, pgprot_t prot)
|
unsigned long vma_end, pgprot_t prot)
|
{
|
{
|
if (vma_offset > vtdata.screen.memsize ||
|
if (vma_offset > vtdata.screen.memsize ||
|
vma_end - vma_start + vma_offset > vtdata.screen.memsize)
|
vma_end - vma_start + vma_offset > vtdata.screen.memsize)
|
return -EINVAL;
|
return -EINVAL;
|
return remap_page_range(vma_start, SCREEN2_BASE + vma_offset,
|
return remap_page_range(vma_start, SCREEN2_BASE + vma_offset,
|
vma_end - vma_start, prot);
|
vma_end - vma_start, prot);
|
}
|
}
|
|
|
#ifdef DEBUG
|
#ifdef DEBUG
|
static int vcd_validate (struct con_struct *vcd, const char *msg)
|
static int vcd_validate (struct con_struct *vcd, const char *msg)
|
{
|
{
|
unsigned long old_scrorigin, old_scrpos, old_buforigin, old_bufpos, w = 0;
|
unsigned long old_scrorigin, old_scrpos, old_buforigin, old_bufpos, w = 0;
|
|
|
old_scrorigin = vcd->screen.origin;
|
old_scrorigin = vcd->screen.origin;
|
old_scrpos = vcd->screen.pos;
|
old_scrpos = vcd->screen.pos;
|
old_buforigin = vtdata.buffer.origin;
|
old_buforigin = vtdata.buffer.origin;
|
old_bufpos = vcd->buffer.pos;
|
old_bufpos = vcd->buffer.pos;
|
if (vcd->screen.origin < SCREEN1_BASE || vcd->screen.origin > SCREEN1_END) {
|
if (vcd->screen.origin < SCREEN1_BASE || vcd->screen.origin > SCREEN1_END) {
|
vcd->screen.origin = SCREEN2_BASE;
|
vcd->screen.origin = SCREEN2_BASE;
|
w = 1;
|
w = 1;
|
}
|
}
|
if (vcd->screen.pos < SCREEN1_BASE || vcd->screen.pos > SCREEN2_END) {
|
if (vcd->screen.pos < SCREEN1_BASE || vcd->screen.pos > SCREEN2_END) {
|
vcd->screen.pos = SCREEN2_BASE;
|
vcd->screen.pos = SCREEN2_BASE;
|
w = 1;
|
w = 1;
|
}
|
}
|
|
|
if (w)
|
if (w)
|
printk ("*** CONSOLE ERROR: %s: (%p): origin = %08lX pos = %08lX ***\n",
|
printk ("*** CONSOLE ERROR: %s: (%p): origin = %08lX pos = %08lX ***\n",
|
msg, vcd, old_scrorigin, old_scrpos);
|
msg, vcd, old_scrorigin, old_scrpos);
|
return w;
|
return w;
|
}
|
}
|
#endif
|
#endif
|
|
|
void no_scroll(char *str, int *ints)
|
void no_scroll(char *str, int *ints)
|
{
|
{
|
}
|
}
|
|
|
static unsigned long __origin; /* Offset of currently displayed screen */
|
static unsigned long __origin; /* Offset of currently displayed screen */
|
|
|
static void __set_origin(unsigned long offset)
|
static void __set_origin(unsigned long offset)
|
{
|
{
|
unsigned long flags;
|
unsigned long flags;
|
|
|
clear_selection ();
|
clear_selection ();
|
|
|
offset = offset - vtdata.screen.memstart;
|
offset = offset - vtdata.screen.memstart;
|
if (offset >= vtdata.screen.memsize)
|
if (offset >= vtdata.screen.memsize)
|
offset -= vtdata.screen.memsize;
|
offset -= vtdata.screen.memsize;
|
|
|
save_flags_cli (flags);
|
save_flags_cli (flags);
|
__origin = offset;
|
__origin = offset;
|
video_set_dma(0, vtdata.screen.memsize, offset);
|
video_set_dma(0, vtdata.screen.memsize, offset);
|
restore_flags(flags);
|
restore_flags(flags);
|
}
|
}
|
|
|
void scrollback(int lines)
|
void scrollback(int lines)
|
{
|
{
|
}
|
}
|
|
|
void scrollfront(int lines)
|
void scrollfront(int lines)
|
{
|
{
|
}
|
}
|
|
|
void scroll_set_origin (unsigned long offset)
|
void scroll_set_origin (unsigned long offset)
|
{
|
{
|
__set_origin(offset);
|
__set_origin(offset);
|
}
|
}
|
|
|
static void set_origin (const struct vt * const vt)
|
static void set_origin (const struct vt * const vt)
|
{
|
{
|
if (vtdata.fgconsole != vt || vt->vtd->vc_mode == KD_GRAPHICS)
|
if (vtdata.fgconsole != vt || vt->vtd->vc_mode == KD_GRAPHICS)
|
return;
|
return;
|
__set_origin(vt->vcd->screen.origin);
|
__set_origin(vt->vcd->screen.origin);
|
}
|
}
|
|
|
/* -------------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------------
|
* Cursor
|
* Cursor
|
* ------------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------------- */
|
|
|
static char cursor_on = 0;
|
static char cursor_on = 0;
|
static unsigned long cp;
|
static unsigned long cp;
|
|
|
static void put_cursor(char on_off,unsigned long newcp)
|
static void put_cursor(char on_off,unsigned long newcp)
|
{
|
{
|
static char con;
|
static char con;
|
unsigned long cp_p = cp;
|
unsigned long cp_p = cp;
|
int c = vtdata.screen.bytespercharh == 8 ? color_table[15] : 0x11 * color_table[15];
|
int c = vtdata.screen.bytespercharh == 8 ? color_table[15] : 0x11 * color_table[15];
|
int i;
|
int i;
|
|
|
if (vtdata.fgconsole->vtd->vc_mode == KD_GRAPHICS)
|
if (vtdata.fgconsole->vtd->vc_mode == KD_GRAPHICS)
|
return;
|
return;
|
|
|
cp = newcp;
|
cp = newcp;
|
|
|
if (con != on_off) {
|
if (con != on_off) {
|
if (cp_p != -1)
|
if (cp_p != -1)
|
for (i = 0; i < vtdata.screen.bytespercharh; i++)
|
for (i = 0; i < vtdata.screen.bytespercharh; i++)
|
((unsigned char*)cp_p)[i]^=c;
|
((unsigned char*)cp_p)[i]^=c;
|
con = on_off;
|
con = on_off;
|
}
|
}
|
}
|
}
|
|
|
static void vsync_irq(int irq, void *dev_id, struct pt_regs *regs)
|
static void vsync_irq(int irq, void *dev_id, struct pt_regs *regs)
|
{
|
{
|
static char cursor_flash = 16;
|
static char cursor_flash = 16;
|
|
|
if (!--cursor_flash) {
|
if (!--cursor_flash) {
|
cursor_flash = 16;
|
cursor_flash = 16;
|
cursor_on = cursor_on ? 0 : 1;
|
cursor_on = cursor_on ? 0 : 1;
|
if (vtdata.fgconsole->vcd->screen.cursoron > 0)
|
if (vtdata.fgconsole->vcd->screen.cursoron > 0)
|
put_cursor(cursor_on,cp);
|
put_cursor(cursor_on,cp);
|
}
|
}
|
}
|
}
|
|
|
static void hide_cursor(void)
|
static void hide_cursor(void)
|
{
|
{
|
put_cursor (0, -1);
|
put_cursor (0, -1);
|
}
|
}
|
|
|
static void set_cursor (const struct vt * const vt)
|
static void set_cursor (const struct vt * const vt)
|
{
|
{
|
unsigned long flags;
|
unsigned long flags;
|
|
|
if (vt != vtdata.fgconsole || vt->vtd->vc_mode == KD_GRAPHICS)
|
if (vt != vtdata.fgconsole || vt->vtd->vc_mode == KD_GRAPHICS)
|
return;
|
return;
|
|
|
save_flags_cli (flags);
|
save_flags_cli (flags);
|
if (vt->vcd->deccm) {
|
if (vt->vcd->deccm) {
|
#ifdef DEBUG
|
#ifdef DEBUG
|
vcd_validate (vt->vcd, "set_cursor");
|
vcd_validate (vt->vcd, "set_cursor");
|
#endif
|
#endif
|
cp = vt->vcd->screen.pos + vtdata.numcolumns *
|
cp = vt->vcd->screen.pos + vtdata.numcolumns *
|
vtdata.screen.bytespercharh * (vtdata.screen.bytespercharv - 1);
|
vtdata.screen.bytespercharh * (vtdata.screen.bytespercharv - 1);
|
} else
|
} else
|
hide_cursor();
|
hide_cursor();
|
restore_flags(flags);
|
restore_flags(flags);
|
}
|
}
|
|
|
static void vcd_removecursors (const struct vt *vt)
|
static void vcd_removecursors (const struct vt *vt)
|
{
|
{
|
unsigned long flags;
|
unsigned long flags;
|
|
|
save_flags_cli (flags);
|
save_flags_cli (flags);
|
|
|
if (--vt->vcd->screen.cursoron == 0 && vtdata.fgconsole == vt)
|
if (--vt->vcd->screen.cursoron == 0 && vtdata.fgconsole == vt)
|
put_cursor (0, cp);
|
put_cursor (0, cp);
|
|
|
restore_flags (flags);
|
restore_flags (flags);
|
}
|
}
|
|
|
static void vcd_restorecursors(const struct vt *vt)
|
static void vcd_restorecursors(const struct vt *vt)
|
{
|
{
|
unsigned long flags;
|
unsigned long flags;
|
|
|
save_flags_cli (flags);
|
save_flags_cli (flags);
|
|
|
if (++vt->vcd->screen.cursoron == 1 && cursor_on && vtdata.fgconsole == vt)
|
if (++vt->vcd->screen.cursoron == 1 && cursor_on && vtdata.fgconsole == vt)
|
put_cursor (1, cp);
|
put_cursor (1, cp);
|
|
|
restore_flags (flags);
|
restore_flags (flags);
|
}
|
}
|
|
|
/* -----------------------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------------------
|
* VC stuff
|
* VC stuff
|
* ----------------------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------------------- */
|
/*
|
/*
|
* gotoxy() must verify all boundaries, because the arguments
|
* gotoxy() must verify all boundaries, because the arguments
|
* might also be negative. If a given position is out of
|
* might also be negative. If a given position is out of
|
* bounds, the cursor is placed at the nearest margin.
|
* bounds, the cursor is placed at the nearest margin.
|
*/
|
*/
|
static void gotoxy (struct con_struct *vcd, int new_x, int new_y)
|
static void gotoxy (struct con_struct *vcd, int new_x, int new_y)
|
{
|
{
|
int min_y, max_y;
|
int min_y, max_y;
|
|
|
if (new_x < 0)
|
if (new_x < 0)
|
vcd->curstate.x = 0;
|
vcd->curstate.x = 0;
|
else
|
else
|
if (new_x >= vtdata.numcolumns)
|
if (new_x >= vtdata.numcolumns)
|
vcd->curstate.x = vtdata.numcolumns - 1;
|
vcd->curstate.x = vtdata.numcolumns - 1;
|
else
|
else
|
vcd->curstate.x = new_x;
|
vcd->curstate.x = new_x;
|
|
|
if (vcd->decom) {
|
if (vcd->decom) {
|
new_y += vcd->top;
|
new_y += vcd->top;
|
min_y = vcd->top;
|
min_y = vcd->top;
|
max_y = vcd->bottom;
|
max_y = vcd->bottom;
|
} else {
|
} else {
|
min_y = 0;
|
min_y = 0;
|
max_y = vtdata.numrows;
|
max_y = vtdata.numrows;
|
}
|
}
|
|
|
if (new_y < min_y)
|
if (new_y < min_y)
|
vcd->curstate.y = min_y;
|
vcd->curstate.y = min_y;
|
else if (new_y >= max_y)
|
else if (new_y >= max_y)
|
vcd->curstate.y = max_y - 1;
|
vcd->curstate.y = max_y - 1;
|
else
|
else
|
vcd->curstate.y = new_y;
|
vcd->curstate.y = new_y;
|
|
|
vcd->driver.gotoxy (vcd);
|
vcd->driver.gotoxy (vcd);
|
vcd->need_wrap = 0;
|
vcd->need_wrap = 0;
|
#ifdef DEBUG
|
#ifdef DEBUG
|
vcd_validate (vcd, "gotoxy");
|
vcd_validate (vcd, "gotoxy");
|
#endif
|
#endif
|
}
|
}
|
|
|
/* for absolute user moves, when decom is set */
|
/* for absolute user moves, when decom is set */
|
static void gotoxay (struct con_struct *vcd, int new_x, int new_y)
|
static void gotoxay (struct con_struct *vcd, int new_x, int new_y)
|
{
|
{
|
gotoxy(vcd, new_x, vcd->decom ? (vcd->top+new_y) : new_y);
|
gotoxy(vcd, new_x, vcd->decom ? (vcd->top+new_y) : new_y);
|
}
|
}
|
|
|
static void update_attr (const struct vt * const vt)
|
static void update_attr (const struct vt * const vt)
|
{
|
{
|
unsigned int backcol, forecol;
|
unsigned int backcol, forecol;
|
|
|
backcol = color_table[vt->vcd->curstate.backcol];
|
backcol = color_table[vt->vcd->curstate.backcol];
|
if (vt->vcd->curstate.flags & FLG_BOLD)
|
if (vt->vcd->curstate.flags & FLG_BOLD)
|
forecol = color_table[vt->vcd->curstate.forecol + 8];
|
forecol = color_table[vt->vcd->curstate.forecol + 8];
|
else
|
else
|
forecol = color_table[vt->vcd->curstate.forecol];
|
forecol = color_table[vt->vcd->curstate.forecol];
|
vt->vcd->combined_state = (vt->vcd->curstate.flags << 24) |
|
vt->vcd->combined_state = (vt->vcd->curstate.flags << 24) |
|
(backcol << 16) |
|
(backcol << 16) |
|
(forecol << 8);
|
(forecol << 8);
|
switch (vtdata.screen.bitsperpix) {
|
switch (vtdata.screen.bitsperpix) {
|
case 1:
|
case 1:
|
vt->vcd->cached_backcolwrd = 0;
|
vt->vcd->cached_backcolwrd = 0;
|
break;
|
break;
|
default:
|
default:
|
case 4:
|
case 4:
|
vt->vcd->cached_backcolwrd = 0x11111111 * backcol;
|
vt->vcd->cached_backcolwrd = 0x11111111 * backcol;
|
break;
|
break;
|
case 8:
|
case 8:
|
vt->vcd->cached_backcolwrd = 0x01010101 * backcol;
|
vt->vcd->cached_backcolwrd = 0x01010101 * backcol;
|
break;
|
break;
|
}
|
}
|
}
|
}
|
|
|
static void default_attr (const struct vt * const vt)
|
static void default_attr (const struct vt * const vt)
|
{
|
{
|
vt->vcd->curstate.flags &= ~(FLG_INVERSE|FLG_FLASH|FLG_UNDERLINE|FLG_ITALIC|FLG_BOLD);
|
vt->vcd->curstate.flags &= ~(FLG_INVERSE|FLG_FLASH|FLG_UNDERLINE|FLG_ITALIC|FLG_BOLD);
|
vt->vcd->curstate.forecol = vt->vcd->def_forecol;
|
vt->vcd->curstate.forecol = vt->vcd->def_forecol;
|
vt->vcd->curstate.backcol = vt->vcd->def_backcol;
|
vt->vcd->curstate.backcol = vt->vcd->def_backcol;
|
}
|
}
|
|
|
static int csi_m (const struct vt * const vt)
|
static int csi_m (const struct vt * const vt)
|
{
|
{
|
struct con_struct *vcd = vt->vcd;
|
struct con_struct *vcd = vt->vcd;
|
int i, ret = 0;
|
int i, ret = 0;
|
|
|
for (i = 0; i <= vcd->npar; i++) {
|
for (i = 0; i <= vcd->npar; i++) {
|
switch (vcd->par[i]) {
|
switch (vcd->par[i]) {
|
case 0:
|
case 0:
|
default_attr (vt);
|
default_attr (vt);
|
break;
|
break;
|
case 1:
|
case 1:
|
vcd->curstate.flags |= FLG_BOLD;
|
vcd->curstate.flags |= FLG_BOLD;
|
break; /* Bold */
|
break; /* Bold */
|
case 2:
|
case 2:
|
vcd->curstate.flags &= ~FLG_BOLD;
|
vcd->curstate.flags &= ~FLG_BOLD;
|
break; /* Feint */
|
break; /* Feint */
|
case 3:
|
case 3:
|
vcd->curstate.flags |= FLG_ITALIC;
|
vcd->curstate.flags |= FLG_ITALIC;
|
break; /* Italic */
|
break; /* Italic */
|
case 4:
|
case 4:
|
vcd->curstate.flags |= FLG_UNDERLINE;
|
vcd->curstate.flags |= FLG_UNDERLINE;
|
break; /* Underline */
|
break; /* Underline */
|
case 5:
|
case 5:
|
case 6:
|
case 6:
|
vcd->curstate.flags |= FLG_FLASH;
|
vcd->curstate.flags |= FLG_FLASH;
|
break; /* Flash */
|
break; /* Flash */
|
case 7:
|
case 7:
|
vcd->curstate.flags |= FLG_INVERSE;
|
vcd->curstate.flags |= FLG_INVERSE;
|
break; /* Inverse chars */
|
break; /* Inverse chars */
|
|
|
case 10:
|
case 10:
|
/* ANSI X3.64-1979 (SCO-ish?)
|
/* ANSI X3.64-1979 (SCO-ish?)
|
* Select primary font, don't display
|
* Select primary font, don't display
|
* control chars if defined, don't set
|
* control chars if defined, don't set
|
* bit 8 on output.
|
* bit 8 on output.
|
*/
|
*/
|
vcd->translate = set_translate(vcd->curstate.flags & FLG_CHRSET
|
vcd->translate = set_translate(vcd->curstate.flags & FLG_CHRSET
|
? vcd->curstate.G1_charset
|
? vcd->curstate.G1_charset
|
: vcd->curstate.G0_charset);
|
: vcd->curstate.G0_charset);
|
vcd->disp_ctrl = 0;
|
vcd->disp_ctrl = 0;
|
vcd->toggle_meta = 0;
|
vcd->toggle_meta = 0;
|
ret = 1;
|
ret = 1;
|
break;
|
break;
|
case 11:
|
case 11:
|
/* ANSI X3.64-1979 (SCO-ish?)
|
/* ANSI X3.64-1979 (SCO-ish?)
|
* Select first alternate font, let's
|
* Select first alternate font, let's
|
* chars < 32 be displayed as ROM chars.
|
* chars < 32 be displayed as ROM chars.
|
*/
|
*/
|
vcd->translate = set_translate(IBMPC_MAP);
|
vcd->translate = set_translate(IBMPC_MAP);
|
vcd->disp_ctrl = 1;
|
vcd->disp_ctrl = 1;
|
vcd->toggle_meta = 0;
|
vcd->toggle_meta = 0;
|
ret = 1;
|
ret = 1;
|
break;
|
break;
|
case 12:
|
case 12:
|
/* ANSI X3.64-1979 (SCO-ish?)
|
/* ANSI X3.64-1979 (SCO-ish?)
|
* Select second alternate font, toggle
|
* Select second alternate font, toggle
|
* high bit before displaying as ROM char.
|
* high bit before displaying as ROM char.
|
*/
|
*/
|
vcd->translate = set_translate(IBMPC_MAP);
|
vcd->translate = set_translate(IBMPC_MAP);
|
vcd->disp_ctrl = 1;
|
vcd->disp_ctrl = 1;
|
vcd->toggle_meta = 1;
|
vcd->toggle_meta = 1;
|
ret = 1;
|
ret = 1;
|
break;
|
break;
|
case 21:
|
case 21:
|
case 22:
|
case 22:
|
vcd->curstate.flags &= ~FLG_BOLD;
|
vcd->curstate.flags &= ~FLG_BOLD;
|
break;
|
break;
|
case 24:
|
case 24:
|
vcd->curstate.flags &= ~FLG_UNDERLINE;
|
vcd->curstate.flags &= ~FLG_UNDERLINE;
|
break;
|
break;
|
case 25:
|
case 25:
|
vcd->curstate.flags &= ~FLG_FLASH;
|
vcd->curstate.flags &= ~FLG_FLASH;
|
break;
|
break;
|
case 27:
|
case 27:
|
vcd->curstate.flags &= ~FLG_INVERSE;
|
vcd->curstate.flags &= ~FLG_INVERSE;
|
break;
|
break;
|
case 30:
|
case 30:
|
case 31:
|
case 31:
|
case 32:
|
case 32:
|
case 33:
|
case 33:
|
case 34:
|
case 34:
|
case 35:
|
case 35:
|
case 36:
|
case 36:
|
case 37:
|
case 37:
|
vcd->curstate.forecol = vcd->par[i]-30;
|
vcd->curstate.forecol = vcd->par[i]-30;
|
break; /* Foreground colour */
|
break; /* Foreground colour */
|
case 38:
|
case 38:
|
vcd->curstate.forecol = vcd->def_forecol;
|
vcd->curstate.forecol = vcd->def_forecol;
|
vcd->curstate.flags &= ~FLG_UNDERLINE;
|
vcd->curstate.flags &= ~FLG_UNDERLINE;
|
break;
|
break;
|
case 39:
|
case 39:
|
vcd->curstate.forecol = vcd->def_forecol;
|
vcd->curstate.forecol = vcd->def_forecol;
|
vcd->curstate.flags &= ~FLG_UNDERLINE;
|
vcd->curstate.flags &= ~FLG_UNDERLINE;
|
break; /* Default foreground colour */
|
break; /* Default foreground colour */
|
case 40:
|
case 40:
|
case 41:
|
case 41:
|
case 42:
|
case 42:
|
case 43:
|
case 43:
|
case 44:
|
case 44:
|
case 45:
|
case 45:
|
case 46:
|
case 46:
|
case 47:
|
case 47:
|
vcd->curstate.backcol = vcd->par[i]-40;
|
vcd->curstate.backcol = vcd->par[i]-40;
|
break; /* Background colour */
|
break; /* Background colour */
|
case 49:
|
case 49:
|
vcd->curstate.backcol = vcd->def_backcol;
|
vcd->curstate.backcol = vcd->def_backcol;
|
break; /* Default background colour */
|
break; /* Default background colour */
|
}
|
}
|
}
|
}
|
update_attr (vt);
|
update_attr (vt);
|
return ret;
|
return ret;
|
}
|
}
|
|
|
static void respond_string (char *p, struct tty_struct *tty)
|
static void respond_string (char *p, struct tty_struct *tty)
|
{
|
{
|
while (*p)
|
while (*p)
|
tty_insert_flip_char (tty, *p++, 0);
|
tty_insert_flip_char (tty, *p++, 0);
|
tty_schedule_flip (tty);
|
tty_schedule_flip (tty);
|
}
|
}
|
|
|
static void cursor_report (const struct vt *vt)
|
static void cursor_report (const struct vt *vt)
|
{
|
{
|
char buf[40];
|
char buf[40];
|
|
|
sprintf (buf, "\033[%d;%dR", vt->vcd->curstate.y + (vt->vcd->decom ? vt->vcd->top + 1 : 1),
|
sprintf (buf, "\033[%d;%dR", vt->vcd->curstate.y + (vt->vcd->decom ? vt->vcd->top + 1 : 1),
|
vt->vcd->curstate.x + 1);
|
vt->vcd->curstate.x + 1);
|
respond_string (buf, *vt->tty);
|
respond_string (buf, *vt->tty);
|
}
|
}
|
|
|
static void status_report (struct tty_struct *tty)
|
static void status_report (struct tty_struct *tty)
|
{
|
{
|
respond_string ("\033[0n", tty);
|
respond_string ("\033[0n", tty);
|
}
|
}
|
|
|
static void respond_ID (struct tty_struct *tty)
|
static void respond_ID (struct tty_struct *tty)
|
{
|
{
|
respond_string(VT102ID, tty);
|
respond_string(VT102ID, tty);
|
}
|
}
|
|
|
void mouse_report (struct tty_struct *tty, int butt, int mrx, int mry)
|
void mouse_report (struct tty_struct *tty, int butt, int mrx, int mry)
|
{
|
{
|
char buf[8];
|
char buf[8];
|
|
|
sprintf (buf,"\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx),
|
sprintf (buf,"\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx),
|
(char)('!'+mry));
|
(char)('!'+mry));
|
respond_string(buf, tty);
|
respond_string(buf, tty);
|
}
|
}
|
|
|
/* invoked by ioctl(TIOCLINUX) */
|
/* invoked by ioctl(TIOCLINUX) */
|
int mouse_reporting (void)
|
int mouse_reporting (void)
|
{
|
{
|
return vtdata.fgconsole->vcd->report_mouse;
|
return vtdata.fgconsole->vcd->report_mouse;
|
}
|
}
|
|
|
static inline unsigned long screenpos (const struct vt * const vt, int offset)
|
static inline unsigned long screenpos (const struct vt * const vt, int offset)
|
{
|
{
|
int hx, hy;
|
int hx, hy;
|
|
|
hx = offset % vtdata.numcolumns;
|
hx = offset % vtdata.numcolumns;
|
hy = offset / vtdata.numcolumns;
|
hy = offset / vtdata.numcolumns;
|
return vt->vcd->screen.origin + hy * vtdata.screen.sizerow + hx * vtdata.screen.bytespercharh;
|
return vt->vcd->screen.origin + hy * vtdata.screen.sizerow + hx * vtdata.screen.bytespercharh;
|
}
|
}
|
|
|
void invert_screen (const struct vt * const vt, unsigned int offset, unsigned int count)
|
void invert_screen (const struct vt * const vt, unsigned int offset, unsigned int count)
|
{
|
{
|
struct con_struct *vcd = vt->vcd;
|
struct con_struct *vcd = vt->vcd;
|
unsigned long *buffer = vcd->driver.buffer_pos(vcd, offset);
|
unsigned long *buffer = vcd->driver.buffer_pos(vcd, offset);
|
unsigned long p, pp;
|
unsigned long p, pp;
|
int i;
|
int i;
|
|
|
for (i = 0; i <= count; i++)
|
for (i = 0; i <= count; i++)
|
buffer[i] ^= FLG_INVERSE << 24;
|
buffer[i] ^= FLG_INVERSE << 24;
|
|
|
if (vt == vtdata.fgconsole) {
|
if (vt == vtdata.fgconsole) {
|
int hx, hy, hex, hey;
|
int hx, hy, hex, hey;
|
|
|
hx = offset % vtdata.numcolumns;
|
hx = offset % vtdata.numcolumns;
|
hy = offset / vtdata.numcolumns;
|
hy = offset / vtdata.numcolumns;
|
hex = (offset + count) % vtdata.numcolumns;
|
hex = (offset + count) % vtdata.numcolumns;
|
hey = (offset + count) / vtdata.numcolumns;
|
hey = (offset + count) / vtdata.numcolumns;
|
|
|
p = vcd->screen.origin + hy * vtdata.screen.sizerow;
|
p = vcd->screen.origin + hy * vtdata.screen.sizerow;
|
pp = p + hx * vtdata.screen.bytespercharh;
|
pp = p + hx * vtdata.screen.bytespercharh;
|
for (;hy <= hey; hy ++) {
|
for (;hy <= hey; hy ++) {
|
for (; hx < ((hy == hey) ? hex + 1 : vtdata.numcolumns); hx ++) {
|
for (; hx < ((hy == hey) ? hex + 1 : vtdata.numcolumns); hx ++) {
|
ll_write_char (pp, *buffer++);
|
ll_write_char (pp, *buffer++);
|
pp += vtdata.screen.bytespercharh;
|
pp += vtdata.screen.bytespercharh;
|
}
|
}
|
hx = 0;
|
hx = 0;
|
pp = p += vtdata.screen.sizerow;
|
pp = p += vtdata.screen.sizerow;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
void complement_pos (const struct vt * const vt, unsigned int offset)
|
void complement_pos (const struct vt * const vt, unsigned int offset)
|
{
|
{
|
static unsigned long old = 0;
|
static unsigned long old = 0;
|
static unsigned long p = 0;
|
static unsigned long p = 0;
|
unsigned long complement;
|
unsigned long complement;
|
|
|
switch (vtdata.screen.bitsperpix) {
|
switch (vtdata.screen.bitsperpix) {
|
case 4:
|
case 4:
|
complement = 0x00070700;
|
complement = 0x00070700;
|
break;
|
break;
|
case 8:
|
case 8:
|
#ifndef HAS_VIDC20
|
#ifndef HAS_VIDC20
|
complement = 0x00fcfc00;
|
complement = 0x00fcfc00;
|
#else
|
#else
|
complement = 0x00070700;
|
complement = 0x00070700;
|
#endif
|
#endif
|
break;
|
break;
|
default:
|
default:
|
complement = 0;
|
complement = 0;
|
}
|
}
|
|
|
if (p)
|
if (p)
|
ll_write_char (p, old);
|
ll_write_char (p, old);
|
if ((int)offset == -1)
|
if ((int)offset == -1)
|
p = 0;
|
p = 0;
|
else {
|
else {
|
old = *vt->vcd->driver.buffer_pos(vt->vcd, offset);
|
old = *vt->vcd->driver.buffer_pos(vt->vcd, offset);
|
p = screenpos (vt, offset);
|
p = screenpos (vt, offset);
|
ll_write_char (p, old ^ complement);
|
ll_write_char (p, old ^ complement);
|
}
|
}
|
}
|
}
|
|
|
unsigned long screen_word (const struct vt * const vt, unsigned int offset)
|
unsigned long screen_word (const struct vt * const vt, unsigned int offset)
|
{
|
{
|
return *vt->vcd->driver.buffer_pos (vt->vcd, offset);
|
return *vt->vcd->driver.buffer_pos (vt->vcd, offset);
|
}
|
}
|
|
|
int scrw2glyph (unsigned long scr_word)
|
int scrw2glyph (unsigned long scr_word)
|
{
|
{
|
return scr_word & 255;
|
return scr_word & 255;
|
}
|
}
|
|
|
unsigned long *screen_pos (const struct vt * const vt, unsigned int offset)
|
unsigned long *screen_pos (const struct vt * const vt, unsigned int offset)
|
{
|
{
|
return vt->vcd->driver.buffer_pos (vt->vcd, offset);
|
return vt->vcd->driver.buffer_pos (vt->vcd, offset);
|
}
|
}
|
|
|
void getconsxy (const struct vt * const vt, char *p)
|
void getconsxy (const struct vt * const vt, char *p)
|
{
|
{
|
p[0] = vt->vcd->curstate.x;
|
p[0] = vt->vcd->curstate.x;
|
p[1] = vt->vcd->curstate.y;
|
p[1] = vt->vcd->curstate.y;
|
}
|
}
|
|
|
void putconsxy (const struct vt * const vt, char *p)
|
void putconsxy (const struct vt * const vt, char *p)
|
{
|
{
|
gotoxy (vt->vcd, p[0], p[1]);
|
gotoxy (vt->vcd, p[0], p[1]);
|
set_cursor (vt);
|
set_cursor (vt);
|
}
|
}
|
|
|
static void csi_J (const struct vt * const vt, int vpar);
|
static void csi_J (const struct vt * const vt, int vpar);
|
|
|
static void set_mode (const struct vt * const vt, int on_off)
|
static void set_mode (const struct vt * const vt, int on_off)
|
{
|
{
|
struct con_struct *vcd = vt->vcd;
|
struct con_struct *vcd = vt->vcd;
|
int i;
|
int i;
|
|
|
for (i = 0; i <= vcd->npar; i++)
|
for (i = 0; i <= vcd->npar; i++)
|
if (vcd->ques)
|
if (vcd->ques)
|
switch(vcd->par[i]) { /* DEC private modes set/reset */
|
switch(vcd->par[i]) { /* DEC private modes set/reset */
|
case 1: /* Cursor keys send ^[Ox/^[[x */
|
case 1: /* Cursor keys send ^[Ox/^[[x */
|
if (on_off)
|
if (on_off)
|
set_kbd(decckm);
|
set_kbd(decckm);
|
else
|
else
|
clr_kbd(decckm);
|
clr_kbd(decckm);
|
break;
|
break;
|
case 3: /* 80/132 mode switch unimplemented */
|
case 3: /* 80/132 mode switch unimplemented */
|
vcd->deccolm = on_off;
|
vcd->deccolm = on_off;
|
csi_J (vt, 2);
|
csi_J (vt, 2);
|
gotoxy (vcd, 0, 0);
|
gotoxy (vcd, 0, 0);
|
break;
|
break;
|
case 5: /* Inverted screen on/off */
|
case 5: /* Inverted screen on/off */
|
if (vcd->decscnm != on_off) {
|
if (vcd->decscnm != on_off) {
|
vcd->decscnm = on_off;
|
vcd->decscnm = on_off;
|
invert_screen (vt, 0, vtdata.buffer.totsize);
|
invert_screen (vt, 0, vtdata.buffer.totsize);
|
update_attr (vt);
|
update_attr (vt);
|
}
|
}
|
break;
|
break;
|
case 6: /* Origin relative/absolute */
|
case 6: /* Origin relative/absolute */
|
vcd->decom = on_off;
|
vcd->decom = on_off;
|
gotoxay (vcd, 0, 0);
|
gotoxay (vcd, 0, 0);
|
break;
|
break;
|
case 7: /* Autowrap on/off */
|
case 7: /* Autowrap on/off */
|
vcd->decawm = on_off;
|
vcd->decawm = on_off;
|
break;
|
break;
|
case 8: /* Autorepeat on/off */
|
case 8: /* Autorepeat on/off */
|
if (on_off)
|
if (on_off)
|
set_kbd(decarm);
|
set_kbd(decarm);
|
else
|
else
|
clr_kbd(decarm);
|
clr_kbd(decarm);
|
break;
|
break;
|
case 9:
|
case 9:
|
vcd->report_mouse = on_off ? 1 : 0;
|
vcd->report_mouse = on_off ? 1 : 0;
|
break;
|
break;
|
case 25: /* Cursor on/off */
|
case 25: /* Cursor on/off */
|
vcd->deccm = on_off;
|
vcd->deccm = on_off;
|
set_cursor (vt);
|
set_cursor (vt);
|
break;
|
break;
|
case 1000:
|
case 1000:
|
vcd->report_mouse = on_off ? 2 : 0;
|
vcd->report_mouse = on_off ? 2 : 0;
|
break;
|
break;
|
}
|
}
|
else
|
else
|
switch(vcd->par[i]) { /* ANSI modes set/reset */
|
switch(vcd->par[i]) { /* ANSI modes set/reset */
|
case 3: /* Monitor (display ctrls) */
|
case 3: /* Monitor (display ctrls) */
|
vcd->disp_ctrl = on_off;
|
vcd->disp_ctrl = on_off;
|
break;
|
break;
|
case 4: /* Insert mode on/off */
|
case 4: /* Insert mode on/off */
|
vcd->decim = on_off;
|
vcd->decim = on_off;
|
break;
|
break;
|
case 20: /* Lf, Enter = CrLf/Lf */
|
case 20: /* Lf, Enter = CrLf/Lf */
|
if (on_off)
|
if (on_off)
|
set_kbd(lnm);
|
set_kbd(lnm);
|
else
|
else
|
clr_kbd(lnm);
|
clr_kbd(lnm);
|
break;
|
break;
|
}
|
}
|
}
|
}
|
|
|
static void setterm_command (const struct vt * const vt)
|
static void setterm_command (const struct vt * const vt)
|
{
|
{
|
struct con_struct *vcd = vt->vcd;
|
struct con_struct *vcd = vt->vcd;
|
switch (vt->vcd->par[0]) {
|
switch (vt->vcd->par[0]) {
|
case 1: /* Set colour for underline mode (implemented as an underline) */
|
case 1: /* Set colour for underline mode (implemented as an underline) */
|
case 2: /* set colour for half intensity mode (unimplemented) */
|
case 2: /* set colour for half intensity mode (unimplemented) */
|
break;
|
break;
|
case 8:
|
case 8:
|
vcd->def_forecol = vcd->curstate.forecol;
|
vcd->def_forecol = vcd->curstate.forecol;
|
vcd->def_backcol = vcd->curstate.backcol;
|
vcd->def_backcol = vcd->curstate.backcol;
|
break;
|
break;
|
case 9:
|
case 9:
|
vtdata.screen.blankinterval =
|
vtdata.screen.blankinterval =
|
((vcd->par[1] < 60) ? vcd->par[1] : 60) * 60 * HZ;
|
((vcd->par[1] < 60) ? vcd->par[1] : 60) * 60 * HZ;
|
vt_pokeblankedconsole ();
|
vt_pokeblankedconsole ();
|
break;
|
break;
|
case 10: /* set bell frequency in Hz */
|
case 10: /* set bell frequency in Hz */
|
if (vcd->npar >= 1)
|
if (vcd->npar >= 1)
|
vcd->bell_pitch = vcd->par[1];
|
vcd->bell_pitch = vcd->par[1];
|
else
|
else
|
vcd->bell_pitch = DEFAULT_BELL_PITCH;
|
vcd->bell_pitch = DEFAULT_BELL_PITCH;
|
break;
|
break;
|
case 11: /* set bell duration in msec */
|
case 11: /* set bell duration in msec */
|
if (vcd->npar >= 1)
|
if (vcd->npar >= 1)
|
vcd->bell_duration = (vcd->par[1] < 2000) ?
|
vcd->bell_duration = (vcd->par[1] < 2000) ?
|
vcd->par[1]*HZ/1000 : 0;
|
vcd->par[1]*HZ/1000 : 0;
|
else
|
else
|
vcd->bell_duration = DEFAULT_BELL_DURATION;
|
vcd->bell_duration = DEFAULT_BELL_DURATION;
|
break;
|
break;
|
case 12: { /* bring specified console to the front */
|
case 12: { /* bring specified console to the front */
|
int arg = vcd->par[1];
|
int arg = vcd->par[1];
|
if (arg >= 1 && vt_allocated(vt_con_data + (arg - 1) ))
|
if (arg >= 1 && vt_allocated(vt_con_data + (arg - 1) ))
|
vt_updatescreen(vt_con_data + (arg - 1));
|
vt_updatescreen(vt_con_data + (arg - 1));
|
break;
|
break;
|
}
|
}
|
case 13: /* unblank the screen */
|
case 13: /* unblank the screen */
|
vt_do_unblankscreen ();
|
vt_do_unblankscreen ();
|
break;
|
break;
|
case 14: /* set vesa powerdown interval */
|
case 14: /* set vesa powerdown interval */
|
#if todo
|
#if todo
|
vesa_off_interval = ((vcd->par[1] < 60) ? vcd->par[1] : 60) * 60 * HZ;
|
vesa_off_interval = ((vcd->par[1] < 60) ? vcd->par[1] : 60) * 60 * HZ;
|
#endif
|
#endif
|
break;
|
break;
|
}
|
}
|
}
|
}
|
|
|
static void csi_J (const struct vt * const vt, int vpar)
|
static void csi_J (const struct vt * const vt, int vpar)
|
{
|
{
|
unsigned char endx, endy;
|
unsigned char endx, endy;
|
unsigned char startx, starty;
|
unsigned char startx, starty;
|
|
|
switch (vpar) {
|
switch (vpar) {
|
case 0: /* erase from cursor to bottom of screen (including char at (x, y) */
|
case 0: /* erase from cursor to bottom of screen (including char at (x, y) */
|
startx = vt->vcd->curstate.x;
|
startx = vt->vcd->curstate.x;
|
starty = vt->vcd->curstate.y;
|
starty = vt->vcd->curstate.y;
|
endx = vtdata.numcolumns - 1;
|
endx = vtdata.numcolumns - 1;
|
endy = vtdata.numrows - 1;
|
endy = vtdata.numrows - 1;
|
break;
|
break;
|
case 1: /* erase from top of screen to cursor (including char at (x, y) */
|
case 1: /* erase from top of screen to cursor (including char at (x, y) */
|
startx = 0;
|
startx = 0;
|
starty = 0;
|
starty = 0;
|
endx = vt->vcd->curstate.x;
|
endx = vt->vcd->curstate.x;
|
endy = vt->vcd->curstate.y;
|
endy = vt->vcd->curstate.y;
|
break;
|
break;
|
case 2: /* erase entire screen */
|
case 2: /* erase entire screen */
|
startx = 0;
|
startx = 0;
|
starty = 0;
|
starty = 0;
|
endx = vtdata.numcolumns - 1;
|
endx = vtdata.numcolumns - 1;
|
endy = vtdata.numrows - 1;
|
endy = vtdata.numrows - 1;
|
#if TODO
|
#if TODO
|
origin = video_mem_base;
|
origin = video_mem_base;
|
set_origin (currcons);
|
set_origin (currcons);
|
gotoxy (currcons, x, y);
|
gotoxy (currcons, x, y);
|
#endif
|
#endif
|
break;
|
break;
|
default:
|
default:
|
return;
|
return;
|
}
|
}
|
vt->vcd->driver.erase (vt->vcd, startx, starty, endx, endy);
|
vt->vcd->driver.erase (vt->vcd, startx, starty, endx, endy);
|
/*vt->vcd->need_wrap = 0; why? We don't move the cursor... */
|
/*vt->vcd->need_wrap = 0; why? We don't move the cursor... */
|
}
|
}
|
|
|
static void csi_K (const struct vt * const vt, int vpar)
|
static void csi_K (const struct vt * const vt, int vpar)
|
{
|
{
|
unsigned char endx;
|
unsigned char endx;
|
unsigned char startx;
|
unsigned char startx;
|
|
|
switch(vpar) {
|
switch(vpar) {
|
case 0: /* erase from cursor to end of line */
|
case 0: /* erase from cursor to end of line */
|
startx = vt->vcd->curstate.x;
|
startx = vt->vcd->curstate.x;
|
endx = vtdata.numcolumns - 1;
|
endx = vtdata.numcolumns - 1;
|
break;
|
break;
|
case 1: /* erase from beginning of line to cursor */
|
case 1: /* erase from beginning of line to cursor */
|
startx = 0;
|
startx = 0;
|
endx = vt->vcd->curstate.x;
|
endx = vt->vcd->curstate.x;
|
break;
|
break;
|
case 2: /* erase entire line */
|
case 2: /* erase entire line */
|
startx = 0;
|
startx = 0;
|
endx = vtdata.numcolumns - 1;
|
endx = vtdata.numcolumns - 1;
|
break;
|
break;
|
default:
|
default:
|
return;
|
return;
|
}
|
}
|
vt->vcd->driver.erase(vt->vcd, startx, vt->vcd->curstate.y, endx, vt->vcd->curstate.y);
|
vt->vcd->driver.erase(vt->vcd, startx, vt->vcd->curstate.y, endx, vt->vcd->curstate.y);
|
/*vt->vcd->need_wrap = 0; why? We don't move the cursor... */
|
/*vt->vcd->need_wrap = 0; why? We don't move the cursor... */
|
}
|
}
|
|
|
static void csi_X (const struct vt * const vt, int vpar) /* erase the following vpar positions */
|
static void csi_X (const struct vt * const vt, int vpar) /* erase the following vpar positions */
|
{ /* not vt100? */
|
{ /* not vt100? */
|
unsigned char countx, county;
|
unsigned char countx, county;
|
unsigned char startx, starty;
|
unsigned char startx, starty;
|
|
|
if (!vpar)
|
if (!vpar)
|
vpar++;
|
vpar++;
|
|
|
startx = vt->vcd->curstate.x;
|
startx = vt->vcd->curstate.x;
|
starty = vt->vcd->curstate.y;
|
starty = vt->vcd->curstate.y;
|
countx = 0;
|
countx = 0;
|
county = 0;
|
county = 0;
|
#if TODO
|
#if TODO
|
vt->vcd->driver.erase(vt->vcd,startx,starty,countx,county);
|
vt->vcd->driver.erase(vt->vcd,startx,starty,countx,county);
|
#endif
|
#endif
|
/*vt->vcd->need_wrap = 0; why? We don't move the cursor... */
|
/*vt->vcd->need_wrap = 0; why? We don't move the cursor... */
|
}
|
}
|
|
|
static void csi_at (const struct vt * const vt, int nr)
|
static void csi_at (const struct vt * const vt, int nr)
|
{
|
{
|
if (nr > vtdata.numcolumns - vt->vcd->curstate.x)
|
if (nr > vtdata.numcolumns - vt->vcd->curstate.x)
|
nr = vtdata.numcolumns - vt->vcd->curstate.x;
|
nr = vtdata.numcolumns - vt->vcd->curstate.x;
|
else if (!nr)
|
else if (!nr)
|
nr = 1;
|
nr = 1;
|
vt->vcd->driver.insert_char(vt->vcd, nr);
|
vt->vcd->driver.insert_char(vt->vcd, nr);
|
}
|
}
|
|
|
static void csi_L (const struct vt * const vt, int nr)
|
static void csi_L (const struct vt * const vt, int nr)
|
{
|
{
|
if (nr > vtdata.numrows - vt->vcd->curstate.y)
|
if (nr > vtdata.numrows - vt->vcd->curstate.y)
|
nr = vtdata.numrows - vt->vcd->curstate.y;
|
nr = vtdata.numrows - vt->vcd->curstate.y;
|
else if (!nr)
|
else if (!nr)
|
nr = 1;
|
nr = 1;
|
vt->vcd->driver.scroll_down (vt->vcd, vt->vcd->curstate.y, vt->vcd->bottom, nr);
|
vt->vcd->driver.scroll_down (vt->vcd, vt->vcd->curstate.y, vt->vcd->bottom, nr);
|
/* vt->vcd->need_wrap = 0; why? We haven't moved the cursor. */
|
/* vt->vcd->need_wrap = 0; why? We haven't moved the cursor. */
|
}
|
}
|
|
|
static void csi_P (const struct vt * const vt, int nr)
|
static void csi_P (const struct vt * const vt, int nr)
|
{
|
{
|
if (nr > vtdata.numcolumns)
|
if (nr > vtdata.numcolumns)
|
nr = vtdata.numcolumns;
|
nr = vtdata.numcolumns;
|
else if (!nr)
|
else if (!nr)
|
nr = 1;
|
nr = 1;
|
vt->vcd->driver.delete_char(vt->vcd, nr);
|
vt->vcd->driver.delete_char(vt->vcd, nr);
|
}
|
}
|
|
|
static void csi_M (const struct vt * const vt, int nr)
|
static void csi_M (const struct vt * const vt, int nr)
|
{
|
{
|
if (nr > vtdata.numrows)
|
if (nr > vtdata.numrows)
|
nr = vtdata.numrows;
|
nr = vtdata.numrows;
|
else if (!nr)
|
else if (!nr)
|
nr = 1;
|
nr = 1;
|
vt->vcd->driver.scroll_up (vt->vcd, vt->vcd->curstate.y, vt->vcd->bottom, nr);
|
vt->vcd->driver.scroll_up (vt->vcd, vt->vcd->curstate.y, vt->vcd->bottom, nr);
|
/* vt->vcd->need_wrap = 0; why? we haven't moved the cursor. */
|
/* vt->vcd->need_wrap = 0; why? we haven't moved the cursor. */
|
}
|
}
|
|
|
enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
|
enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
|
EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
|
EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
|
ESpalette };
|
ESpalette };
|
|
|
static void reset_terminal (const struct vt * const vt, int initialising)
|
static void reset_terminal (const struct vt * const vt, int initialising)
|
{
|
{
|
struct con_struct *vcd;
|
struct con_struct *vcd;
|
|
|
vcd = vt->vcd;
|
vcd = vt->vcd;
|
|
|
vcd->top = 0;
|
vcd->top = 0;
|
vcd->bottom = vtdata.numrows;
|
vcd->bottom = vtdata.numrows;
|
vcd->state = ESnormal;
|
vcd->state = ESnormal;
|
vcd->ques = 0;
|
vcd->ques = 0;
|
vcd->translate = set_translate (LAT1_MAP);
|
vcd->translate = set_translate (LAT1_MAP);
|
vcd->curstate.G0_charset = LAT1_MAP;
|
vcd->curstate.G0_charset = LAT1_MAP;
|
vcd->curstate.G1_charset = GRAF_MAP;
|
vcd->curstate.G1_charset = GRAF_MAP;
|
vcd->curstate.flags = 0;
|
vcd->curstate.flags = 0;
|
vcd->need_wrap = 0;
|
vcd->need_wrap = 0;
|
vcd->report_mouse = 0;
|
vcd->report_mouse = 0;
|
vcd->utf = 0;
|
vcd->utf = 0;
|
vcd->utf_count = 0;
|
vcd->utf_count = 0;
|
vcd->disp_ctrl = 0;
|
vcd->disp_ctrl = 0;
|
vcd->toggle_meta = 0;
|
vcd->toggle_meta = 0;
|
vcd->decscnm = 0;
|
vcd->decscnm = 0;
|
vcd->decom = 0;
|
vcd->decom = 0;
|
vcd->decawm = 1;
|
vcd->decawm = 1;
|
vcd->deccm = 1;
|
vcd->deccm = 1;
|
vcd->decim = 0;
|
vcd->decim = 0;
|
vcd->curstate.forecol = 7;
|
vcd->curstate.forecol = 7;
|
vcd->curstate.backcol = 0;
|
vcd->curstate.backcol = 0;
|
vcd->def_forecol = 7;
|
vcd->def_forecol = 7;
|
vcd->def_backcol = 0;
|
vcd->def_backcol = 0;
|
vcd->tab_stop[0] = 0x01010100;
|
vcd->tab_stop[0] = 0x01010100;
|
vcd->tab_stop[1] =
|
vcd->tab_stop[1] =
|
vcd->tab_stop[2] =
|
vcd->tab_stop[2] =
|
vcd->tab_stop[3] =
|
vcd->tab_stop[3] =
|
vcd->tab_stop[4] = 0x01010101;
|
vcd->tab_stop[4] = 0x01010101;
|
|
|
set_kbd (decarm);
|
set_kbd (decarm);
|
clr_kbd (decckm);
|
clr_kbd (decckm);
|
clr_kbd(kbdapplic);
|
clr_kbd(kbdapplic);
|
clr_kbd(lnm);
|
clr_kbd(lnm);
|
|
|
vt->kbd->lockstate = 0;
|
vt->kbd->lockstate = 0;
|
vt->kbd->ledmode = LED_SHOW_FLAGS;
|
vt->kbd->ledmode = LED_SHOW_FLAGS;
|
vt->kbd->ledflagstate = vt->kbd->default_ledflagstate;
|
vt->kbd->ledflagstate = vt->kbd->default_ledflagstate;
|
if (!initialising)
|
if (!initialising)
|
set_leds ();
|
set_leds ();
|
|
|
if (vcd->screen.palette_entries) {
|
if (vcd->screen.palette_entries) {
|
kfree (vcd->screen.palette_entries);
|
kfree (vcd->screen.palette_entries);
|
vcd->screen.palette_entries = 0;
|
vcd->screen.palette_entries = 0;
|
}
|
}
|
|
|
gotoxy (vcd, 0, 0);
|
gotoxy (vcd, 0, 0);
|
vcd->savedstate = vcd->curstate;
|
vcd->savedstate = vcd->curstate;
|
update_attr (vt);
|
update_attr (vt);
|
|
|
if (!initialising)
|
if (!initialising)
|
csi_J (vt, 2);
|
csi_J (vt, 2);
|
}
|
}
|
|
|
|
|
static inline void update_palette(const struct vt * const vt)
|
static inline void update_palette(const struct vt * const vt)
|
{
|
{
|
const unsigned long *palette_entries;
|
const unsigned long *palette_entries;
|
int i;
|
int i;
|
|
|
if (vt->vcd->screen.palette_entries || vt->vtd->vc_mode != KD_GRAPHICS)
|
if (vt->vcd->screen.palette_entries || vt->vtd->vc_mode != KD_GRAPHICS)
|
palette_entries = default_palette_entries;
|
palette_entries = default_palette_entries;
|
else
|
else
|
palette_entries = vt->vcd->screen.palette_entries;
|
palette_entries = vt->vcd->screen.palette_entries;
|
|
|
palette_setpixel(0);
|
palette_setpixel(0);
|
for (i = MAX_PIX; i > 3; i -= 4) {
|
for (i = MAX_PIX; i > 3; i -= 4) {
|
palette_write(*palette_entries++);
|
palette_write(*palette_entries++);
|
palette_write(*palette_entries++);
|
palette_write(*palette_entries++);
|
palette_write(*palette_entries++);
|
palette_write(*palette_entries++);
|
palette_write(*palette_entries++);
|
palette_write(*palette_entries++);
|
}
|
}
|
for (; i > 0; i--)
|
for (; i > 0; i--)
|
palette_write(*palette_entries++);
|
palette_write(*palette_entries++);
|
}
|
}
|
|
|
void update_scrmem (const struct vt * const vt, int start, int length)
|
void update_scrmem (const struct vt * const vt, int start, int length)
|
{
|
{
|
unsigned long p, pp, sx, sy, ex, ey;
|
unsigned long p, pp, sx, sy, ex, ey;
|
unsigned long *buffer;
|
unsigned long *buffer;
|
|
|
length += start;
|
length += start;
|
sy = start / vtdata.numcolumns;
|
sy = start / vtdata.numcolumns;
|
sx = start % vtdata.numcolumns;
|
sx = start % vtdata.numcolumns;
|
ey = length / vtdata.numcolumns;
|
ey = length / vtdata.numcolumns;
|
ex = length % vtdata.numcolumns;
|
ex = length % vtdata.numcolumns;
|
|
|
if (ey > vtdata.numrows)
|
if (ey > vtdata.numrows)
|
ey = vtdata.numrows;
|
ey = vtdata.numrows;
|
|
|
p = vt->vcd->screen.origin + sy * vtdata.screen.sizerow;
|
p = vt->vcd->screen.origin + sy * vtdata.screen.sizerow;
|
buffer = vt->vcd->buffer.buffer + start;
|
buffer = vt->vcd->buffer.buffer + start;
|
|
|
if (ey > sy) {
|
if (ey > sy) {
|
for (; sy < ey; sy++) {
|
for (; sy < ey; sy++) {
|
pp = p + sx * vtdata.screen.bytespercharh;
|
pp = p + sx * vtdata.screen.bytespercharh;
|
for (; sx < vtdata.numcolumns; sx++) {
|
for (; sx < vtdata.numcolumns; sx++) {
|
ll_write_char (pp, *buffer++);
|
ll_write_char (pp, *buffer++);
|
pp += vtdata.screen.bytespercharh;
|
pp += vtdata.screen.bytespercharh;
|
}
|
}
|
p += vtdata.screen.sizerow;
|
p += vtdata.screen.sizerow;
|
sx = 0;
|
sx = 0;
|
}
|
}
|
}
|
}
|
|
|
if (ey == sy && ex) {
|
if (ey == sy && ex) {
|
for (; sx < ex; sx++) {
|
for (; sx < ex; sx++) {
|
ll_write_char (p, *buffer++);
|
ll_write_char (p, *buffer++);
|
p += vtdata.screen.bytespercharh;
|
p += vtdata.screen.bytespercharh;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
void set_scrmem (const struct vt * const vt, long offset)
|
void set_scrmem (const struct vt * const vt, long offset)
|
{
|
{
|
unsigned long p, pp, my, by;
|
unsigned long p, pp, my, by;
|
unsigned long *buffer;
|
unsigned long *buffer;
|
|
|
p = vt->vcd->screen.origin;
|
p = vt->vcd->screen.origin;
|
buffer = vt->vcd->buffer.buffer;
|
buffer = vt->vcd->buffer.buffer;
|
|
|
by = vtdata.screen.sizerow;
|
by = vtdata.screen.sizerow;
|
for (my = vtdata.numrows; my > 0; my--) {
|
for (my = vtdata.numrows; my > 0; my--) {
|
int mx, bx = vtdata.screen.bytespercharh;
|
int mx, bx = vtdata.screen.bytespercharh;
|
pp = p;
|
pp = p;
|
mx = vtdata.numcolumns;
|
mx = vtdata.numcolumns;
|
while (mx > 8) {
|
while (mx > 8) {
|
mx -= 8;
|
mx -= 8;
|
ll_write_char (pp, *buffer++); pp += bx;
|
ll_write_char (pp, *buffer++); pp += bx;
|
ll_write_char (pp, *buffer++); pp += bx;
|
ll_write_char (pp, *buffer++); pp += bx;
|
ll_write_char (pp, *buffer++); pp += bx;
|
ll_write_char (pp, *buffer++); pp += bx;
|
ll_write_char (pp, *buffer++); pp += bx;
|
ll_write_char (pp, *buffer++); pp += bx;
|
ll_write_char (pp, *buffer++); pp += bx;
|
ll_write_char (pp, *buffer++); pp += bx;
|
ll_write_char (pp, *buffer++); pp += bx;
|
ll_write_char (pp, *buffer++); pp += bx;
|
ll_write_char (pp, *buffer++); pp += bx;
|
ll_write_char (pp, *buffer++); pp += bx;
|
ll_write_char (pp, *buffer++); pp += bx;
|
ll_write_char (pp, *buffer++); pp += bx;
|
}
|
}
|
while (mx > 0) {
|
while (mx > 0) {
|
mx -= 1;
|
mx -= 1;
|
ll_write_char (pp, *buffer++); pp += bx;
|
ll_write_char (pp, *buffer++); pp += bx;
|
}
|
}
|
p += by;
|
p += by;
|
}
|
}
|
pp = vt->vcd->screen.origin + vtdata.screen.memsize;
|
pp = vt->vcd->screen.origin + vtdata.screen.memsize;
|
memsetl((unsigned long *)p, vt->vcd->cached_backcolwrd, pp - p);
|
memsetl((unsigned long *)p, vt->vcd->cached_backcolwrd, pp - p);
|
update_palette(vt);
|
update_palette(vt);
|
}
|
}
|
|
|
/*
|
/*
|
* PIO_FONT support
|
* PIO_FONT support
|
*/
|
*/
|
int con_set_font (char *arg)
|
int con_set_font (char *arg)
|
{
|
{
|
return -EINVAL;
|
return -EINVAL;
|
}
|
}
|
|
|
int con_get_font (char *arg)
|
int con_get_font (char *arg)
|
{
|
{
|
return -EINVAL;
|
return -EINVAL;
|
}
|
}
|
|
|
void con_reset_palette (const struct vt * const vt)
|
void con_reset_palette (const struct vt * const vt)
|
{
|
{
|
}
|
}
|
|
|
void con_set_palette (const struct vt * const vt)
|
void con_set_palette (const struct vt * const vt)
|
{
|
{
|
update_palette(vt);
|
update_palette(vt);
|
}
|
}
|
|
|
/* == arm specific console code ============================================================== */
|
/* == arm specific console code ============================================================== */
|
|
|
int do_screendump(int arg)
|
int do_screendump(int arg)
|
{
|
{
|
char *buf = (char *)arg;
|
char *buf = (char *)arg;
|
int l;
|
int l;
|
if (!suser())
|
if (!suser())
|
return -EPERM;
|
return -EPERM;
|
l = verify_area (VERIFY_WRITE, buf, 2);
|
l = verify_area (VERIFY_WRITE, buf, 2);
|
if (l)
|
if (l)
|
return l;
|
return l;
|
return -ENOSYS;
|
return -ENOSYS;
|
}
|
}
|
|
|
void vcd_disallocate (struct vt *vt)
|
void vcd_disallocate (struct vt *vt)
|
{
|
{
|
if (vt->vcd && vt->vcd->buffer.kmalloced) {
|
if (vt->vcd && vt->vcd->buffer.kmalloced) {
|
vfree (vt->vcd->buffer.buffer);
|
vfree (vt->vcd->buffer.buffer);
|
vt->vcd->buffer.buffer = NULL;
|
vt->vcd->buffer.buffer = NULL;
|
vt->vcd->buffer.kmalloced = 0;
|
vt->vcd->buffer.kmalloced = 0;
|
}
|
}
|
}
|
}
|
|
|
int vcd_resize(unsigned long lines, unsigned long cols)
|
int vcd_resize(unsigned long lines, unsigned long cols)
|
{/* TODO */
|
{/* TODO */
|
return -ENOMEM;
|
return -ENOMEM;
|
}
|
}
|
|
|
void vcd_blankscreen(int nopowersave)
|
void vcd_blankscreen(int nopowersave)
|
{
|
{
|
unsigned int pix;
|
unsigned int pix;
|
|
|
/* DISABLE VIDEO */
|
/* DISABLE VIDEO */
|
palette_setpixel(0);
|
palette_setpixel(0);
|
for (pix = 0; pix < MAX_PIX; pix++)
|
for (pix = 0; pix < MAX_PIX; pix++)
|
palette_write(0);
|
palette_write(0);
|
}
|
}
|
|
|
void vcd_unblankscreen (void)
|
void vcd_unblankscreen (void)
|
{
|
{
|
update_palette(vtdata.fgconsole);
|
update_palette(vtdata.fgconsole);
|
}
|
}
|
|
|
static unsigned long old_origin;
|
static unsigned long old_origin;
|
|
|
void vcd_savestate (const struct vt *vt, int blanked)
|
void vcd_savestate (const struct vt *vt, int blanked)
|
{
|
{
|
struct con_struct *vcd = vt->vcd;
|
struct con_struct *vcd = vt->vcd;
|
clear_selection ();
|
clear_selection ();
|
vcd_removecursors (vt);
|
vcd_removecursors (vt);
|
old_origin = vt->vcd->screen.origin;
|
old_origin = vt->vcd->screen.origin;
|
|
|
if (blanked)
|
if (blanked)
|
vtdata.blanked = NULL;
|
vtdata.blanked = NULL;
|
|
|
memcpy (vcd->buffer.buffer, vtdata.buffer.buffer + vtdata.buffer.origin,
|
memcpy (vcd->buffer.buffer, vtdata.buffer.buffer + vtdata.buffer.origin,
|
vtdata.buffer.totsize << 2);
|
vtdata.buffer.totsize << 2);
|
vcd->buffer.pos -= vtdata.buffer.origin;
|
vcd->buffer.pos -= vtdata.buffer.origin;
|
vcd->driver = buffer_driver;
|
vcd->driver = buffer_driver;
|
#ifdef DEBUG
|
#ifdef DEBUG
|
vcd_validate (vt->vcd, "vcd_savestate");
|
vcd_validate (vt->vcd, "vcd_savestate");
|
#endif
|
#endif
|
}
|
}
|
|
|
void vcd_restorestate (const struct vt *vt)
|
void vcd_restorestate (const struct vt *vt)
|
{
|
{
|
struct con_struct *vcd = vt->vcd;
|
struct con_struct *vcd = vt->vcd;
|
int text_mode;
|
int text_mode;
|
/*
|
/*
|
* Reset the origin on this VT to be the same as the previous.
|
* Reset the origin on this VT to be the same as the previous.
|
* This way we don't get any jumps when we change VT's.
|
* This way we don't get any jumps when we change VT's.
|
*/
|
*/
|
text_mode = vt->vtd->vc_mode == KD_TEXT ? 1 : 0;
|
text_mode = vt->vtd->vc_mode == KD_TEXT ? 1 : 0;
|
memcpy (vtdata.buffer.buffer, vcd->buffer.buffer, vtdata.buffer.totsize << 2);
|
memcpy (vtdata.buffer.buffer, vcd->buffer.buffer, vtdata.buffer.totsize << 2);
|
vtdata.buffer.origin = 0;
|
vtdata.buffer.origin = 0;
|
if (text_mode) {
|
if (text_mode) {
|
vt->vcd->screen.origin = old_origin;
|
vt->vcd->screen.origin = old_origin;
|
set_scrmem (vt, 0);
|
set_scrmem (vt, 0);
|
} else
|
} else
|
vt->vcd->screen.origin = SCREEN2_BASE;
|
vt->vcd->screen.origin = SCREEN2_BASE;
|
vcd->driver = screen_driver;
|
vcd->driver = screen_driver;
|
gotoxy(vt->vcd, vt->vcd->curstate.x, vt->vcd->curstate.y);
|
gotoxy(vt->vcd, vt->vcd->curstate.x, vt->vcd->curstate.y);
|
#ifdef DEBUG
|
#ifdef DEBUG
|
vcd_validate (vt->vcd, "vcd_restorestate");
|
vcd_validate (vt->vcd, "vcd_restorestate");
|
#endif
|
#endif
|
set_origin(vt);
|
set_origin(vt);
|
set_cursor(vt);
|
set_cursor(vt);
|
if (text_mode)
|
if (text_mode)
|
vcd_restorecursors (vt);
|
vcd_restorecursors (vt);
|
set_leds ();
|
set_leds ();
|
}
|
}
|
|
|
void vcd_setup_graphics (const struct vt *vt)
|
void vcd_setup_graphics (const struct vt *vt)
|
{
|
{
|
clear_selection ();
|
clear_selection ();
|
vcd_removecursors (vt);
|
vcd_removecursors (vt);
|
__set_origin (vtdata.screen.memstart);
|
__set_origin (vtdata.screen.memstart);
|
}
|
}
|
|
|
/*===============================================================================================*/
|
/*===============================================================================================*/
|
|
|
static int vcd_write_utf (struct con_struct *vcd, int c)
|
static int vcd_write_utf (struct con_struct *vcd, int c)
|
{
|
{
|
/* Combine UTF-8 into Unicode */
|
/* Combine UTF-8 into Unicode */
|
/* Incomplete characters silently ignored */
|
/* Incomplete characters silently ignored */
|
if (c < 0x80) {
|
if (c < 0x80) {
|
vcd->utf_count = 0;
|
vcd->utf_count = 0;
|
return c;
|
return c;
|
}
|
}
|
|
|
if (vcd->utf_count > 0 && (c & 0xc0) == 0x80) {
|
if (vcd->utf_count > 0 && (c & 0xc0) == 0x80) {
|
vcd->utf_char = (vcd->utf_char << 6) | (c & 0x3f);
|
vcd->utf_char = (vcd->utf_char << 6) | (c & 0x3f);
|
if (--vcd->utf_count == 0)
|
if (--vcd->utf_count == 0)
|
return vcd->utf_char;
|
return vcd->utf_char;
|
else
|
else
|
return -1;
|
return -1;
|
} else {
|
} else {
|
unsigned int count, chr;
|
unsigned int count, chr;
|
if ((c & 0xe0) == 0xc0) {
|
if ((c & 0xe0) == 0xc0) {
|
count = 1;
|
count = 1;
|
chr = (c & 0x1f);
|
chr = (c & 0x1f);
|
} else if ((c & 0xf0) == 0xe0) {
|
} else if ((c & 0xf0) == 0xe0) {
|
count = 2;
|
count = 2;
|
chr = (c & 0x0f);
|
chr = (c & 0x0f);
|
} else if ((c & 0xf8) == 0xf0) {
|
} else if ((c & 0xf8) == 0xf0) {
|
count = 3;
|
count = 3;
|
chr = (c & 0x07);
|
chr = (c & 0x07);
|
} else if ((c & 0xfc) == 0xf8) {
|
} else if ((c & 0xfc) == 0xf8) {
|
count = 4;
|
count = 4;
|
chr = (c & 0x03);
|
chr = (c & 0x03);
|
} else if ((c & 0xfe) == 0xfc) {
|
} else if ((c & 0xfe) == 0xfc) {
|
count = 5;
|
count = 5;
|
chr = (c & 0x01);
|
chr = (c & 0x01);
|
} else {
|
} else {
|
count = 0;
|
count = 0;
|
chr = 0;
|
chr = 0;
|
}
|
}
|
vcd->utf_count = count;
|
vcd->utf_count = count;
|
vcd->utf_char = chr;
|
vcd->utf_char = chr;
|
return -1;
|
return -1;
|
}
|
}
|
}
|
}
|
|
|
static int vcd_write_ctrl (const struct vt *vt, unsigned int c)
|
static int vcd_write_ctrl (const struct vt *vt, unsigned int c)
|
{
|
{
|
struct con_struct *vcd = vt->vcd;
|
struct con_struct *vcd = vt->vcd;
|
/*
|
/*
|
* Control characters can be used in the _middle_
|
* Control characters can be used in the _middle_
|
* of an escape sequence.
|
* of an escape sequence.
|
*/
|
*/
|
switch (c) {
|
switch (c) {
|
case 0:
|
case 0:
|
return 0;
|
return 0;
|
case 7:
|
case 7:
|
if (vcd->bell_duration)
|
if (vcd->bell_duration)
|
vt_mksound (vcd->bell_pitch, 72, vcd->bell_duration);
|
vt_mksound (vcd->bell_pitch, 72, vcd->bell_duration);
|
return 0;
|
return 0;
|
case 8:
|
case 8:
|
if (vcd->need_wrap)
|
if (vcd->need_wrap)
|
vcd->need_wrap = 0;
|
vcd->need_wrap = 0;
|
else if (vcd->curstate.x) {
|
else if (vcd->curstate.x) {
|
vcd->curstate.x --;
|
vcd->curstate.x --;
|
if (vtdata.fgconsole == vt)
|
if (vtdata.fgconsole == vt)
|
vcd->screen.pos -= vtdata.screen.bytespercharh;
|
vcd->screen.pos -= vtdata.screen.bytespercharh;
|
vcd->buffer.pos -= 1;
|
vcd->buffer.pos -= 1;
|
vcd->need_wrap = 0;
|
vcd->need_wrap = 0;
|
}
|
}
|
return 0;
|
return 0;
|
case 9:
|
case 9:
|
if (vtdata.fgconsole == vt)
|
if (vtdata.fgconsole == vt)
|
vcd->screen.pos -= vcd->curstate.x * vtdata.screen.bytespercharh;
|
vcd->screen.pos -= vcd->curstate.x * vtdata.screen.bytespercharh;
|
vcd->buffer.pos -= vcd->curstate.x;
|
vcd->buffer.pos -= vcd->curstate.x;
|
while (vcd->curstate.x < vtdata.numcolumns - 1) {
|
while (vcd->curstate.x < vtdata.numcolumns - 1) {
|
vcd->curstate.x++;
|
vcd->curstate.x++;
|
if (vcd->tab_stop[vcd->curstate.x >> 5] & (1 << (vcd->curstate.x & 31)))
|
if (vcd->tab_stop[vcd->curstate.x >> 5] & (1 << (vcd->curstate.x & 31)))
|
break;
|
break;
|
}
|
}
|
if (vtdata.fgconsole == vt)
|
if (vtdata.fgconsole == vt)
|
vcd->screen.pos += vcd->curstate.x * vtdata.screen.bytespercharh;
|
vcd->screen.pos += vcd->curstate.x * vtdata.screen.bytespercharh;
|
vcd->buffer.pos += vcd->curstate.x;
|
vcd->buffer.pos += vcd->curstate.x;
|
return 0;
|
return 0;
|
case 10:
|
case 10:
|
case 11:
|
case 11:
|
case 12:
|
case 12:
|
if (vcd->curstate.y + 1 == vcd->bottom)
|
if (vcd->curstate.y + 1 == vcd->bottom)
|
vcd->driver.scroll_up (vcd, vcd->top, vcd->bottom, 1);
|
vcd->driver.scroll_up (vcd, vcd->top, vcd->bottom, 1);
|
else if (vcd->curstate.y < vtdata.numrows - 1) {
|
else if (vcd->curstate.y < vtdata.numrows - 1) {
|
vcd->curstate.y ++;
|
vcd->curstate.y ++;
|
if (vtdata.fgconsole == vt)
|
if (vtdata.fgconsole == vt)
|
vcd->screen.pos += vtdata.screen.sizerow;
|
vcd->screen.pos += vtdata.screen.sizerow;
|
vcd->buffer.pos += vtdata.buffer.sizerow;
|
vcd->buffer.pos += vtdata.buffer.sizerow;
|
}
|
}
|
vcd->need_wrap = 0;
|
vcd->need_wrap = 0;
|
if (!is_kbd(lnm))
|
if (!is_kbd(lnm))
|
return 0;
|
return 0;
|
case 13:
|
case 13:
|
if (vtdata.fgconsole == vt)
|
if (vtdata.fgconsole == vt)
|
vcd->screen.pos -= vcd->curstate.x * vtdata.screen.bytespercharh;
|
vcd->screen.pos -= vcd->curstate.x * vtdata.screen.bytespercharh;
|
vcd->buffer.pos -= vcd->curstate.x;
|
vcd->buffer.pos -= vcd->curstate.x;
|
vcd->curstate.x = vcd->need_wrap = 0;
|
vcd->curstate.x = vcd->need_wrap = 0;
|
return 0;
|
return 0;
|
case 14:
|
case 14:
|
vcd->curstate.flags |= FLG_CHRSET;
|
vcd->curstate.flags |= FLG_CHRSET;
|
vcd->disp_ctrl = 1;
|
vcd->disp_ctrl = 1;
|
vcd->translate = set_translate(vcd->curstate.G1_charset);
|
vcd->translate = set_translate(vcd->curstate.G1_charset);
|
return 1;
|
return 1;
|
case 15:
|
case 15:
|
vcd->curstate.flags &= ~FLG_CHRSET;
|
vcd->curstate.flags &= ~FLG_CHRSET;
|
vcd->disp_ctrl = 0;
|
vcd->disp_ctrl = 0;
|
vcd->translate = set_translate(vcd->curstate.G0_charset);
|
vcd->translate = set_translate(vcd->curstate.G0_charset);
|
return 1;
|
return 1;
|
case 24:
|
case 24:
|
case 26:
|
case 26:
|
vcd->state = ESnormal;
|
vcd->state = ESnormal;
|
return 0;
|
return 0;
|
case 27:
|
case 27:
|
vcd->state = ESesc;
|
vcd->state = ESesc;
|
return 0;
|
return 0;
|
case 127:
|
case 127:
|
/* ignored */
|
/* ignored */
|
return 0;
|
return 0;
|
case 128+27:
|
case 128+27:
|
vcd->state = ESsquare;
|
vcd->state = ESsquare;
|
return 0;
|
return 0;
|
}
|
}
|
|
|
switch(vcd->state) {
|
switch(vcd->state) {
|
case ESesc:
|
case ESesc:
|
vcd->state = ESnormal;
|
vcd->state = ESnormal;
|
switch (c) {
|
switch (c) {
|
case '[':
|
case '[':
|
vcd->state = ESsquare;
|
vcd->state = ESsquare;
|
break;
|
break;
|
case ']':
|
case ']':
|
vcd->state = ESnonstd;
|
vcd->state = ESnonstd;
|
break;
|
break;
|
case '%':
|
case '%':
|
vcd->state = ESpercent;
|
vcd->state = ESpercent;
|
break;
|
break;
|
case 'E':
|
case 'E':
|
if (vtdata.fgconsole == vt)
|
if (vtdata.fgconsole == vt)
|
vcd->screen.pos -= vcd->curstate.x * vtdata.screen.bytespercharh;
|
vcd->screen.pos -= vcd->curstate.x * vtdata.screen.bytespercharh;
|
vcd->buffer.pos -= vcd->curstate.x;
|
vcd->buffer.pos -= vcd->curstate.x;
|
vcd->curstate.x = vcd->need_wrap = 0;
|
vcd->curstate.x = vcd->need_wrap = 0;
|
case 'D':
|
case 'D':
|
if (vcd->curstate.y + 1 == vcd->bottom)
|
if (vcd->curstate.y + 1 == vcd->bottom)
|
vcd->driver.scroll_up (vcd, vcd->top, vcd->bottom, 1);
|
vcd->driver.scroll_up (vcd, vcd->top, vcd->bottom, 1);
|
else if (vcd->curstate.y < vtdata.numrows - 1) {
|
else if (vcd->curstate.y < vtdata.numrows - 1) {
|
vcd->curstate.y ++;
|
vcd->curstate.y ++;
|
if (vtdata.fgconsole == vt)
|
if (vtdata.fgconsole == vt)
|
vcd->screen.pos += vtdata.screen.sizerow;
|
vcd->screen.pos += vtdata.screen.sizerow;
|
vcd->buffer.pos += vtdata.buffer.sizerow;
|
vcd->buffer.pos += vtdata.buffer.sizerow;
|
}
|
}
|
/* vcd->need_wrap = 0; why should we reset this when the x position is the same? */
|
/* vcd->need_wrap = 0; why should we reset this when the x position is the same? */
|
break;
|
break;
|
case 'M':
|
case 'M':
|
if (vcd->curstate.y == vcd->top)
|
if (vcd->curstate.y == vcd->top)
|
vcd->driver.scroll_down (vcd, vcd->top, vcd->bottom, 1);
|
vcd->driver.scroll_down (vcd, vcd->top, vcd->bottom, 1);
|
else if (vcd->curstate.y > 0) {
|
else if (vcd->curstate.y > 0) {
|
vcd->curstate.y --;
|
vcd->curstate.y --;
|
if (vtdata.fgconsole == vt)
|
if (vtdata.fgconsole == vt)
|
vcd->screen.pos -= vtdata.screen.sizerow;
|
vcd->screen.pos -= vtdata.screen.sizerow;
|
vcd->buffer.pos -= vtdata.buffer.sizerow;
|
vcd->buffer.pos -= vtdata.buffer.sizerow;
|
}
|
}
|
/* vcd->need_wrap = 0; why should we reset this when the x position is the same? */
|
/* vcd->need_wrap = 0; why should we reset this when the x position is the same? */
|
break;
|
break;
|
case 'H':
|
case 'H':
|
vcd->tab_stop[vcd->curstate.x >> 5] |= (1 << (vcd->curstate.x & 31));
|
vcd->tab_stop[vcd->curstate.x >> 5] |= (1 << (vcd->curstate.x & 31));
|
break;
|
break;
|
case 'Z':
|
case 'Z':
|
respond_ID (*vt->tty);
|
respond_ID (*vt->tty);
|
break;
|
break;
|
case '7':
|
case '7':
|
vcd->savedstate = vcd->curstate;
|
vcd->savedstate = vcd->curstate;
|
break;
|
break;
|
case '8':
|
case '8':
|
vcd->curstate = vcd->savedstate;
|
vcd->curstate = vcd->savedstate;
|
gotoxy(vt->vcd, vt->vcd->curstate.x, vt->vcd->curstate.y);
|
gotoxy(vt->vcd, vt->vcd->curstate.x, vt->vcd->curstate.y);
|
update_attr (vt);
|
update_attr (vt);
|
return 1;
|
return 1;
|
case '(':
|
case '(':
|
vcd->state = ESsetG0;
|
vcd->state = ESsetG0;
|
break;
|
break;
|
case ')':
|
case ')':
|
vcd->state = ESsetG1;
|
vcd->state = ESsetG1;
|
break;
|
break;
|
case '#':
|
case '#':
|
vcd->state = EShash;
|
vcd->state = EShash;
|
break;
|
break;
|
case 'c':
|
case 'c':
|
reset_terminal (vt, 0);
|
reset_terminal (vt, 0);
|
break;
|
break;
|
case '>': /* Numeric keypad */
|
case '>': /* Numeric keypad */
|
clr_kbd (kbdapplic);
|
clr_kbd (kbdapplic);
|
break;
|
break;
|
case '=': /* Appl. keypad */
|
case '=': /* Appl. keypad */
|
set_kbd (kbdapplic);
|
set_kbd (kbdapplic);
|
break;
|
break;
|
}
|
}
|
return 0;
|
return 0;
|
case ESnonstd:
|
case ESnonstd:
|
vcd->state = ESnormal;
|
vcd->state = ESnormal;
|
switch (c) {
|
switch (c) {
|
case 'P': /* palette escape sequence */
|
case 'P': /* palette escape sequence */
|
for (vcd->npar = 0; vcd->npar < NPAR; vcd->npar++)
|
for (vcd->npar = 0; vcd->npar < NPAR; vcd->npar++)
|
vcd->par[vcd->npar] = 0;
|
vcd->par[vcd->npar] = 0;
|
vcd->npar = 0 ;
|
vcd->npar = 0 ;
|
vcd->state = ESpalette;
|
vcd->state = ESpalette;
|
return 0;
|
return 0;
|
case 'R': /* reset palette */
|
case 'R': /* reset palette */
|
con_reset_palette (vt);
|
con_reset_palette (vt);
|
default:
|
default:
|
return 0;
|
return 0;
|
}
|
}
|
case ESpalette:
|
case ESpalette:
|
if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) {
|
if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) {
|
vcd->par[vcd->npar++] = (c > '9' ? (c & 0xDF) - 'A' + 10 : c - '0');
|
vcd->par[vcd->npar++] = (c > '9' ? (c & 0xDF) - 'A' + 10 : c - '0');
|
if (vcd->npar == 7) {
|
if (vcd->npar == 7) {
|
#if TODO
|
#if TODO
|
int i = par[0]*3, j = 1;
|
int i = par[0]*3, j = 1;
|
palette[i] = 16*par[j++];
|
palette[i] = 16*par[j++];
|
palette[i++] += par[j++];
|
palette[i++] += par[j++];
|
palette[i] = 16*par[j++];
|
palette[i] = 16*par[j++];
|
palette[i++] += par[j++];
|
palette[i++] += par[j++];
|
palette[i] = 16*par[j++];
|
palette[i] = 16*par[j++];
|
palette[i++] += par[j];
|
palette[i++] += par[j];
|
#endif
|
#endif
|
con_set_palette (vt);
|
con_set_palette (vt);
|
vcd->state = ESnormal;
|
vcd->state = ESnormal;
|
}
|
}
|
} else
|
} else
|
vcd->state = ESnormal;
|
vcd->state = ESnormal;
|
return 0;
|
return 0;
|
case ESsquare:
|
case ESsquare:
|
for (vcd->npar = 0; vcd->npar < NPAR; vcd->npar++)
|
for (vcd->npar = 0; vcd->npar < NPAR; vcd->npar++)
|
vcd->par[vcd->npar] = 0;
|
vcd->par[vcd->npar] = 0;
|
vcd->npar = 0;
|
vcd->npar = 0;
|
vcd->state = ESgetpars;
|
vcd->state = ESgetpars;
|
if (c == '[') { /* Function key */
|
if (c == '[') { /* Function key */
|
vcd->state = ESfunckey;
|
vcd->state = ESfunckey;
|
return 0;
|
return 0;
|
}
|
}
|
|
|
vcd->ques = (c == '?');
|
vcd->ques = (c == '?');
|
if (vcd->ques)
|
if (vcd->ques)
|
return 0;
|
return 0;
|
case ESgetpars:
|
case ESgetpars:
|
if (c == ';' && vcd->npar < NPAR - 1) {
|
if (c == ';' && vcd->npar < NPAR - 1) {
|
vcd->npar ++;
|
vcd->npar ++;
|
return 0;
|
return 0;
|
} else
|
} else
|
if (c >= '0' && c <= '9') {
|
if (c >= '0' && c <= '9') {
|
vcd->par[vcd->npar] = vcd->par[vcd->npar] * 10 + c - '0';
|
vcd->par[vcd->npar] = vcd->par[vcd->npar] * 10 + c - '0';
|
return 0;
|
return 0;
|
} else
|
} else
|
vcd->state = ESgotpars;
|
vcd->state = ESgotpars;
|
case ESgotpars:
|
case ESgotpars:
|
vcd->state=ESnormal;
|
vcd->state=ESnormal;
|
switch (c) {
|
switch (c) {
|
case 'h':
|
case 'h':
|
set_mode(vt, 1);
|
set_mode(vt, 1);
|
return 0;
|
return 0;
|
case 'l':
|
case 'l':
|
set_mode(vt, 0);
|
set_mode(vt, 0);
|
return 0;
|
return 0;
|
case 'n':
|
case 'n':
|
if (!vcd->ques) {
|
if (!vcd->ques) {
|
if (vcd->par[0] == 5)
|
if (vcd->par[0] == 5)
|
status_report (*vt->tty);
|
status_report (*vt->tty);
|
else
|
else
|
if (vcd->par[0] == 6)
|
if (vcd->par[0] == 6)
|
cursor_report (vt);
|
cursor_report (vt);
|
}
|
}
|
return 0;
|
return 0;
|
}
|
}
|
if (vcd->ques) {
|
if (vcd->ques) {
|
vcd->ques = 0;
|
vcd->ques = 0;
|
return 0;
|
return 0;
|
}
|
}
|
switch(c) {
|
switch(c) {
|
case 'G':
|
case 'G':
|
case '`':
|
case '`':
|
if (vcd->par[0])
|
if (vcd->par[0])
|
vcd->par[0]--;
|
vcd->par[0]--;
|
gotoxy (vcd, vcd->par[0], vcd->curstate.y);
|
gotoxy (vcd, vcd->par[0], vcd->curstate.y);
|
return 0;
|
return 0;
|
case 'A':
|
case 'A':
|
if (!vcd->par[0])
|
if (!vcd->par[0])
|
vcd->par[0]++;
|
vcd->par[0]++;
|
gotoxy (vcd, vcd->curstate.x, vcd->curstate.y - vcd->par[0]);
|
gotoxy (vcd, vcd->curstate.x, vcd->curstate.y - vcd->par[0]);
|
return 0;
|
return 0;
|
case 'B':
|
case 'B':
|
case 'e':
|
case 'e':
|
if (!vcd->par[0])
|
if (!vcd->par[0])
|
vcd->par[0]++;
|
vcd->par[0]++;
|
gotoxy (vcd, vcd->curstate.x, vcd->curstate.y + vcd->par[0]);
|
gotoxy (vcd, vcd->curstate.x, vcd->curstate.y + vcd->par[0]);
|
return 0;
|
return 0;
|
case 'C':
|
case 'C':
|
case 'a':
|
case 'a':
|
if (!vcd->par[0])
|
if (!vcd->par[0])
|
vcd->par[0]++;
|
vcd->par[0]++;
|
gotoxy (vcd, vcd->curstate.x + vcd->par[0], vcd->curstate.y);
|
gotoxy (vcd, vcd->curstate.x + vcd->par[0], vcd->curstate.y);
|
return 0;
|
return 0;
|
case 'D':
|
case 'D':
|
if (!vcd->par[0])
|
if (!vcd->par[0])
|
vcd->par[0]++;
|
vcd->par[0]++;
|
gotoxy (vcd, vcd->curstate.x - vcd->par[0], vcd->curstate.y);
|
gotoxy (vcd, vcd->curstate.x - vcd->par[0], vcd->curstate.y);
|
return 0;
|
return 0;
|
case 'E':
|
case 'E':
|
if (!vcd->par[0])
|
if (!vcd->par[0])
|
vcd->par[0]++;
|
vcd->par[0]++;
|
gotoxy (vcd, 0, vcd->curstate.y + vcd->par[0]);
|
gotoxy (vcd, 0, vcd->curstate.y + vcd->par[0]);
|
return 0;
|
return 0;
|
case 'F':
|
case 'F':
|
if (!vcd->par[0])
|
if (!vcd->par[0])
|
vcd->par[0]++;
|
vcd->par[0]++;
|
gotoxy (vcd, 0, vcd->curstate.y - vcd->par[0]);
|
gotoxy (vcd, 0, vcd->curstate.y - vcd->par[0]);
|
return 0;
|
return 0;
|
case 'd':
|
case 'd':
|
if (vcd->par[0])
|
if (vcd->par[0])
|
vcd->par[0]--;
|
vcd->par[0]--;
|
gotoxay (vcd, vcd->curstate.x, vcd->par[0]);
|
gotoxay (vcd, vcd->curstate.x, vcd->par[0]);
|
return 0;
|
return 0;
|
case 'H':
|
case 'H':
|
case 'f':
|
case 'f':
|
if (vcd->par[0])
|
if (vcd->par[0])
|
vcd->par[0]--;
|
vcd->par[0]--;
|
if (vcd->par[1])
|
if (vcd->par[1])
|
vcd->par[1]--;
|
vcd->par[1]--;
|
gotoxay (vcd, vcd->par[1], vcd->par[0]);
|
gotoxay (vcd, vcd->par[1], vcd->par[0]);
|
return 0;
|
return 0;
|
case 'J':
|
case 'J':
|
csi_J (vt, vcd->par[0]);
|
csi_J (vt, vcd->par[0]);
|
return 0;
|
return 0;
|
case 'K':
|
case 'K':
|
csi_K (vt, vcd->par[0]);
|
csi_K (vt, vcd->par[0]);
|
return 0;
|
return 0;
|
case 'L':
|
case 'L':
|
csi_L (vt, vcd->par[0]);
|
csi_L (vt, vcd->par[0]);
|
return 0;
|
return 0;
|
case 'M':
|
case 'M':
|
csi_M (vt, vcd->par[0]);
|
csi_M (vt, vcd->par[0]);
|
return 0;
|
return 0;
|
case 'P':
|
case 'P':
|
csi_P (vt, vcd->par[0]);
|
csi_P (vt, vcd->par[0]);
|
return 0;
|
return 0;
|
case 'c':
|
case 'c':
|
if (!vcd->par[0])
|
if (!vcd->par[0])
|
respond_ID(*vt->tty);
|
respond_ID(*vt->tty);
|
return 0;
|
return 0;
|
case 'g':
|
case 'g':
|
if (!vcd->par[0])
|
if (!vcd->par[0])
|
vcd->tab_stop[vcd->curstate.x >> 5] &= ~(1 << (vcd->curstate.x & 31));
|
vcd->tab_stop[vcd->curstate.x >> 5] &= ~(1 << (vcd->curstate.x & 31));
|
else
|
else
|
if (vcd->par[0] == 3) {
|
if (vcd->par[0] == 3) {
|
vcd->tab_stop[0] =
|
vcd->tab_stop[0] =
|
vcd->tab_stop[1] =
|
vcd->tab_stop[1] =
|
vcd->tab_stop[2] =
|
vcd->tab_stop[2] =
|
vcd->tab_stop[3] =
|
vcd->tab_stop[3] =
|
vcd->tab_stop[4] = 0;
|
vcd->tab_stop[4] = 0;
|
}
|
}
|
return 0;
|
return 0;
|
case 'm':
|
case 'm':
|
return csi_m (vt);
|
return csi_m (vt);
|
case 'q': /* DECLL - but only 3 leds */
|
case 'q': /* DECLL - but only 3 leds */
|
/* map 0,1,2,3 to 0,1,2,4 */
|
/* map 0,1,2,3 to 0,1,2,4 */
|
if (vcd->par[0] < 4)
|
if (vcd->par[0] < 4)
|
setledstate(vt->kbd, (vcd->par[0] < 3 ? vcd->par[0] : 4));
|
setledstate(vt->kbd, (vcd->par[0] < 3 ? vcd->par[0] : 4));
|
return 0;
|
return 0;
|
case 'r':
|
case 'r':
|
if (!vcd->par[0])
|
if (!vcd->par[0])
|
vcd->par[0]++;
|
vcd->par[0]++;
|
if (!vcd->par[1])
|
if (!vcd->par[1])
|
vcd->par[1] = vtdata.numrows;
|
vcd->par[1] = vtdata.numrows;
|
if (vcd->par[0] < vcd->par[1] && vcd->par[1] <= vtdata.numrows) {
|
if (vcd->par[0] < vcd->par[1] && vcd->par[1] <= vtdata.numrows) {
|
vcd->top = vcd->par[0] - 1;
|
vcd->top = vcd->par[0] - 1;
|
vcd->bottom = vcd->par[1];
|
vcd->bottom = vcd->par[1];
|
gotoxay (vcd, 0, 0);
|
gotoxay (vcd, 0, 0);
|
}
|
}
|
return 0;
|
return 0;
|
case 's':
|
case 's':
|
vcd->savedstate = vcd->curstate;
|
vcd->savedstate = vcd->curstate;
|
return 0;
|
return 0;
|
case 'u':
|
case 'u':
|
vcd->curstate = vcd->savedstate;
|
vcd->curstate = vcd->savedstate;
|
update_attr (vt);
|
update_attr (vt);
|
return 1;
|
return 1;
|
case 'X':
|
case 'X':
|
csi_X (vt, vcd->par[0]);
|
csi_X (vt, vcd->par[0]);
|
return 0;
|
return 0;
|
case '@':
|
case '@':
|
csi_at (vt, vcd->par[0]);
|
csi_at (vt, vcd->par[0]);
|
return 0;
|
return 0;
|
case ']': /* setterm functions */
|
case ']': /* setterm functions */
|
setterm_command (vt);
|
setterm_command (vt);
|
return 0;
|
return 0;
|
}
|
}
|
return 0;
|
return 0;
|
case ESpercent:
|
case ESpercent:
|
vcd->state = ESnormal;
|
vcd->state = ESnormal;
|
switch (c) {
|
switch (c) {
|
case '@': /* defined in ISO 2022 */
|
case '@': /* defined in ISO 2022 */
|
vcd->utf = 0;
|
vcd->utf = 0;
|
return 0;
|
return 0;
|
case 'G': /* prelim official escape code */
|
case 'G': /* prelim official escape code */
|
case '8': /* retained for compatibility */
|
case '8': /* retained for compatibility */
|
vcd->utf = 1;
|
vcd->utf = 1;
|
return 0;
|
return 0;
|
}
|
}
|
return 0;
|
return 0;
|
case ESfunckey:
|
case ESfunckey:
|
vcd->state = ESnormal;
|
vcd->state = ESnormal;
|
return 0;
|
return 0;
|
case EShash:
|
case EShash:
|
vcd->state = ESnormal;
|
vcd->state = ESnormal;
|
if (c == '8') {
|
if (c == '8') {
|
/* DEC screen alignment test. kludge :-) */
|
/* DEC screen alignment test. kludge :-) */
|
}
|
}
|
return 0;
|
return 0;
|
case ESsetG0:
|
case ESsetG0:
|
vcd->state = ESnormal;
|
vcd->state = ESnormal;
|
if (c == '0')
|
if (c == '0')
|
vcd->curstate.G0_charset = GRAF_MAP;
|
vcd->curstate.G0_charset = GRAF_MAP;
|
else
|
else
|
if (c == 'B')
|
if (c == 'B')
|
vcd->curstate.G0_charset = LAT1_MAP;
|
vcd->curstate.G0_charset = LAT1_MAP;
|
else
|
else
|
if (c == 'U')
|
if (c == 'U')
|
vcd->curstate.G0_charset = IBMPC_MAP;
|
vcd->curstate.G0_charset = IBMPC_MAP;
|
else
|
else
|
if (c == 'K')
|
if (c == 'K')
|
vcd->curstate.G0_charset = USER_MAP;
|
vcd->curstate.G0_charset = USER_MAP;
|
if ((vcd->curstate.flags & FLG_CHRSET) == 0) {
|
if ((vcd->curstate.flags & FLG_CHRSET) == 0) {
|
vcd->translate = set_translate(vcd->curstate.G0_charset);
|
vcd->translate = set_translate(vcd->curstate.G0_charset);
|
return 1;
|
return 1;
|
}
|
}
|
return 0;
|
return 0;
|
case ESsetG1:
|
case ESsetG1:
|
vcd->state = ESnormal;
|
vcd->state = ESnormal;
|
if (c == '0')
|
if (c == '0')
|
vcd->curstate.G1_charset = GRAF_MAP;
|
vcd->curstate.G1_charset = GRAF_MAP;
|
else
|
else
|
if (c == 'B')
|
if (c == 'B')
|
vcd->curstate.G1_charset = LAT1_MAP;
|
vcd->curstate.G1_charset = LAT1_MAP;
|
else
|
else
|
if (c == 'U')
|
if (c == 'U')
|
vcd->curstate.G1_charset = IBMPC_MAP;
|
vcd->curstate.G1_charset = IBMPC_MAP;
|
else
|
else
|
if (c == 'K')
|
if (c == 'K')
|
vcd->curstate.G1_charset = USER_MAP;
|
vcd->curstate.G1_charset = USER_MAP;
|
if (vcd->curstate.flags & FLG_CHRSET) {
|
if (vcd->curstate.flags & FLG_CHRSET) {
|
vcd->translate = set_translate(vcd->curstate.G1_charset);
|
vcd->translate = set_translate(vcd->curstate.G1_charset);
|
return 1;
|
return 1;
|
}
|
}
|
return 0;
|
return 0;
|
default:
|
default:
|
vcd->state = ESnormal;
|
vcd->state = ESnormal;
|
}
|
}
|
return 0;
|
return 0;
|
}
|
}
|
|
|
static inline void vcd_write_char (struct con_struct *vcd, unsigned int c)
|
static inline void vcd_write_char (struct con_struct *vcd, unsigned int c)
|
{
|
{
|
if (c & ~console_charmask)
|
if (c & ~console_charmask)
|
return;
|
return;
|
vcd->driver.write_char (vcd, vcd->combined_state | (c & 255));
|
vcd->driver.write_char (vcd, vcd->combined_state | (c & 255));
|
}
|
}
|
|
|
int vcd_write (const struct vt *vt, int from_user, const unsigned char *buf, int count)
|
int vcd_write (const struct vt *vt, int from_user, const unsigned char *buf, int count)
|
{
|
{
|
int strt_count = count;
|
int strt_count = count;
|
unsigned short *cached_trans;
|
unsigned short *cached_trans;
|
unsigned int cached_ctrls;
|
unsigned int cached_ctrls;
|
register struct con_struct *vcd;
|
register struct con_struct *vcd;
|
|
|
if (from_user && get_fs () == KERNEL_DS)
|
if (from_user && get_fs () == KERNEL_DS)
|
from_user = 0;
|
from_user = 0;
|
|
|
vcd = vt->vcd;
|
vcd = vt->vcd;
|
|
|
#ifdef DEBUG
|
#ifdef DEBUG
|
vcd_validate (vcd, "vcd_write entry");
|
vcd_validate (vcd, "vcd_write entry");
|
#endif
|
#endif
|
|
|
vcd_removecursors (vt);
|
vcd_removecursors (vt);
|
if (vt == vtdata.select.vt)
|
if (vt == vtdata.select.vt)
|
clear_selection();
|
clear_selection();
|
|
|
disable_bh (CONSOLE_BH);
|
disable_bh (CONSOLE_BH);
|
recache:
|
recache:
|
cached_ctrls = vcd->disp_ctrl ? CTRL_ALWAYS : CTRL_ACTION;
|
cached_ctrls = vcd->disp_ctrl ? CTRL_ALWAYS : CTRL_ACTION;
|
cached_trans = vcd->translate + (vcd->toggle_meta ? 0x80 : 0);
|
cached_trans = vcd->translate + (vcd->toggle_meta ? 0x80 : 0);
|
|
|
while (!(*vt->tty)->stopped && count) {
|
while (!(*vt->tty)->stopped && count) {
|
int tc, c;
|
int tc, c;
|
enable_bh(CONSOLE_BH);
|
enable_bh(CONSOLE_BH);
|
__asm__("teq %3, #0
|
__asm__("teq %3, #0
|
ldreqb %0, [%1], #1
|
ldreqb %0, [%1], #1
|
ldrnebt %0, [%1], #1" : "=r" (c), "=&r" (buf) : "1" (buf), "r" (from_user));
|
ldrnebt %0, [%1], #1" : "=r" (c), "=&r" (buf) : "1" (buf), "r" (from_user));
|
disable_bh(CONSOLE_BH);
|
disable_bh(CONSOLE_BH);
|
count --;
|
count --;
|
|
|
if (vcd->utf) {
|
if (vcd->utf) {
|
if ((tc = vcd_write_utf (vcd, c)) < 0)
|
if ((tc = vcd_write_utf (vcd, c)) < 0)
|
continue;
|
continue;
|
c = tc;
|
c = tc;
|
} else
|
} else
|
tc = cached_trans[c];
|
tc = cached_trans[c];
|
|
|
if (vcd->state == ESnormal && tc && (c != 127 || vcd->disp_ctrl) && (c != 128+27)) {
|
if (vcd->state == ESnormal && tc && (c != 127 || vcd->disp_ctrl) && (c != 128+27)) {
|
if (c >= 32 || (!vcd->utf && !(cached_ctrls & (1 << c)))) { /* ok */
|
if (c >= 32 || (!vcd->utf && !(cached_ctrls & (1 << c)))) { /* ok */
|
tc = conv_uni_to_pc (tc);
|
tc = conv_uni_to_pc (tc);
|
if (tc == -4)
|
if (tc == -4)
|
/* If we got -4 (not found) then see if we have
|
/* If we got -4 (not found) then see if we have
|
defined a replacement character (U+FFFD) */
|
defined a replacement character (U+FFFD) */
|
tc = conv_uni_to_pc (0xfffd);
|
tc = conv_uni_to_pc (0xfffd);
|
else if (tc == -3)
|
else if (tc == -3)
|
/* Bad hash table -- hope for the best */
|
/* Bad hash table -- hope for the best */
|
tc = c;
|
tc = c;
|
|
|
vcd_write_char (vcd, tc);
|
vcd_write_char (vcd, tc);
|
continue;
|
continue;
|
}
|
}
|
}
|
}
|
|
|
if (vcd_write_ctrl (vt, c))
|
if (vcd_write_ctrl (vt, c))
|
goto recache;
|
goto recache;
|
else
|
else
|
continue;
|
continue;
|
}
|
}
|
if (vt->vtd->vc_mode != KD_GRAPHICS)
|
if (vt->vtd->vc_mode != KD_GRAPHICS)
|
set_cursor (vt);
|
set_cursor (vt);
|
vcd_restorecursors (vt);
|
vcd_restorecursors (vt);
|
enable_bh(CONSOLE_BH);
|
enable_bh(CONSOLE_BH);
|
#ifdef DEBUG
|
#ifdef DEBUG
|
vcd_validate (vcd, "vcd_write exit");
|
vcd_validate (vcd, "vcd_write exit");
|
#endif
|
#endif
|
return strt_count - count;
|
return strt_count - count;
|
}
|
}
|
|
|
int vcd_ioctl (const struct vt *vt, int cmd, unsigned long arg)
|
int vcd_ioctl (const struct vt *vt, int cmd, unsigned long arg)
|
{
|
{
|
int i;
|
int i;
|
switch (cmd) {
|
switch (cmd) {
|
case VT_GETPALETTE: {
|
case VT_GETPALETTE: {
|
unsigned long pix, num, *ptr;
|
unsigned long pix, num, *ptr;
|
const unsigned long *entries;
|
const unsigned long *entries;
|
|
|
ptr = (unsigned long *)arg;
|
ptr = (unsigned long *)arg;
|
|
|
if ((i = verify_area (VERIFY_READ, ptr, 12)) != 0)
|
if ((i = verify_area (VERIFY_READ, ptr, 12)) != 0)
|
return i;
|
return i;
|
|
|
pix = get_user (ptr);
|
pix = get_user (ptr);
|
num = get_user (ptr + 1);
|
num = get_user (ptr + 1);
|
if (!num)
|
if (!num)
|
return 0;
|
return 0;
|
if (pix > 255 || pix + num > 256)
|
if (pix > 255 || pix + num > 256)
|
return -EINVAL;
|
return -EINVAL;
|
|
|
ptr = (unsigned long *) get_user (ptr + 2);
|
ptr = (unsigned long *) get_user (ptr + 2);
|
if ((i = verify_area (VERIFY_WRITE, ptr, num * sizeof (unsigned long))) != 0)
|
if ((i = verify_area (VERIFY_WRITE, ptr, num * sizeof (unsigned long))) != 0)
|
return i;
|
return i;
|
|
|
if (vt->vcd->screen.palette_entries)
|
if (vt->vcd->screen.palette_entries)
|
entries = vt->vcd->screen.palette_entries + pix;
|
entries = vt->vcd->screen.palette_entries + pix;
|
else
|
else
|
entries = default_palette_entries + pix;
|
entries = default_palette_entries + pix;
|
memcpy_tofs(ptr, entries, num * sizeof (unsigned long));
|
memcpy_tofs(ptr, entries, num * sizeof (unsigned long));
|
return 0;
|
return 0;
|
}
|
}
|
case VT_SETPALETTE: {
|
case VT_SETPALETTE: {
|
unsigned long pix, num, *ptr, *sval;
|
unsigned long pix, num, *ptr, *sval;
|
|
|
ptr = (unsigned long *)arg;
|
ptr = (unsigned long *)arg;
|
|
|
if ((i = verify_area (VERIFY_READ, ptr, 12)) != 0)
|
if ((i = verify_area (VERIFY_READ, ptr, 12)) != 0)
|
return i;
|
return i;
|
|
|
pix = get_user (ptr);
|
pix = get_user (ptr);
|
num = get_user (ptr + 1);
|
num = get_user (ptr + 1);
|
if (!num)
|
if (!num)
|
return 0;
|
return 0;
|
if (pix > 255 || pix + num > 256)
|
if (pix > 255 || pix + num > 256)
|
return -EINVAL;
|
return -EINVAL;
|
|
|
ptr = (unsigned long *) get_user (ptr + 2);
|
ptr = (unsigned long *) get_user (ptr + 2);
|
if ((i = verify_area (VERIFY_READ, ptr, num * sizeof (unsigned long))) != 0)
|
if ((i = verify_area (VERIFY_READ, ptr, num * sizeof (unsigned long))) != 0)
|
return i;
|
return i;
|
|
|
if (!vt->vcd->screen.palette_entries) {
|
if (!vt->vcd->screen.palette_entries) {
|
void *entries;
|
void *entries;
|
entries = kmalloc (sizeof (unsigned long) * 256, GFP_KERNEL);
|
entries = kmalloc (sizeof (unsigned long) * 256, GFP_KERNEL);
|
if (!vt->vcd->screen.palette_entries) {
|
if (!vt->vcd->screen.palette_entries) {
|
if (!entries)
|
if (!entries)
|
return -ENOMEM;
|
return -ENOMEM;
|
memcpy (entries, default_palette_entries, 256 * sizeof (unsigned long));
|
memcpy (entries, default_palette_entries, 256 * sizeof (unsigned long));
|
vt->vcd->screen.palette_entries = entries;
|
vt->vcd->screen.palette_entries = entries;
|
}
|
}
|
}
|
}
|
sval = vt->vcd->screen.palette_entries + pix;
|
sval = vt->vcd->screen.palette_entries + pix;
|
memcpy_fromfs (sval, ptr, num * sizeof (unsigned long));
|
memcpy_fromfs (sval, ptr, num * sizeof (unsigned long));
|
palette_setpixel(pix);
|
palette_setpixel(pix);
|
for (i = num; i > 3; i -= 4) {
|
for (i = num; i > 3; i -= 4) {
|
palette_write (*sval++);
|
palette_write (*sval++);
|
palette_write (*sval++);
|
palette_write (*sval++);
|
palette_write (*sval++);
|
palette_write (*sval++);
|
palette_write (*sval++);
|
palette_write (*sval++);
|
}
|
}
|
if (i & 2) {
|
if (i & 2) {
|
palette_write (*sval++);
|
palette_write (*sval++);
|
palette_write (*sval++);
|
palette_write (*sval++);
|
}
|
}
|
if (i & 1)
|
if (i & 1)
|
palette_write (*sval++);
|
palette_write (*sval++);
|
return 0;
|
return 0;
|
}
|
}
|
|
|
case PIO_FONT:
|
case PIO_FONT:
|
if (vt->vtd->vc_mode != KD_TEXT)
|
if (vt->vtd->vc_mode != KD_TEXT)
|
return -EINVAL;
|
return -EINVAL;
|
return con_set_font((char *)arg);
|
return con_set_font((char *)arg);
|
/* con_set_font() defined in console.c */
|
/* con_set_font() defined in console.c */
|
|
|
case GIO_FONT:
|
case GIO_FONT:
|
if (vt->vtd->vc_mode != KD_TEXT)
|
if (vt->vtd->vc_mode != KD_TEXT)
|
return -EINVAL;
|
return -EINVAL;
|
return con_get_font((char *)arg);
|
return con_get_font((char *)arg);
|
/* con_get_font() defined in console.c */
|
/* con_get_font() defined in console.c */
|
|
|
case PIO_SCRNMAP:
|
case PIO_SCRNMAP:
|
return con_set_trans_old ((char *)arg);
|
return con_set_trans_old ((char *)arg);
|
|
|
case GIO_SCRNMAP:
|
case GIO_SCRNMAP:
|
return con_get_trans_old((char *)arg);
|
return con_get_trans_old((char *)arg);
|
|
|
case PIO_UNISCRNMAP:
|
case PIO_UNISCRNMAP:
|
return con_set_trans_new((short *)arg);
|
return con_set_trans_new((short *)arg);
|
|
|
case GIO_UNISCRNMAP:
|
case GIO_UNISCRNMAP:
|
return con_get_trans_new((short *)arg);
|
return con_get_trans_new((short *)arg);
|
|
|
case PIO_UNIMAPCLR: {
|
case PIO_UNIMAPCLR: {
|
struct unimapinit ui;
|
struct unimapinit ui;
|
|
|
i = verify_area(VERIFY_READ, (void *)arg, sizeof(struct unimapinit));
|
i = verify_area(VERIFY_READ, (void *)arg, sizeof(struct unimapinit));
|
if (i)
|
if (i)
|
return i;
|
return i;
|
memcpy_fromfs(&ui, (void *)arg, sizeof(struct unimapinit));
|
memcpy_fromfs(&ui, (void *)arg, sizeof(struct unimapinit));
|
con_clear_unimap(&ui);
|
con_clear_unimap(&ui);
|
return 0;
|
return 0;
|
}
|
}
|
|
|
case PIO_UNIMAP: {
|
case PIO_UNIMAP: {
|
i = verify_area(VERIFY_READ, (void *)arg, sizeof(struct unimapdesc));
|
i = verify_area(VERIFY_READ, (void *)arg, sizeof(struct unimapdesc));
|
if (i == 0) {
|
if (i == 0) {
|
struct unimapdesc *ud;
|
struct unimapdesc *ud;
|
u_short ct;
|
u_short ct;
|
struct unipair *list;
|
struct unipair *list;
|
|
|
ud = (struct unimapdesc *) arg;
|
ud = (struct unimapdesc *) arg;
|
ct = get_fs_word(&ud->entry_ct);
|
ct = get_fs_word(&ud->entry_ct);
|
list = (struct unipair *) get_fs_long(&ud->entries);
|
list = (struct unipair *) get_fs_long(&ud->entries);
|
|
|
i = verify_area(VERIFY_READ, (void *) list,
|
i = verify_area(VERIFY_READ, (void *) list,
|
ct*sizeof(struct unipair));
|
ct*sizeof(struct unipair));
|
if (!i)
|
if (!i)
|
return con_set_unimap(ct, list);
|
return con_set_unimap(ct, list);
|
}
|
}
|
return i;
|
return i;
|
}
|
}
|
|
|
case GIO_UNIMAP: {
|
case GIO_UNIMAP: {
|
i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct unimapdesc));
|
i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct unimapdesc));
|
if (i == 0) {
|
if (i == 0) {
|
struct unimapdesc *ud;
|
struct unimapdesc *ud;
|
u_short ct;
|
u_short ct;
|
struct unipair *list;
|
struct unipair *list;
|
|
|
ud = (struct unimapdesc *) arg;
|
ud = (struct unimapdesc *) arg;
|
ct = get_fs_word(&ud->entry_ct);
|
ct = get_fs_word(&ud->entry_ct);
|
list = (struct unipair *) get_fs_long(&ud->entries);
|
list = (struct unipair *) get_fs_long(&ud->entries);
|
if (ct)
|
if (ct)
|
i = verify_area(VERIFY_WRITE, (void *) list,
|
i = verify_area(VERIFY_WRITE, (void *) list,
|
ct*sizeof(struct unipair));
|
ct*sizeof(struct unipair));
|
if (!i)
|
if (!i)
|
return con_get_unimap(ct, &(ud->entry_ct), list);
|
return con_get_unimap(ct, &(ud->entry_ct), list);
|
}
|
}
|
return i;
|
return i;
|
}
|
}
|
|
|
default:
|
default:
|
return -ENOIOCTLCMD;
|
return -ENOIOCTLCMD;
|
}
|
}
|
}
|
}
|
|
|
void console_print(const char *b)
|
void console_print(const char *b)
|
{
|
{
|
static int printing = 0;
|
static int printing = 0;
|
struct vt *vt = vtdata.fgconsole;
|
struct vt *vt = vtdata.fgconsole;
|
struct con_struct * const vcd = vt->vcd;
|
struct con_struct * const vcd = vt->vcd;
|
unsigned char c;
|
unsigned char c;
|
|
|
#ifdef DEBUG
|
#ifdef DEBUG
|
vcd_validate (vcd, "console_print entry");
|
vcd_validate (vcd, "console_print entry");
|
#endif
|
#endif
|
|
|
if (!printable || printing || vt->vtd->vc_mode == KD_GRAPHICS)
|
if (!printable || printing || vt->vtd->vc_mode == KD_GRAPHICS)
|
return; /* console not yet initialized */
|
return; /* console not yet initialized */
|
printing = 1;
|
printing = 1;
|
|
|
if (!vt_allocated(vtdata.fgconsole)) {
|
if (!vt_allocated(vtdata.fgconsole)) {
|
/* impossible */
|
/* impossible */
|
printk ("console_print: tty %d not allocated ??\n", vtdata.fgconsole->num);
|
printk ("console_print: tty %d not allocated ??\n", vtdata.fgconsole->num);
|
printing = 0;
|
printing = 0;
|
return;
|
return;
|
}
|
}
|
|
|
#ifdef CONFIG_SERIAL_ECHO
|
#ifdef CONFIG_SERIAL_ECHO
|
serial_echo_print (b);
|
serial_echo_print (b);
|
#endif
|
#endif
|
vcd_removecursors (vt);
|
vcd_removecursors (vt);
|
while ((c = *b++) != 0)
|
while ((c = *b++) != 0)
|
screen_driver.put_char(vcd, vcd->combined_state | (c & 255));
|
screen_driver.put_char(vcd, vcd->combined_state | (c & 255));
|
set_cursor (vt);
|
set_cursor (vt);
|
vcd_restorecursors (vt);
|
vcd_restorecursors (vt);
|
|
|
vt_pokeblankedconsole ();
|
vt_pokeblankedconsole ();
|
printing = 0;
|
printing = 0;
|
#ifdef DEBUG
|
#ifdef DEBUG
|
vcd_validate (vt->vcd, "console_print exit");
|
vcd_validate (vt->vcd, "console_print exit");
|
#endif
|
#endif
|
}
|
}
|
|
|
/*===============================================================================================*/
|
/*===============================================================================================*/
|
|
|
int vcd_init (struct vt *vt, int kmallocok, unsigned long *kmem)
|
int vcd_init (struct vt *vt, int kmallocok, unsigned long *kmem)
|
{
|
{
|
struct con_struct *vcd = vt->vcd;
|
struct con_struct *vcd = vt->vcd;
|
memset (vcd, 0, sizeof (*vcd));
|
memset (vcd, 0, sizeof (*vcd));
|
|
|
vcd->screen.origin = vtdata.screen.memstart;
|
vcd->screen.origin = vtdata.screen.memstart;
|
vcd->screen.cursoron = (kmem ? 1 : 0);
|
vcd->screen.cursoron = (kmem ? 1 : 0);
|
vcd->screen.palette_entries = NULL;
|
vcd->screen.palette_entries = NULL;
|
vcd->driver = buffer_driver;
|
vcd->driver = buffer_driver;
|
if (kmallocok) {
|
if (kmallocok) {
|
vcd->buffer.buffer = vmalloc (vtdata.buffer.totsize * sizeof (unsigned long));
|
vcd->buffer.buffer = vmalloc (vtdata.buffer.totsize * sizeof (unsigned long));
|
if (!vt->vcd->buffer.buffer)
|
if (!vt->vcd->buffer.buffer)
|
return -ENOMEM;
|
return -ENOMEM;
|
vcd->buffer.kmalloced = 1;
|
vcd->buffer.kmalloced = 1;
|
} else {
|
} else {
|
vcd->buffer.buffer = (unsigned long *) *kmem;
|
vcd->buffer.buffer = (unsigned long *) *kmem;
|
*kmem += vtdata.buffer.totsize * sizeof (unsigned long);
|
*kmem += vtdata.buffer.totsize * sizeof (unsigned long);
|
}
|
}
|
|
|
vt->vtd->paste_wait = NULL;
|
vt->vtd->paste_wait = NULL;
|
reset_terminal (vt, (kmem ? 1 : 0));
|
reset_terminal (vt, (kmem ? 1 : 0));
|
return 0;
|
return 0;
|
}
|
}
|
|
|
/*
|
/*
|
* We allow this irq to be shared
|
* We allow this irq to be shared
|
*/
|
*/
|
static struct irqaction vsyncirq = { vsync_irq, SA_SHIRQ, 0, "vsync", NULL, NULL };
|
static struct irqaction vsyncirq = { vsync_irq, SA_SHIRQ, 0, "vsync", NULL, NULL };
|
|
|
unsigned long vcd_pre_init (unsigned long kmem, struct vt *vt)
|
unsigned long vcd_pre_init (unsigned long kmem, struct vt *vt)
|
{
|
{
|
int colours, i;
|
int colours, i;
|
|
|
switch (bytes_per_char_h) {
|
switch (bytes_per_char_h) {
|
default:
|
default:
|
case 1:
|
case 1:
|
default_palette_entries = palette_1;
|
default_palette_entries = palette_1;
|
vtdata.screen.bytespercharh = 1;
|
vtdata.screen.bytespercharh = 1;
|
vtdata.screen.bitsperpix = 1;
|
vtdata.screen.bitsperpix = 1;
|
color_table = color_1;
|
color_table = color_1;
|
colours = 1;
|
colours = 1;
|
break;
|
break;
|
case 4:
|
case 4:
|
default_palette_entries = palette_4;
|
default_palette_entries = palette_4;
|
vtdata.screen.bytespercharh = 4;
|
vtdata.screen.bytespercharh = 4;
|
vtdata.screen.bitsperpix = 4;
|
vtdata.screen.bitsperpix = 4;
|
color_table = color_4;
|
color_table = color_4;
|
colours = 16;
|
colours = 16;
|
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
con_charconvtable[i] =
|
con_charconvtable[i] =
|
(i & 128 ? 1 << 0 : 0) |
|
(i & 128 ? 1 << 0 : 0) |
|
(i & 64 ? 1 << 4 : 0) |
|
(i & 64 ? 1 << 4 : 0) |
|
(i & 32 ? 1 << 8 : 0) |
|
(i & 32 ? 1 << 8 : 0) |
|
(i & 16 ? 1 << 12 : 0) |
|
(i & 16 ? 1 << 12 : 0) |
|
(i & 8 ? 1 << 16 : 0) |
|
(i & 8 ? 1 << 16 : 0) |
|
(i & 4 ? 1 << 20 : 0) |
|
(i & 4 ? 1 << 20 : 0) |
|
(i & 2 ? 1 << 24 : 0) |
|
(i & 2 ? 1 << 24 : 0) |
|
(i & 1 ? 1 << 28 : 0);
|
(i & 1 ? 1 << 28 : 0);
|
break;
|
break;
|
case 8:
|
case 8:
|
default_palette_entries = palette_8;
|
default_palette_entries = palette_8;
|
vtdata.screen.bytespercharh = 8;
|
vtdata.screen.bytespercharh = 8;
|
vtdata.screen.bitsperpix = 8;
|
vtdata.screen.bitsperpix = 8;
|
color_table = color_8;
|
color_table = color_8;
|
colours = 256;
|
colours = 256;
|
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
con_charconvtable[i] =
|
con_charconvtable[i] =
|
(i & 8 ? 1 << 0 : 0) |
|
(i & 8 ? 1 << 0 : 0) |
|
(i & 4 ? 1 << 8 : 0) |
|
(i & 4 ? 1 << 8 : 0) |
|
(i & 2 ? 1 << 16 : 0) |
|
(i & 2 ? 1 << 16 : 0) |
|
(i & 1 ? 1 << 24 : 0);
|
(i & 1 ? 1 << 24 : 0);
|
break;
|
break;
|
}
|
}
|
video_size_row = vtdata.numcolumns * vtdata.screen.bytespercharh;
|
video_size_row = vtdata.numcolumns * vtdata.screen.bytespercharh;
|
vtdata.screen.bytespercharv = bytes_per_char_v;
|
vtdata.screen.bytespercharv = bytes_per_char_v;
|
vtdata.screen.sizerow = video_size_row * vtdata.screen.bytespercharv;
|
vtdata.screen.sizerow = video_size_row * vtdata.screen.bytespercharv;
|
vtdata.screen.totsize = vtdata.screen.sizerow * vtdata.numrows;
|
vtdata.screen.totsize = vtdata.screen.sizerow * vtdata.numrows;
|
|
|
vtdata.screen.memsize = ((vtdata.screen.totsize - 1) | (PAGE_SIZE - 1)) + 1;
|
vtdata.screen.memsize = ((vtdata.screen.totsize - 1) | (PAGE_SIZE - 1)) + 1;
|
vtdata.screen.memend = SCREEN1_END;
|
vtdata.screen.memend = SCREEN1_END;
|
vtdata.screen.memstart = vtdata.screen.memend - vtdata.screen.memsize;
|
vtdata.screen.memstart = vtdata.screen.memend - vtdata.screen.memsize;
|
vtdata.buffer.buffer = (unsigned long *)kmem;
|
vtdata.buffer.buffer = (unsigned long *)kmem;
|
vtdata.buffer.sizerow = vtdata.numcolumns;
|
vtdata.buffer.sizerow = vtdata.numcolumns;
|
vtdata.buffer.totsize = vtdata.numcolumns * vtdata.numrows;
|
vtdata.buffer.totsize = vtdata.numcolumns * vtdata.numrows;
|
vtdata.buffer.lastorigin = vtdata.buffer.totsize * 2;
|
vtdata.buffer.lastorigin = vtdata.buffer.totsize * 2;
|
kmem = (unsigned long)(vtdata.buffer.buffer + vtdata.buffer.totsize * 3);
|
kmem = (unsigned long)(vtdata.buffer.buffer + vtdata.buffer.totsize * 3);
|
memzero (vtdata.buffer.buffer, vtdata.buffer.totsize * 3 << 2);
|
memzero (vtdata.buffer.buffer, vtdata.buffer.totsize * 3 << 2);
|
|
|
kmem = map_screen_mem (vtdata.screen.memstart, kmem, 1);
|
kmem = map_screen_mem (vtdata.screen.memstart, kmem, 1);
|
|
|
palette_setpixel(0);
|
palette_setpixel(0);
|
for (i = 0; i < MAX_PIX; i++)
|
for (i = 0; i < MAX_PIX; i++)
|
palette_write(default_palette_entries[i]);
|
palette_write(default_palette_entries[i]);
|
|
|
vcd_init (vt, 0, &kmem);
|
vcd_init (vt, 0, &kmem);
|
vt->vcd->driver = screen_driver;
|
vt->vcd->driver = screen_driver;
|
|
|
gotoxy (vt->vcd, ORIG_X, ORIG_Y);
|
gotoxy (vt->vcd, ORIG_X, ORIG_Y);
|
set_origin (vt);
|
set_origin (vt);
|
csi_J (vt, 0);
|
csi_J (vt, 0);
|
printable = 1;
|
printable = 1;
|
|
|
#ifdef CONFIG_SERIAL_ECHO
|
#ifdef CONFIG_SERIAL_ECHO
|
serial_echo_init (SERIAL_ECHO_PORT);
|
serial_echo_init (SERIAL_ECHO_PORT);
|
#endif
|
#endif
|
printk ("Console: %s %s %dx%dx%d, %d virtual console%s (max %d)\n",
|
printk ("Console: %s %s %dx%dx%d, %d virtual console%s (max %d)\n",
|
colours != 1 ? "colour" : "mono",
|
colours != 1 ? "colour" : "mono",
|
"A-series",
|
"A-series",
|
vtdata.numcolumns, vtdata.numrows, colours,
|
vtdata.numcolumns, vtdata.numrows, colours,
|
MIN_NR_CONSOLES,
|
MIN_NR_CONSOLES,
|
(MIN_NR_CONSOLES == 1) ? "":"s",
|
(MIN_NR_CONSOLES == 1) ? "":"s",
|
MAX_NR_CONSOLES);
|
MAX_NR_CONSOLES);
|
|
|
register_console (console_print);
|
register_console (console_print);
|
|
|
if (setup_arm_irq(IRQ_VSYNCPULSE, &vsyncirq))
|
if (setup_arm_irq(IRQ_VSYNCPULSE, &vsyncirq))
|
panic ("Unable to get VSYNC irq for console\n");
|
panic ("Unable to get VSYNC irq for console\n");
|
|
|
return kmem;
|
return kmem;
|
}
|
}
|
|
|
/*
|
/*
|
* Report the current status of the vc. This is exported to modules (ARub)
|
* Report the current status of the vc. This is exported to modules (ARub)
|
*/
|
*/
|
int con_get_info(int *mode, int *shift, int *col, int *row,
|
int con_get_info(int *mode, int *shift, int *col, int *row,
|
struct tty_struct **tty)
|
struct tty_struct **tty)
|
{
|
{
|
extern int shift_state;
|
extern int shift_state;
|
|
|
if (mode) *mode = vtdata.fgconsole->vtd->vc_mode;
|
if (mode) *mode = vtdata.fgconsole->vtd->vc_mode;
|
if (shift) *shift = shift_state;
|
if (shift) *shift = shift_state;
|
if (col) *col = vtdata.numcolumns;
|
if (col) *col = vtdata.numcolumns;
|
if (row) *row = vtdata.numrows;
|
if (row) *row = vtdata.numrows;
|
if (tty) *tty = *vtdata.fgconsole->tty;
|
if (tty) *tty = *vtdata.fgconsole->tty;
|
return vtdata.fgconsole->num;
|
return vtdata.fgconsole->num;
|
}
|
}
|
|
|