📄 matroxfb_accel.c
字号:
for (i = width; i > 0; dstoff += step, srcoff += step, i--) mga_writew(ACCESS_FBINFO(video.vbase), dstoff, mga_readw(ACCESS_FBINFO(video.vbase), srcoff)); height--; dstoff += p->next_line - width * step; srcoff += p->next_line - width * step; } } else { unsigned int off; off = (height - 1) * p->next_line + (width - 1) * step; srcoff += off; dstoff += off; while (height > 0) { int i; for (i = width; i > 0; dstoff -= step, srcoff -= step, i--) mga_writew(ACCESS_FBINFO(video.vbase), dstoff, mga_readw(ACCESS_FBINFO(video.vbase), srcoff)); dstoff -= p->next_line - width * step; srcoff -= p->next_line - width * step; height--; } } CRITEND}static void matrox_text_clear(struct vc_data* conp, struct display* p, int sy, int sx, int height, int width) { unsigned int offs; unsigned int val; unsigned int step; CRITFLAGS MINFO_FROM_DISP(p); step = ACCESS_FBINFO(devflags.textstep); offs = sy * p->next_line + sx * step; val = ntohs((attr_bgcol(p, conp->vc_video_erase_char) << 4) | attr_fgcol(p, conp->vc_video_erase_char) | (' ' << 8)); CRITBEGIN while (height > 0) { int i; for (i = width; i > 0; offs += step, i--) mga_writew(ACCESS_FBINFO(video.vbase), offs, val); offs += p->next_line - width * step; height--; } CRITEND}static void matrox_text_putc(struct vc_data* conp, struct display* p, int c, int yy, int xx) { unsigned int offs; unsigned int chr; unsigned int step; CRITFLAGS MINFO_FROM_DISP(p); step = ACCESS_FBINFO(devflags.textstep); offs = yy * p->next_line + xx * step; chr = attr_fgcol(p,c) | (attr_bgcol(p,c) << 4) | ((c & p->charmask) << 8); if (chr & 0x10000) chr |= 0x08; CRITBEGIN mga_writew(ACCESS_FBINFO(video.vbase), offs, ntohs(chr)); CRITEND}static void matrox_text_putcs(struct vc_data* conp, struct display* p, const unsigned short* s, int count, int yy, int xx) { unsigned int offs; unsigned int attr; unsigned int step; u_int16_t c; CRITFLAGS MINFO_FROM_DISP(p); step = ACCESS_FBINFO(devflags.textstep); offs = yy * p->next_line + xx * step; c = scr_readw(s); attr = attr_fgcol(p, c) | (attr_bgcol(p, c) << 4); CRITBEGIN while (count-- > 0) { unsigned int chr = ((scr_readw(s++)) & p->charmask) << 8; if (chr & 0x10000) chr ^= 0x10008; mga_writew(ACCESS_FBINFO(video.vbase), offs, ntohs(attr|chr)); offs += step; } CRITEND}static void matrox_text_revc(struct display* p, int xx, int yy) { unsigned int offs; unsigned int step; CRITFLAGS MINFO_FROM_DISP(p); step = ACCESS_FBINFO(devflags.textstep); offs = yy * p->next_line + xx * step + 1; CRITBEGIN mga_writeb(ACCESS_FBINFO(video.vbase), offs, mga_readb(ACCESS_FBINFO(video.vbase), offs) ^ 0x77); CRITEND}static void matrox_text_createcursor(WPMINFO struct display* p) { CRITFLAGS if (ACCESS_FBINFO(currcon_display) != p) return; matroxfb_createcursorshape(PMINFO p, 0); CRITBEGIN mga_setr(M_CRTC_INDEX, 0x0A, ACCESS_FBINFO(cursor.u)); mga_setr(M_CRTC_INDEX, 0x0B, ACCESS_FBINFO(cursor.d) - 1); CRITEND}static void matrox_text_cursor(struct display* p, int mode, int x, int y) { unsigned int pos; CRITFLAGS MINFO_FROM_DISP(p); if (ACCESS_FBINFO(currcon_display) != p) return; if (mode == CM_ERASE) { if (ACCESS_FBINFO(cursor.state) != CM_ERASE) { CRITBEGIN mga_setr(M_CRTC_INDEX, 0x0A, 0x20); CRITEND ACCESS_FBINFO(cursor.state) = CM_ERASE; } return; } if ((p->conp->vc_cursor_type & CUR_HWMASK) != ACCESS_FBINFO(cursor.type)) matrox_text_createcursor(PMINFO p); /* DO NOT CHECK cursor.x != x because of matroxfb_vgaHWinit moves cursor to 0,0 */ ACCESS_FBINFO(cursor.x) = x; ACCESS_FBINFO(cursor.y) = y; pos = p->next_line / ACCESS_FBINFO(devflags.textstep) * y + x; CRITBEGIN mga_setr(M_CRTC_INDEX, 0x0F, pos); mga_setr(M_CRTC_INDEX, 0x0E, pos >> 8); mga_setr(M_CRTC_INDEX, 0x0A, ACCESS_FBINFO(cursor.u)); CRITEND ACCESS_FBINFO(cursor.state) = CM_DRAW;}void matrox_text_round(CPMINFO struct fb_var_screeninfo* var, struct display* p) { unsigned hf; unsigned vf; unsigned vxres; unsigned ych; hf = fontwidth(p); if (!hf) hf = 8; /* do not touch xres */ vxres = (var->xres_virtual + hf - 1) / hf; if (vxres >= 256) vxres = 255; if (vxres < 16) vxres = 16; vxres = (vxres + 1) & ~1; /* must be even */ vf = fontheight(p); if (!vf) vf = 16; if (var->yres < var->yres_virtual) { ych = ACCESS_FBINFO(devflags.textvram) / vxres; var->yres_virtual = ych * vf; } else ych = var->yres_virtual / vf; if (vxres * ych > ACCESS_FBINFO(devflags.textvram)) { ych = ACCESS_FBINFO(devflags.textvram) / vxres; var->yres_virtual = ych * vf; } var->xres_virtual = vxres * hf;}EXPORT_SYMBOL(matrox_text_round);static int matrox_text_setfont(struct display* p, int width, int height) { DBG("matrox_text_setfont"); if (p) { MINFO_FROM_DISP(p); matrox_text_round(PMINFO &p->var, p); p->next_line = p->line_length = ((p->var.xres_virtual / (fontwidth(p)?fontwidth(p):8)) * ACCESS_FBINFO(devflags.textstep)); if (p->conp) matrox_text_createcursor(PMINFO p); } return 0;}#define matrox_cfb16_revc matrox_cfbX_revc#define matrox_cfb24_revc matrox_cfbX_revc#define matrox_cfb32_revc matrox_cfbX_revc#define matrox_cfb24_clear matrox_cfb32_clear#define matrox_cfb24_putc matrox_cfb32_putc#define matrox_cfb24_putcs matrox_cfb32_putcs#ifdef FBCON_HAS_VGATEXTstatic struct display_switch matroxfb_text = { setup: matrox_text_setup, bmove: matrox_text_bmove, clear: matrox_text_clear, putc: matrox_text_putc, putcs: matrox_text_putcs, revc: matrox_text_revc, cursor: matrox_text_cursor, set_font: matrox_text_setfont, fontwidthmask: FONTWIDTH(8)|FONTWIDTH(9)};#endif#ifdef FBCON_HAS_CFB4static struct display_switch matroxfb_cfb4 = { setup: fbcon_cfb4_setup, bmove: matrox_cfb4_bmove, clear: matrox_cfb4_clear, putc: fbcon_cfb4_putc, putcs: fbcon_cfb4_putcs, revc: matrox_cfb4_revc, fontwidthmask: FONTWIDTH(8) /* fix, fix, fix it */};#endif#ifdef FBCON_HAS_CFB8static struct display_switch matroxfb_cfb8 = { setup: fbcon_cfb8_setup, bmove: matrox_cfbX_bmove, clear: matrox_cfb8_clear, putc: matrox_cfb8_putc, putcs: matrox_cfb8_putcs, revc: matrox_cfb8_revc, clear_margins: matrox_cfbX_clear_margins, fontwidthmask: ~1 /* FONTWIDTHS */};#endif#ifdef FBCON_HAS_CFB16static struct display_switch matroxfb_cfb16 = { setup: fbcon_cfb16_setup, bmove: matrox_cfbX_bmove, clear: matrox_cfb16_clear, putc: matrox_cfb16_putc, putcs: matrox_cfb16_putcs, revc: matrox_cfb16_revc, clear_margins: matrox_cfbX_clear_margins, fontwidthmask: ~1 /* FONTWIDTHS */};#endif#ifdef FBCON_HAS_CFB24static struct display_switch matroxfb_cfb24 = { setup: fbcon_cfb24_setup, bmove: matrox_cfbX_bmove, clear: matrox_cfb24_clear, putc: matrox_cfb24_putc, putcs: matrox_cfb24_putcs, revc: matrox_cfb24_revc, clear_margins: matrox_cfbX_clear_margins, fontwidthmask: ~1 /* FONTWIDTHS */ /* TODO: and what about non-aligned access on BE? I think that there are no in my code */};#endif#ifdef FBCON_HAS_CFB32static struct display_switch matroxfb_cfb32 = { setup: fbcon_cfb32_setup, bmove: matrox_cfbX_bmove, clear: matrox_cfb32_clear, putc: matrox_cfb32_putc, putcs: matrox_cfb32_putcs, revc: matrox_cfb32_revc, clear_margins: matrox_cfbX_clear_margins, fontwidthmask: ~1 /* FONTWIDTHS */};#endifvoid initMatrox(WPMINFO struct display* p) { struct display_switch *swtmp; DBG("initMatrox") if (ACCESS_FBINFO(currcon_display) != p) return; if (p->dispsw && p->conp) fb_con.con_cursor(p->conp, CM_ERASE); p->dispsw_data = NULL; if ((p->var.accel_flags & FB_ACCELF_TEXT) != FB_ACCELF_TEXT) { if (p->type == FB_TYPE_TEXT) { swtmp = &matroxfb_text; } else { switch (p->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB4 case 4: swtmp = &fbcon_cfb4; break;#endif#ifdef FBCON_HAS_CFB8 case 8: swtmp = &fbcon_cfb8; break;#endif#ifdef FBCON_HAS_CFB16 case 16: p->dispsw_data = &ACCESS_FBINFO(cmap.cfb16); swtmp = &fbcon_cfb16; break;#endif#ifdef FBCON_HAS_CFB24 case 24: p->dispsw_data = &ACCESS_FBINFO(cmap.cfb24); swtmp = &fbcon_cfb24; break;#endif#ifdef FBCON_HAS_CFB32 case 32: p->dispsw_data = &ACCESS_FBINFO(cmap.cfb32); swtmp = &fbcon_cfb32; break;#endif default: p->dispsw = &fbcon_dummy; return; } } dprintk(KERN_INFO "matroxfb: acceleration disabled\n"); } else if (p->type == FB_TYPE_TEXT) { swtmp = &matroxfb_text; } else { switch (p->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB4 case 4: swtmp = &matroxfb_cfb4; break;#endif#ifdef FBCON_HAS_CFB8 case 8: swtmp = &matroxfb_cfb8; break;#endif#ifdef FBCON_HAS_CFB16 case 16: p->dispsw_data = &ACCESS_FBINFO(cmap.cfb16); swtmp = &matroxfb_cfb16; break;#endif#ifdef FBCON_HAS_CFB24 case 24: p->dispsw_data = &ACCESS_FBINFO(cmap.cfb24); swtmp = &matroxfb_cfb24; break;#endif#ifdef FBCON_HAS_CFB32 case 32: p->dispsw_data = &ACCESS_FBINFO(cmap.cfb32); swtmp = &matroxfb_cfb32; break;#endif default: p->dispsw = &fbcon_dummy; return; } } memcpy(&ACCESS_FBINFO(dispsw), swtmp, sizeof(ACCESS_FBINFO(dispsw))); p->dispsw = &ACCESS_FBINFO(dispsw); if ((p->type != FB_TYPE_TEXT) && ACCESS_FBINFO(devflags.hwcursor)) { ACCESS_FBINFO(hw_switch)->selhwcursor(PMINFO p); }}EXPORT_SYMBOL(initMatrox);void matrox_init_putc(WPMINFO struct display* p, void (*dac_createcursor)(WPMINFO struct display* p)) { int i; if (p && p->conp) { if (p->type == FB_TYPE_TEXT) { matrox_text_createcursor(PMINFO p); matrox_text_loadfont(PMINFO p); i = 0; } else { dac_createcursor(PMINFO p); i = matroxfb_fastfont_tryset(PMINFO p); } } else i = 0; if (i) { ACCESS_FBINFO(curr.putc) = matrox_cfbX_fastputc; ACCESS_FBINFO(curr.putcs) = matrox_cfbX_fastputcs; } else { ACCESS_FBINFO(curr.putc) = matrox_cfbX_putc; ACCESS_FBINFO(curr.putcs) = matrox_cfbX_putcs; }}EXPORT_SYMBOL(matrox_init_putc);MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -