/*
|
/*
|
* linux/drivers/char/console.c
|
* linux/drivers/char/console.c
|
*
|
*
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
*/
|
*/
|
/*
|
/*
|
* console.c
|
* console.c
|
*
|
*
|
* This module exports the console io functions:
|
* This module exports the console io functions:
|
*
|
*
|
* 'void do_keyboard_interrupt(void)'
|
* 'void do_keyboard_interrupt(void)'
|
*
|
*
|
* 'int vc_allocate(unsigned int console)'
|
* 'int vc_allocate(unsigned int console)'
|
* 'int vc_cons_allocated(unsigned int console)'
|
* 'int vc_cons_allocated(unsigned int console)'
|
* 'int vc_resize(unsigned long lines, unsigned long cols)'
|
* 'int vc_resize(unsigned long lines, unsigned long cols)'
|
* 'int vc_resize_con(unsigned long lines, unsigned long cols,
|
* 'int vc_resize_con(unsigned long lines, unsigned long cols,
|
* unsigned int currcons)'
|
* unsigned int currcons)'
|
* 'void vc_disallocate(unsigned int currcons)'
|
* 'void vc_disallocate(unsigned int currcons)'
|
*
|
*
|
* 'unsigned long con_init(unsigned long)'
|
* 'unsigned long con_init(unsigned long)'
|
* 'int con_open(struct tty_struct *tty, struct file * filp)'
|
* 'int con_open(struct tty_struct *tty, struct file * filp)'
|
* 'void con_write(struct tty_struct * tty)'
|
* 'void con_write(struct tty_struct * tty)'
|
* 'void console_print(const char * b)'
|
* 'void console_print(const char * b)'
|
* 'void update_screen(int new_console)'
|
* 'void update_screen(int new_console)'
|
*
|
*
|
* 'void do_blank_screen(int)'
|
* 'void do_blank_screen(int)'
|
* 'void do_unblank_screen(void)'
|
* 'void do_unblank_screen(void)'
|
* 'void poke_blanked_console(void)'
|
* 'void poke_blanked_console(void)'
|
*
|
*
|
* 'unsigned short *screen_pos(int currcons, int w_offset, int viewed)'
|
* 'unsigned short *screen_pos(int currcons, int w_offset, int viewed)'
|
* 'void complement_pos(int currcons, int offset)'
|
* 'void complement_pos(int currcons, int offset)'
|
* 'void invert_screen(int currcons, int offset, int count, int shift)'
|
* 'void invert_screen(int currcons, int offset, int count, int shift)'
|
*
|
*
|
* 'void scrollback(int lines)'
|
* 'void scrollback(int lines)'
|
* 'void scrollfront(int lines)'
|
* 'void scrollfront(int lines)'
|
*
|
*
|
* 'int con_get_font(char *)'
|
* 'int con_get_font(char *)'
|
* 'int con_set_font(char *)'
|
* 'int con_set_font(char *)'
|
*
|
*
|
* '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)'
|
* 'int mouse_reporting(void)'
|
* 'int mouse_reporting(void)'
|
*
|
*
|
* 'unsigned long get_video_num_lines(unsigned int console)'
|
* 'unsigned long get_video_num_lines(unsigned int console)'
|
* 'unsigned long get_video_num_columns(unsigned int console)'
|
* 'unsigned long get_video_num_columns(unsigned int console)'
|
* 'unsigned long get_video_size_row(unsigned int console)'
|
* 'unsigned long get_video_size_row(unsigned int console)'
|
*
|
*
|
* Hopefully this will be a rather complete VT102 implementation.
|
* Hopefully this will be a rather complete VT102 implementation.
|
*
|
*
|
* Beeping thanks to John T Kohl.
|
* Beeping thanks to John T Kohl.
|
*
|
*
|
* Virtual Consoles, Screen Blanking, Screen Dumping, Color, Graphics
|
* Virtual Consoles, Screen Blanking, Screen Dumping, Color, Graphics
|
* Chars, and VT100 enhancements by Peter MacDonald.
|
* Chars, and VT100 enhancements by Peter MacDonald.
|
*
|
*
|
* Copy and paste function by Andrew Haylett,
|
* Copy and paste function by Andrew Haylett,
|
* some enhancements by Alessandro Rubini.
|
* some enhancements by Alessandro Rubini.
|
*
|
*
|
* User definable mapping table and font loading by Eugene G. Crosser,
|
* User definable mapping table and font loading by Eugene G. Crosser,
|
* <crosser@pccross.msk.su>
|
* <crosser@pccross.msk.su>
|
*
|
*
|
* Code to check for different video-cards mostly by Galen Hunt,
|
* Code to check for different video-cards mostly by Galen Hunt,
|
* <g-hunt@ee.utah.edu>
|
* <g-hunt@ee.utah.edu>
|
*
|
*
|
* Rudimentary ISO 10646/Unicode/UTF-8 character set support by
|
* Rudimentary ISO 10646/Unicode/UTF-8 character set support by
|
* Markus Kuhn, <mskuhn@immd4.informatik.uni-erlangen.de>.
|
* Markus Kuhn, <mskuhn@immd4.informatik.uni-erlangen.de>.
|
*
|
*
|
* Dynamic allocation of consoles, aeb@cwi.nl, May 1994
|
* Dynamic allocation of consoles, aeb@cwi.nl, May 1994
|
* Resizing of consoles, aeb, 940926
|
* Resizing of consoles, aeb, 940926
|
*
|
*
|
* Code for xterm like mouse click reporting by Peter Orbaek 20-Jul-94
|
* Code for xterm like mouse click reporting by Peter Orbaek 20-Jul-94
|
* <poe@daimi.aau.dk>
|
* <poe@daimi.aau.dk>
|
*
|
*
|
* 680x0 LINUX support by Arno Griffioen (arno@usn.nl)
|
* 680x0 LINUX support by Arno Griffioen (arno@usn.nl)
|
*
|
*
|
* 9-Apr-94: Arno Griffioen: fixed scrolling and delete-char bug.
|
* 9-Apr-94: Arno Griffioen: fixed scrolling and delete-char bug.
|
* Scrolling code moved to amicon.c
|
* Scrolling code moved to amicon.c
|
*
|
*
|
* 18-Apr-94: David Carter [carter@cs.bris.ac.uk]. 680x0 LINUX modified
|
* 18-Apr-94: David Carter [carter@cs.bris.ac.uk]. 680x0 LINUX modified
|
* Integrated support for new low level driver `amicon_ocs.c'
|
* Integrated support for new low level driver `amicon_ocs.c'
|
*
|
*
|
*/
|
*/
|
|
|
#define BLANK 0x0020
|
#define BLANK 0x0020
|
#undef CAN_LOAD_EGA_FONTS /* undefine if the user must not do this */
|
#undef CAN_LOAD_EGA_FONTS /* undefine if the user must not do this */
|
|
|
/* 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 some special action
|
* corresponding to that bit number invokes some 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 overridden by disp_ctrl */
|
#define CTRL_ALWAYS 0x0800f501 /* Cannot be overridden 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/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/string.h>
|
#include <linux/string.h>
|
#include <linux/errno.h>
|
#include <linux/errno.h>
|
#include <linux/console.h>
|
#include <linux/console.h>
|
#include <linux/kd.h>
|
#include <linux/kd.h>
|
#include <linux/malloc.h>
|
#include <linux/malloc.h>
|
#include <linux/major.h>
|
#include <linux/major.h>
|
#include <linux/mm.h>
|
#include <linux/mm.h>
|
#include <linux/ioport.h>
|
#include <linux/ioport.h>
|
|
|
#include <asm/io.h>
|
#include <asm/io.h>
|
#include <asm/segment.h>
|
#include <asm/segment.h>
|
#include <asm/system.h>
|
#include <asm/system.h>
|
#include <asm/bitops.h>
|
#include <asm/bitops.h>
|
|
|
#include "../../../drivers/char/kbd_kern.h"
|
#include "../../../drivers/char/kbd_kern.h"
|
#include "../../../drivers/char/vt_kern.h"
|
#include "../../../drivers/char/vt_kern.h"
|
#include "../../../drivers/char/consolemap.h"
|
#include "../../../drivers/char/consolemap.h"
|
#include "../../../drivers/char/selection.h"
|
#include "../../../drivers/char/selection.h"
|
|
|
|
|
#ifndef MIN
|
#ifndef MIN
|
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
#endif
|
#endif
|
|
|
struct tty_driver console_driver;
|
struct tty_driver console_driver;
|
static int console_refcount;
|
static int console_refcount;
|
static struct tty_struct *console_table[MAX_NR_CONSOLES];
|
static struct tty_struct *console_table[MAX_NR_CONSOLES];
|
static struct termios *console_termios[MAX_NR_CONSOLES];
|
static struct termios *console_termios[MAX_NR_CONSOLES];
|
static struct termios *console_termios_locked[MAX_NR_CONSOLES];
|
static struct termios *console_termios_locked[MAX_NR_CONSOLES];
|
|
|
static void vc_init(unsigned int console, int do_clear);
|
static void vc_init(unsigned int console, int do_clear);
|
|
|
static void update_attr(int currcons);
|
static void update_attr(int currcons);
|
static void gotoxy(int currcons, int new_x, int new_y);
|
static void gotoxy(int currcons, int new_x, int new_y);
|
static void save_cur(int currcons);
|
static void save_cur(int currcons);
|
static void blank_screen(void);
|
static void blank_screen(void);
|
static void unblank_screen(void);
|
static void unblank_screen(void);
|
extern void change_console(unsigned int);
|
extern void change_console(unsigned int);
|
static inline void set_cursor(int currcons);
|
static inline void set_cursor(int currcons);
|
static void reset_terminal(int currcons, int do_clear);
|
static void reset_terminal(int currcons, int do_clear);
|
extern void reset_vc(unsigned int new_console);
|
extern void reset_vc(unsigned int new_console);
|
extern void vt_init(void);
|
extern void vt_init(void);
|
extern void register_console(void (*proc)(const char *));
|
extern void register_console(void (*proc)(const char *));
|
extern void vesa_blank(void);
|
extern void vesa_blank(void);
|
extern void vesa_unblank(void);
|
extern void vesa_unblank(void);
|
extern void compute_shiftstate(void);
|
extern void compute_shiftstate(void);
|
void poke_blanked_console(void);
|
void poke_blanked_console(void);
|
void do_blank_screen(int);
|
void do_blank_screen(int);
|
|
|
unsigned long video_num_lines;
|
unsigned long video_num_lines;
|
unsigned long video_num_columns;
|
unsigned long video_num_columns;
|
unsigned long video_size_row;
|
unsigned long video_size_row;
|
|
|
static int printable = 0; /* Is console ready for printing? */
|
static int printable = 0; /* Is console ready for printing? */
|
unsigned long video_font_height; /* Height of current screen font */
|
unsigned long video_font_height; /* Height of current screen font */
|
unsigned long video_scan_lines; /* Number of scan lines on screen */
|
unsigned long video_scan_lines; /* Number of scan lines on screen */
|
unsigned long default_font_height; /* Height of default screen font */
|
unsigned long default_font_height; /* Height of default screen font */
|
int video_mode_512ch = 0; /* 512-character mode */
|
int video_mode_512ch = 0; /* 512-character mode */
|
static unsigned short console_charmask = 0x0ff;
|
static unsigned short console_charmask = 0x0ff;
|
|
|
static unsigned short *vc_scrbuf[MAX_NR_CONSOLES];
|
static unsigned short *vc_scrbuf[MAX_NR_CONSOLES];
|
|
|
/* used by kbd_bh - set by keyboard_interrupt */
|
/* used by kbd_bh - set by keyboard_interrupt */
|
int do_poke_blanked_console = 0;
|
int do_poke_blanked_console = 0;
|
int console_blanked = 0;
|
int console_blanked = 0;
|
static int blankinterval = 10*60*HZ;
|
static int blankinterval = 10*60*HZ;
|
|
|
static struct vc {
|
static struct vc {
|
struct vc_data *d;
|
struct vc_data *d;
|
|
|
/* might add scrmem, vt_struct, kbd at some time,
|
/* might add scrmem, vt_struct, kbd at some time,
|
to have everything in one place - the disadvantage
|
to have everything in one place - the disadvantage
|
would be that vc_cons etc can no longer be static */
|
would be that vc_cons etc can no longer be static */
|
} vc_cons [MAX_NR_CONSOLES];
|
} vc_cons [MAX_NR_CONSOLES];
|
struct consw *conswitchp;
|
struct consw *conswitchp;
|
|
|
#define cols (vc_cons[currcons].d->vc_cols)
|
#define cols (vc_cons[currcons].d->vc_cols)
|
#define rows (vc_cons[currcons].d->vc_rows)
|
#define rows (vc_cons[currcons].d->vc_rows)
|
#define size_row (vc_cons[currcons].d->vc_size_row)
|
#define size_row (vc_cons[currcons].d->vc_size_row)
|
#define screenbuf_size (vc_cons[currcons].d->vc_screenbuf_size)
|
#define screenbuf_size (vc_cons[currcons].d->vc_screenbuf_size)
|
#define cons_num (vc_cons[currcons].d->vc_num)
|
#define cons_num (vc_cons[currcons].d->vc_num)
|
#define origin (vc_cons[currcons].d->vc_origin)
|
#define origin (vc_cons[currcons].d->vc_origin)
|
#define scr_end (vc_cons[currcons].d->vc_scr_end)
|
#define scr_end (vc_cons[currcons].d->vc_scr_end)
|
#define pos (vc_cons[currcons].d->vc_pos)
|
#define pos (vc_cons[currcons].d->vc_pos)
|
#define top (vc_cons[currcons].d->vc_top)
|
#define top (vc_cons[currcons].d->vc_top)
|
#define bottom (vc_cons[currcons].d->vc_bottom)
|
#define bottom (vc_cons[currcons].d->vc_bottom)
|
#define x (vc_cons[currcons].d->vc_x)
|
#define x (vc_cons[currcons].d->vc_x)
|
#define y (vc_cons[currcons].d->vc_y)
|
#define y (vc_cons[currcons].d->vc_y)
|
#define vc_state (vc_cons[currcons].d->vc_state)
|
#define vc_state (vc_cons[currcons].d->vc_state)
|
#define npar (vc_cons[currcons].d->vc_npar)
|
#define npar (vc_cons[currcons].d->vc_npar)
|
#define par (vc_cons[currcons].d->vc_par)
|
#define par (vc_cons[currcons].d->vc_par)
|
#define ques (vc_cons[currcons].d->vc_ques)
|
#define ques (vc_cons[currcons].d->vc_ques)
|
#define attr (vc_cons[currcons].d->vc_attr)
|
#define attr (vc_cons[currcons].d->vc_attr)
|
#define saved_x (vc_cons[currcons].d->vc_saved_x)
|
#define saved_x (vc_cons[currcons].d->vc_saved_x)
|
#define saved_y (vc_cons[currcons].d->vc_saved_y)
|
#define saved_y (vc_cons[currcons].d->vc_saved_y)
|
#define translate (vc_cons[currcons].d->vc_translate)
|
#define translate (vc_cons[currcons].d->vc_translate)
|
#define G0_charset (vc_cons[currcons].d->vc_G0_charset)
|
#define G0_charset (vc_cons[currcons].d->vc_G0_charset)
|
#define G1_charset (vc_cons[currcons].d->vc_G1_charset)
|
#define G1_charset (vc_cons[currcons].d->vc_G1_charset)
|
#define saved_G0 (vc_cons[currcons].d->vc_saved_G0)
|
#define saved_G0 (vc_cons[currcons].d->vc_saved_G0)
|
#define saved_G1 (vc_cons[currcons].d->vc_saved_G1)
|
#define saved_G1 (vc_cons[currcons].d->vc_saved_G1)
|
#define utf (vc_cons[currcons].d->vc_utf)
|
#define utf (vc_cons[currcons].d->vc_utf)
|
#define utf_count (vc_cons[currcons].d->vc_utf_count)
|
#define utf_count (vc_cons[currcons].d->vc_utf_count)
|
#define utf_char (vc_cons[currcons].d->vc_utf_char)
|
#define utf_char (vc_cons[currcons].d->vc_utf_char)
|
#define video_mem_start (vc_cons[currcons].d->vc_video_mem_start)
|
#define video_mem_start (vc_cons[currcons].d->vc_video_mem_start)
|
#define video_mem_end (vc_cons[currcons].d->vc_video_mem_end)
|
#define video_mem_end (vc_cons[currcons].d->vc_video_mem_end)
|
#define video_erase_char (vc_cons[currcons].d->vc_video_erase_char)
|
#define video_erase_char (vc_cons[currcons].d->vc_video_erase_char)
|
#define disp_ctrl (vc_cons[currcons].d->vc_disp_ctrl)
|
#define disp_ctrl (vc_cons[currcons].d->vc_disp_ctrl)
|
#define toggle_meta (vc_cons[currcons].d->vc_toggle_meta)
|
#define toggle_meta (vc_cons[currcons].d->vc_toggle_meta)
|
#define decscnm (vc_cons[currcons].d->vc_decscnm)
|
#define decscnm (vc_cons[currcons].d->vc_decscnm)
|
#define decom (vc_cons[currcons].d->vc_decom)
|
#define decom (vc_cons[currcons].d->vc_decom)
|
#define decawm (vc_cons[currcons].d->vc_decawm)
|
#define decawm (vc_cons[currcons].d->vc_decawm)
|
#define deccm (vc_cons[currcons].d->vc_deccm)
|
#define deccm (vc_cons[currcons].d->vc_deccm)
|
#define decim (vc_cons[currcons].d->vc_decim)
|
#define decim (vc_cons[currcons].d->vc_decim)
|
#define deccolm (vc_cons[currcons].d->vc_deccolm)
|
#define deccolm (vc_cons[currcons].d->vc_deccolm)
|
#define need_wrap (vc_cons[currcons].d->vc_need_wrap)
|
#define need_wrap (vc_cons[currcons].d->vc_need_wrap)
|
#define has_scrolled (vc_cons[currcons].d->vc_has_scrolled)
|
#define has_scrolled (vc_cons[currcons].d->vc_has_scrolled)
|
#define kmalloced (vc_cons[currcons].d->vc_kmalloced)
|
#define kmalloced (vc_cons[currcons].d->vc_kmalloced)
|
#define report_mouse (vc_cons[currcons].d->vc_report_mouse)
|
#define report_mouse (vc_cons[currcons].d->vc_report_mouse)
|
#define can_do_color (vc_cons[currcons].d->vc_can_do_color)
|
#define can_do_color (vc_cons[currcons].d->vc_can_do_color)
|
#define color (vc_cons[currcons].d->vc_color)
|
#define color (vc_cons[currcons].d->vc_color)
|
#define s_color (vc_cons[currcons].d->vc_s_color)
|
#define s_color (vc_cons[currcons].d->vc_s_color)
|
#define def_color (vc_cons[currcons].d->vc_def_color)
|
#define def_color (vc_cons[currcons].d->vc_def_color)
|
#define foreground (color & 0x0f)
|
#define foreground (color & 0x0f)
|
#define background (color & 0xf0)
|
#define background (color & 0xf0)
|
#define charset (vc_cons[currcons].d->vc_charset)
|
#define charset (vc_cons[currcons].d->vc_charset)
|
#define s_charset (vc_cons[currcons].d->vc_s_charset)
|
#define s_charset (vc_cons[currcons].d->vc_s_charset)
|
#define intensity (vc_cons[currcons].d->vc_intensity)
|
#define intensity (vc_cons[currcons].d->vc_intensity)
|
#define underline (vc_cons[currcons].d->vc_underline)
|
#define underline (vc_cons[currcons].d->vc_underline)
|
#define blink (vc_cons[currcons].d->vc_blink)
|
#define blink (vc_cons[currcons].d->vc_blink)
|
#define reverse (vc_cons[currcons].d->vc_reverse)
|
#define reverse (vc_cons[currcons].d->vc_reverse)
|
#define s_intensity (vc_cons[currcons].d->vc_s_intensity)
|
#define s_intensity (vc_cons[currcons].d->vc_s_intensity)
|
#define s_underline (vc_cons[currcons].d->vc_s_underline)
|
#define s_underline (vc_cons[currcons].d->vc_s_underline)
|
#define s_blink (vc_cons[currcons].d->vc_s_blink)
|
#define s_blink (vc_cons[currcons].d->vc_s_blink)
|
#define s_reverse (vc_cons[currcons].d->vc_s_reverse)
|
#define s_reverse (vc_cons[currcons].d->vc_s_reverse)
|
#define ulcolor (vc_cons[currcons].d->vc_ulcolor)
|
#define ulcolor (vc_cons[currcons].d->vc_ulcolor)
|
#define halfcolor (vc_cons[currcons].d->vc_halfcolor)
|
#define halfcolor (vc_cons[currcons].d->vc_halfcolor)
|
#define tab_stop (vc_cons[currcons].d->vc_tab_stop)
|
#define tab_stop (vc_cons[currcons].d->vc_tab_stop)
|
#define bell_pitch (vc_cons[currcons].d->vc_bell_pitch)
|
#define bell_pitch (vc_cons[currcons].d->vc_bell_pitch)
|
#define bell_duration (vc_cons[currcons].d->vc_bell_duration)
|
#define bell_duration (vc_cons[currcons].d->vc_bell_duration)
|
#define sw (vc_cons[currcons].d->vc_sw)
|
#define sw (vc_cons[currcons].d->vc_sw)
|
|
|
#define vcmode (vt_cons[currcons]->vc_mode)
|
#define vcmode (vt_cons[currcons]->vc_mode)
|
#if 0 /* XXX */
|
#if 0 /* XXX */
|
#define vtmode (vt_cons[currcons]->vt_mode)
|
#define vtmode (vt_cons[currcons]->vt_mode)
|
#define vtpid (vt_cons[currcons]->vt_pid)
|
#define vtpid (vt_cons[currcons]->vt_pid)
|
#define vtnewvt (vt_cons[currcons]->vt_newvt)
|
#define vtnewvt (vt_cons[currcons]->vt_newvt)
|
#endif
|
#endif
|
|
|
#define structsize (sizeof(struct vc_data) + sizeof(struct vt_struct))
|
#define structsize (sizeof(struct vc_data) + sizeof(struct vt_struct))
|
|
|
int vc_cons_allocated(unsigned int i)
|
int vc_cons_allocated(unsigned int i)
|
{
|
{
|
return (i < MAX_NR_CONSOLES && vc_cons[i].d);
|
return (i < MAX_NR_CONSOLES && vc_cons[i].d);
|
}
|
}
|
|
|
int vc_allocate(unsigned int currcons) /* return 0 on success */
|
int vc_allocate(unsigned int currcons) /* return 0 on success */
|
{
|
{
|
if (currcons >= MAX_NR_CONSOLES)
|
if (currcons >= MAX_NR_CONSOLES)
|
return -ENODEV;
|
return -ENODEV;
|
if (!vc_cons[currcons].d) {
|
if (!vc_cons[currcons].d) {
|
long p, q;
|
long p, q;
|
|
|
/* prevent users from taking too much memory */
|
/* prevent users from taking too much memory */
|
if (currcons >= MAX_NR_USER_CONSOLES && !suser())
|
if (currcons >= MAX_NR_USER_CONSOLES && !suser())
|
return -EPERM;
|
return -EPERM;
|
|
|
/* due to the granularity of kmalloc, we waste some memory here */
|
/* due to the granularity of kmalloc, we waste some memory here */
|
/* the alloc is done in two steps, to optimize the common situation
|
/* the alloc is done in two steps, to optimize the common situation
|
of a 25x80 console (structsize=216, screenbuf_size=4000) */
|
of a 25x80 console (structsize=216, screenbuf_size=4000) */
|
p = (long) kmalloc(structsize, GFP_KERNEL);
|
p = (long) kmalloc(structsize, GFP_KERNEL);
|
if (!p)
|
if (!p)
|
return -ENOMEM;
|
return -ENOMEM;
|
vc_cons[currcons].d = (struct vc_data *) p;
|
vc_cons[currcons].d = (struct vc_data *) p;
|
vt_cons[currcons] = (struct vt_struct *)(p+sizeof(struct vc_data));
|
vt_cons[currcons] = (struct vt_struct *)(p+sizeof(struct vc_data));
|
|
|
/* ++Geert: sw->con_init determines console size */
|
/* ++Geert: sw->con_init determines console size */
|
sw = conswitchp;
|
sw = conswitchp;
|
cons_num = currcons;
|
cons_num = currcons;
|
sw->con_init (vc_cons[currcons].d);
|
sw->con_init (vc_cons[currcons].d);
|
size_row = cols<<1;
|
size_row = cols<<1;
|
screenbuf_size = rows*size_row;
|
screenbuf_size = rows*size_row;
|
|
|
q = (long) kmalloc(screenbuf_size, GFP_KERNEL);
|
q = (long) kmalloc(screenbuf_size, GFP_KERNEL);
|
if (!q) {
|
if (!q) {
|
kfree_s((char *) p, structsize);
|
kfree_s((char *) p, structsize);
|
vc_cons[currcons].d = NULL;
|
vc_cons[currcons].d = NULL;
|
return -ENOMEM;
|
return -ENOMEM;
|
}
|
}
|
vc_scrbuf[currcons] = (unsigned short *) q;
|
vc_scrbuf[currcons] = (unsigned short *) q;
|
kmalloced = 1;
|
kmalloced = 1;
|
vc_init (currcons, 1);
|
vc_init (currcons, 1);
|
}
|
}
|
return 0;
|
return 0;
|
}
|
}
|
|
|
/*
|
/*
|
* Change # of rows and columns (0 means the size of fg_console)
|
* Change # of rows and columns (0 means the size of fg_console)
|
* [this is to be used together with some user program
|
* [this is to be used together with some user program
|
* like resize that changes the hardware videomode]
|
* like resize that changes the hardware videomode]
|
*/
|
*/
|
int vc_resize(unsigned long lines, unsigned long columns)
|
int vc_resize(unsigned long lines, unsigned long columns)
|
{
|
{
|
unsigned long cc, ll, ss, sr;
|
unsigned long cc, ll, ss, sr;
|
unsigned long occ, oll, oss, osr;
|
unsigned long occ, oll, oss, osr;
|
unsigned short *p;
|
unsigned short *p;
|
unsigned int currcons = fg_console, i;
|
unsigned int currcons = fg_console, i;
|
unsigned short *newscreens[MAX_NR_CONSOLES];
|
unsigned short *newscreens[MAX_NR_CONSOLES];
|
long ol, nl, rlth, rrem;
|
long ol, nl, rlth, rrem;
|
|
|
cc = (columns ? columns : cols);
|
cc = (columns ? columns : cols);
|
ll = (lines ? lines : rows);
|
ll = (lines ? lines : rows);
|
sr = cc << 1;
|
sr = cc << 1;
|
ss = sr * ll;
|
ss = sr * ll;
|
|
|
/*
|
/*
|
* Some earlier version had all consoles of potentially
|
* Some earlier version had all consoles of potentially
|
* different sizes, but that was really messy.
|
* different sizes, but that was really messy.
|
* So now we only change if there is room for all consoles
|
* So now we only change if there is room for all consoles
|
* of the same size.
|
* of the same size.
|
*/
|
*/
|
for (currcons = 0; currcons < MAX_NR_CONSOLES; currcons++) {
|
for (currcons = 0; currcons < MAX_NR_CONSOLES; currcons++) {
|
if (!vc_cons_allocated(currcons))
|
if (!vc_cons_allocated(currcons))
|
newscreens[currcons] = 0;
|
newscreens[currcons] = 0;
|
else {
|
else {
|
p = (unsigned short *) kmalloc(ss, GFP_USER);
|
p = (unsigned short *) kmalloc(ss, GFP_USER);
|
if (!p) {
|
if (!p) {
|
for (i = 0; i< currcons; i++)
|
for (i = 0; i< currcons; i++)
|
if (newscreens[i])
|
if (newscreens[i])
|
kfree_s(newscreens[i], ss);
|
kfree_s(newscreens[i], ss);
|
return -ENOMEM;
|
return -ENOMEM;
|
}
|
}
|
newscreens[currcons] = p;
|
newscreens[currcons] = p;
|
}
|
}
|
}
|
}
|
|
|
#if 0 /* XXX */
|
#if 0 /* XXX */
|
get_scrmem(fg_console);
|
get_scrmem(fg_console);
|
#endif
|
#endif
|
|
|
for (currcons = 0; currcons < MAX_NR_CONSOLES; currcons++) {
|
for (currcons = 0; currcons < MAX_NR_CONSOLES; currcons++) {
|
if (!vc_cons_allocated(currcons))
|
if (!vc_cons_allocated(currcons))
|
continue;
|
continue;
|
|
|
oll = rows;
|
oll = rows;
|
occ = cols;
|
occ = cols;
|
osr = size_row;
|
osr = size_row;
|
oss = screenbuf_size;
|
oss = screenbuf_size;
|
|
|
rows = ll;
|
rows = ll;
|
cols = cc;
|
cols = cc;
|
size_row = sr;
|
size_row = sr;
|
screenbuf_size = ss;
|
screenbuf_size = ss;
|
|
|
rlth = MIN(osr, sr);
|
rlth = MIN(osr, sr);
|
rrem = sr - rlth;
|
rrem = sr - rlth;
|
ol = origin;
|
ol = origin;
|
nl = (long) newscreens[currcons];
|
nl = (long) newscreens[currcons];
|
if (ll < oll)
|
if (ll < oll)
|
ol += (oll - ll) * osr;
|
ol += (oll - ll) * osr;
|
|
|
update_attr(currcons);
|
update_attr(currcons);
|
while (ol < scr_end) {
|
while (ol < scr_end) {
|
/* ++Geert: TODO: Because the attributes have different meanings
|
/* ++Geert: TODO: Because the attributes have different meanings
|
on monochrome and color, they should really be converted if
|
on monochrome and color, they should really be converted if
|
can_do_color changes... */
|
can_do_color changes... */
|
memcpyw((unsigned short *) nl, (unsigned short *) ol, rlth);
|
memcpyw((unsigned short *) nl, (unsigned short *) ol, rlth);
|
if (rrem)
|
if (rrem)
|
memsetw((void *)(nl + rlth), video_erase_char, rrem);
|
memsetw((void *)(nl + rlth), video_erase_char, rrem);
|
ol += osr;
|
ol += osr;
|
nl += sr;
|
nl += sr;
|
}
|
}
|
|
|
if (kmalloced)
|
if (kmalloced)
|
kfree_s(vc_scrbuf[currcons], oss);
|
kfree_s(vc_scrbuf[currcons], oss);
|
vc_scrbuf[currcons] = newscreens[currcons];
|
vc_scrbuf[currcons] = newscreens[currcons];
|
kmalloced = 1;
|
kmalloced = 1;
|
screenbuf_size = ss;
|
screenbuf_size = ss;
|
|
|
origin = (long) video_mem_start = vc_scrbuf[currcons];
|
origin = (long) video_mem_start = vc_scrbuf[currcons];
|
scr_end = video_mem_end = ((long) video_mem_start) + ss;
|
scr_end = video_mem_end = ((long) video_mem_start) + ss;
|
|
|
if (scr_end > nl)
|
if (scr_end > nl)
|
memsetw((void *) nl, video_erase_char, scr_end - nl);
|
memsetw((void *) nl, video_erase_char, scr_end - nl);
|
|
|
/* do part of a reset_terminal() */
|
/* do part of a reset_terminal() */
|
top = 0;
|
top = 0;
|
bottom = rows;
|
bottom = rows;
|
gotoxy(currcons, x, y);
|
gotoxy(currcons, x, y);
|
save_cur(currcons);
|
save_cur(currcons);
|
}
|
}
|
|
|
#if 0 /* XXX */
|
#if 0 /* XXX */
|
set_scrmem(fg_console, 0);
|
set_scrmem(fg_console, 0);
|
set_origin(fg_console);
|
set_origin(fg_console);
|
#endif /* XXX */
|
#endif /* XXX */
|
update_screen(fg_console);
|
update_screen(fg_console);
|
set_cursor(fg_console);
|
set_cursor(fg_console);
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
/*
|
/*
|
* ++Geert: Change # of rows and columns for one specific console.
|
* ++Geert: Change # of rows and columns for one specific console.
|
* Of course it's not messy to have all consoles of potentially different sizes,
|
* Of course it's not messy to have all consoles of potentially different sizes,
|
* except on PCish hardware :-)
|
* except on PCish hardware :-)
|
*
|
*
|
* This is called by the low level console driver (arch/m68k/console/fbcon.c or
|
* This is called by the low level console driver (arch/m68k/console/fbcon.c or
|
* arch/m68k/console/txtcon.c)
|
* arch/m68k/console/txtcon.c)
|
*/
|
*/
|
void vc_resize_con(unsigned long lines, unsigned long columns,
|
void vc_resize_con(unsigned long lines, unsigned long columns,
|
unsigned int currcons)
|
unsigned int currcons)
|
{
|
{
|
unsigned long cc, ll, ss, sr;
|
unsigned long cc, ll, ss, sr;
|
unsigned long occ, oll, oss, osr;
|
unsigned long occ, oll, oss, osr;
|
unsigned short *newscreen;
|
unsigned short *newscreen;
|
long ol, nl, rlth, rrem;
|
long ol, nl, rlth, rrem;
|
struct winsize ws;
|
struct winsize ws;
|
|
|
if (!columns || !lines || currcons >= MAX_NR_CONSOLES)
|
if (!columns || !lines || currcons >= MAX_NR_CONSOLES)
|
return;
|
return;
|
|
|
cc = columns;
|
cc = columns;
|
ll = lines;
|
ll = lines;
|
sr = cc << 1;
|
sr = cc << 1;
|
ss = sr * ll;
|
ss = sr * ll;
|
|
|
if (!vc_cons_allocated(currcons))
|
if (!vc_cons_allocated(currcons))
|
newscreen = 0;
|
newscreen = 0;
|
else if (!(newscreen = (unsigned short *) kmalloc(ss, GFP_USER)))
|
else if (!(newscreen = (unsigned short *) kmalloc(ss, GFP_USER)))
|
return;
|
return;
|
|
|
if (vc_cons_allocated(currcons)) {
|
if (vc_cons_allocated(currcons)) {
|
oll = rows;
|
oll = rows;
|
occ = cols;
|
occ = cols;
|
osr = size_row;
|
osr = size_row;
|
oss = screenbuf_size;
|
oss = screenbuf_size;
|
|
|
rows = ll;
|
rows = ll;
|
cols = cc;
|
cols = cc;
|
size_row = sr;
|
size_row = sr;
|
screenbuf_size = ss;
|
screenbuf_size = ss;
|
|
|
rlth = MIN(osr, sr);
|
rlth = MIN(osr, sr);
|
rrem = sr - rlth;
|
rrem = sr - rlth;
|
ol = origin;
|
ol = origin;
|
nl = (long) newscreen;
|
nl = (long) newscreen;
|
if (ll < oll)
|
if (ll < oll)
|
ol += (oll - ll) * osr;
|
ol += (oll - ll) * osr;
|
|
|
update_attr(currcons);
|
update_attr(currcons);
|
while (ol < scr_end) {
|
while (ol < scr_end) {
|
/* ++Geert: TODO: Because the attributes have different meanings
|
/* ++Geert: TODO: Because the attributes have different meanings
|
on monochrome and color, they should really be converted if
|
on monochrome and color, they should really be converted if
|
can_do_color changes... */
|
can_do_color changes... */
|
memcpyw((unsigned short *) nl, (unsigned short *) ol, rlth);
|
memcpyw((unsigned short *) nl, (unsigned short *) ol, rlth);
|
if (rrem)
|
if (rrem)
|
memsetw((void *)(nl + rlth), video_erase_char, rrem);
|
memsetw((void *)(nl + rlth), video_erase_char, rrem);
|
ol += osr;
|
ol += osr;
|
nl += sr;
|
nl += sr;
|
}
|
}
|
|
|
if (kmalloced)
|
if (kmalloced)
|
kfree_s(vc_scrbuf[currcons], oss);
|
kfree_s(vc_scrbuf[currcons], oss);
|
vc_scrbuf[currcons] = newscreen;
|
vc_scrbuf[currcons] = newscreen;
|
kmalloced = 1;
|
kmalloced = 1;
|
screenbuf_size = ss;
|
screenbuf_size = ss;
|
|
|
origin = (long) video_mem_start = vc_scrbuf[currcons];
|
origin = (long) video_mem_start = vc_scrbuf[currcons];
|
scr_end = video_mem_end = ((long)video_mem_start) + ss;
|
scr_end = video_mem_end = ((long)video_mem_start) + ss;
|
|
|
if (scr_end > nl)
|
if (scr_end > nl)
|
memsetw((void *) nl, video_erase_char, scr_end - nl);
|
memsetw((void *) nl, video_erase_char, scr_end - nl);
|
|
|
/* do part of a reset_terminal() */
|
/* do part of a reset_terminal() */
|
top = 0;
|
top = 0;
|
bottom = rows;
|
bottom = rows;
|
gotoxy(currcons, x, y);
|
gotoxy(currcons, x, y);
|
save_cur(currcons);
|
save_cur(currcons);
|
|
|
ws.ws_row = rows;
|
ws.ws_row = rows;
|
ws.ws_col = cols;
|
ws.ws_col = cols;
|
if (memcmp(&ws, &console_table[currcons]->winsize, sizeof (struct winsize)) &&
|
if (memcmp(&ws, &console_table[currcons]->winsize, sizeof (struct winsize)) &&
|
console_table[currcons]->pgrp > 0)
|
console_table[currcons]->pgrp > 0)
|
kill_pg(console_table[currcons]->pgrp, SIGWINCH, 1);
|
kill_pg(console_table[currcons]->pgrp, SIGWINCH, 1);
|
console_table[currcons]->winsize = ws;
|
console_table[currcons]->winsize = ws;
|
}
|
}
|
|
|
if (currcons == fg_console)
|
if (currcons == fg_console)
|
update_screen(fg_console);
|
update_screen(fg_console);
|
}
|
}
|
|
|
void vc_disallocate(unsigned int currcons)
|
void vc_disallocate(unsigned int currcons)
|
{
|
{
|
if (vc_cons_allocated(currcons)) {
|
if (vc_cons_allocated(currcons)) {
|
if (kmalloced)
|
if (kmalloced)
|
kfree_s(vc_scrbuf[currcons], screenbuf_size);
|
kfree_s(vc_scrbuf[currcons], screenbuf_size);
|
if (currcons >= MIN_NR_CONSOLES)
|
if (currcons >= MIN_NR_CONSOLES)
|
kfree_s(vc_cons[currcons].d, structsize);
|
kfree_s(vc_cons[currcons].d, structsize);
|
vc_cons[currcons].d = 0;
|
vc_cons[currcons].d = 0;
|
}
|
}
|
}
|
}
|
|
|
|
|
#define set_kbd(x) set_vc_kbd_mode(kbd_table+currcons,x)
|
#define set_kbd(x) set_vc_kbd_mode(kbd_table+currcons,x)
|
#define clr_kbd(x) clr_vc_kbd_mode(kbd_table+currcons,x)
|
#define clr_kbd(x) clr_vc_kbd_mode(kbd_table+currcons,x)
|
#define is_kbd(x) vc_kbd_mode(kbd_table+currcons,x)
|
#define is_kbd(x) vc_kbd_mode(kbd_table+currcons,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"
|
|
|
static unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
|
static unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
|
8,12,10,14, 9,13,11,15 };
|
8,12,10,14, 9,13,11,15 };
|
|
|
/*
|
/*
|
* gotoxy() must verify all boundaries, because the arguments
|
* gotoxy() must verify all boundaries, because the arguments
|
* might also be negative. If the given position is out of
|
* might also be negative. If the 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(int currcons, int new_x, int new_y)
|
static void gotoxy(int currcons, int new_x, int new_y)
|
{
|
{
|
int max_y;
|
int max_y;
|
|
|
if (new_x < 0)
|
if (new_x < 0)
|
x = 0;
|
x = 0;
|
else
|
else
|
if (new_x >= cols)
|
if (new_x >= cols)
|
x = cols - 1;
|
x = cols - 1;
|
else
|
else
|
x = new_x;
|
x = new_x;
|
if (decom) {
|
if (decom) {
|
new_y += top;
|
new_y += top;
|
max_y = bottom;
|
max_y = bottom;
|
} else
|
} else
|
max_y = rows;
|
max_y = rows;
|
if (new_y < 0)
|
if (new_y < 0)
|
y = 0;
|
y = 0;
|
else
|
else
|
if (new_y >= max_y)
|
if (new_y >= max_y)
|
y = max_y - 1;
|
y = max_y - 1;
|
else
|
else
|
y = new_y;
|
y = new_y;
|
pos = video_mem_start + y * cols + x;
|
pos = video_mem_start + y * cols + x;
|
need_wrap = 0;
|
need_wrap = 0;
|
}
|
}
|
|
|
static void hide_cursor(int currcons)
|
static void hide_cursor(int currcons)
|
{
|
{
|
sw->con_cursor(vc_cons[currcons].d,CM_ERASE);
|
sw->con_cursor(vc_cons[currcons].d,CM_ERASE);
|
return;
|
return;
|
}
|
}
|
|
|
static void set_cursor(int currcons)
|
static void set_cursor(int currcons)
|
{
|
{
|
if (currcons != fg_console || console_blanked || vcmode == KD_GRAPHICS)
|
if (currcons != fg_console || console_blanked || vcmode == KD_GRAPHICS)
|
return;
|
return;
|
if (deccm)
|
if (deccm)
|
sw->con_cursor(vc_cons[currcons].d,CM_DRAW);
|
sw->con_cursor(vc_cons[currcons].d,CM_DRAW);
|
else
|
else
|
hide_cursor(currcons);
|
hide_cursor(currcons);
|
return;
|
return;
|
}
|
}
|
|
|
void no_scroll(char *str, int *ints)
|
void no_scroll(char *str, int *ints)
|
{
|
{
|
/*
|
/*
|
* no_scroll currently does nothing on the m68k.
|
* no_scroll currently does nothing on the m68k.
|
*/
|
*/
|
}
|
}
|
|
|
/*
|
/*
|
* Arno:
|
* Arno:
|
* Why do we need these? The keyboard code doesn't seem to do anything
|
* Why do we need these? The keyboard code doesn't seem to do anything
|
* with them either...
|
* with them either...
|
*/
|
*/
|
void scrollfront(int l)
|
void scrollfront(int l)
|
{
|
{
|
return;
|
return;
|
}
|
}
|
|
|
void scrollback(int l)
|
void scrollback(int l)
|
{
|
{
|
return;
|
return;
|
}
|
}
|
|
|
static void scrup(int currcons, unsigned int t, unsigned int b,
|
static void scrup(int currcons, unsigned int t, unsigned int b,
|
int nr)
|
int nr)
|
{
|
{
|
unsigned short *p;
|
unsigned short *p;
|
int i;
|
int i;
|
|
|
if (b > rows || t >= b)
|
if (b > rows || t >= b)
|
return;
|
return;
|
|
|
memmove (video_mem_start + t * cols,
|
memmove (video_mem_start + t * cols,
|
video_mem_start + (t + nr) * cols,
|
video_mem_start + (t + nr) * cols,
|
(b - t - nr) * cols * 2);
|
(b - t - nr) * cols * 2);
|
|
|
p = video_mem_start + (b - nr) * cols;
|
p = video_mem_start + (b - nr) * cols;
|
for (i = nr * cols; i > 0; i--)
|
for (i = nr * cols; i > 0; i--)
|
*p++ = video_erase_char;
|
*p++ = video_erase_char;
|
|
|
if (currcons != fg_console)
|
if (currcons != fg_console)
|
return;
|
return;
|
/*
|
/*
|
* Arno:
|
* Arno:
|
* Scrolling has now been moved to amicon.c where it should have
|
* Scrolling has now been moved to amicon.c where it should have
|
* been all along.
|
* been all along.
|
*/
|
*/
|
sw->con_scroll(vc_cons[currcons].d, t, b, SM_UP, nr);
|
sw->con_scroll(vc_cons[currcons].d, t, b, SM_UP, nr);
|
|
|
return;
|
return;
|
|
|
}
|
}
|
|
|
static void scrdown(int currcons, unsigned int t, unsigned int b,
|
static void scrdown(int currcons, unsigned int t, unsigned int b,
|
int nr)
|
int nr)
|
{
|
{
|
unsigned short *p;
|
unsigned short *p;
|
int i;
|
int i;
|
|
|
if (b > rows || t >= b)
|
if (b > rows || t >= b)
|
return;
|
return;
|
|
|
memmove (video_mem_start + (t + nr) * cols,
|
memmove (video_mem_start + (t + nr) * cols,
|
video_mem_start + t * cols,
|
video_mem_start + t * cols,
|
(b - t - nr) * cols * 2);
|
(b - t - nr) * cols * 2);
|
|
|
p = video_mem_start + t * cols;
|
p = video_mem_start + t * cols;
|
for (i = nr * cols; i > 0; i--)
|
for (i = nr * cols; i > 0; i--)
|
*p++ = video_erase_char;
|
*p++ = video_erase_char;
|
|
|
if (currcons != fg_console)
|
if (currcons != fg_console)
|
return;
|
return;
|
/*
|
/*
|
* Arno:
|
* Arno:
|
* Scrolling has now been moved to amicon.c where it should have
|
* Scrolling has now been moved to amicon.c where it should have
|
* been all along.
|
* been all along.
|
*/
|
*/
|
sw->con_scroll(vc_cons[currcons].d, t, b, SM_DOWN, nr);
|
sw->con_scroll(vc_cons[currcons].d, t, b, SM_DOWN, nr);
|
|
|
return;
|
return;
|
}
|
}
|
|
|
static void lf(int currcons)
|
static void lf(int currcons)
|
{
|
{
|
/* don't scroll if above bottom of scrolling region, or
|
/* don't scroll if above bottom of scrolling region, or
|
* if below scrolling region
|
* if below scrolling region
|
*/
|
*/
|
if (y+1 == bottom)
|
if (y+1 == bottom)
|
scrup(currcons,top,bottom, 1);
|
scrup(currcons,top,bottom, 1);
|
else if (y < rows-1) {
|
else if (y < rows-1) {
|
y++;
|
y++;
|
pos += cols;
|
pos += cols;
|
}
|
}
|
need_wrap = 0;
|
need_wrap = 0;
|
}
|
}
|
|
|
static void ri(int currcons)
|
static void ri(int currcons)
|
{
|
{
|
/* don't scroll if below top of scrolling region, or
|
/* don't scroll if below top of scrolling region, or
|
* if above scrolling region
|
* if above scrolling region
|
*/
|
*/
|
if (y == top)
|
if (y == top)
|
scrdown(currcons,top,bottom, 1);
|
scrdown(currcons,top,bottom, 1);
|
else if (y > 0) {
|
else if (y > 0) {
|
y--;
|
y--;
|
pos -= cols;
|
pos -= cols;
|
}
|
}
|
need_wrap = 0;
|
need_wrap = 0;
|
}
|
}
|
|
|
static inline void cr(int currcons)
|
static inline void cr(int currcons)
|
{
|
{
|
pos -= x;
|
pos -= x;
|
need_wrap = x = 0;
|
need_wrap = x = 0;
|
}
|
}
|
|
|
static inline void bs(int currcons)
|
static inline void bs(int currcons)
|
{
|
{
|
if (x) {
|
if (x) {
|
pos--;
|
pos--;
|
x--;
|
x--;
|
need_wrap = 0;
|
need_wrap = 0;
|
}
|
}
|
}
|
}
|
|
|
static inline void del(int currcons)
|
static inline void del(int currcons)
|
{
|
{
|
/* ignored */
|
/* ignored */
|
}
|
}
|
|
|
static void csi_J(int currcons, int vpar)
|
static void csi_J(int currcons, int vpar)
|
{
|
{
|
unsigned long count;
|
unsigned long count;
|
unsigned short *start;
|
unsigned short *start;
|
|
|
switch (vpar) {
|
switch (vpar) {
|
case 0: /* erase from cursor to end of display */
|
case 0: /* erase from cursor to end of display */
|
count = (video_mem_start
|
count = (video_mem_start
|
+ cols * rows
|
+ cols * rows
|
- pos);
|
- pos);
|
start = pos;
|
start = pos;
|
if (currcons != fg_console)
|
if (currcons != fg_console)
|
break;
|
break;
|
/* 680x0 do in two stages */
|
/* 680x0 do in two stages */
|
sw->con_clear(vc_cons[currcons].d,y,x,1,cols-x);
|
sw->con_clear(vc_cons[currcons].d,y,x,1,cols-x);
|
sw->con_clear(vc_cons[currcons].d,y+1,0,rows-y-1, cols);
|
sw->con_clear(vc_cons[currcons].d,y+1,0,rows-y-1, cols);
|
break;
|
break;
|
case 1: /* erase from start to cursor */
|
case 1: /* erase from start to cursor */
|
count = pos - video_mem_start + 1;
|
count = pos - video_mem_start + 1;
|
start = video_mem_start;
|
start = video_mem_start;
|
if (currcons != fg_console)
|
if (currcons != fg_console)
|
break;
|
break;
|
/* 680x0 do in two stages */
|
/* 680x0 do in two stages */
|
sw->con_clear(vc_cons[currcons].d,0,0,y, cols);
|
sw->con_clear(vc_cons[currcons].d,0,0,y, cols);
|
sw->con_clear(vc_cons[currcons].d,y,0,1,x + 1);
|
sw->con_clear(vc_cons[currcons].d,y,0,1,x + 1);
|
break;
|
break;
|
case 2: /* erase whole display */
|
case 2: /* erase whole display */
|
count = cols * rows;
|
count = cols * rows;
|
start = video_mem_start;
|
start = video_mem_start;
|
if (currcons != fg_console)
|
if (currcons != fg_console)
|
break;
|
break;
|
sw->con_clear(vc_cons[currcons].d,0,0,rows, cols);
|
sw->con_clear(vc_cons[currcons].d,0,0,rows, cols);
|
break;
|
break;
|
default:
|
default:
|
return;
|
return;
|
}
|
}
|
while (count-- > 0)
|
while (count-- > 0)
|
*start++ = video_erase_char;
|
*start++ = video_erase_char;
|
need_wrap = 0;
|
need_wrap = 0;
|
}
|
}
|
|
|
static void csi_K(int currcons, int vpar)
|
static void csi_K(int currcons, int vpar)
|
{
|
{
|
unsigned long count;
|
unsigned long count;
|
unsigned short *start;
|
unsigned short *start;
|
|
|
switch (vpar) {
|
switch (vpar) {
|
case 0: /* erase from cursor to end of line */
|
case 0: /* erase from cursor to end of line */
|
count = cols - x;
|
count = cols - x;
|
start = pos;
|
start = pos;
|
if (currcons != fg_console)
|
if (currcons != fg_console)
|
break;
|
break;
|
sw->con_clear(vc_cons[currcons].d,y,x,1,cols-x);
|
sw->con_clear(vc_cons[currcons].d,y,x,1,cols-x);
|
break;
|
break;
|
case 1: /* erase from start of line to cursor */
|
case 1: /* erase from start of line to cursor */
|
start = pos - x;
|
start = pos - x;
|
count = x + 1;
|
count = x + 1;
|
if (currcons != fg_console)
|
if (currcons != fg_console)
|
break;
|
break;
|
sw->con_clear(vc_cons[currcons].d,y,0,1,x + 1);
|
sw->con_clear(vc_cons[currcons].d,y,0,1,x + 1);
|
break;
|
break;
|
case 2: /* erase whole line */
|
case 2: /* erase whole line */
|
start = pos - x;
|
start = pos - x;
|
count = cols;
|
count = cols;
|
if (currcons != fg_console)
|
if (currcons != fg_console)
|
break;
|
break;
|
sw->con_clear(vc_cons[currcons].d,y,0,1,cols);
|
sw->con_clear(vc_cons[currcons].d,y,0,1,cols);
|
break;
|
break;
|
default:
|
default:
|
return;
|
return;
|
}
|
}
|
while (count-- > 0)
|
while (count-- > 0)
|
*start++ = video_erase_char;
|
*start++ = video_erase_char;
|
need_wrap = 0;
|
need_wrap = 0;
|
}
|
}
|
|
|
static void csi_X(int currcons, int vpar) /* erase the following vpar positions */
|
static void csi_X(int currcons, int vpar) /* erase the following vpar positions */
|
{ /* not vt100? */
|
{ /* not vt100? */
|
unsigned long count;
|
unsigned long count;
|
unsigned short * start;
|
unsigned short * start;
|
|
|
if (!vpar)
|
if (!vpar)
|
vpar++;
|
vpar++;
|
|
|
start=pos;
|
start=pos;
|
count=(vpar > cols-x) ? (cols-x) : vpar;
|
count=(vpar > cols-x) ? (cols-x) : vpar;
|
|
|
if (currcons == fg_console)
|
if (currcons == fg_console)
|
sw->con_clear(vc_cons[currcons].d,y,x,1,count);
|
sw->con_clear(vc_cons[currcons].d,y,x,1,count);
|
|
|
while (count-- > 0)
|
while (count-- > 0)
|
*start++ = video_erase_char;
|
*start++ = video_erase_char;
|
need_wrap = 0;
|
need_wrap = 0;
|
}
|
}
|
|
|
/*
|
/*
|
* Arno:
|
* Arno:
|
* On 680x0 attributes are currently not used. This piece of code
|
* On 680x0 attributes are currently not used. This piece of code
|
* seems hardware independent, but uses the EGA/VGA way of representing
|
* seems hardware independent, but uses the EGA/VGA way of representing
|
* attributes.
|
* attributes.
|
* TODO: modify for 680x0 and add attribute processing to putc code.
|
* TODO: modify for 680x0 and add attribute processing to putc code.
|
*
|
*
|
* ++roman: I completely changed the attribute format for monochrome
|
* ++roman: I completely changed the attribute format for monochrome
|
* mode (!can_do_color). The formerly used MDA (monochrome display
|
* mode (!can_do_color). The formerly used MDA (monochrome display
|
* adapter) format didn't allow the combination of certain effects.
|
* adapter) format didn't allow the combination of certain effects.
|
* Now the attribute is just a bit vector:
|
* Now the attribute is just a bit vector:
|
* Bit 0..1: intensity (0..2)
|
* Bit 0..1: intensity (0..2)
|
* Bit 2 : underline
|
* Bit 2 : underline
|
* Bit 3 : reverse
|
* Bit 3 : reverse
|
* Bit 7 : blink
|
* Bit 7 : blink
|
*/
|
*/
|
static void update_attr(int currcons)
|
static void update_attr(int currcons)
|
{
|
{
|
if (!can_do_color) {
|
if (!can_do_color) {
|
/* Special treatment for monochrome */
|
/* Special treatment for monochrome */
|
attr = intensity |
|
attr = intensity |
|
(underline ? 4 : 0) |
|
(underline ? 4 : 0) |
|
((reverse ^ decscnm) ? 8 : 0) |
|
((reverse ^ decscnm) ? 8 : 0) |
|
(blink ? 0x80 : 0);
|
(blink ? 0x80 : 0);
|
video_erase_char = ' ' | ((reverse ^ decscnm) ? 0x800 : 0);
|
video_erase_char = ' ' | ((reverse ^ decscnm) ? 0x800 : 0);
|
return;
|
return;
|
}
|
}
|
|
|
attr = color;
|
attr = color;
|
if (underline)
|
if (underline)
|
attr = (attr & 0xf0) | ulcolor;
|
attr = (attr & 0xf0) | ulcolor;
|
else if (intensity == 0)
|
else if (intensity == 0)
|
attr = (attr & 0xf0) | halfcolor;
|
attr = (attr & 0xf0) | halfcolor;
|
if (reverse ^ decscnm)
|
if (reverse ^ decscnm)
|
attr = reverse_video_char(attr);
|
attr = reverse_video_char(attr);
|
if (blink)
|
if (blink)
|
attr ^= 0x80;
|
attr ^= 0x80;
|
if (intensity == 2)
|
if (intensity == 2)
|
attr ^= 0x08;
|
attr ^= 0x08;
|
if (decscnm)
|
if (decscnm)
|
video_erase_char = (reverse_video_char(color) << 8) | ' ';
|
video_erase_char = (reverse_video_char(color) << 8) | ' ';
|
else
|
else
|
video_erase_char = (color << 8) | ' ';
|
video_erase_char = (color << 8) | ' ';
|
}
|
}
|
|
|
static void default_attr(int currcons)
|
static void default_attr(int currcons)
|
{
|
{
|
intensity = 1;
|
intensity = 1;
|
underline = 0;
|
underline = 0;
|
reverse = 0;
|
reverse = 0;
|
blink = 0;
|
blink = 0;
|
color = def_color;
|
color = def_color;
|
}
|
}
|
|
|
static void csi_m(int currcons)
|
static void csi_m(int currcons)
|
{
|
{
|
int i;
|
int i;
|
|
|
for (i=0;i<=npar;i++)
|
for (i=0;i<=npar;i++)
|
switch (par[i]) {
|
switch (par[i]) {
|
case 0: /* all attributes off */
|
case 0: /* all attributes off */
|
default_attr(currcons);
|
default_attr(currcons);
|
break;
|
break;
|
case 1:
|
case 1:
|
intensity = 2;
|
intensity = 2;
|
break;
|
break;
|
case 2:
|
case 2:
|
intensity = 0;
|
intensity = 0;
|
break;
|
break;
|
case 4:
|
case 4:
|
underline = 1;
|
underline = 1;
|
break;
|
break;
|
case 5:
|
case 5:
|
blink = 1;
|
blink = 1;
|
break;
|
break;
|
case 7:
|
case 7:
|
reverse = 1;
|
reverse = 1;
|
break;
|
break;
|
case 10: /* ANSI X3.64-1979 (SCO-ish?)
|
case 10: /* 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.
|
*/
|
*/
|
translate = set_translate(charset == 0
|
translate = set_translate(charset == 0
|
? G0_charset
|
? G0_charset
|
: G1_charset);
|
: G1_charset);
|
disp_ctrl = 0;
|
disp_ctrl = 0;
|
toggle_meta = 0;
|
toggle_meta = 0;
|
break;
|
break;
|
case 11: /* ANSI X3.64-1979 (SCO-ish?)
|
case 11: /* 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.
|
*/
|
*/
|
translate = set_translate(IBMPC_MAP);
|
translate = set_translate(IBMPC_MAP);
|
disp_ctrl = 1;
|
disp_ctrl = 1;
|
toggle_meta = 0;
|
toggle_meta = 0;
|
break;
|
break;
|
case 12: /* ANSI X3.64-1979 (SCO-ish?)
|
case 12: /* 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.
|
*/
|
*/
|
translate = set_translate(IBMPC_MAP);
|
translate = set_translate(IBMPC_MAP);
|
disp_ctrl = 1;
|
disp_ctrl = 1;
|
toggle_meta = 1;
|
toggle_meta = 1;
|
break;
|
break;
|
case 21:
|
case 21:
|
case 22:
|
case 22:
|
intensity = 1;
|
intensity = 1;
|
break;
|
break;
|
case 24:
|
case 24:
|
underline = 0;
|
underline = 0;
|
break;
|
break;
|
case 25:
|
case 25:
|
blink = 0;
|
blink = 0;
|
break;
|
break;
|
case 27:
|
case 27:
|
reverse = 0;
|
reverse = 0;
|
break;
|
break;
|
case 38: /* ANSI X3.64-1979 (SCO-ish?)
|
case 38: /* ANSI X3.64-1979 (SCO-ish?)
|
* Enables underscore, white foreground
|
* Enables underscore, white foreground
|
* with white underscore (Linux - use
|
* with white underscore (Linux - use
|
* default foreground).
|
* default foreground).
|
*/
|
*/
|
color = (def_color & 0x0f) | background;
|
color = (def_color & 0x0f) | background;
|
underline = 1;
|
underline = 1;
|
break;
|
break;
|
case 39: /* ANSI X3.64-1979 (SCO-ish?)
|
case 39: /* ANSI X3.64-1979 (SCO-ish?)
|
* Disable underline option.
|
* Disable underline option.
|
* Reset colour to default? It did this
|
* Reset colour to default? It did this
|
* before...
|
* before...
|
*/
|
*/
|
color = (def_color & 0x0f) | background;
|
color = (def_color & 0x0f) | background;
|
underline = 0;
|
underline = 0;
|
break;
|
break;
|
case 49:
|
case 49:
|
color = (def_color & 0xf0) | foreground;
|
color = (def_color & 0xf0) | foreground;
|
break;
|
break;
|
default:
|
default:
|
if (par[i] >= 30 && par[i] <= 37)
|
if (par[i] >= 30 && par[i] <= 37)
|
color = color_table[par[i]-30]
|
color = color_table[par[i]-30]
|
| background;
|
| background;
|
else if (par[i] >= 40 && par[i] <= 47)
|
else if (par[i] >= 40 && par[i] <= 47)
|
color = (color_table[par[i]-40]<<4)
|
color = (color_table[par[i]-40]<<4)
|
| foreground;
|
| foreground;
|
break;
|
break;
|
}
|
}
|
update_attr(currcons);
|
update_attr(currcons);
|
}
|
}
|
|
|
static void respond_string(const char * p, struct tty_struct * tty)
|
static void respond_string(const char * p, struct tty_struct * tty)
|
{
|
{
|
while (*p) {
|
while (*p) {
|
tty_insert_flip_char(tty, *p, 0);
|
tty_insert_flip_char(tty, *p, 0);
|
p++;
|
p++;
|
}
|
}
|
tty_schedule_flip(tty);
|
tty_schedule_flip(tty);
|
}
|
}
|
|
|
static void cursor_report(int currcons, struct tty_struct * tty)
|
static void cursor_report(int currcons, struct tty_struct * tty)
|
{
|
{
|
char buf[40];
|
char buf[40];
|
|
|
sprintf(buf, "\033[%ld;%ldR", y + (decom ? top+1 : 1), x+1);
|
sprintf(buf, "\033[%ld;%ldR", y + (decom ? top+1 : 1), x+1);
|
respond_string(buf, tty);
|
respond_string(buf, tty);
|
}
|
}
|
|
|
static inline void status_report(struct tty_struct * tty)
|
static inline void status_report(struct tty_struct * tty)
|
{
|
{
|
respond_string("\033[0n", tty); /* Terminal ok */
|
respond_string("\033[0n", tty); /* Terminal ok */
|
}
|
}
|
|
|
static inline void respond_ID(struct tty_struct * tty)
|
static inline 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 via ioctl(TIOCLINUX) */
|
/* invoked via ioctl(TIOCLINUX) */
|
int mouse_reporting(void)
|
int mouse_reporting(void)
|
{
|
{
|
int currcons = fg_console;
|
int currcons = fg_console;
|
|
|
return report_mouse;
|
return report_mouse;
|
}
|
}
|
|
|
static inline unsigned short *screenpos(int currcons, int offset, int viewed)
|
static inline unsigned short *screenpos(int currcons, int offset, int viewed)
|
{
|
{
|
unsigned short *p = (unsigned short *)(origin + offset);
|
unsigned short *p = (unsigned short *)(origin + offset);
|
#if 0
|
#if 0
|
if (viewed && currcons == fg_console)
|
if (viewed && currcons == fg_console)
|
p -= (__real_origin - __origin);
|
p -= (__real_origin - __origin);
|
#endif
|
#endif
|
return p;
|
return p;
|
}
|
}
|
|
|
/* Note: inverting the screen twice should revert to the original state */
|
/* Note: inverting the screen twice should revert to the original state */
|
void invert_screen(int currcons, int offset, int count, int viewed)
|
void invert_screen(int currcons, int offset, int count, int viewed)
|
{
|
{
|
unsigned short *p;
|
unsigned short *p;
|
unsigned short xx, yy, oldattr;
|
unsigned short xx, yy, oldattr;
|
|
|
count /= 2;
|
count /= 2;
|
p = screenpos(currcons, offset, viewed);
|
p = screenpos(currcons, offset, viewed);
|
xx = (offset >> 1) % cols;
|
xx = (offset >> 1) % cols;
|
yy = (offset >> 1) / cols;
|
yy = (offset >> 1) / cols;
|
oldattr = attr;
|
oldattr = attr;
|
if (can_do_color)
|
if (can_do_color)
|
while (count--) {
|
while (count--) {
|
unsigned short old = scr_readw(p);
|
unsigned short old = scr_readw(p);
|
unsigned short new = reverse_video_short(old);
|
unsigned short new = reverse_video_short(old);
|
scr_writew(new, p);
|
scr_writew(new, p);
|
p++;
|
p++;
|
if (currcons != fg_console)
|
if (currcons != fg_console)
|
continue;
|
continue;
|
attr = new >> 8;
|
attr = new >> 8;
|
sw->con_putc(vc_cons[currcons].d, new & 0xff, yy, xx);
|
sw->con_putc(vc_cons[currcons].d, new & 0xff, yy, xx);
|
if (++xx == cols)
|
if (++xx == cols)
|
xx = 0, ++yy;
|
xx = 0, ++yy;
|
}
|
}
|
else
|
else
|
while (count--) {
|
while (count--) {
|
unsigned short old = scr_readw(p);
|
unsigned short old = scr_readw(p);
|
unsigned short new = old ^ 0x800;
|
unsigned short new = old ^ 0x800;
|
scr_writew(new, p);
|
scr_writew(new, p);
|
p++;
|
p++;
|
if (currcons != fg_console)
|
if (currcons != fg_console)
|
continue;
|
continue;
|
attr = new >> 8;
|
attr = new >> 8;
|
sw->con_putc(vc_cons[currcons].d, new & 0xff, yy, xx);
|
sw->con_putc(vc_cons[currcons].d, new & 0xff, yy, xx);
|
if (++xx == cols)
|
if (++xx == cols)
|
xx = 0, ++yy;
|
xx = 0, ++yy;
|
}
|
}
|
attr = oldattr;
|
attr = oldattr;
|
}
|
}
|
|
|
/* used by selection: complement pointer position */
|
/* used by selection: complement pointer position */
|
void complement_pos(int currcons, int offset)
|
void complement_pos(int currcons, int offset)
|
{
|
{
|
static unsigned short *p = NULL;
|
static unsigned short *p = NULL;
|
static unsigned short old = 0;
|
static unsigned short old = 0;
|
static unsigned short oldx = 0, oldy = 0;
|
static unsigned short oldx = 0, oldy = 0;
|
unsigned short new, oldattr;
|
unsigned short new, oldattr;
|
|
|
oldattr = attr;
|
oldattr = attr;
|
if (p) {
|
if (p) {
|
scr_writew(old, p);
|
scr_writew(old, p);
|
if (currcons == fg_console) {
|
if (currcons == fg_console) {
|
attr = old >> 8;
|
attr = old >> 8;
|
sw->con_putc(vc_cons[currcons].d, old & 0xff, oldy, oldx);
|
sw->con_putc(vc_cons[currcons].d, old & 0xff, oldy, oldx);
|
attr = oldattr;
|
attr = oldattr;
|
}
|
}
|
}
|
}
|
if (offset == -1)
|
if (offset == -1)
|
p = NULL;
|
p = NULL;
|
else {
|
else {
|
p = screenpos(currcons, offset, 1);
|
p = screenpos(currcons, offset, 1);
|
old = scr_readw(p);
|
old = scr_readw(p);
|
oldx = (offset >> 1) % cols;
|
oldx = (offset >> 1) % cols;
|
oldy = (offset >> 1) / cols;
|
oldy = (offset >> 1) / cols;
|
if (can_do_color)
|
if (can_do_color)
|
new = old ^ 0x7700;
|
new = old ^ 0x7700;
|
else
|
else
|
new = old ^ 0x800;
|
new = old ^ 0x800;
|
scr_writew(new, p);
|
scr_writew(new, p);
|
if (currcons == fg_console) {
|
if (currcons == fg_console) {
|
attr = new >> 8;
|
attr = new >> 8;
|
sw->con_putc(vc_cons[currcons].d, new & 0xff, oldy, oldx);
|
sw->con_putc(vc_cons[currcons].d, new & 0xff, oldy, oldx);
|
attr = oldattr;
|
attr = oldattr;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
/* used by selection */
|
/* used by selection */
|
unsigned short screen_word(int currcons, int offset, int viewed)
|
unsigned short screen_word(int currcons, int offset, int viewed)
|
{
|
{
|
return scr_readw(screenpos(currcons, offset, viewed));
|
return scr_readw(screenpos(currcons, offset, viewed));
|
}
|
}
|
|
|
/* used by selection - convert a screen word to a glyph number */
|
/* used by selection - convert a screen word to a glyph number */
|
int scrw2glyph(unsigned short scr_word)
|
int scrw2glyph(unsigned short scr_word)
|
{
|
{
|
return ( video_mode_512ch )
|
return ( video_mode_512ch )
|
? ((scr_word & 0x0800) >> 3) + (scr_word & 0x00ff)
|
? ((scr_word & 0x0800) >> 3) + (scr_word & 0x00ff)
|
: scr_word & 0x00ff;
|
: scr_word & 0x00ff;
|
}
|
}
|
|
|
/* used by vcs - note the word offset */
|
/* used by vcs - note the word offset */
|
unsigned short *screen_pos(int currcons, int w_offset, int viewed)
|
unsigned short *screen_pos(int currcons, int w_offset, int viewed)
|
{
|
{
|
return screenpos(currcons, 2 * w_offset, viewed);
|
return screenpos(currcons, 2 * w_offset, viewed);
|
}
|
}
|
|
|
void getconsxy(int currcons, char *p)
|
void getconsxy(int currcons, char *p)
|
{
|
{
|
p[0] = x;
|
p[0] = x;
|
p[1] = y;
|
p[1] = y;
|
}
|
}
|
|
|
void putconsxy(int currcons, char *p)
|
void putconsxy(int currcons, char *p)
|
{
|
{
|
gotoxy(currcons, p[0], p[1]);
|
gotoxy(currcons, p[0], p[1]);
|
set_cursor(currcons);
|
set_cursor(currcons);
|
}
|
}
|
|
|
static void set_mode(int currcons, int on_off)
|
static void set_mode(int currcons, int on_off)
|
{
|
{
|
int i;
|
int i;
|
|
|
for (i=0; i<=npar; i++)
|
for (i=0; i<=npar; i++)
|
if (ques) switch(par[i]) { /* DEC private modes set/reset */
|
if (ques) switch(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 */
|
deccolm = on_off;
|
deccolm = on_off;
|
#if 0
|
#if 0
|
(void) vc_resize(rows, deccolm ? 132 : 80);
|
(void) vc_resize(rows, deccolm ? 132 : 80);
|
/* this alone does not suffice; some user mode
|
/* this alone does not suffice; some user mode
|
utility has to change the hardware regs */
|
utility has to change the hardware regs */
|
#endif
|
#endif
|
break;
|
break;
|
case 5: /* Inverted screen on/off */
|
case 5: /* Inverted screen on/off */
|
if (decscnm != on_off) {
|
if (decscnm != on_off) {
|
decscnm = on_off;
|
decscnm = on_off;
|
invert_screen(currcons, 0, screenbuf_size, 0);
|
invert_screen(currcons, 0, screenbuf_size, 0);
|
update_attr(currcons);
|
update_attr(currcons);
|
}
|
}
|
break;
|
break;
|
case 6: /* Origin relative/absolute */
|
case 6: /* Origin relative/absolute */
|
decom = on_off;
|
decom = on_off;
|
gotoxy(currcons,0,0);
|
gotoxy(currcons,0,0);
|
break;
|
break;
|
case 7: /* Autowrap on/off */
|
case 7: /* Autowrap on/off */
|
decawm = on_off;
|
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:
|
report_mouse = on_off ? 1 : 0;
|
report_mouse = on_off ? 1 : 0;
|
break;
|
break;
|
case 25: /* Cursor on/off */
|
case 25: /* Cursor on/off */
|
deccm = on_off;
|
deccm = on_off;
|
set_cursor(currcons);
|
set_cursor(currcons);
|
break;
|
break;
|
case 1000:
|
case 1000:
|
report_mouse = on_off ? 2 : 0;
|
report_mouse = on_off ? 2 : 0;
|
break;
|
break;
|
} else switch(par[i]) { /* ANSI modes set/reset */
|
} else switch(par[i]) { /* ANSI modes set/reset */
|
case 3: /* Monitor (display ctrls) */
|
case 3: /* Monitor (display ctrls) */
|
disp_ctrl = on_off;
|
disp_ctrl = on_off;
|
break;
|
break;
|
case 4: /* Insert Mode on/off */
|
case 4: /* Insert Mode on/off */
|
decim = on_off;
|
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(int currcons)
|
static void setterm_command(int currcons)
|
{
|
{
|
switch(par[0]) {
|
switch(par[0]) {
|
case 1: /* set color for underline mode */
|
case 1: /* set color for underline mode */
|
if (can_do_color && par[1] < 16) {
|
if (can_do_color && par[1] < 16) {
|
ulcolor = color_table[par[1]];
|
ulcolor = color_table[par[1]];
|
if (underline)
|
if (underline)
|
update_attr(currcons);
|
update_attr(currcons);
|
}
|
}
|
break;
|
break;
|
case 2: /* set color for half intensity mode */
|
case 2: /* set color for half intensity mode */
|
if (can_do_color && par[1] < 16) {
|
if (can_do_color && par[1] < 16) {
|
halfcolor = color_table[par[1]];
|
halfcolor = color_table[par[1]];
|
if (intensity == 0)
|
if (intensity == 0)
|
update_attr(currcons);
|
update_attr(currcons);
|
}
|
}
|
break;
|
break;
|
case 8: /* store colors as defaults */
|
case 8: /* store colors as defaults */
|
def_color = attr;
|
def_color = attr;
|
default_attr(currcons);
|
default_attr(currcons);
|
update_attr(currcons);
|
update_attr(currcons);
|
break;
|
break;
|
case 9: /* set blanking interval */
|
case 9: /* set blanking interval */
|
blankinterval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
|
blankinterval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
|
poke_blanked_console();
|
poke_blanked_console();
|
break;
|
break;
|
case 10: /* set bell frequency in Hz */
|
case 10: /* set bell frequency in Hz */
|
if (npar >= 1)
|
if (npar >= 1)
|
bell_pitch = par[1];
|
bell_pitch = par[1];
|
else
|
else
|
bell_pitch = DEFAULT_BELL_PITCH;
|
bell_pitch = DEFAULT_BELL_PITCH;
|
break;
|
break;
|
case 11: /* set bell duration in msec */
|
case 11: /* set bell duration in msec */
|
if (npar >= 1)
|
if (npar >= 1)
|
bell_duration = (par[1] < 2000) ?
|
bell_duration = (par[1] < 2000) ?
|
par[1]*HZ/1000 : 0;
|
par[1]*HZ/1000 : 0;
|
else
|
else
|
bell_duration = DEFAULT_BELL_DURATION;
|
bell_duration = DEFAULT_BELL_DURATION;
|
break;
|
break;
|
case 12: /* bring specified console to the front */
|
case 12: /* bring specified console to the front */
|
if (par[1] >= 1 && vc_cons_allocated(par[1]-1))
|
if (par[1] >= 1 && vc_cons_allocated(par[1]-1))
|
update_screen(par[1]-1);
|
update_screen(par[1]-1);
|
break;
|
break;
|
case 13: /* unblank the screen */
|
case 13: /* unblank the screen */
|
unblank_screen();
|
unblank_screen();
|
break;
|
break;
|
}
|
}
|
}
|
}
|
|
|
static void insert_char(int currcons)
|
static void insert_char(int currcons)
|
{
|
{
|
int i;
|
int i;
|
unsigned short *p = pos;
|
unsigned short *p = pos;
|
|
|
for (i = cols - x - 2; i >= 0; i--)
|
for (i = cols - x - 2; i >= 0; i--)
|
p[i + 1] = p[i];
|
p[i + 1] = p[i];
|
*pos = video_erase_char;
|
*pos = video_erase_char;
|
need_wrap = 0;
|
need_wrap = 0;
|
|
|
if (currcons != fg_console)
|
if (currcons != fg_console)
|
return;
|
return;
|
|
|
/* Arno:
|
/* Arno:
|
* Move the remainder of the line (-1 character) one spot to the right
|
* Move the remainder of the line (-1 character) one spot to the right
|
*/
|
*/
|
sw->con_bmove(vc_cons[currcons].d,y,x,y,x+1,1,(cols-x-1));
|
sw->con_bmove(vc_cons[currcons].d,y,x,y,x+1,1,(cols-x-1));
|
/*
|
/*
|
* Print the erase char on the current position
|
* Print the erase char on the current position
|
*/
|
*/
|
sw->con_putc(vc_cons[currcons].d,(video_erase_char & 0x00ff),y,x);
|
sw->con_putc(vc_cons[currcons].d,(video_erase_char & 0x00ff),y,x);
|
}
|
}
|
|
|
static void csi_at(int currcons, unsigned int nr)
|
static void csi_at(int currcons, unsigned int nr)
|
{
|
{
|
int i;
|
int i;
|
unsigned short *p;
|
unsigned short *p;
|
|
|
if (nr > cols - x)
|
if (nr > cols - x)
|
nr = cols - x;
|
nr = cols - x;
|
else if (!nr)
|
else if (!nr)
|
nr = 1;
|
nr = 1;
|
|
|
p = pos + cols - x - nr;
|
p = pos + cols - x - nr;
|
while (--p >= pos)
|
while (--p >= pos)
|
p[nr] = *p;
|
p[nr] = *p;
|
for (i = 0; i < nr; i++)
|
for (i = 0; i < nr; i++)
|
*++p = video_erase_char;
|
*++p = video_erase_char;
|
need_wrap = 0;
|
need_wrap = 0;
|
|
|
if (currcons != fg_console)
|
if (currcons != fg_console)
|
return;
|
return;
|
|
|
sw->con_bmove (vc_cons[currcons].d, y, x, y, x + nr,
|
sw->con_bmove (vc_cons[currcons].d, y, x, y, x + nr,
|
1, cols - x - nr);
|
1, cols - x - nr);
|
while (nr--)
|
while (nr--)
|
sw->con_putc (vc_cons[currcons].d, video_erase_char & 0x00ff,
|
sw->con_putc (vc_cons[currcons].d, video_erase_char & 0x00ff,
|
y, x + nr);
|
y, x + nr);
|
}
|
}
|
|
|
static void csi_L(int currcons, unsigned int nr)
|
static void csi_L(int currcons, unsigned int nr)
|
{
|
{
|
if (nr > rows)
|
if (nr > rows)
|
nr = rows;
|
nr = rows;
|
else if (!nr)
|
else if (!nr)
|
nr = 1;
|
nr = 1;
|
scrdown (currcons, y, bottom, nr);
|
scrdown (currcons, y, bottom, nr);
|
need_wrap = 0;
|
need_wrap = 0;
|
}
|
}
|
|
|
static void csi_P(int currcons, unsigned int nr)
|
static void csi_P(int currcons, unsigned int nr)
|
{
|
{
|
int i;
|
int i;
|
unsigned short *p, *end;
|
unsigned short *p, *end;
|
|
|
if (nr > cols - x)
|
if (nr > cols - x)
|
nr = cols - x;
|
nr = cols - x;
|
else if (!nr)
|
else if (!nr)
|
nr = 1;
|
nr = 1;
|
|
|
p = pos;
|
p = pos;
|
end = pos + cols - x - nr;
|
end = pos + cols - x - nr;
|
while (p < end)
|
while (p < end)
|
*p = p[nr], p++;
|
*p = p[nr], p++;
|
for (i = 0; i < nr; i++)
|
for (i = 0; i < nr; i++)
|
*p++ = video_erase_char;
|
*p++ = video_erase_char;
|
need_wrap = 0;
|
need_wrap = 0;
|
|
|
if (currcons != fg_console)
|
if (currcons != fg_console)
|
return;
|
return;
|
|
|
sw->con_bmove (vc_cons[currcons].d, y, x + nr, y, x,
|
sw->con_bmove (vc_cons[currcons].d, y, x + nr, y, x,
|
1, cols - x - nr);
|
1, cols - x - nr);
|
|
|
while (nr--)
|
while (nr--)
|
sw->con_putc (vc_cons[currcons].d, video_erase_char & 0x00ff,
|
sw->con_putc (vc_cons[currcons].d, video_erase_char & 0x00ff,
|
y, cols - 1 - nr);
|
y, cols - 1 - nr);
|
}
|
}
|
|
|
static void csi_M(int currcons, unsigned int nr)
|
static void csi_M(int currcons, unsigned int nr)
|
{
|
{
|
if (nr > rows)
|
if (nr > rows)
|
nr = rows;
|
nr = rows;
|
else if (!nr)
|
else if (!nr)
|
nr=1;
|
nr=1;
|
scrup (currcons, y, bottom, nr);
|
scrup (currcons, y, bottom, nr);
|
need_wrap = 0;
|
need_wrap = 0;
|
}
|
}
|
|
|
static void save_cur(int currcons)
|
static void save_cur(int currcons)
|
{
|
{
|
saved_x = x;
|
saved_x = x;
|
saved_y = y;
|
saved_y = y;
|
s_intensity = intensity;
|
s_intensity = intensity;
|
s_underline = underline;
|
s_underline = underline;
|
s_blink = blink;
|
s_blink = blink;
|
s_reverse = reverse;
|
s_reverse = reverse;
|
s_charset = charset;
|
s_charset = charset;
|
s_color = color;
|
s_color = color;
|
saved_G0 = G0_charset;
|
saved_G0 = G0_charset;
|
saved_G1 = G1_charset;
|
saved_G1 = G1_charset;
|
}
|
}
|
|
|
static void restore_cur(int currcons)
|
static void restore_cur(int currcons)
|
{
|
{
|
gotoxy(currcons,saved_x,saved_y);
|
gotoxy(currcons,saved_x,saved_y);
|
intensity = s_intensity;
|
intensity = s_intensity;
|
underline = s_underline;
|
underline = s_underline;
|
blink = s_blink;
|
blink = s_blink;
|
reverse = s_reverse;
|
reverse = s_reverse;
|
charset = s_charset;
|
charset = s_charset;
|
color = s_color;
|
color = s_color;
|
G0_charset = saved_G0;
|
G0_charset = saved_G0;
|
G1_charset = saved_G1;
|
G1_charset = saved_G1;
|
translate = set_translate(charset ? G1_charset : G0_charset);
|
translate = set_translate(charset ? G1_charset : G0_charset);
|
update_attr(currcons);
|
update_attr(currcons);
|
need_wrap = 0;
|
need_wrap = 0;
|
}
|
}
|
|
|
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(int currcons, int do_clear)
|
static void reset_terminal(int currcons, int do_clear)
|
{
|
{
|
top = 0;
|
top = 0;
|
bottom = rows;
|
bottom = rows;
|
vc_state = ESnormal;
|
vc_state = ESnormal;
|
ques = 0;
|
ques = 0;
|
translate = set_translate(LAT1_MAP);
|
translate = set_translate(LAT1_MAP);
|
G0_charset = LAT1_MAP;
|
G0_charset = LAT1_MAP;
|
G1_charset = GRAF_MAP;
|
G1_charset = GRAF_MAP;
|
charset = 0;
|
charset = 0;
|
need_wrap = 0;
|
need_wrap = 0;
|
report_mouse = 0;
|
report_mouse = 0;
|
utf = 0;
|
utf = 0;
|
utf_count = 0;
|
utf_count = 0;
|
|
|
disp_ctrl = 0;
|
disp_ctrl = 0;
|
toggle_meta = 0;
|
toggle_meta = 0;
|
|
|
decscnm = 0;
|
decscnm = 0;
|
decom = 0;
|
decom = 0;
|
decawm = 1;
|
decawm = 1;
|
deccm = 1;
|
deccm = 1;
|
decim = 0;
|
decim = 0;
|
|
|
set_kbd(decarm);
|
set_kbd(decarm);
|
clr_kbd(decckm);
|
clr_kbd(decckm);
|
clr_kbd(kbdapplic);
|
clr_kbd(kbdapplic);
|
clr_kbd(lnm);
|
clr_kbd(lnm);
|
kbd_table[currcons].lockstate = 0;
|
kbd_table[currcons].lockstate = 0;
|
kbd_table[currcons].slockstate = 0;
|
kbd_table[currcons].slockstate = 0;
|
kbd_table[currcons].ledmode = LED_SHOW_FLAGS;
|
kbd_table[currcons].ledmode = LED_SHOW_FLAGS;
|
kbd_table[currcons].ledflagstate = kbd_table[currcons].default_ledflagstate;
|
kbd_table[currcons].ledflagstate = kbd_table[currcons].default_ledflagstate;
|
set_leds();
|
set_leds();
|
|
|
default_attr(currcons);
|
default_attr(currcons);
|
update_attr(currcons);
|
update_attr(currcons);
|
|
|
tab_stop[0] = 0x01010100;
|
tab_stop[0] = 0x01010100;
|
tab_stop[1] =
|
tab_stop[1] =
|
tab_stop[2] =
|
tab_stop[2] =
|
tab_stop[3] =
|
tab_stop[3] =
|
tab_stop[4] = 0x01010101;
|
tab_stop[4] = 0x01010101;
|
|
|
bell_pitch = DEFAULT_BELL_PITCH;
|
bell_pitch = DEFAULT_BELL_PITCH;
|
bell_duration = DEFAULT_BELL_DURATION;
|
bell_duration = DEFAULT_BELL_DURATION;
|
|
|
gotoxy(currcons,0,0);
|
gotoxy(currcons,0,0);
|
save_cur(currcons);
|
save_cur(currcons);
|
if (do_clear)
|
if (do_clear)
|
csi_J(currcons,2);
|
csi_J(currcons,2);
|
}
|
}
|
|
|
/*
|
/*
|
* Turn the Scroll-Lock LED on when the tty is stopped
|
* Turn the Scroll-Lock LED on when the tty is stopped
|
*/
|
*/
|
static void con_stop(struct tty_struct *tty)
|
static void con_stop(struct tty_struct *tty)
|
{
|
{
|
int console_num;
|
int console_num;
|
if (!tty)
|
if (!tty)
|
return;
|
return;
|
console_num = MINOR(tty->device) - (tty->driver.minor_start);
|
console_num = MINOR(tty->device) - (tty->driver.minor_start);
|
if (!vc_cons_allocated(console_num))
|
if (!vc_cons_allocated(console_num))
|
return;
|
return;
|
set_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
|
set_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
|
set_leds();
|
set_leds();
|
}
|
}
|
|
|
/*
|
/*
|
* Turn the Scroll-Lock LED off when the console is started
|
* Turn the Scroll-Lock LED off when the console is started
|
*/
|
*/
|
static void con_start(struct tty_struct *tty)
|
static void con_start(struct tty_struct *tty)
|
{
|
{
|
int console_num;
|
int console_num;
|
if (!tty)
|
if (!tty)
|
return;
|
return;
|
console_num = MINOR(tty->device) - (tty->driver.minor_start);
|
console_num = MINOR(tty->device) - (tty->driver.minor_start);
|
if (!vc_cons_allocated(console_num))
|
if (!vc_cons_allocated(console_num))
|
return;
|
return;
|
clr_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
|
clr_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
|
set_leds();
|
set_leds();
|
}
|
}
|
|
|
static int con_write(struct tty_struct * tty, int from_user,
|
static int con_write(struct tty_struct * tty, int from_user,
|
const unsigned char *buf, int count)
|
const unsigned char *buf, int count)
|
{
|
{
|
int c, tc, ok, n = 0;
|
int c, tc, ok, n = 0;
|
unsigned int currcons;
|
unsigned int currcons;
|
struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
|
struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
|
|
|
currcons = vt->vc_num;
|
currcons = vt->vc_num;
|
if (!vc_cons_allocated(currcons)) {
|
if (!vc_cons_allocated(currcons)) {
|
/* could this happen? */
|
/* could this happen? */
|
static int error = 0;
|
static int error = 0;
|
if (!error) {
|
if (!error) {
|
error = 1;
|
error = 1;
|
printk("con_write: tty %d not allocated\n", currcons+1);
|
printk("con_write: tty %d not allocated\n", currcons+1);
|
}
|
}
|
return 0;
|
return 0;
|
}
|
}
|
|
|
/* undraw cursor first */
|
/* undraw cursor first */
|
if (currcons == fg_console)
|
if (currcons == fg_console)
|
hide_cursor(currcons);
|
hide_cursor(currcons);
|
|
|
/* clear the selection */
|
/* clear the selection */
|
if (currcons == sel_cons)
|
if (currcons == sel_cons)
|
clear_selection();
|
clear_selection();
|
|
|
disable_bh(CONSOLE_BH);
|
disable_bh(CONSOLE_BH);
|
while (count) {
|
while (count) {
|
enable_bh(CONSOLE_BH);
|
enable_bh(CONSOLE_BH);
|
c = from_user ? get_user(buf) : *buf;
|
c = from_user ? get_user(buf) : *buf;
|
buf++; n++; count--;
|
buf++; n++; count--;
|
disable_bh(CONSOLE_BH);
|
disable_bh(CONSOLE_BH);
|
|
|
if (utf) {
|
if (utf) {
|
/* Combine UTF-8 into Unicode */
|
/* Combine UTF-8 into Unicode */
|
/* Incomplete characters silently ignored */
|
/* Incomplete characters silently ignored */
|
if(c > 0x7f) {
|
if(c > 0x7f) {
|
if (utf_count > 0 && (c & 0xc0) == 0x80) {
|
if (utf_count > 0 && (c & 0xc0) == 0x80) {
|
utf_char = (utf_char << 6) | (c & 0x3f);
|
utf_char = (utf_char << 6) | (c & 0x3f);
|
utf_count--;
|
utf_count--;
|
if (utf_count == 0)
|
if (utf_count == 0)
|
tc = c = utf_char;
|
tc = c = utf_char;
|
else continue;
|
else continue;
|
} else {
|
} else {
|
if ((c & 0xe0) == 0xc0) {
|
if ((c & 0xe0) == 0xc0) {
|
utf_count = 1;
|
utf_count = 1;
|
utf_char = (c & 0x1f);
|
utf_char = (c & 0x1f);
|
} else if ((c & 0xf0) == 0xe0) {
|
} else if ((c & 0xf0) == 0xe0) {
|
utf_count = 2;
|
utf_count = 2;
|
utf_char = (c & 0x0f);
|
utf_char = (c & 0x0f);
|
} else if ((c & 0xf8) == 0xf0) {
|
} else if ((c & 0xf8) == 0xf0) {
|
utf_count = 3;
|
utf_count = 3;
|
utf_char = (c & 0x07);
|
utf_char = (c & 0x07);
|
} else if ((c & 0xfc) == 0xf8) {
|
} else if ((c & 0xfc) == 0xf8) {
|
utf_count = 4;
|
utf_count = 4;
|
utf_char = (c & 0x03);
|
utf_char = (c & 0x03);
|
} else if ((c & 0xfe) == 0xfc) {
|
} else if ((c & 0xfe) == 0xfc) {
|
utf_count = 5;
|
utf_count = 5;
|
utf_char = (c & 0x01);
|
utf_char = (c & 0x01);
|
} else
|
} else
|
utf_count = 0;
|
utf_count = 0;
|
continue;
|
continue;
|
}
|
}
|
} else {
|
} else {
|
tc = c;
|
tc = c;
|
utf_count = 0;
|
utf_count = 0;
|
}
|
}
|
} else { /* no utf */
|
} else { /* no utf */
|
tc = translate[toggle_meta ? (c|0x80) : c];
|
tc = translate[toggle_meta ? (c|0x80) : c];
|
}
|
}
|
|
|
/* If the original code was < 32 we only allow a
|
/* If the original code was < 32 we only allow a
|
* glyph to be displayed if the code is not normally
|
* glyph to be displayed if the code is not normally
|
* used (such as for cursor movement) or if the
|
* used (such as for cursor movement) or if the
|
* disp_ctrl mode has been explicitly enabled.
|
* disp_ctrl mode has been explicitly enabled.
|
* Note: ESC is *never* allowed to be displayed as
|
* Note: ESC is *never* allowed to be displayed as
|
* that would disable all escape sequences!
|
* that would disable all escape sequences!
|
* To display font position 0x1B, go into UTF mode
|
* To display font position 0x1B, go into UTF mode
|
* and display character U+F01B, or change the mapping.
|
* and display character U+F01B, or change the mapping.
|
*/
|
*/
|
ok = (tc && (c >= 32 || (!utf && !(((disp_ctrl ? CTRL_ALWAYS
|
ok = (tc && (c >= 32 || (!utf && !(((disp_ctrl ? CTRL_ALWAYS
|
: CTRL_ACTION) >> c) & 1))));
|
: CTRL_ACTION) >> c) & 1))));
|
|
|
if (vc_state == ESnormal && ok) {
|
if (vc_state == ESnormal && ok) {
|
/* Now try to find out how to display it */
|
/* Now try to find out how to display it */
|
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;
|
}
|
}
|
if (tc & ~console_charmask)
|
if (tc & ~console_charmask)
|
continue; /* Conversion failed */
|
continue; /* Conversion failed */
|
|
|
if (need_wrap) {
|
if (need_wrap) {
|
cr(currcons);
|
cr(currcons);
|
lf(currcons);
|
lf(currcons);
|
}
|
}
|
|
|
#if 1 /* XXX */
|
#if 1 /* XXX */
|
/* DPC: 1994-04-12
|
/* DPC: 1994-04-12
|
* Speed up overstrike mode, using new putcs.
|
* Speed up overstrike mode, using new putcs.
|
*
|
*
|
* P.S. I hate 8 spaces per tab! Use Emacs!
|
* P.S. I hate 8 spaces per tab! Use Emacs!
|
*/
|
*/
|
|
|
/* Only use this for the foreground console,
|
/* Only use this for the foreground console,
|
where we really draw the chars */
|
where we really draw the chars */
|
|
|
if (count > 2 &&
|
if (count > 2 &&
|
!decim && !utf && currcons == fg_console) {
|
!decim && !utf && currcons == fg_console) {
|
static char putcs_buf[256];
|
static char putcs_buf[256];
|
char *p = putcs_buf;
|
char *p = putcs_buf;
|
int putcs_count = 1;
|
int putcs_count = 1;
|
ushort nextx = x + 1;
|
ushort nextx = x + 1;
|
|
|
*p++ = tc;
|
*p++ = tc;
|
*pos++ = tc | (attr << 8);
|
*pos++ = tc | (attr << 8);
|
|
|
if (nextx == cols) {
|
if (nextx == cols) {
|
sw->con_putc(vc_cons[currcons].d,
|
sw->con_putc(vc_cons[currcons].d,
|
*putcs_buf, y, x);
|
*putcs_buf, y, x);
|
pos--;
|
pos--;
|
need_wrap = decawm;
|
need_wrap = decawm;
|
continue;
|
continue;
|
}
|
}
|
|
|
/* TAB TAB TAB - Arghh!!!! */
|
/* TAB TAB TAB - Arghh!!!! */
|
|
|
while (count)
|
while (count)
|
{
|
{
|
enable_bh(CONSOLE_BH);
|
enable_bh(CONSOLE_BH);
|
c = from_user ? get_user(buf) : *buf;
|
c = from_user ? get_user(buf) : *buf;
|
disable_bh(CONSOLE_BH);
|
disable_bh(CONSOLE_BH);
|
tc = translate[toggle_meta ? (c|0x80) : c];
|
tc = translate[toggle_meta ? (c|0x80) : c];
|
if (!tc ||
|
if (!tc ||
|
!(c >= 32
|
!(c >= 32
|
|| !(((disp_ctrl ? CTRL_ALWAYS
|
|| !(((disp_ctrl ? CTRL_ALWAYS
|
: CTRL_ACTION) >> c) & 1)))
|
: CTRL_ACTION) >> c) & 1)))
|
break;
|
break;
|
tc = conv_uni_to_pc(tc);
|
tc = conv_uni_to_pc(tc);
|
if (tc == -4)
|
if (tc == -4)
|
tc = conv_uni_to_pc(0xfffd);
|
tc = conv_uni_to_pc(0xfffd);
|
else if (tc == -3)
|
else if (tc == -3)
|
tc = c;
|
tc = c;
|
|
|
buf++; n++; count--;
|
buf++; n++; count--;
|
if (tc & ~console_charmask)
|
if (tc & ~console_charmask)
|
continue; /* Conversion failed */
|
continue; /* Conversion failed */
|
|
|
*p++ = tc;
|
*p++ = tc;
|
*pos++ = tc | (attr << 8);
|
*pos++ = tc | (attr << 8);
|
++putcs_count;
|
++putcs_count;
|
++nextx;
|
++nextx;
|
if (nextx == cols ||
|
if (nextx == cols ||
|
putcs_count == sizeof (putcs_buf))
|
putcs_count == sizeof (putcs_buf))
|
break;
|
break;
|
}
|
}
|
|
|
sw->con_putcs(vc_cons[currcons].d,
|
sw->con_putcs(vc_cons[currcons].d,
|
putcs_buf, putcs_count, y, x);
|
putcs_buf, putcs_count, y, x);
|
if (nextx == cols) {
|
if (nextx == cols) {
|
pos--;
|
pos--;
|
x = cols-1;
|
x = cols-1;
|
need_wrap = decawm;
|
need_wrap = decawm;
|
} else
|
} else
|
x += putcs_count;
|
x += putcs_count;
|
continue;
|
continue;
|
}
|
}
|
|
|
/* DPC: End of putcs support */
|
/* DPC: End of putcs support */
|
#endif
|
#endif
|
|
|
if (decim)
|
if (decim)
|
insert_char(currcons);
|
insert_char(currcons);
|
*pos = (attr << 8) + tc;
|
*pos = (attr << 8) + tc;
|
if (currcons == fg_console)
|
if (currcons == fg_console)
|
sw->con_putc(vc_cons[currcons].d,tc,y,x);
|
sw->con_putc(vc_cons[currcons].d,tc,y,x);
|
if (x == cols - 1)
|
if (x == cols - 1)
|
need_wrap = decawm;
|
need_wrap = decawm;
|
else {
|
else {
|
pos++;
|
pos++;
|
x++;
|
x++;
|
}
|
}
|
continue;
|
continue;
|
}
|
}
|
|
|
/*
|
/*
|
* 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 7:
|
case 7:
|
if (bell_duration)
|
if (bell_duration)
|
kd_mksound(bell_pitch, bell_duration);
|
kd_mksound(bell_pitch, bell_duration);
|
continue;
|
continue;
|
case 8:
|
case 8:
|
bs(currcons);
|
bs(currcons);
|
continue;
|
continue;
|
case 9:
|
case 9:
|
pos -= x;
|
pos -= x;
|
while (x < cols - 1) {
|
while (x < cols - 1) {
|
x++;
|
x++;
|
if (tab_stop[x >> 5] & (1 << (x & 31)))
|
if (tab_stop[x >> 5] & (1 << (x & 31)))
|
break;
|
break;
|
}
|
}
|
pos += x;
|
pos += x;
|
continue;
|
continue;
|
case 10: case 11: case 12:
|
case 10: case 11: case 12:
|
lf(currcons);
|
lf(currcons);
|
if (!is_kbd(lnm))
|
if (!is_kbd(lnm))
|
continue;
|
continue;
|
case 13:
|
case 13:
|
cr(currcons);
|
cr(currcons);
|
continue;
|
continue;
|
case 14:
|
case 14:
|
charset = 1;
|
charset = 1;
|
translate = set_translate(G1_charset);
|
translate = set_translate(G1_charset);
|
disp_ctrl = 1;
|
disp_ctrl = 1;
|
continue;
|
continue;
|
case 15:
|
case 15:
|
charset = 0;
|
charset = 0;
|
translate = set_translate(G0_charset);
|
translate = set_translate(G0_charset);
|
disp_ctrl = 0;
|
disp_ctrl = 0;
|
continue;
|
continue;
|
case 24: case 26:
|
case 24: case 26:
|
vc_state = ESnormal;
|
vc_state = ESnormal;
|
continue;
|
continue;
|
case 27:
|
case 27:
|
vc_state = ESesc;
|
vc_state = ESesc;
|
continue;
|
continue;
|
case 127:
|
case 127:
|
del(currcons);
|
del(currcons);
|
continue;
|
continue;
|
case 128+27:
|
case 128+27:
|
vc_state = ESsquare;
|
vc_state = ESsquare;
|
continue;
|
continue;
|
}
|
}
|
switch(vc_state) {
|
switch(vc_state) {
|
case ESesc:
|
case ESesc:
|
vc_state = ESnormal;
|
vc_state = ESnormal;
|
switch (c) {
|
switch (c) {
|
case '[':
|
case '[':
|
vc_state = ESsquare;
|
vc_state = ESsquare;
|
continue;
|
continue;
|
case ']':
|
case ']':
|
vc_state = ESnonstd;
|
vc_state = ESnonstd;
|
continue;
|
continue;
|
case '%':
|
case '%':
|
vc_state = ESpercent;
|
vc_state = ESpercent;
|
continue;
|
continue;
|
case 'E':
|
case 'E':
|
cr(currcons);
|
cr(currcons);
|
lf(currcons);
|
lf(currcons);
|
continue;
|
continue;
|
case 'M':
|
case 'M':
|
ri(currcons);
|
ri(currcons);
|
continue;
|
continue;
|
case 'D':
|
case 'D':
|
lf(currcons);
|
lf(currcons);
|
continue;
|
continue;
|
case 'H':
|
case 'H':
|
tab_stop[x >> 5] |= (1 << (x & 31));
|
tab_stop[x >> 5] |= (1 << (x & 31));
|
continue;
|
continue;
|
case 'Z':
|
case 'Z':
|
respond_ID(tty);
|
respond_ID(tty);
|
continue;
|
continue;
|
case '7':
|
case '7':
|
save_cur(currcons);
|
save_cur(currcons);
|
continue;
|
continue;
|
case '8':
|
case '8':
|
restore_cur(currcons);
|
restore_cur(currcons);
|
continue;
|
continue;
|
case '(':
|
case '(':
|
vc_state = ESsetG0;
|
vc_state = ESsetG0;
|
continue;
|
continue;
|
case ')':
|
case ')':
|
vc_state = ESsetG1;
|
vc_state = ESsetG1;
|
continue;
|
continue;
|
case '#':
|
case '#':
|
vc_state = EShash;
|
vc_state = EShash;
|
continue;
|
continue;
|
case 'c':
|
case 'c':
|
reset_terminal(currcons,1);
|
reset_terminal(currcons,1);
|
continue;
|
continue;
|
case '>': /* Numeric keypad */
|
case '>': /* Numeric keypad */
|
clr_kbd(kbdapplic);
|
clr_kbd(kbdapplic);
|
continue;
|
continue;
|
case '=': /* Appl. keypad */
|
case '=': /* Appl. keypad */
|
set_kbd(kbdapplic);
|
set_kbd(kbdapplic);
|
continue;
|
continue;
|
}
|
}
|
continue;
|
continue;
|
case ESnonstd:
|
case ESnonstd:
|
if (c=='P') { /* palette escape sequence */
|
if (c=='P') { /* palette escape sequence */
|
for (npar=0; npar<NPAR; npar++)
|
for (npar=0; npar<NPAR; npar++)
|
par[npar] = 0 ;
|
par[npar] = 0 ;
|
npar = 0 ;
|
npar = 0 ;
|
vc_state = ESpalette;
|
vc_state = ESpalette;
|
continue;
|
continue;
|
} else if (c=='R') { /* reset palette */
|
} else if (c=='R') { /* reset palette */
|
#if 0
|
#if 0
|
reset_palette (currcons);
|
reset_palette (currcons);
|
#endif
|
#endif
|
vc_state = ESnormal;
|
vc_state = ESnormal;
|
} else
|
} else
|
vc_state = ESnormal;
|
vc_state = ESnormal;
|
continue;
|
continue;
|
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') ) {
|
par[npar++] = (c>'9' ? (c&0xDF)-'A'+10 : c-'0') ;
|
par[npar++] = (c>'9' ? (c&0xDF)-'A'+10 : c-'0') ;
|
if (npar==7) {
|
if (npar==7) {
|
#if 0
|
#if 0
|
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];
|
set_palette() ;
|
set_palette() ;
|
#endif
|
#endif
|
vc_state = ESnormal;
|
vc_state = ESnormal;
|
}
|
}
|
} else
|
} else
|
vc_state = ESnormal;
|
vc_state = ESnormal;
|
continue;
|
continue;
|
case ESsquare:
|
case ESsquare:
|
for(npar = 0 ; npar < NPAR ; npar++)
|
for(npar = 0 ; npar < NPAR ; npar++)
|
par[npar] = 0;
|
par[npar] = 0;
|
npar = 0;
|
npar = 0;
|
vc_state = ESgetpars;
|
vc_state = ESgetpars;
|
if (c == '[') { /* Function key */
|
if (c == '[') { /* Function key */
|
vc_state=ESfunckey;
|
vc_state=ESfunckey;
|
continue;
|
continue;
|
}
|
}
|
ques = (c=='?');
|
ques = (c=='?');
|
if (ques)
|
if (ques)
|
continue;
|
continue;
|
case ESgetpars:
|
case ESgetpars:
|
if (c==';' && npar<NPAR-1) {
|
if (c==';' && npar<NPAR-1) {
|
npar++;
|
npar++;
|
continue;
|
continue;
|
} else if (c>='0' && c<='9') {
|
} else if (c>='0' && c<='9') {
|
par[npar] *= 10;
|
par[npar] *= 10;
|
par[npar] += c-'0';
|
par[npar] += c-'0';
|
continue;
|
continue;
|
} else vc_state=ESgotpars;
|
} else vc_state=ESgotpars;
|
case ESgotpars:
|
case ESgotpars:
|
vc_state = ESnormal;
|
vc_state = ESnormal;
|
switch(c) {
|
switch(c) {
|
case 'h':
|
case 'h':
|
set_mode(currcons,1);
|
set_mode(currcons,1);
|
continue;
|
continue;
|
case 'l':
|
case 'l':
|
set_mode(currcons,0);
|
set_mode(currcons,0);
|
continue;
|
continue;
|
case 'n':
|
case 'n':
|
if (!ques)
|
if (!ques)
|
if (par[0] == 5)
|
if (par[0] == 5)
|
status_report(tty);
|
status_report(tty);
|
else if (par[0] == 6)
|
else if (par[0] == 6)
|
cursor_report(currcons,tty);
|
cursor_report(currcons,tty);
|
continue;
|
continue;
|
}
|
}
|
if (ques) {
|
if (ques) {
|
ques = 0;
|
ques = 0;
|
continue;
|
continue;
|
}
|
}
|
switch(c) {
|
switch(c) {
|
case 'G': case '`':
|
case 'G': case '`':
|
if (par[0]) par[0]--;
|
if (par[0]) par[0]--;
|
gotoxy(currcons,par[0],y);
|
gotoxy(currcons,par[0],y);
|
continue;
|
continue;
|
case 'A':
|
case 'A':
|
if (!par[0]) par[0]++;
|
if (!par[0]) par[0]++;
|
gotoxy(currcons,x,y-par[0]);
|
gotoxy(currcons,x,y-par[0]);
|
continue;
|
continue;
|
case 'B': case 'e':
|
case 'B': case 'e':
|
if (!par[0]) par[0]++;
|
if (!par[0]) par[0]++;
|
gotoxy(currcons,x,y+par[0]);
|
gotoxy(currcons,x,y+par[0]);
|
continue;
|
continue;
|
case 'C': case 'a':
|
case 'C': case 'a':
|
if (!par[0]) par[0]++;
|
if (!par[0]) par[0]++;
|
gotoxy(currcons,x+par[0],y);
|
gotoxy(currcons,x+par[0],y);
|
continue;
|
continue;
|
case 'D':
|
case 'D':
|
if (!par[0]) par[0]++;
|
if (!par[0]) par[0]++;
|
gotoxy(currcons,x-par[0],y);
|
gotoxy(currcons,x-par[0],y);
|
continue;
|
continue;
|
case 'E':
|
case 'E':
|
if (!par[0]) par[0]++;
|
if (!par[0]) par[0]++;
|
gotoxy(currcons,0,y+par[0]);
|
gotoxy(currcons,0,y+par[0]);
|
continue;
|
continue;
|
case 'F':
|
case 'F':
|
if (!par[0]) par[0]++;
|
if (!par[0]) par[0]++;
|
gotoxy(currcons,0,y-par[0]);
|
gotoxy(currcons,0,y-par[0]);
|
continue;
|
continue;
|
case 'd':
|
case 'd':
|
if (par[0]) par[0]--;
|
if (par[0]) par[0]--;
|
gotoxy(currcons,x,par[0]);
|
gotoxy(currcons,x,par[0]);
|
continue;
|
continue;
|
case 'H': case 'f':
|
case 'H': case 'f':
|
if (par[0]) par[0]--;
|
if (par[0]) par[0]--;
|
if (par[1]) par[1]--;
|
if (par[1]) par[1]--;
|
gotoxy(currcons,par[1],par[0]);
|
gotoxy(currcons,par[1],par[0]);
|
continue;
|
continue;
|
case 'J':
|
case 'J':
|
csi_J(currcons,par[0]);
|
csi_J(currcons,par[0]);
|
continue;
|
continue;
|
case 'K':
|
case 'K':
|
csi_K(currcons,par[0]);
|
csi_K(currcons,par[0]);
|
continue;
|
continue;
|
case 'L':
|
case 'L':
|
csi_L(currcons,par[0]);
|
csi_L(currcons,par[0]);
|
continue;
|
continue;
|
case 'M':
|
case 'M':
|
csi_M(currcons,par[0]);
|
csi_M(currcons,par[0]);
|
continue;
|
continue;
|
case 'P':
|
case 'P':
|
csi_P(currcons,par[0]);
|
csi_P(currcons,par[0]);
|
continue;
|
continue;
|
case 'c':
|
case 'c':
|
if (!par[0])
|
if (!par[0])
|
respond_ID(tty);
|
respond_ID(tty);
|
continue;
|
continue;
|
case 'g':
|
case 'g':
|
if (!par[0])
|
if (!par[0])
|
tab_stop[x >> 5] &= ~(1 << (x & 31));
|
tab_stop[x >> 5] &= ~(1 << (x & 31));
|
else if (par[0] == 3) {
|
else if (par[0] == 3) {
|
tab_stop[0] =
|
tab_stop[0] =
|
tab_stop[1] =
|
tab_stop[1] =
|
tab_stop[2] =
|
tab_stop[2] =
|
tab_stop[3] =
|
tab_stop[3] =
|
tab_stop[4] = 0;
|
tab_stop[4] = 0;
|
}
|
}
|
continue;
|
continue;
|
case 'm':
|
case 'm':
|
csi_m(currcons);
|
csi_m(currcons);
|
continue;
|
continue;
|
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 (par[0] < 4)
|
if (par[0] < 4)
|
setledstate(kbd_table + currcons,
|
setledstate(kbd_table + currcons,
|
(par[0] < 3) ? par[0] : 4);
|
(par[0] < 3) ? par[0] : 4);
|
continue;
|
continue;
|
case 'r':
|
case 'r':
|
if (!par[0])
|
if (!par[0])
|
par[0]++;
|
par[0]++;
|
if (!par[1])
|
if (!par[1])
|
par[1] = rows;
|
par[1] = rows;
|
/* Minimum allowed region is 2 lines */
|
/* Minimum allowed region is 2 lines */
|
if (par[0] < par[1] &&
|
if (par[0] < par[1] &&
|
par[1] <= rows) {
|
par[1] <= rows) {
|
top=par[0]-1;
|
top=par[0]-1;
|
bottom=par[1];
|
bottom=par[1];
|
gotoxy(currcons,0,0);
|
gotoxy(currcons,0,0);
|
}
|
}
|
continue;
|
continue;
|
case 's':
|
case 's':
|
save_cur(currcons);
|
save_cur(currcons);
|
continue;
|
continue;
|
case 'u':
|
case 'u':
|
restore_cur(currcons);
|
restore_cur(currcons);
|
continue;
|
continue;
|
case 'X':
|
case 'X':
|
csi_X(currcons, par[0]);
|
csi_X(currcons, par[0]);
|
continue;
|
continue;
|
case '@':
|
case '@':
|
csi_at(currcons,par[0]);
|
csi_at(currcons,par[0]);
|
continue;
|
continue;
|
case ']': /* setterm functions */
|
case ']': /* setterm functions */
|
setterm_command(currcons);
|
setterm_command(currcons);
|
continue;
|
continue;
|
}
|
}
|
continue;
|
continue;
|
case ESpercent:
|
case ESpercent:
|
vc_state = ESnormal;
|
vc_state = ESnormal;
|
switch (c) {
|
switch (c) {
|
case '@': /* defined in ISO 2022 */
|
case '@': /* defined in ISO 2022 */
|
utf = 0;
|
utf = 0;
|
continue;
|
continue;
|
case 'G': /* prelim official escape code */
|
case 'G': /* prelim official escape code */
|
case '8': /* retained for compatibility */
|
case '8': /* retained for compatibility */
|
utf = 1;
|
utf = 1;
|
continue;
|
continue;
|
}
|
}
|
continue;
|
continue;
|
case ESfunckey:
|
case ESfunckey:
|
vc_state = ESnormal;
|
vc_state = ESnormal;
|
continue;
|
continue;
|
case EShash:
|
case EShash:
|
vc_state = ESnormal;
|
vc_state = ESnormal;
|
if (c == '8') {
|
if (c == '8') {
|
/* DEC screen alignment test. kludge :-) */
|
/* DEC screen alignment test. kludge :-) */
|
video_erase_char =
|
video_erase_char =
|
(video_erase_char & 0xff00) | 'E';
|
(video_erase_char & 0xff00) | 'E';
|
/* Arno:
|
/* Arno:
|
* Doesn't work, because csi_J(c,2)
|
* Doesn't work, because csi_J(c,2)
|
* calls con_clear and doesn't print
|
* calls con_clear and doesn't print
|
* the erase char..
|
* the erase char..
|
*/
|
*/
|
csi_J(currcons, 2);
|
csi_J(currcons, 2);
|
video_erase_char =
|
video_erase_char =
|
(video_erase_char & 0xff00) | ' ';
|
(video_erase_char & 0xff00) | ' ';
|
}
|
}
|
continue;
|
continue;
|
case ESsetG0:
|
case ESsetG0:
|
if (c == '0')
|
if (c == '0')
|
G0_charset = GRAF_MAP;
|
G0_charset = GRAF_MAP;
|
else if (c == 'B')
|
else if (c == 'B')
|
G0_charset = LAT1_MAP;
|
G0_charset = LAT1_MAP;
|
else if (c == 'U')
|
else if (c == 'U')
|
G0_charset = IBMPC_MAP;
|
G0_charset = IBMPC_MAP;
|
else if (c == 'K')
|
else if (c == 'K')
|
G0_charset = USER_MAP;
|
G0_charset = USER_MAP;
|
if (charset == 0)
|
if (charset == 0)
|
translate = set_translate(G0_charset);
|
translate = set_translate(G0_charset);
|
vc_state = ESnormal;
|
vc_state = ESnormal;
|
continue;
|
continue;
|
case ESsetG1:
|
case ESsetG1:
|
if (c == '0')
|
if (c == '0')
|
G1_charset = GRAF_MAP;
|
G1_charset = GRAF_MAP;
|
else if (c == 'B')
|
else if (c == 'B')
|
G1_charset = LAT1_MAP;
|
G1_charset = LAT1_MAP;
|
else if (c == 'U')
|
else if (c == 'U')
|
G1_charset = IBMPC_MAP;
|
G1_charset = IBMPC_MAP;
|
else if (c == 'K')
|
else if (c == 'K')
|
G1_charset = USER_MAP;
|
G1_charset = USER_MAP;
|
if (charset == 1)
|
if (charset == 1)
|
translate = set_translate(G1_charset);
|
translate = set_translate(G1_charset);
|
vc_state = ESnormal;
|
vc_state = ESnormal;
|
continue;
|
continue;
|
default:
|
default:
|
vc_state = ESnormal;
|
vc_state = ESnormal;
|
}
|
}
|
}
|
}
|
if (vcmode != KD_GRAPHICS)
|
if (vcmode != KD_GRAPHICS)
|
set_cursor(currcons);
|
set_cursor(currcons);
|
enable_bh(CONSOLE_BH);
|
enable_bh(CONSOLE_BH);
|
return n;
|
return n;
|
}
|
}
|
|
|
static int con_write_room(struct tty_struct *tty)
|
static int con_write_room(struct tty_struct *tty)
|
{
|
{
|
if (tty->stopped)
|
if (tty->stopped)
|
return 0;
|
return 0;
|
return 4096; /* No limit, really; we're not buffering */
|
return 4096; /* No limit, really; we're not buffering */
|
}
|
}
|
|
|
static int con_chars_in_buffer(struct tty_struct *tty)
|
static int con_chars_in_buffer(struct tty_struct *tty)
|
{
|
{
|
return 0; /* we're not buffering */
|
return 0; /* we're not buffering */
|
}
|
}
|
|
|
void poke_blanked_console(void)
|
void poke_blanked_console(void)
|
{
|
{
|
timer_active &= ~(1<<BLANK_TIMER);
|
timer_active &= ~(1<<BLANK_TIMER);
|
if (vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
|
if (vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
|
return;
|
return;
|
if (console_blanked) {
|
if (console_blanked) {
|
timer_table[BLANK_TIMER].fn = unblank_screen;
|
timer_table[BLANK_TIMER].fn = unblank_screen;
|
timer_table[BLANK_TIMER].expires = 0;
|
timer_table[BLANK_TIMER].expires = 0;
|
timer_active |= 1<<BLANK_TIMER;
|
timer_active |= 1<<BLANK_TIMER;
|
} else if (blankinterval) {
|
} else if (blankinterval) {
|
timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
|
timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
|
timer_active |= 1<<BLANK_TIMER;
|
timer_active |= 1<<BLANK_TIMER;
|
}
|
}
|
}
|
}
|
|
|
/* DPC: New version of console_print using putcs */
|
/* DPC: New version of console_print using putcs */
|
|
|
void console_print(const char * b)
|
void console_print(const char * b)
|
{
|
{
|
int currcons = fg_console;
|
int currcons = fg_console;
|
unsigned char c;
|
unsigned char c;
|
const char *start = b;
|
const char *start = b;
|
ushort count = 0;
|
ushort count = 0;
|
ushort myx = x;
|
ushort myx = x;
|
static int printing = 0;
|
static int printing = 0;
|
|
|
if (!printable || printing)
|
if (!printable || printing)
|
return; /* console not yet initialized */
|
return; /* console not yet initialized */
|
printing = 1;
|
printing = 1;
|
|
|
if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1))
|
if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1))
|
currcons = kmsg_redirect - 1;
|
currcons = kmsg_redirect - 1;
|
|
|
if (!vc_cons_allocated(currcons)) {
|
if (!vc_cons_allocated(currcons)) {
|
/* impossible */
|
/* impossible */
|
printk("console_print: tty %d not allocated ??\n", currcons+1);
|
printk("console_print: tty %d not allocated ??\n", currcons+1);
|
printing = 0;
|
printing = 0;
|
return;
|
return;
|
}
|
}
|
|
|
/* undraw cursor first */
|
/* undraw cursor first */
|
hide_cursor(currcons);
|
hide_cursor(currcons);
|
|
|
/* Contrived structure to try to emulate original need_wrap behaviour
|
/* Contrived structure to try to emulate original need_wrap behaviour
|
* Problems caused when we have need_wrap set on '\n' character */
|
* Problems caused when we have need_wrap set on '\n' character */
|
|
|
while ((c = *(b++)) != 0) {
|
while ((c = *(b++)) != 0) {
|
if (c == 10 || c == 13 || c == 8 || need_wrap) {
|
if (c == 10 || c == 13 || c == 8 || need_wrap) {
|
if ((count = b - start - 1) > 0) {
|
if ((count = b - start - 1) > 0) {
|
sw->con_putcs(vc_cons[currcons].d, start, count ,
|
sw->con_putcs(vc_cons[currcons].d, start, count ,
|
y, x);
|
y, x);
|
x += count;
|
x += count;
|
if (need_wrap)
|
if (need_wrap)
|
x--;
|
x--;
|
}
|
}
|
|
|
if (c == 8) { /* backspace */
|
if (c == 8) { /* backspace */
|
bs(currcons);
|
bs(currcons);
|
start = b;
|
start = b;
|
myx = x;
|
myx = x;
|
continue;
|
continue;
|
}
|
}
|
if (c != 13)
|
if (c != 13)
|
lf(currcons);
|
lf(currcons);
|
cr(currcons);
|
cr(currcons);
|
|
|
if (c == 10 || c == 13) {
|
if (c == 10 || c == 13) {
|
start = b; myx = x; continue;
|
start = b; myx = x; continue;
|
}
|
}
|
|
|
start = b-1; myx = x;
|
start = b-1; myx = x;
|
}
|
}
|
|
|
*pos = c | (attr << 8);
|
*pos = c | (attr << 8);
|
if (myx == cols - 1) {
|
if (myx == cols - 1) {
|
need_wrap = 1;
|
need_wrap = 1;
|
continue;
|
continue;
|
}
|
}
|
pos++;
|
pos++;
|
myx++;
|
myx++;
|
}
|
}
|
|
|
if ((count = b - start -1) > 0) {
|
if ((count = b - start -1) > 0) {
|
sw->con_putcs(vc_cons[currcons].d, start, count ,
|
sw->con_putcs(vc_cons[currcons].d, start, count ,
|
y, x);
|
y, x);
|
x += count;
|
x += count;
|
if (x == cols)
|
if (x == cols)
|
{
|
{
|
x--;
|
x--;
|
need_wrap = 1;
|
need_wrap = 1;
|
}
|
}
|
}
|
}
|
|
|
set_cursor(currcons);
|
set_cursor(currcons);
|
poke_blanked_console();
|
poke_blanked_console();
|
printing = 0;
|
printing = 0;
|
}
|
}
|
|
|
|
|
/*
|
/*
|
* con_throttle and con_unthrottle are only used for
|
* con_throttle and con_unthrottle are only used for
|
* paste_selection(), which has to stuff in a large number of
|
* paste_selection(), which has to stuff in a large number of
|
* characters...
|
* characters...
|
*/
|
*/
|
static void con_throttle(struct tty_struct *tty)
|
static void con_throttle(struct tty_struct *tty)
|
{
|
{
|
}
|
}
|
|
|
static void con_unthrottle(struct tty_struct *tty)
|
static void con_unthrottle(struct tty_struct *tty)
|
{
|
{
|
struct vt_struct *vt = (struct vt_struct *) tty->driver_data;
|
struct vt_struct *vt = (struct vt_struct *) tty->driver_data;
|
|
|
wake_up_interruptible(&vt->paste_wait);
|
wake_up_interruptible(&vt->paste_wait);
|
}
|
}
|
|
|
static void vc_init(unsigned int currcons, int do_clear)
|
static void vc_init(unsigned int currcons, int do_clear)
|
{
|
{
|
long base = (long) vc_scrbuf[currcons];
|
long base = (long) vc_scrbuf[currcons];
|
|
|
pos = (unsigned short *)(origin = (ulong)video_mem_start = base);
|
pos = (unsigned short *)(origin = (ulong)video_mem_start = base);
|
scr_end = base + screenbuf_size;
|
scr_end = base + screenbuf_size;
|
video_mem_end = base + screenbuf_size;
|
video_mem_end = base + screenbuf_size;
|
reset_vc(currcons);
|
reset_vc(currcons);
|
def_color = 0x07; /* white */
|
def_color = 0x07; /* white */
|
ulcolor = 0x0f; /* bold white */
|
ulcolor = 0x0f; /* bold white */
|
halfcolor = 0x08; /* grey */
|
halfcolor = 0x08; /* grey */
|
vt_cons[currcons]->paste_wait = 0;
|
vt_cons[currcons]->paste_wait = 0;
|
reset_terminal(currcons, do_clear);
|
reset_terminal(currcons, do_clear);
|
}
|
}
|
|
|
/*
|
/*
|
* This is the console switching bottom half handler.
|
* This is the console switching bottom half handler.
|
*
|
*
|
* Doing console switching in a bottom half handler allows
|
* Doing console switching in a bottom half handler allows
|
* us to do the switches asynchronously (needed when we want
|
* us to do the switches asynchronously (needed when we want
|
* to switch due to a keyboard interrupt), while still giving
|
* to switch due to a keyboard interrupt), while still giving
|
* us the option to easily disable it to avoid races when we
|
* us the option to easily disable it to avoid races when we
|
* need to write to the console.
|
* need to write to the console.
|
*/
|
*/
|
static void console_bh(void)
|
static void console_bh(void)
|
{
|
{
|
if (want_console >= 0) {
|
if (want_console >= 0) {
|
if (want_console != fg_console) {
|
if (want_console != fg_console) {
|
change_console(want_console);
|
change_console(want_console);
|
/* we only changed when the console had already
|
/* we only changed when the console had already
|
been allocated - a new console is not created
|
been allocated - a new console is not created
|
in an interrupt routine */
|
in an interrupt routine */
|
}
|
}
|
want_console = -1;
|
want_console = -1;
|
}
|
}
|
if (do_poke_blanked_console) { /* do not unblank for a LED change */
|
if (do_poke_blanked_console) { /* do not unblank for a LED change */
|
do_poke_blanked_console = 0;
|
do_poke_blanked_console = 0;
|
poke_blanked_console();
|
poke_blanked_console();
|
}
|
}
|
}
|
}
|
|
|
/*
|
/*
|
* unsigned long con_init(unsigned long);
|
* unsigned long con_init(unsigned long);
|
*
|
*
|
* This routine initializes console interrupts, and does nothing
|
* This routine initializes console interrupts, and does nothing
|
* else. If you want the screen to clear, call tty_write with
|
* else. If you want the screen to clear, call tty_write with
|
* the appropriate escape-sequence.
|
* the appropriate escape-sequence.
|
*
|
*
|
* Reads the information preserved by setup.s to determine the current display
|
* Reads the information preserved by setup.s to determine the current display
|
* type and sets everything accordingly.
|
* type and sets everything accordingly.
|
*/
|
*/
|
unsigned long con_init(unsigned long kmem_start)
|
unsigned long con_init(unsigned long kmem_start)
|
{
|
{
|
char *display_desc = "????";
|
char *display_desc = "????";
|
unsigned int currcons = 0;
|
unsigned int currcons = 0;
|
extern int serial_debug;
|
extern int serial_debug;
|
|
|
memset(&console_driver, 0, sizeof(struct tty_driver));
|
memset(&console_driver, 0, sizeof(struct tty_driver));
|
console_driver.magic = TTY_DRIVER_MAGIC;
|
console_driver.magic = TTY_DRIVER_MAGIC;
|
console_driver.name = "tty";
|
console_driver.name = "tty";
|
console_driver.name_base = 1;
|
console_driver.name_base = 1;
|
console_driver.major = TTY_MAJOR;
|
console_driver.major = TTY_MAJOR;
|
console_driver.minor_start = 1;
|
console_driver.minor_start = 1;
|
console_driver.num = MAX_NR_CONSOLES;
|
console_driver.num = MAX_NR_CONSOLES;
|
console_driver.type = TTY_DRIVER_TYPE_CONSOLE;
|
console_driver.type = TTY_DRIVER_TYPE_CONSOLE;
|
console_driver.init_termios = tty_std_termios;
|
console_driver.init_termios = tty_std_termios;
|
console_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
|
console_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
|
console_driver.refcount = &console_refcount;
|
console_driver.refcount = &console_refcount;
|
console_driver.table = console_table;
|
console_driver.table = console_table;
|
console_driver.termios = console_termios;
|
console_driver.termios = console_termios;
|
console_driver.termios_locked = console_termios_locked;
|
console_driver.termios_locked = console_termios_locked;
|
|
|
console_driver.open = con_open;
|
console_driver.open = con_open;
|
console_driver.write = con_write;
|
console_driver.write = con_write;
|
console_driver.write_room = con_write_room;
|
console_driver.write_room = con_write_room;
|
console_driver.chars_in_buffer = con_chars_in_buffer;
|
console_driver.chars_in_buffer = con_chars_in_buffer;
|
console_driver.ioctl = vt_ioctl;
|
console_driver.ioctl = vt_ioctl;
|
console_driver.stop = con_stop;
|
console_driver.stop = con_stop;
|
console_driver.start = con_start;
|
console_driver.start = con_start;
|
console_driver.throttle = con_throttle;
|
console_driver.throttle = con_throttle;
|
console_driver.unthrottle = con_unthrottle;
|
console_driver.unthrottle = con_unthrottle;
|
|
|
if (tty_register_driver(&console_driver))
|
if (tty_register_driver(&console_driver))
|
panic("Couldn't register console driver\n");
|
panic("Couldn't register console driver\n");
|
|
|
kmem_start = conswitchp->con_startup (kmem_start, &display_desc);
|
kmem_start = conswitchp->con_startup (kmem_start, &display_desc);
|
|
|
timer_table[BLANK_TIMER].fn = blank_screen;
|
timer_table[BLANK_TIMER].fn = blank_screen;
|
timer_table[BLANK_TIMER].expires = 0;
|
timer_table[BLANK_TIMER].expires = 0;
|
if (blankinterval) {
|
if (blankinterval) {
|
timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
|
timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
|
timer_active |= 1<<BLANK_TIMER;
|
timer_active |= 1<<BLANK_TIMER;
|
}
|
}
|
|
|
/* Due to kmalloc roundup allocating statically is more efficient -
|
/* Due to kmalloc roundup allocating statically is more efficient -
|
so provide MIN_NR_CONSOLES for people with very little memory */
|
so provide MIN_NR_CONSOLES for people with very little memory */
|
for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
|
for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
|
vc_cons[currcons].d = (struct vc_data *) kmem_start;
|
vc_cons[currcons].d = (struct vc_data *) kmem_start;
|
kmem_start += sizeof(struct vc_data);
|
kmem_start += sizeof(struct vc_data);
|
vt_cons[currcons] = (struct vt_struct *) kmem_start;
|
vt_cons[currcons] = (struct vt_struct *) kmem_start;
|
kmem_start += sizeof(struct vt_struct);
|
kmem_start += sizeof(struct vt_struct);
|
|
|
/* ++Geert: sw->con_init determines console size */
|
/* ++Geert: sw->con_init determines console size */
|
sw = conswitchp;
|
sw = conswitchp;
|
cons_num = currcons;
|
cons_num = currcons;
|
sw->con_init (vc_cons[currcons].d);
|
sw->con_init (vc_cons[currcons].d);
|
size_row = cols<<1;
|
size_row = cols<<1;
|
screenbuf_size = rows*size_row;
|
screenbuf_size = rows*size_row;
|
|
|
vc_scrbuf[currcons] = (unsigned short *) kmem_start;
|
vc_scrbuf[currcons] = (unsigned short *) kmem_start;
|
kmem_start += screenbuf_size;
|
kmem_start += screenbuf_size;
|
kmalloced = 0;
|
kmalloced = 0;
|
vc_init(currcons, currcons);
|
vc_init(currcons, currcons);
|
}
|
}
|
|
|
currcons = fg_console = 0;
|
currcons = fg_console = 0;
|
|
|
gotoxy(currcons,0,0);
|
gotoxy(currcons,0,0);
|
csi_J(currcons, 0);
|
csi_J(currcons, 0);
|
printable = 1;
|
printable = 1;
|
update_screen(fg_console);
|
update_screen(fg_console);
|
sw->con_cursor(vc_cons[currcons].d, CM_DRAW);
|
sw->con_cursor(vc_cons[currcons].d, CM_DRAW);
|
printable = 1;
|
printable = 1;
|
|
|
/* If "serdebug" cmd line option was present, don't register for printk */
|
/* If "serdebug" cmd line option was present, don't register for printk */
|
if (!serial_debug)
|
if (!serial_debug)
|
register_console(console_print);
|
register_console(console_print);
|
printk("Console: %s %s %ldx%ld, %d virtual console%s (max %d)\n",
|
printk("Console: %s %s %ldx%ld, %d virtual console%s (max %d)\n",
|
can_do_color ? "colour":"mono",
|
can_do_color ? "colour":"mono",
|
display_desc,
|
display_desc,
|
cols,rows,
|
cols,rows,
|
MIN_NR_CONSOLES, (MIN_NR_CONSOLES == 1) ? "" : "s", MAX_NR_CONSOLES);
|
MIN_NR_CONSOLES, (MIN_NR_CONSOLES == 1) ? "" : "s", MAX_NR_CONSOLES);
|
|
|
init_bh(CONSOLE_BH, console_bh);
|
init_bh(CONSOLE_BH, console_bh);
|
return kmem_start;
|
return kmem_start;
|
}
|
}
|
|
|
void do_blank_screen(int nopowersave)
|
void do_blank_screen(int nopowersave)
|
{
|
{
|
int currcons;
|
int currcons;
|
|
|
if (console_blanked)
|
if (console_blanked)
|
return;
|
return;
|
|
|
if (!vc_cons_allocated(fg_console)) {
|
if (!vc_cons_allocated(fg_console)) {
|
/* impossible */
|
/* impossible */
|
printk("blank_screen: tty %d not allocated ??\n", fg_console+1);
|
printk("blank_screen: tty %d not allocated ??\n", fg_console+1);
|
return;
|
return;
|
}
|
}
|
|
|
/* don't blank graphics */
|
/* don't blank graphics */
|
if (vt_cons[fg_console]->vc_mode == KD_TEXT) {
|
if (vt_cons[fg_console]->vc_mode == KD_TEXT) {
|
timer_active &= ~(1<<BLANK_TIMER);
|
timer_active &= ~(1<<BLANK_TIMER);
|
timer_table[BLANK_TIMER].fn = unblank_screen;
|
timer_table[BLANK_TIMER].fn = unblank_screen;
|
|
|
/* try not to lose information by blanking,
|
/* try not to lose information by blanking,
|
and not to waste memory */
|
and not to waste memory */
|
currcons = fg_console;
|
currcons = fg_console;
|
has_scrolled = 0;
|
has_scrolled = 0;
|
sw->con_blank (1);
|
sw->con_blank (1);
|
}
|
}
|
else
|
else
|
hide_cursor(fg_console);
|
hide_cursor(fg_console);
|
console_blanked = fg_console + 1;
|
console_blanked = fg_console + 1;
|
}
|
}
|
|
|
void do_unblank_screen(void)
|
void do_unblank_screen(void)
|
{
|
{
|
int currcons;
|
int currcons;
|
|
|
if (!console_blanked)
|
if (!console_blanked)
|
return;
|
return;
|
if (!vc_cons_allocated(fg_console)) {
|
if (!vc_cons_allocated(fg_console)) {
|
/* impossible */
|
/* impossible */
|
printk("unblank_screen: tty %d not allocated ??\n", fg_console+1);
|
printk("unblank_screen: tty %d not allocated ??\n", fg_console+1);
|
return;
|
return;
|
}
|
}
|
timer_table[BLANK_TIMER].fn = blank_screen;
|
timer_table[BLANK_TIMER].fn = blank_screen;
|
if (blankinterval) {
|
if (blankinterval) {
|
timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
|
timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
|
timer_active |= 1<<BLANK_TIMER;
|
timer_active |= 1<<BLANK_TIMER;
|
}
|
}
|
|
|
currcons = fg_console;
|
currcons = fg_console;
|
console_blanked = 0;
|
console_blanked = 0;
|
if (sw->con_blank (0))
|
if (sw->con_blank (0))
|
/* Low-level driver cannot restore -> do it ourselves */
|
/* Low-level driver cannot restore -> do it ourselves */
|
update_screen( fg_console );
|
update_screen( fg_console );
|
set_cursor (fg_console);
|
set_cursor (fg_console);
|
}
|
}
|
|
|
void update_screen(int new_console)
|
void update_screen(int new_console)
|
{
|
{
|
int currcons = fg_console;
|
int currcons = fg_console;
|
int xx, yy, startx, attr_save;
|
int xx, yy, startx, attr_save;
|
char buf[256], *bufp;
|
char buf[256], *bufp;
|
unsigned short *p;
|
unsigned short *p;
|
static int lock = 0;
|
static int lock = 0;
|
|
|
if (/* new_console == fg_console || */ lock)
|
if (/* new_console == fg_console || */ lock)
|
return;
|
return;
|
if (!vc_cons_allocated(new_console)) {
|
if (!vc_cons_allocated(new_console)) {
|
/* strange ... */
|
/* strange ... */
|
printk("update_screen: tty %d not allocated ??\n", new_console+1);
|
printk("update_screen: tty %d not allocated ??\n", new_console+1);
|
return;
|
return;
|
}
|
}
|
lock = 1;
|
lock = 1;
|
|
|
clear_selection();
|
clear_selection();
|
|
|
currcons = fg_console = new_console;
|
currcons = fg_console = new_console;
|
sw->con_cursor (vc_cons[currcons].d, CM_ERASE);
|
sw->con_cursor (vc_cons[currcons].d, CM_ERASE);
|
sw->con_switch (vc_cons[new_console].d);
|
sw->con_switch (vc_cons[new_console].d);
|
/* Update the screen contents */
|
/* Update the screen contents */
|
p = video_mem_start;
|
p = video_mem_start;
|
attr_save = attr;
|
attr_save = attr;
|
for (yy = 0; yy < rows; yy++)
|
for (yy = 0; yy < rows; yy++)
|
{
|
{
|
bufp = buf;
|
bufp = buf;
|
for (startx = xx = 0; xx < cols; xx++)
|
for (startx = xx = 0; xx < cols; xx++)
|
{
|
{
|
if (attr != ((*p >> 8) & 0xff))
|
if (attr != ((*p >> 8) & 0xff))
|
{
|
{
|
if (bufp > buf)
|
if (bufp > buf)
|
sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf,
|
sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf,
|
yy, startx);
|
yy, startx);
|
startx = xx;
|
startx = xx;
|
bufp = buf;
|
bufp = buf;
|
attr = (*p >> 8) & 0xff;
|
attr = (*p >> 8) & 0xff;
|
}
|
}
|
*bufp++ = *p++;
|
*bufp++ = *p++;
|
if (bufp == buf + sizeof (buf))
|
if (bufp == buf + sizeof (buf))
|
{
|
{
|
sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf,
|
sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf,
|
yy, startx);
|
yy, startx);
|
startx = xx + 1;
|
startx = xx + 1;
|
bufp = buf;
|
bufp = buf;
|
}
|
}
|
}
|
}
|
if (bufp > buf)
|
if (bufp > buf)
|
sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf,
|
sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf,
|
yy, startx);
|
yy, startx);
|
}
|
}
|
set_cursor (currcons);
|
set_cursor (currcons);
|
attr = attr_save;
|
attr = attr_save;
|
set_leds();
|
set_leds();
|
compute_shiftstate();
|
compute_shiftstate();
|
lock = 0;
|
lock = 0;
|
}
|
}
|
|
|
/*
|
/*
|
* If a blank_screen is due to a timer, then a power save is allowed.
|
* If a blank_screen is due to a timer, then a power save is allowed.
|
* If it is related to console_switching, then avoid vesa_blank().
|
* If it is related to console_switching, then avoid vesa_blank().
|
*/
|
*/
|
static void blank_screen(void)
|
static void blank_screen(void)
|
{
|
{
|
do_blank_screen(0);
|
do_blank_screen(0);
|
}
|
}
|
|
|
static void unblank_screen(void)
|
static void unblank_screen(void)
|
{
|
{
|
do_unblank_screen();
|
do_unblank_screen();
|
}
|
}
|
|
|
/*
|
/*
|
* Allocate the console screen memory.
|
* Allocate the console screen memory.
|
*/
|
*/
|
int con_open(struct tty_struct *tty, struct file * filp)
|
int con_open(struct tty_struct *tty, struct file * filp)
|
{
|
{
|
unsigned int currcons;
|
unsigned int currcons;
|
int i;
|
int i;
|
|
|
currcons = MINOR(tty->device) - tty->driver.minor_start;
|
currcons = MINOR(tty->device) - tty->driver.minor_start;
|
|
|
i = vc_allocate(currcons);
|
i = vc_allocate(currcons);
|
if (i)
|
if (i)
|
return i;
|
return i;
|
|
|
vt_cons[currcons]->vc_num = currcons;
|
vt_cons[currcons]->vc_num = currcons;
|
tty->driver_data = vt_cons[currcons];
|
tty->driver_data = vt_cons[currcons];
|
|
|
if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
|
if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
|
tty->winsize.ws_row = rows;
|
tty->winsize.ws_row = rows;
|
tty->winsize.ws_col = cols;
|
tty->winsize.ws_col = cols;
|
}
|
}
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
/*
|
/*
|
* PIO_FONT support.
|
* PIO_FONT support.
|
*
|
*
|
* The font loading code goes back to the codepage package by
|
* The font loading code goes back to the codepage package by
|
* Joel Hoffman (joel@wam.umd.edu). (He reports that the original
|
* Joel Hoffman (joel@wam.umd.edu). (He reports that the original
|
* reference is: "From: p. 307 of _Programmer's Guide to PC & PS/2
|
* reference is: "From: p. 307 of _Programmer's Guide to PC & PS/2
|
* Video Systems_ by Richard Wilton. 1987. Microsoft Press".)
|
* Video Systems_ by Richard Wilton. 1987. Microsoft Press".)
|
*
|
*
|
* Change for certain monochrome monitors by Yury Shevchuck
|
* Change for certain monochrome monitors by Yury Shevchuck
|
* (sizif@botik.yaroslavl.su).
|
* (sizif@botik.yaroslavl.su).
|
*/
|
*/
|
|
|
#define colourmap ((char *)0xa0000)
|
#define colourmap ((char *)0xa0000)
|
/* Pauline Middelink <middelin@polyware.iaf.nl> reports that we
|
/* Pauline Middelink <middelin@polyware.iaf.nl> reports that we
|
should use 0xA0000 for the bwmap as well.. */
|
should use 0xA0000 for the bwmap as well.. */
|
#define blackwmap ((char *)0xa0000)
|
#define blackwmap ((char *)0xa0000)
|
#define cmapsz 8192
|
#define cmapsz 8192
|
#define seq_port_reg (0x3c4)
|
#define seq_port_reg (0x3c4)
|
#define seq_port_val (0x3c5)
|
#define seq_port_val (0x3c5)
|
#define gr_port_reg (0x3ce)
|
#define gr_port_reg (0x3ce)
|
#define gr_port_val (0x3cf)
|
#define gr_port_val (0x3cf)
|
|
|
static int set_get_font(char * arg, int set)
|
static int set_get_font(char * arg, int set)
|
{
|
{
|
#ifdef CAN_LOAD_EGA_FONTS
|
#ifdef CAN_LOAD_EGA_FONTS
|
int i;
|
int i;
|
char *charmap;
|
char *charmap;
|
int beg;
|
int beg;
|
|
|
/* no use to "load" CGA... */
|
/* no use to "load" CGA... */
|
|
|
if (video_type == VIDEO_TYPE_EGAC) {
|
if (video_type == VIDEO_TYPE_EGAC) {
|
charmap = colourmap;
|
charmap = colourmap;
|
beg = 0x0e;
|
beg = 0x0e;
|
} else if (video_type == VIDEO_TYPE_EGAM) {
|
} else if (video_type == VIDEO_TYPE_EGAM) {
|
charmap = blackwmap;
|
charmap = blackwmap;
|
beg = 0x0a;
|
beg = 0x0a;
|
} else
|
} else
|
return -EINVAL;
|
return -EINVAL;
|
|
|
i = verify_area(set ? VERIFY_READ : VERIFY_WRITE, (void *)arg, cmapsz);
|
i = verify_area(set ? VERIFY_READ : VERIFY_WRITE, (void *)arg, cmapsz);
|
if (i)
|
if (i)
|
return i;
|
return i;
|
|
|
cli();
|
cli();
|
outb_p( 0x00, seq_port_reg ); /* First, the sequencer */
|
outb_p( 0x00, seq_port_reg ); /* First, the sequencer */
|
outb_p( 0x01, seq_port_val ); /* Synchronous reset */
|
outb_p( 0x01, seq_port_val ); /* Synchronous reset */
|
outb_p( 0x02, seq_port_reg );
|
outb_p( 0x02, seq_port_reg );
|
outb_p( 0x04, seq_port_val ); /* CPU writes only to map 2 */
|
outb_p( 0x04, seq_port_val ); /* CPU writes only to map 2 */
|
outb_p( 0x04, seq_port_reg );
|
outb_p( 0x04, seq_port_reg );
|
outb_p( 0x07, seq_port_val ); /* Sequential addressing */
|
outb_p( 0x07, seq_port_val ); /* Sequential addressing */
|
outb_p( 0x00, seq_port_reg );
|
outb_p( 0x00, seq_port_reg );
|
outb_p( 0x03, seq_port_val ); /* Clear synchronous reset */
|
outb_p( 0x03, seq_port_val ); /* Clear synchronous reset */
|
|
|
outb_p( 0x04, gr_port_reg ); /* Now, the graphics controller */
|
outb_p( 0x04, gr_port_reg ); /* Now, the graphics controller */
|
outb_p( 0x02, gr_port_val ); /* select map 2 */
|
outb_p( 0x02, gr_port_val ); /* select map 2 */
|
outb_p( 0x05, gr_port_reg );
|
outb_p( 0x05, gr_port_reg );
|
outb_p( 0x00, gr_port_val ); /* disable odd-even addressing */
|
outb_p( 0x00, gr_port_val ); /* disable odd-even addressing */
|
outb_p( 0x06, gr_port_reg );
|
outb_p( 0x06, gr_port_reg );
|
outb_p( 0x00, gr_port_val ); /* map start at A000:0000 */
|
outb_p( 0x00, gr_port_val ); /* map start at A000:0000 */
|
sti();
|
sti();
|
|
|
if (set)
|
if (set)
|
memcpy_fromfs (charmap, arg, cmapsz);
|
memcpy_fromfs (charmap, arg, cmapsz);
|
else
|
else
|
memcpy_tofs (arg, charmap, cmapsz);
|
memcpy_tofs (arg, charmap, cmapsz);
|
|
|
cli();
|
cli();
|
outb_p( 0x00, seq_port_reg ); /* First, the sequencer */
|
outb_p( 0x00, seq_port_reg ); /* First, the sequencer */
|
outb_p( 0x01, seq_port_val ); /* Synchronous reset */
|
outb_p( 0x01, seq_port_val ); /* Synchronous reset */
|
outb_p( 0x02, seq_port_reg );
|
outb_p( 0x02, seq_port_reg );
|
outb_p( 0x03, seq_port_val ); /* CPU writes to maps 0 and 1 */
|
outb_p( 0x03, seq_port_val ); /* CPU writes to maps 0 and 1 */
|
outb_p( 0x04, seq_port_reg );
|
outb_p( 0x04, seq_port_reg );
|
outb_p( 0x03, seq_port_val ); /* odd-even addressing */
|
outb_p( 0x03, seq_port_val ); /* odd-even addressing */
|
outb_p( 0x00, seq_port_reg );
|
outb_p( 0x00, seq_port_reg );
|
outb_p( 0x03, seq_port_val ); /* clear synchronous reset */
|
outb_p( 0x03, seq_port_val ); /* clear synchronous reset */
|
|
|
outb_p( 0x04, gr_port_reg ); /* Now, the graphics controller */
|
outb_p( 0x04, gr_port_reg ); /* Now, the graphics controller */
|
outb_p( 0x00, gr_port_val ); /* select map 0 for CPU */
|
outb_p( 0x00, gr_port_val ); /* select map 0 for CPU */
|
outb_p( 0x05, gr_port_reg );
|
outb_p( 0x05, gr_port_reg );
|
outb_p( 0x10, gr_port_val ); /* enable even-odd addressing */
|
outb_p( 0x10, gr_port_val ); /* enable even-odd addressing */
|
outb_p( 0x06, gr_port_reg );
|
outb_p( 0x06, gr_port_reg );
|
outb_p( beg, gr_port_val ); /* map starts at b800:0 or b000:0 */
|
outb_p( beg, gr_port_val ); /* map starts at b800:0 or b000:0 */
|
sti();
|
sti();
|
|
|
return 0;
|
return 0;
|
#else
|
#else
|
return -EINVAL;
|
return -EINVAL;
|
#endif
|
#endif
|
}
|
}
|
|
|
/*
|
/*
|
* Load palette into the EGA/VGA DAC registers. arg points to a colour
|
* Load palette into the EGA/VGA DAC registers. arg points to a colour
|
* map, 3 bytes per colour, 16 colours, range from 0 to 255.
|
* map, 3 bytes per colour, 16 colours, range from 0 to 255.
|
*/
|
*/
|
|
|
int con_set_cmap (unsigned char *arg)
|
int con_set_cmap (unsigned char *arg)
|
{
|
{
|
return -EINVAL;
|
return -EINVAL;
|
}
|
}
|
|
|
int con_get_cmap (unsigned char *arg)
|
int con_get_cmap (unsigned char *arg)
|
{
|
{
|
return -EINVAL;
|
return -EINVAL;
|
}
|
}
|
|
|
void reset_palette(int currcons)
|
void reset_palette(int currcons)
|
{
|
{
|
}
|
}
|
|
|
void set_palette(void)
|
void set_palette(void)
|
{
|
{
|
}
|
}
|
|
|
/*
|
/*
|
* Load font into the EGA/VGA character generator. arg points to a 8192
|
* Load font into the EGA/VGA character generator. arg points to a 8192
|
* byte map, 32 bytes per character. Only first H of them are used for
|
* byte map, 32 bytes per character. Only first H of them are used for
|
* 8xH fonts (0 < H <= 32).
|
* 8xH fonts (0 < H <= 32).
|
*/
|
*/
|
|
|
int con_set_font (char *arg)
|
int con_set_font (char *arg)
|
{
|
{
|
hashtable_contents_valid = 0;
|
hashtable_contents_valid = 0;
|
return set_get_font (arg,1);
|
return set_get_font (arg,1);
|
}
|
}
|
|
|
int con_get_font (char *arg)
|
int con_get_font (char *arg)
|
{
|
{
|
return set_get_font (arg,0);
|
return set_get_font (arg,0);
|
}
|
}
|
|
|
/*
|
/*
|
* Adjust the screen to fit a font of a certain height
|
* Adjust the screen to fit a font of a certain height
|
*
|
*
|
* Returns < 0 for error, 0 if nothing changed, and the number
|
* Returns < 0 for error, 0 if nothing changed, and the number
|
* of lines on the adjusted console if changed.
|
* of lines on the adjusted console if changed.
|
*/
|
*/
|
int con_adjust_height(unsigned long fontheight)
|
int con_adjust_height(unsigned long fontheight)
|
{
|
{
|
return -EINVAL;
|
return -EINVAL;
|
}
|
}
|
|
|
void set_vesa_blanking(int arg)
|
void set_vesa_blanking(int arg)
|
{
|
{
|
}
|
}
|
|
|
unsigned long get_video_num_lines(unsigned int currcons)
|
unsigned long get_video_num_lines(unsigned int currcons)
|
{
|
{
|
return(rows);
|
return(rows);
|
}
|
}
|
|
|
unsigned long get_video_num_columns(unsigned int currcons)
|
unsigned long get_video_num_columns(unsigned int currcons)
|
{
|
{
|
return(cols);
|
return(cols);
|
}
|
}
|
|
|
unsigned long get_video_size_row(unsigned int currcons)
|
unsigned long get_video_size_row(unsigned int currcons)
|
{
|
{
|
return(size_row);
|
return(size_row);
|
}
|
}
|
|
|