vt.c
来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 2,768 行 · 第 1/5 页
C
2,768 行
if (currcons == sel_cons) clear_selection(); sw->con_cursor(vc_cons[currcons].d,CM_ERASE); hide_softcursor(currcons);}static void set_cursor(int currcons){ if (!IS_FG || console_blanked || vcmode == KD_GRAPHICS) return; if (deccm) { if (currcons == sel_cons) clear_selection(); add_softcursor(currcons); if ((cursor_type & 0x0f) != 1) sw->con_cursor(vc_cons[currcons].d,CM_DRAW); } else hide_cursor(currcons);}static void set_origin(int currcons){ WARN_CONSOLE_UNLOCKED(); if (!IS_VISIBLE || !sw->con_set_origin || !sw->con_set_origin(vc_cons[currcons].d)) origin = (unsigned long) screenbuf; visible_origin = origin; scr_end = origin + screenbuf_size; pos = origin + video_size_row*y + 2*x;}static inline void save_screen(int currcons){ WARN_CONSOLE_UNLOCKED(); if (sw->con_save_screen) sw->con_save_screen(vc_cons[currcons].d);}/* * Redrawing of screen */static void clear_buffer_attributes(int currcons){ unsigned short *p = (unsigned short *) origin; int count = screenbuf_size/2; int mask = hi_font_mask | 0xff; for (; count > 0; count--, p++) { scr_writew((scr_readw(p)&mask) | (video_erase_char&~mask), p); }}void redraw_screen(int new_console, int is_switch){ int redraw = 1; int currcons, old_console; WARN_CONSOLE_UNLOCKED(); if (!vc_cons_allocated(new_console)) { /* strange ... */ /* printk("redraw_screen: tty %d not allocated ??\n", new_console+1); */ return; } if (is_switch) { currcons = fg_console; hide_cursor(currcons); if (fg_console != new_console) { struct vc_data **display = vc_cons[new_console].d->vc_display_fg; old_console = (*display) ? (*display)->vc_num : fg_console; *display = vc_cons[new_console].d; fg_console = new_console; currcons = old_console; if (!IS_VISIBLE) { save_screen(currcons); set_origin(currcons); } currcons = new_console; if (old_console == new_console) redraw = 0; } } else { currcons = new_console; hide_cursor(currcons); } if (redraw) { int update; int old_was_color = vc_cons[currcons].d->vc_can_do_color; set_origin(currcons); update = sw->con_switch(vc_cons[currcons].d); set_palette(currcons); /* * If console changed from mono<->color, the best we can do * is to clear the buffer attributes. As it currently stands, * rebuilding new attributes from the old buffer is not doable * without overly complex code. */ if (old_was_color != vc_cons[currcons].d->vc_can_do_color) { update_attr(currcons); clear_buffer_attributes(currcons); } if (update && vcmode != KD_GRAPHICS) do_update_region(currcons, origin, screenbuf_size/2); } set_cursor(currcons); if (is_switch) { set_leds(); compute_shiftstate(); }}/* * Allocation, freeing and resizing of VTs. */int vc_cons_allocated(unsigned int i){ return (i < MAX_NR_CONSOLES && vc_cons[i].d);}static void visual_init(int currcons, int init){ /* ++Geert: sw->con_init determines console size */ if (sw) module_put(sw->owner); sw = conswitchp;#ifndef VT_SINGLE_DRIVER if (con_driver_map[currcons]) sw = con_driver_map[currcons];#endif __module_get(sw->owner); cons_num = currcons; display_fg = &master_display_fg; vc_cons[currcons].d->vc_uni_pagedir_loc = &vc_cons[currcons].d->vc_uni_pagedir; vc_cons[currcons].d->vc_uni_pagedir = 0; hi_font_mask = 0; complement_mask = 0; can_do_color = 0; sw->con_init(vc_cons[currcons].d, init); if (!complement_mask) complement_mask = can_do_color ? 0x7700 : 0x0800; s_complement_mask = complement_mask; video_size_row = video_num_columns<<1; screenbuf_size = video_num_lines*video_size_row;}int vc_allocate(unsigned int currcons) /* return 0 on success */{ WARN_CONSOLE_UNLOCKED(); if (currcons >= MAX_NR_CONSOLES) return -ENXIO; if (!vc_cons[currcons].d) { long p, q; /* prevent users from taking too much memory */ if (currcons >= MAX_NR_USER_CONSOLES && !capable(CAP_SYS_RESOURCE)) return -EPERM; /* due to the granularity of kmalloc, we waste some memory here */ /* the alloc is done in two steps, to optimize the common situation of a 25x80 console (structsize=216, screenbuf_size=4000) */ /* although the numbers above are not valid since long ago, the point is still up-to-date and the comment still has its value even if only as a historical artifact. --mj, July 1998 */ p = (long) kmalloc(structsize, GFP_KERNEL); if (!p) return -ENOMEM; memset((void *)p, 0, structsize); vc_cons[currcons].d = (struct vc_data *)p; vt_cons[currcons] = (struct vt_struct *)(p+sizeof(struct vc_data)); visual_init(currcons, 1); if (!*vc_cons[currcons].d->vc_uni_pagedir_loc) con_set_default_unimap(currcons); q = (long)kmalloc(screenbuf_size, GFP_KERNEL); if (!q) { kfree((char *) p); vc_cons[currcons].d = NULL; vt_cons[currcons] = NULL; return -ENOMEM; } screenbuf = (unsigned short *) q; kmalloced = 1; vc_init(currcons, video_num_lines, video_num_columns, 1); if (!pm_con) { pm_con = pm_register(PM_SYS_DEV, PM_SYS_VGA, pm_con_request); } } return 0;}inline int resize_screen(int currcons, int width, int height){ /* Resizes the resolution of the display adapater */ int err = 0; if (vcmode != KD_GRAPHICS && sw->con_resize) err = sw->con_resize(vc_cons[currcons].d, width, height); return err;}/* * Change # of rows and columns (0 means unchanged/the size of fg_console) * [this is to be used together with some user program * like resize that changes the hardware videomode] */int vc_resize(int currcons, unsigned int cols, unsigned int lines){ unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0; unsigned int old_cols, old_rows, old_row_size, old_screen_size; unsigned int new_cols, new_rows, new_row_size, new_screen_size; unsigned short *newscreen; WARN_CONSOLE_UNLOCKED(); if (!vc_cons_allocated(currcons)) return -ENXIO; new_cols = (cols ? cols : video_num_columns); new_rows = (lines ? lines : video_num_lines); new_row_size = new_cols << 1; new_screen_size = new_row_size * new_rows; if (new_cols == video_num_columns && new_rows == video_num_lines) return 0; newscreen = (unsigned short *) kmalloc(new_screen_size, GFP_USER); if (!newscreen) return -ENOMEM; old_rows = video_num_lines; old_cols = video_num_columns; old_row_size = video_size_row; old_screen_size = screenbuf_size; err = resize_screen(currcons, new_cols, new_rows); if (err) { kfree(newscreen); return err; } video_num_lines = new_rows; video_num_columns = new_cols; video_size_row = new_row_size; screenbuf_size = new_screen_size; rlth = min(old_row_size, new_row_size); rrem = new_row_size - rlth; old_origin = origin; new_origin = (long) newscreen; new_scr_end = new_origin + new_screen_size; if (new_rows < old_rows) old_origin += (old_rows - new_rows) * old_row_size; update_attr(currcons); while (old_origin < scr_end) { scr_memcpyw((unsigned short *) new_origin, (unsigned short *) old_origin, rlth); if (rrem) scr_memsetw((void *)(new_origin + rlth), video_erase_char, rrem); old_origin += old_row_size; new_origin += new_row_size; } if (new_scr_end > new_origin) scr_memsetw((void *) new_origin, video_erase_char, new_scr_end - new_origin); if (kmalloced) kfree(screenbuf); screenbuf = newscreen; kmalloced = 1; screenbuf_size = new_screen_size; set_origin(currcons); /* do part of a reset_terminal() */ top = 0; bottom = video_num_lines; gotoxy(currcons, x, y); save_cur(currcons); if (vc_cons[currcons].d->vc_tty) { struct winsize ws, *cws = &vc_cons[currcons].d->vc_tty->winsize; memset(&ws, 0, sizeof(ws)); ws.ws_row = video_num_lines; ws.ws_col = video_num_columns; ws.ws_ypixel = video_scan_lines; if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col) && vc_cons[currcons].d->vc_tty->pgrp > 0) kill_pg(vc_cons[currcons].d->vc_tty->pgrp, SIGWINCH, 1); *cws = ws; } if (IS_VISIBLE) update_screen(currcons); return err;}void vc_disallocate(unsigned int currcons){ WARN_CONSOLE_UNLOCKED(); if (vc_cons_allocated(currcons)) { sw->con_deinit(vc_cons[currcons].d); if (kmalloced) kfree(screenbuf); if (currcons >= MIN_NR_CONSOLES) kfree(vc_cons[currcons].d); vc_cons[currcons].d = NULL; }}/* * VT102 emulator */#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 is_kbd(x) vc_kbd_mode(kbd_table+currcons,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"unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7, 8,12,10,14, 9,13,11,15 };/* the default colour table, for VGA+ colour systems */int default_red[] = {0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa, 0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff};int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa, 0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff};int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa, 0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff};/* * gotoxy() must verify all boundaries, because the arguments * might also be negative. If the given position is out of * bounds, the cursor is placed at the nearest margin. */static void gotoxy(int currcons, int new_x, int new_y){ int min_y, max_y; if (new_x < 0) x = 0; else if (new_x >= video_num_columns) x = video_num_columns - 1; else x = new_x; if (decom) { min_y = top; max_y = bottom; } else { min_y = 0; max_y = video_num_lines; } if (new_y < min_y) y = min_y; else if (new_y >= max_y) y = max_y - 1; else y = new_y; pos = origin + y*video_size_row + (x<<1); need_wrap = 0;}/* for absolute user moves, when decom is set */static void gotoxay(int currcons, int new_x, int new_y){ gotoxy(currcons, new_x, decom ? (top+new_y) : new_y);}void scrollback(int lines){ int currcons = fg_console; if (!lines) lines = video_num_lines/2; scrolldelta(-lines);}void scrollfront(int lines){ int currcons = fg_console; if (!lines) lines = video_num_lines/2; scrolldelta(lines);}static void lf(int currcons){ /* don't scroll if above bottom of scrolling region, or * if below scrolling region */ if (y+1 == bottom) scrup(currcons,top,bottom,1); else if (y < video_num_lines-1) { y++; pos += video_size_row; } need_wrap = 0;}static void ri(int currcons){ /* don't scroll if below top of scrolling region, or * if above scrolling region */ if (y == top) scrdown(currcons,top,bottom,1); else if (y > 0) { y--; pos -= video_size_row; } need_wrap = 0;}static inline void cr(int currcons){ pos -= x<<1; need_wrap = x = 0;}static inline void bs(int currcons){ if (x) { pos -= 2; x--; need_wrap = 0; }}static inline void del(int currcons){ /* ignored */}static void csi_J(int currcons, int vpar){ unsigned int count; unsigned short * start; switch (vpar) { case 0: /* erase from cursor to end of display */ count = (scr_end-pos)>>1; start = (unsigned short *) pos; if (DO_UPDATE) { /* do in two stages */ sw->con_clear(vc_cons[currcons].d, y, x, 1, video_num_columns-x); sw->con_clear(vc_cons[currcons].d, y+1, 0, video_num_lines-y-1, video_num_columns); } break; case 1: /* erase from start to cursor */ count = ((pos-origin)>>1)+1; start = (unsigned short *) origin; if (DO_UPDATE) { /* do in two stages */ sw->con_clear(vc_cons[currcons].d, 0, 0, y, video_num_columns); sw->con_clear(vc_cons[currcons].d, y, 0, 1, x + 1); } break; case 2: /* erase whole display */ count = video_num_columns * video_num_lines; start = (unsigned short *) origin; if (DO_UPDATE) sw->con_clear(vc_cons[currcons].d, 0, 0, video_num_lines, video_num_columns); break; default: return; } scr_memsetw(start, video_erase_char, 2*count); need_wrap = 0;}static void csi_K(int currcons, int vpar){ unsigned int count; unsigned short * start; switch (vpar) { case 0: /* erase from cursor to end of line */ count = video_num_columns-x; start = (unsigned short *) pos; if (DO_UPDATE) sw->con_clear(vc_cons[currcons].d, y, x, 1, video_num_columns-x); break; case 1: /* erase from start of line to cursor */ start = (unsigned short *) (pos - (x<<1)); count = x+1; if (DO_UPDATE) sw->con_clear(vc_cons[currcons].d, y, 0, 1, x + 1); break; case 2: /* erase whole line */ start = (unsigned short *) (pos - (x<<1)); count = video_num_columns; if (DO_UPDATE) sw->con_clear(vc_cons[currcons].d, y, 0, 1, video_num_columns); break; default: return; } scr_memsetw(start, video_erase_char, 2 * count); need_wrap = 0;}static void csi_X(int currcons, int vpar) /* erase the following vpar positions */{ /* not vt100? */ int count; if (!vpar) vpar++; count = (vpar > video_num_columns-x) ? (video_num_columns-x) : vpar; scr_memsetw((unsigned short *) pos, video_erase_char, 2 * count); if (DO_UPDATE) sw->con_clear(vc_cons[currcons].d, y, x, 1, count); need_wrap = 0;}static void default_attr(int currcons){ intensity = 1; underline = 0; reverse = 0; blink = 0;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?