📄 intelfbdrv.c
字号:
}static intintelfb_set_mode(struct intelfb_info *dinfo, struct fb_var_screeninfo *var, struct display *disp, int blank){ struct intelfb_hwstate hw; DBG_MSG("intelfb_set_mode (%dx%d-%d)\n", var->xres, var->yres, intelfb_var_to_depth(var)); memcpy(&hw, &dinfo->save_state, sizeof(hw)); if (intelfbhw_mode_to_hw(dinfo, &hw, var)) return -EINVAL; intelfbhw_print_hw_state(dinfo, &hw); if (intelfbhw_program_mode(dinfo, &hw, blank)) return -EINVAL; update_dinfo(dinfo, var, disp); return 0;}static voidintelfb_do_install_cmap(int con, struct fb_info *info){ struct intelfb_info *dinfo = GET_DINFO(info); struct display *disp; if (con != dinfo->currcon) return; disp = GET_DISP(info, con); if (disp->cmap.len) FB_SET_CMAP(&disp->cmap, 1, intelfb_setcolreg, info); else { int size = (disp->var.bits_per_pixel > 8) ? 16 : 256; FB_SET_CMAP(fb_default_cmap(size), 1, intelfb_setcolreg, info); }}static voidcheck_vc_mode(struct intelfb_info *dinfo){#if VERBOSE > 1 DBG_MSG("check_vc_mode\n");#endif if (dinfo->currcon >= 0) { if (vt_cons[dinfo->currcon]->vc_mode != dinfo->vc_mode) { dinfo->vc_mode = vt_cons[dinfo->currcon]->vc_mode; if (dinfo->vc_mode == KD_GRAPHICS) { DBG_MSG("vc_mode changed to KD_GRAPHICS\n"); intelfbhw_2d_stop(dinfo); if (dinfo->cursor.enabled) { intelfbhw_cursor_hide(dinfo); dinfo->cursor.enabled = 1; } } else { DBG_MSG("vc_mode changed to KD_TEXT\n"); intelfbhw_2d_start(dinfo);#if 0 if (dinfo->cursor.enabled) intelfbhw_cursor_show(dinfo);#endif } } }}static voidfbcon_intelfb_setup(struct display *p){ struct intelfb_info *dinfo = GET_DINFO(p->fb_info); DBG_MSG("fbcon_intelfb_setup: accel: %d bpp: %d\n", TEXT_ACCEL(dinfo, &p->var), p->var.bits_per_pixel); switch (p->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB8 case 8: fbcon_cfb8.setup(p); break;#endif#ifdef FBCON_HAS_CFB16 case 16: fbcon_cfb16.setup(p); break;#endif#ifdef FBCON_HAS_CFB32 case 32: fbcon_cfb32.setup(p); break;#endif }}static voidfbcon_intelfb_bmove(struct display *p, int sy, int sx, int dy, int dx, int height, int width){ struct intelfb_info *dinfo = GET_DINFO(p->fb_info);#if VERBOSE > 0 DBG_MSG("fbcon_intelfb_bmove: accel: %d, bpp: %d\n", TEXT_ACCEL(dinfo, &p->var), p->var.bits_per_pixel);#endif if (TEXT_ACCEL(dinfo, &p->var)) { intelfbhw_do_bitblt(dinfo, fontwidth(p) * sx, fontheight(p) * sy, fontwidth(p) * dx, fontheight(p) * dy, fontwidth(p) * width, fontheight(p) * height, dinfo->pitch, p->var.bits_per_pixel); intelfbhw_do_sync(dinfo); return; } /* Non-accel fallback */ switch (p->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB8 case 8: fbcon_cfb8.bmove(p, sy, sx, dy, dx, height, width); break;#endif#ifdef FBCON_HAS_CFB16 case 16: fbcon_cfb16.bmove(p, sy, sx, dy, dx, height, width); break;#endif#ifdef FBCON_HAS_CFB32 case 32: fbcon_cfb32.bmove(p, sy, sx, dy, dx, height, width); break;#endif }}static voidfbcon_intelfb_clear(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width){ struct intelfb_info *dinfo = GET_DINFO(p->fb_info);#if VERBOSE > 0 DBG_MSG("fbcon_intelfb_clear: accel: %d, bpp: %d\n", TEXT_ACCEL(dinfo, &p->var), p->var.bits_per_pixel);#endif if (TEXT_ACCEL(dinfo, &p->var)) { u32 bg = 0; switch (p->var.bits_per_pixel) { case 8: bg = attr_bgcol_ec(p, conp); break; case 16: bg = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)]; break; case 32: bg = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p, conp)]; break; } intelfbhw_do_fillrect(dinfo, fontwidth(p) * sx, fontheight(p) * sy, fontwidth(p) * width, fontheight(p) * height, bg, dinfo->pitch, p->var.bits_per_pixel, PAT_ROP_GXCOPY); intelfbhw_do_sync(dinfo); return; } /* Non-accel fallback */ switch (p->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB8 case 8: fbcon_cfb8.clear(conp, p, sy, sx, height, width); break;#endif#ifdef FBCON_HAS_CFB16 case 16: fbcon_cfb16.clear(conp, p, sy, sx, height, width); break;#endif#ifdef FBCON_HAS_CFB32 case 32: fbcon_cfb32.clear(conp, p, sy, sx, height, width); break;#endif }}static voidfbcon_intelfb_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx){ struct intelfb_info *dinfo = GET_DINFO(p->fb_info);#if VERBOSE > 0 DBG_MSG("fbcon_intelfb_putc: accel: %d, bpp: %d\n", TEXT_ACCEL(dinfo, &p->var), p->var.bits_per_pixel);#endif /* intelfbhw_do_drawglyph() has problems with the 852GM/855GM */ if (TEXT_ACCEL(dinfo, &p->var) && USE_DRAWGLYPH(dinfo)) { u32 bg = 0, fg = 0; u8 *cdat; int fw; switch (p->var.bits_per_pixel) { case 8: bg = attr_bgcol(p, c); fg = attr_fgcol(p, c); break; case 16: bg = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)]; fg = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)]; break; case 32: bg = ((u32 *)p->dispsw_data)[attr_bgcol(p, c)]; fg = ((u32 *)p->dispsw_data)[attr_fgcol(p, c)]; break; } fw = ROUND_UP_TO(fontwidth(p), 8) / 8; cdat = p->fontdata + (c & p->charmask) * fontheight(p) * fw; if (intelfbhw_do_drawglyph(dinfo, fg, bg, fontwidth(p), fontheight(p), cdat, xx * fontwidth(p), yy * fontheight(p), dinfo->pitch, p->var.bits_per_pixel)) { intelfbhw_do_sync(dinfo); return; } } if (TEXT_ACCEL(dinfo, &p->var)) intelfbhw_do_sync(dinfo); /* Non-accel fallback */ switch (p->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB8 case 8: fbcon_cfb8.putc(conp, p, c, yy, xx); break;#endif#ifdef FBCON_HAS_CFB16 case 16: fbcon_cfb16.putc(conp, p, c, yy, xx); break;#endif#ifdef FBCON_HAS_CFB32 case 32: fbcon_cfb32.putc(conp, p, c, yy, xx); break;#endif }}static voidfbcon_intelfb_putcs(struct vc_data *conp, struct display *p, const unsigned short *s, int count, int yy, int xx){ struct intelfb_info *dinfo = GET_DINFO(p->fb_info);#if VERBOSE > 0 DBG_MSG("fbcon_intelfb_putcs: accel: %d, bpp: %d, (%d,%d) %d\n", TEXT_ACCEL(dinfo, &p->var), p->var.bits_per_pixel, xx, yy, count);#endif if (TEXT_ACCEL(dinfo, &p->var) && USE_DRAWGLYPH(dinfo)) { u32 bg = 0, fg = 0; u8 *cdat; int fw; u16 c = scr_readw(s); switch (p->var.bits_per_pixel) { case 8: bg = attr_bgcol(p, c); fg = attr_fgcol(p, c); break; case 16: bg = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)]; fg = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)]; break; case 32: bg = ((u32 *)p->dispsw_data)[attr_bgcol(p, c)]; fg = ((u32 *)p->dispsw_data)[attr_fgcol(p, c)]; break; } fw = ROUND_UP_TO(fontwidth(p), 8) / 8; while (count--) { cdat = p->fontdata + (scr_readw(s++) & p->charmask) * fontheight(p) * fw; intelfbhw_do_drawglyph(dinfo, fg, bg, fontwidth(p), fontheight(p), cdat, xx * fontwidth(p), yy * fontheight(p), dinfo->pitch, p->var.bits_per_pixel); xx++; } intelfbhw_do_sync(dinfo); return; } if (TEXT_ACCEL(dinfo, &p->var)) intelfbhw_do_sync(dinfo); /* Non-accel fallback */ switch (p->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB8 case 8: fbcon_cfb8.putcs(conp, p, s, count, yy, xx); break;#endif#ifdef FBCON_HAS_CFB16 case 16: fbcon_cfb16.putcs(conp, p, s, count, yy, xx); break;#endif#ifdef FBCON_HAS_CFB32 case 32: fbcon_cfb32.putcs(conp, p, s, count, yy, xx); break;#endif }}static voidfbcon_intelfb_revc(struct display *p, int xx, int yy){ struct intelfb_info *dinfo = GET_DINFO(p->fb_info);#if VERBOSE > 0 DBG_MSG("fbcon_intelfb_revc: accel: %d, bpp: %d\n", TEXT_ACCEL(dinfo, &p->var), p->var.bits_per_pixel);#endif if (TEXT_ACCEL(dinfo, &p->var)) { int bpp = p->var.bits_per_pixel; u32 xor_mask = bpp == 8 ? 0x0f : 0xffffffff; intelfbhw_do_fillrect(dinfo, xx * fontwidth(p), yy * fontheight(p), fontwidth(p), fontheight(p), xor_mask, dinfo->pitch, bpp, PAT_ROP_GXXOR); intelfbhw_do_sync(dinfo); return; } /* Non-accel fallback */ switch (p->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB8 case 8: fbcon_cfb8.revc(p, xx, yy); break;#endif#ifdef FBCON_HAS_CFB16 case 16: fbcon_cfb16.revc(p, xx, yy); break;#endif#ifdef FBCON_HAS_CFB32 case 32: fbcon_cfb32.revc(p, xx, yy); break;#endif }}static voidfbcon_intelfb_clear_margins(struct vc_data *conp, struct display *p, int bottom_only){ struct intelfb_info *dinfo = GET_DINFO(p->fb_info);#if VERBOSE > 0 DBG_MSG("fbcon_intelfb_clear_margins: accel: %d, bpp: %d\n", TEXT_ACCEL(dinfo, &p->var), p->var.bits_per_pixel);#endif if (TEXT_ACCEL(dinfo, &p->var)) { u32 cw, ch, rw, bh, rs, bs; cw = fontwidth(p); ch = fontheight(p); rw = p->var.xres % cw; bh = p->var.yres % ch; rs = p->var.xres - rw; bs = p->var.yres - bh; if (!bottom_only && rw) { intelfbhw_do_fillrect(dinfo, p->var.xoffset + rs, 0, rw, p->var.yres_virtual, 0, dinfo->pitch, p->var.bits_per_pixel, PAT_ROP_GXCOPY); } if (bh) { intelfbhw_do_fillrect(dinfo, p->var.xoffset, p->var.yoffset + bs, rs, bh, 0, dinfo->pitch, p->var.bits_per_pixel, PAT_ROP_GXCOPY); } if ((!bottom_only && rw) || bh) { intelfbhw_do_sync(dinfo); } return; } /* Non-accel fallback */ switch (p->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB8 case 8: fbcon_cfb8.clear_margins(conp, p, bottom_only); break;#endif#ifdef FBCON_HAS_CFB16 case 16: fbcon_cfb16.clear_margins(conp, p, bottom_only); break;#endif#ifdef FBCON_HAS_CFB32 case 32: fbcon_cfb32.clear_margins(conp, p, bottom_only); break;#endif }}voidintelfb_create_cursor_shape(struct intelfb_info *dinfo, struct display *disp){ u32 h, cu, cd; DBG_MSG("intelfb_create_cursor_shape\n"); h = fontheight(disp); cd = h; if (cd >= 10) cd --; dinfo->cursor.type = disp->conp->vc_cursor_type & CUR_HWMASK; switch (dinfo->cursor.type) { case CUR_NONE: cu = cd; break; case CUR_UNDERLINE: cu = cd - 2; break; case CUR_LOWER_THIRD: cu = (h * 2) / 3; break; case CUR_LOWER_HALF: cu = h / 2; break; case CUR_TWO_THIRDS: cu = h / 3; break; case CUR_BLOCK: default: cu = 0; cd = h; break; } dinfo->cursor.w = fontwidth(disp); dinfo->cursor.u = cu; dinfo->cursor.d = cd;}static voidintelfb_flashcursor(unsigned long ptr){ struct intelfb_info *dinfo = (struct intelfb_info *)ptr; unsigned long flags;#if VERBOSE > 2 DBG_MSG("intelfb_flashcursor\n");#endif spin_lock_irqsave(&dinfo->DAClock, flags); if (dinfo->cursor.enabled) { if (dinfo->cursor.on) intelfbhw_cursor_hide(dinfo); else intelfbhw_cursor_show(dinfo); dinfo->cursor.enabled = 1; } dinfo->cursor.timer.expires = jiffies + HZ / 2; add_timer(&dinfo->cursor.timer); spin_unlock_irqrestore(&dinfo->DAClock, flags);}static voidfbcon_intelfb_cursor(struct display *disp, int mode, int x, int y){ unsigned long flags = 0; struct intelfb_info *dinfo = GET_DINFO(disp->fb_info);#if VERBOSE > 0 DBG_MSG("fbcon_intelfb_cursor, mode is %d (%d)\n", mode, dinfo->cursor.state);#endif /* * This appears to be the first place that we can detect changes * in vc_mode. We need to know this so that acceleration can be * enabled or disabled so that it won't interfere with an XFree86 * server. */ check_vc_mode(dinfo); if (!dinfo->hwcursor) { disp->dispsw->cursor = NULL; fb_con.con_cursor(disp->conp, mode); disp->dispsw->cursor = fbcon_intelfb_cursor; return; } if (mode == CM_ERASE) { if (dinfo->cursor.state != CM_ERASE) { spin_lock_irqsave(&dinfo->DAClock, flags); dinfo->cursor.state = CM_ERASE; intelfbhw_cursor_hide(dinfo); del_timer(&dinfo->cursor.timer); spin_unlock_irqrestore(&dinfo->DAClock, flags); } return; } if ((disp->conp->vc_cursor_type & CUR_HWMASK) != dinfo->cursor.type) intelfbhw_cursor_load(dinfo, disp); x *= fontwidth(disp); y *= fontheight(disp); y -= disp->var.yoffset; x -= disp->var.xoffset; spin_lock_irqsave(&dinfo->DAClock, flags); if (x != dinfo->cursor.x || y != dinfo->cursor.y || dinfo->cursor.redraw) {#if 1 intelfbhw_cursor_hide(dinfo);#endif intelfbhw_cursor_setcolor(dinfo, 0, 0xffffff); intelfbhw_cursor_setpos(dinfo, x, y); } dinfo->cursor.state = CM_DRAW; mod_timer(&dinfo->cursor.timer, jiffies + HZ / 2); intelfbhw_cursor_show(dinfo); spin_unlock_irqrestore(&dinfo->DAClock, flags);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -