📄 console.c
字号:
/* * linux/arch/arm/drivers/char/console.c * * Modifications (C) 1995, 1996 Russell King *//* * This module exports the console io functions: * * 'int vcd_init (struct vt *vt, int kmallocok, unsigned long *kmem)' * 'unsigned long vcd_pre_init (unsigned long kmem, struct vt *vt)' * 'void vcd_disallocate (struct vt *vt)' * 'int vcd_resize (unsigned long lines, unsigned long cols)' * 'void vcd_blankscreen (int nopowersave)' * 'void vcd_unblankscreen (void)' * 'void vcd_savestate (const struct vt *vt, int blanked)' * 'void vcd_restorestate (const struct vt *vt)' * 'void vcd_setup_graphics (const struct vt *vt)' * 'int vcd_write (const struct vt *vt, int from_user, const unsigned char *buf, int count)' * 'int vcd_ioctl (const struct vt *vt, int cmd, unsigned long arg)' * * * 'unsigned long con_init(unsigned long)' * S 'int con_open(struct tty_struct *tty,struct file *filp)' * S 'void con_write(struct tty_struct *tty)' * S 'void console_print(const char *b)' * * 'void unblank_screen(void)' * 'void scrollback(int lines)' * * 'void scrollfront(int lines)' * * 'int do_screendump(int arg)' * * 'int con_get_font(char *)' * 'int con_set_font(char *)' * 'int con_get_trans(char *)' * 'int con_set_trans(char *)' * * 'int mouse_reporting(void)' */#define BLANK 0x0020/* A bitmap for codes <32. A bit of 1 indicates that the code * corresponding to that bit number invokes a special action * (such as cursor movement) and should not be displayed as a * glyph unless the disp_ctrl mode is explicitly enabled. */#define CTRL_ACTION 0x0d00ff81#define CTRL_ALWAYS 0x0800f501 /* Cannot be overriden by disp_ctrl *//* * Here is the default bell parameters: 750HZ, 1/8th of a second */#define DEFAULT_BELL_PITCH 750#define DEFAULT_BELL_DURATION (HZ/8)/* * 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 * interrupts. We know interrupts aren't enabled when getting a keyboard * interrupt, as we use trap-gates. Hopefully all is well. */ #include <linux/config.h>#include <linux/sched.h>#include <linux/timer.h>#include <linux/interrupt.h>#include <linux/tty.h>#include <linux/tty_flip.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/kd.h>#include <linux/major.h>#include <linux/malloc.h>#include <linux/mm.h>#include <asm/io.h>#include <asm/segment.h>#include <asm/irq.h>#include <asm/hardware.h>#define DEBUG#include "kbd_kern.h"#include "consolemap.h"#include "vt_kern.h"#include "selection.h"#define set_kbd(x) set_vc_kbd_mode (vt->kbd, x)#define clr_kbd(x) clr_vc_kbd_mode (vt->kbd, x)#define is_kbd(x) vc_kbd_mode (vt->kbd, x)#define decarm VC_REPEAT#define decckm VC_CKMODE#define kbdapplic VC_APPLIC#define lnm VC_CRLF/* * this is what the terminal answers to a ESC-Z or csi0c query. */#define VT100ID "\033[?1;2c"#define VT102ID "\033[?6c"extern int setup_arm_irq(int, struct irqaction *);/* * routines to load custom translation table, EGA/VGA font and * VGA colour palette from console.c */extern int con_set_trans_old(unsigned char * table);extern int con_get_trans_old(unsigned char * table);extern int con_set_trans_new(unsigned short * table);extern int con_get_trans_new(unsigned short * table);extern void con_clear_unimap(struct unimapinit *ui);extern int con_set_unimap(ushort ct, struct unipair *list);extern int con_get_unimap(ushort ct, ushort *uct, struct unipair *list);extern void con_set_default_unimap(void);extern int con_set_font(char * fontmap);extern int con_get_font(char * fontmap);/* ARM Extensions */#if defined(HAS_VIDC)extern void memc_write (int reg, int val);extern void vidc_write (int reg, int val);static int __r;#define palette_setpixel(p) __r = p#define palette_write(v) \{ \ int rr = __r++, red, green, blue, vv = (v); \ red = (vv >> 4) & 0x00f; \ green = (vv >> 8) & 0x0f0; \ blue = (vv >> 12) & 0xf00; \ outl((rr<<26)|red|green|blue, IO_VIDC_BASE); \}#define MAX_PIX 16#elif defined(HAS_VIDC20)#define palette_setpixel(p) outl(0x10000000|((p) & 255), IO_VIDC_BASE)#define palette_write(v) outl(0x00000000|((v) & 0x00ffffff), IO_VIDC_BASE)#define MAX_PIX 256#endif/* * from ll_wr_char.S */int bytes_per_char_h, bytes_per_char_v, video_size_row;extern void ll_write_char(unsigned long ps, unsigned long chinfo);extern unsigned long con_charconvtable[256];extern unsigned long map_screen_mem (unsigned long vid_base, unsigned long kmem, int remap);#include <linux/ctype.h>extern struct console_driver screen_driver, buffer_driver;#ifndef MIN#define MIN(a,b) ((a) < (b) ? (a) : (b))#endifstatic void gotoxy (struct con_struct *vcd, int new_x, int new_y);static inline void set_cursor (const struct vt * const vt);extern void reset_vc(const struct vt * const vt);extern void register_console(void (*proc)(const char *));extern void compute_shiftstate(void);extern void con_reset_palette (const struct vt * const vt);extern void con_set_palette (const struct vt * const vt);static int printable; /* Is console ready for printing? */#define console_charmask 0xff#ifndef console_charmaskstatic unsigned short console_charmask = 0x0ff;#endif#include "font.h"static const unsigned long palette_1[MAX_PIX] = { 0x00000000, /* Black */ 0x00ffffff, /* White */ 0x00000000 /* Black */};static const unsigned long palette_4[MAX_PIX] = { 0x00000000, /* Black */ 0x000000cc, /* Red */ 0x0000cc00, /* Green */ 0x0000cccc, /* Yellow */ 0x00cc0000, /* Blue */ 0x00cc00cc, /* Magenta */ 0x00cccc00, /* Cyan */ 0x00cccccc, /* White */ 0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff, 0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff};#if defined(HAS_VIDC)static const unsigned long palette_8[MAX_PIX] = { 0x00000000, 0x00111111, 0x00222222, 0x00333333, 0x00440000, 0x00551111, 0x00662222, 0x00773333, 0x00000044, 0x00111155, 0x00222266, 0x00333377, 0x00440044, 0x00551155, 0x00662266, 0x00773377};#elif defined(HAS_VIDC20)#define palette_8 palette_4#endifstatic const unsigned long *default_palette_entries = palette_4;static const unsigned char color_1[] = {0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 };static const unsigned char color_4[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 };#if defined(HAS_VIDC)static const unsigned char color_8[] = {0x00, 0x18, 0x60, 0x78, 0x84, 0x9C, 0xE4, 0xFC, 0x00, 0x1B, 0x63, 0x7B, 0x87, 0x9F, 0xE7, 0xFF};#elif defined(HAS_VIDC20)static const unsigned char color_8[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 };#endifstatic const unsigned char *color_table = color_4;/*===================================================================================*/#ifdef CONFIG_SERIAL_ECHO#include "serialecho.c"#endif/* * functions to handle /dev/fb */int con_fb_read(char *buf, unsigned long pos, int count){ return -EIO;}int con_fb_write(const char *buf, unsigned long pos, int count){ return -EIO;}int con_fb_mmap(unsigned long vma_start, unsigned long vma_offset, unsigned long vma_end, pgprot_t prot){ if (vma_offset > vtdata.screen.memsize || vma_end - vma_start + vma_offset > vtdata.screen.memsize) return -EINVAL; return remap_page_range(vma_start, SCREEN2_BASE + vma_offset, vma_end - vma_start, prot);}#ifdef DEBUGstatic int vcd_validate (struct con_struct *vcd, const char *msg){ unsigned long old_scrorigin, old_scrpos, old_buforigin, old_bufpos, w = 0; old_scrorigin = vcd->screen.origin; old_scrpos = vcd->screen.pos; old_buforigin = vtdata.buffer.origin; old_bufpos = vcd->buffer.pos; if (vcd->screen.origin < SCREEN1_BASE || vcd->screen.origin > SCREEN1_END) { vcd->screen.origin = SCREEN2_BASE; w = 1; } if (vcd->screen.pos < SCREEN1_BASE || vcd->screen.pos > SCREEN2_END) { vcd->screen.pos = SCREEN2_BASE; w = 1; } if (w) printk ("*** CONSOLE ERROR: %s: (%p): origin = %08lX pos = %08lX ***\n", msg, vcd, old_scrorigin, old_scrpos); return w;}#endifvoid no_scroll(char *str, int *ints){}static unsigned long __origin; /* Offset of currently displayed screen */static void __set_origin(unsigned long offset){ unsigned long flags; clear_selection (); offset = offset - vtdata.screen.memstart; if (offset >= vtdata.screen.memsize) offset -= vtdata.screen.memsize; save_flags_cli (flags); __origin = offset; video_set_dma(0, vtdata.screen.memsize, offset); restore_flags(flags);}void scrollback(int lines){}void scrollfront(int lines){}void scroll_set_origin (unsigned long offset){ __set_origin(offset);}static void set_origin (const struct vt * const vt){ if (vtdata.fgconsole != vt || vt->vtd->vc_mode == KD_GRAPHICS) return; __set_origin(vt->vcd->screen.origin);}/* ------------------------------------------------------------------------------- * Cursor * ------------------------------------------------------------------------------- */static char cursor_on = 0;static unsigned long cp;static void put_cursor(char on_off,unsigned long newcp){ static char con; unsigned long cp_p = cp; int c = vtdata.screen.bytespercharh == 8 ? color_table[15] : 0x11 * color_table[15]; int i; if (vtdata.fgconsole->vtd->vc_mode == KD_GRAPHICS) return; cp = newcp; if (con != on_off) { if (cp_p != -1) for (i = 0; i < vtdata.screen.bytespercharh; i++) ((unsigned char*)cp_p)[i]^=c; con = on_off; }}static void vsync_irq(int irq, void *dev_id, struct pt_regs *regs){ static char cursor_flash = 16; if (!--cursor_flash) { cursor_flash = 16; cursor_on = cursor_on ? 0 : 1; if (vtdata.fgconsole->vcd->screen.cursoron > 0) put_cursor(cursor_on,cp); }}static void hide_cursor(void){ put_cursor (0, -1);}static void set_cursor (const struct vt * const vt){ unsigned long flags; if (vt != vtdata.fgconsole || vt->vtd->vc_mode == KD_GRAPHICS) return; save_flags_cli (flags); if (vt->vcd->deccm) {#ifdef DEBUG vcd_validate (vt->vcd, "set_cursor");#endif cp = vt->vcd->screen.pos + vtdata.numcolumns * vtdata.screen.bytespercharh * (vtdata.screen.bytespercharv - 1); } else hide_cursor(); restore_flags(flags);}static void vcd_removecursors (const struct vt *vt){ unsigned long flags; save_flags_cli (flags); if (--vt->vcd->screen.cursoron == 0 && vtdata.fgconsole == vt) put_cursor (0, cp); restore_flags (flags);}static void vcd_restorecursors(const struct vt *vt){ unsigned long flags; save_flags_cli (flags); if (++vt->vcd->screen.cursoron == 1 && cursor_on && vtdata.fgconsole == vt) put_cursor (1, cp); restore_flags (flags);}/* ----------------------------------------------------------------------------------------- * VC stuff * ----------------------------------------------------------------------------------------- *//* * gotoxy() must verify all boundaries, because the arguments * might also be negative. If a given position is out of * bounds, the cursor is placed at the nearest margin. */static void gotoxy (struct con_struct *vcd, int new_x, int new_y){ int min_y, max_y; if (new_x < 0) vcd->curstate.x = 0; else if (new_x >= vtdata.numcolumns) vcd->curstate.x = vtdata.numcolumns - 1; else vcd->curstate.x = new_x; if (vcd->decom) { new_y += vcd->top; min_y = vcd->top; max_y = vcd->bottom; } else { min_y = 0; max_y = vtdata.numrows; } if (new_y < min_y) vcd->curstate.y = min_y; else if (new_y >= max_y) vcd->curstate.y = max_y - 1; else vcd->curstate.y = new_y; vcd->driver.gotoxy (vcd); vcd->need_wrap = 0;#ifdef DEBUG vcd_validate (vcd, "gotoxy");#endif}/* for absolute user moves, when decom is set */static void gotoxay (struct con_struct *vcd, int new_x, int new_y){ gotoxy(vcd, new_x, vcd->decom ? (vcd->top+new_y) : new_y);}static void update_attr (const struct vt * const vt){ unsigned int backcol, forecol; backcol = color_table[vt->vcd->curstate.backcol]; if (vt->vcd->curstate.flags & FLG_BOLD) forecol = color_table[vt->vcd->curstate.forecol + 8]; else forecol = color_table[vt->vcd->curstate.forecol]; vt->vcd->combined_state = (vt->vcd->curstate.flags << 24) | (backcol << 16) | (forecol << 8); switch (vtdata.screen.bitsperpix) { case 1: vt->vcd->cached_backcolwrd = 0; break; default: case 4: vt->vcd->cached_backcolwrd = 0x11111111 * backcol; break; case 8: vt->vcd->cached_backcolwrd = 0x01010101 * backcol; break; }}static void default_attr (const struct vt * const vt){ vt->vcd->curstate.flags &= ~(FLG_INVERSE|FLG_FLASH|FLG_UNDERLINE|FLG_ITALIC|FLG_BOLD); vt->vcd->curstate.forecol = vt->vcd->def_forecol; vt->vcd->curstate.backcol = vt->vcd->def_backcol;}static int csi_m (const struct vt * const vt){ struct con_struct *vcd = vt->vcd; int i, ret = 0; for (i = 0; i <= vcd->npar; i++) { switch (vcd->par[i]) { case 0: default_attr (vt); break; case 1: vcd->curstate.flags |= FLG_BOLD; break; /* Bold */ case 2: vcd->curstate.flags &= ~FLG_BOLD; break; /* Feint */ case 3: vcd->curstate.flags |= FLG_ITALIC; break; /* Italic */ case 4: vcd->curstate.flags |= FLG_UNDERLINE; break; /* Underline */ case 5: case 6: vcd->curstate.flags |= FLG_FLASH; break; /* Flash */ case 7: vcd->curstate.flags |= FLG_INVERSE; break; /* Inverse chars */ case 10: /* ANSI X3.64-1979 (SCO-ish?) * Select primary font, don't display
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -