fbcon.c
来自「优龙2410linux2.6.8内核源代码」· C语言 代码 · 共 2,412 行 · 第 1/5 页
C
2,412 行
dst = fb_get_buffer_offset(info, &info->pixmap, size); image.data = dst; if (info->pixmap.outbuf) fb_iomove_buf_aligned(info, &info->pixmap, dst, pitch, src, width, image.height); else fb_sysmove_buf_aligned(info, &info->pixmap, dst, pitch, src, width, image.height); info->fbops->fb_imageblit(info, &image);}static void fbcon_putcs(struct vc_data *vc, const unsigned short *s, int count, int ypos, int xpos){ struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]]; struct display *p = &fb_display[vc->vc_num]; if (!info->fbops->fb_blank && console_blanked) return; if (info->state != FBINFO_STATE_RUNNING) return; if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT) return; accel_putcs(vc, info, s, count, real_y(p, ypos), xpos);}static void fbcon_cursor(struct vc_data *vc, int mode){ struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]]; unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; int fgshift = (vc->vc_hi_font_mask) ? 9 : 8; struct display *p = &fb_display[vc->vc_num]; int w = (vc->vc_font.width + 7) >> 3, c; int y = real_y(p, vc->vc_y); struct fb_cursor cursor; if (mode & CM_SOFTBACK) { mode &= ~CM_SOFTBACK; if (softback_lines) { if (y + softback_lines >= vc->vc_rows) mode = CM_ERASE; else y += softback_lines; } } else if (softback_lines) fbcon_set_origin(vc); c = scr_readw((u16 *) vc->vc_pos); cursor.image.data = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height)); cursor.set = FB_CUR_SETCUR; cursor.image.depth = 1; switch (mode) { case CM_ERASE: if (info->cursor.rop == ROP_XOR) { info->cursor.enable = 0; info->cursor.rop = ROP_COPY; info->fbops->fb_cursor(info, &cursor); } break; case CM_MOVE: case CM_DRAW: info->cursor.enable = 1; if (info->cursor.image.fg_color != attr_fgcol(fgshift, c) || info->cursor.image.bg_color != attr_bgcol(bgshift, c)) { cursor.image.fg_color = attr_fgcol(fgshift, c); cursor.image.bg_color = attr_bgcol(bgshift, c); cursor.set |= FB_CUR_SETCMAP; } if ((info->cursor.image.dx != (vc->vc_font.width * vc->vc_x)) || (info->cursor.image.dy != (vc->vc_font.height * y))) { cursor.image.dx = vc->vc_font.width * vc->vc_x; cursor.image.dy = vc->vc_font.height * y; cursor.set |= FB_CUR_SETPOS; } if (info->cursor.image.height != vc->vc_font.height || info->cursor.image.width != vc->vc_font.width) { cursor.image.height = vc->vc_font.height; cursor.image.width = vc->vc_font.width; cursor.set |= FB_CUR_SETSIZE; } if (info->cursor.hot.x || info->cursor.hot.y) { cursor.hot.x = cursor.hot.y = 0; cursor.set |= FB_CUR_SETHOT; } if ((cursor.set & FB_CUR_SETSIZE) || ((vc->vc_cursor_type & 0x0f) != p->cursor_shape) || info->cursor.mask == NULL) { char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC); int cur_height, size, i = 0; if (!mask) return; if (info->cursor.mask) kfree(info->cursor.mask); info->cursor.mask = mask; p->cursor_shape = vc->vc_cursor_type & 0x0f; cursor.set |= FB_CUR_SETSHAPE; switch (vc->vc_cursor_type & 0x0f) { case CUR_NONE: cur_height = 0; break; case CUR_UNDERLINE: cur_height = (vc->vc_font.height < 10) ? 1 : 2; break; case CUR_LOWER_THIRD: cur_height = vc->vc_font.height/3; break; case CUR_LOWER_HALF: cur_height = vc->vc_font.height >> 1; break; case CUR_TWO_THIRDS: cur_height = (vc->vc_font.height << 1)/3; break; case CUR_BLOCK: default: cur_height = vc->vc_font.height; break; } size = (vc->vc_font.height - cur_height) * w; while (size--) mask[i++] = 0; size = cur_height * w; while (size--) mask[i++] = 0xff; } info->cursor.rop = ROP_XOR; info->fbops->fb_cursor(info, &cursor); vbl_cursor_cnt = CURSOR_DRAW_DELAY; break; }}static int scrollback_phys_max = 0;static int scrollback_max = 0;static int scrollback_current = 0;int update_var(int con, struct fb_info *info){ if (con == info->currcon) return fb_pan_display(info, &info->var); return 0;}static void fbcon_set_disp(struct fb_info *info, struct vc_data *vc){ struct display *p = &fb_display[vc->vc_num], *t; struct vc_data **default_mode = vc->vc_display_fg; int display_fg = (*default_mode)->vc_num; int rows, cols, charcnt = 256; info->var.xoffset = info->var.yoffset = p->yscroll = 0; t = &fb_display[display_fg]; if (!vc->vc_font.data) { vc->vc_font.data = p->fontdata = t->fontdata; vc->vc_font.width = (*default_mode)->vc_font.width; vc->vc_font.height = (*default_mode)->vc_font.height; p->userfont = t->userfont; if (p->userfont) REFCOUNT(p->fontdata)++; con_copy_unimap(vc->vc_num, display_fg); } if (p->userfont) charcnt = FNTCHARCNT(p->fontdata); vc->vc_can_do_color = info->var.bits_per_pixel != 1; vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; if (charcnt == 256) { vc->vc_hi_font_mask = 0; } else { vc->vc_hi_font_mask = 0x100; if (vc->vc_can_do_color) vc->vc_complement_mask <<= 1; } cols = info->var.xres / vc->vc_font.width; rows = info->var.yres / vc->vc_font.height; vc_resize(vc->vc_num, cols, rows); if (CON_IS_VISIBLE(vc)) { update_screen(vc->vc_num); if (softback_buf) { int l = fbcon_softback_size / vc->vc_size_row; if (l > 5) softback_end = softback_buf + l * vc->vc_size_row; else { /* Smaller scrollback makes no sense, and 0 would screw the operation totally */ softback_top = 0; } } } switch_screen(fg_console);}static __inline__ void ywrap_up(struct vc_data *vc, int count){ struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]]; struct display *p = &fb_display[vc->vc_num]; p->yscroll += count; if (p->yscroll >= p->vrows) /* Deal with wrap */ p->yscroll -= p->vrows; info->var.xoffset = 0; info->var.yoffset = p->yscroll * vc->vc_font.height; info->var.vmode |= FB_VMODE_YWRAP; update_var(vc->vc_num, info); scrollback_max += count; if (scrollback_max > scrollback_phys_max) scrollback_max = scrollback_phys_max; scrollback_current = 0;}static __inline__ void ywrap_down(struct vc_data *vc, int count){ struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]]; struct display *p = &fb_display[vc->vc_num]; p->yscroll -= count; if (p->yscroll < 0) /* Deal with wrap */ p->yscroll += p->vrows; info->var.xoffset = 0; info->var.yoffset = p->yscroll * vc->vc_font.height; info->var.vmode |= FB_VMODE_YWRAP; update_var(vc->vc_num, info); scrollback_max -= count; if (scrollback_max < 0) scrollback_max = 0; scrollback_current = 0;}static __inline__ void ypan_up(struct vc_data *vc, int count){ struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]]; struct display *p = &fb_display[vc->vc_num]; p->yscroll += count; if (p->yscroll > p->vrows - vc->vc_rows) { accel_bmove(vc, info, p->vrows - vc->vc_rows, 0, 0, 0, vc->vc_rows, vc->vc_cols); p->yscroll -= p->vrows - vc->vc_rows; } info->var.xoffset = 0; info->var.yoffset = p->yscroll * vc->vc_font.height; info->var.vmode &= ~FB_VMODE_YWRAP; update_var(vc->vc_num, info); accel_clear_margins(vc, info, 1); scrollback_max += count; if (scrollback_max > scrollback_phys_max) scrollback_max = scrollback_phys_max; scrollback_current = 0;}static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count){ struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]]; struct display *p = &fb_display[vc->vc_num]; int redraw = 0; p->yscroll += count; if (p->yscroll > p->vrows - vc->vc_rows) { p->yscroll -= p->vrows - vc->vc_rows; redraw = 1; } info->var.xoffset = 0; info->var.yoffset = p->yscroll * vc->vc_font.height; info->var.vmode &= ~FB_VMODE_YWRAP; if (redraw) fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t); update_var(vc->vc_num, info); accel_clear_margins(vc, info, 1); scrollback_max += count; if (scrollback_max > scrollback_phys_max) scrollback_max = scrollback_phys_max; scrollback_current = 0;}static __inline__ void ypan_down(struct vc_data *vc, int count){ struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]]; struct display *p = &fb_display[vc->vc_num]; p->yscroll -= count; if (p->yscroll < 0) { accel_bmove(vc, info, 0, 0, p->vrows - vc->vc_rows, 0, vc->vc_rows, vc->vc_cols); p->yscroll += p->vrows - vc->vc_rows; } info->var.xoffset = 0; info->var.yoffset = p->yscroll * vc->vc_font.height; info->var.vmode &= ~FB_VMODE_YWRAP; update_var(vc->vc_num, info); accel_clear_margins(vc, info, 1); scrollback_max -= count; if (scrollback_max < 0) scrollback_max = 0; scrollback_current = 0;}static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count){ struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]]; struct display *p = &fb_display[vc->vc_num]; int redraw = 0; p->yscroll -= count; if (p->yscroll < 0) { p->yscroll += p->vrows - vc->vc_rows; redraw = 1; } info->var.xoffset = 0; info->var.yoffset = p->yscroll * vc->vc_font.height; info->var.vmode &= ~FB_VMODE_YWRAP; if (redraw) fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count); update_var(vc->vc_num, info); accel_clear_margins(vc, info, 1); scrollback_max -= count; if (scrollback_max < 0) scrollback_max = 0; scrollback_current = 0;}static void fbcon_redraw_softback(struct vc_data *vc, struct display *p, long delta){ struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]]; int count = vc->vc_rows; unsigned short *d, *s; unsigned long n; int line = 0; d = (u16 *) softback_curr; if (d == (u16 *) softback_in) d = (u16 *) vc->vc_origin; n = softback_curr + delta * vc->vc_size_row; softback_lines -= delta; if (delta < 0) { if (softback_curr < softback_top && n < softback_buf) { n += softback_end - softback_buf; if (n < softback_top) { softback_lines -= (softback_top - n) / vc->vc_size_row; n = softback_top; } } else if (softback_curr >= softback_top && n < softback_top) { softback_lines -= (softback_top - n) / vc->vc_size_row; n = softback_top; } } else { if (softback_curr > softback_in && n >= softback_end) { n += softback_buf - softback_end; if (n > softback_in) { n = softback_in; softback_lines = 0; } } else if (softback_curr <= softback_in && n > softback_in) { n = softback_in; softback_lines = 0; } } if (n == softback_curr) return; softback_curr = n; s = (u16 *) softback_curr; if (s == (u16 *) softback_in) s = (u16 *) vc->vc_origin; while (count--) { unsigned short *start; unsigned short *le; unsigned short c; int x = 0; unsigned short attr = 1; start = s; le = advance_row(s, 1); do { c = scr_readw(s); if (attr != (c & 0xff00)) { attr = c & 0xff00; if (s > start) { accel_putcs(vc, info, start, s - start, real_y(p, line), x); x += s - start; start = s; } } if (c == scr_readw(d)) { if (s > start) { accel_putcs(vc, info, start, s - start, real_y(p, line), x); x += s - start + 1; start = s + 1; } else { x++; start++; } } s++; d++; } while (s < le); if (s > start) accel_putcs(vc, info, start, s - start, real_y(p, line), x); line++; if (d == (u16 *) softback_end) d = (u16 *) softback_buf; if (d == (u16 *) softback_in) d = (u16 *) vc->vc_origin; if (s == (u16 *) softback_end) s = (u16 *) softback_buf; if (s == (u16 *) softback_in) s = (u16 *) vc->vc_origin; }}static void fbcon_redraw_move(struct vc_data *vc, struct display *p, int line, int count, int dy){ struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]]; unsigned short *s = (unsigned short *) (vc->vc_origin + vc->vc_size_row * line); while (count--) { unsigned short *start = s; unsigned short *le = advance_row(s, 1); unsigned short c; int x = 0; unsigned short attr = 1; do { c = scr_readw(s); if (attr != (c & 0xff00)) { attr = c & 0xff00; if (s > start) { accel_putcs(vc, info, start, s - start, real_y(p, dy), x); x += s - start; start = s; } } console_conditional_schedule(); s++; } while (s < le); if (s > start) accel_putcs(vc, info, start, s - start, real_y(p, dy), x); console_conditional_schedule(); dy++; }}static void fbcon_redraw(struct vc_data *vc, struct display *p, int line, int count, int offset){ unsigned short *d = (unsigned short *) (vc->vc_origin + vc->vc_size_row * line); struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]]; unsigned short *s = d + offset; while (count--) { unsigned short *start = s; unsigned short *le = advance_row(s, 1); unsigned short c; int x = 0; unsigned short attr = 1; do { c = scr_readw(s); if (attr != (c & 0xff00)) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?