📄 sisusb_con.c
字号:
src = SISUSB_VADDR(sx, sy); dest = SISUSB_VADDR(dx, dy); for (i = height; i > 0; i--) { sisusbcon_memmovew(dest, src, width * 2); src += cols; dest += cols; } } else { src = SISUSB_VADDR(sx, sy + height - 1); dest = SISUSB_VADDR(dx, dy + height - 1); for (i = height; i > 0; i--) { sisusbcon_memmovew(dest, src, width * 2); src -= cols; dest -= cols; } }#endif if (sisusb_is_inactive(c, sisusb)) { up(&sisusb->lock); return; } length = ((height * cols) - dx - (cols - width - dx)) * 2; sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(dx, dy), (u32)SISUSB_HADDR(dx, dy), length, &written); up(&sisusb->lock);}/* interface routine */static intsisusbcon_switch(struct vc_data *c){ struct sisusb_usb_data *sisusb; ssize_t written; int length; /* Returnvalue 0 means we have fully restored screen, * and vt doesn't need to call do_update_region(). * Returnvalue != 0 naturally means the opposite. */ if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num))) return 0; /* sisusb->lock is down */ /* Don't write to screen if in gfx mode */ if (sisusb_is_inactive(c, sisusb)) { up(&sisusb->lock); return 0; } /* That really should not happen. It would mean we are * being called while the vc is using its private buffer * as origin. */ if (c->vc_origin == (unsigned long)c->vc_screenbuf) { up(&sisusb->lock); printk(KERN_DEBUG "sisusb: ASSERT ORIGIN != SCREENBUF!\n"); return 0; } /* Check that we don't copy too much */ length = min((int)c->vc_screenbuf_size, (int)(sisusb->scrbuf + sisusb->scrbuf_size - c->vc_origin)); /* Restore the screen contents */ sisusbcon_memcpyw((u16 *)c->vc_origin, (u16 *)c->vc_screenbuf, length); sisusb_copy_memory(sisusb, (unsigned char *)c->vc_origin, (u32)SISUSB_HADDR(0, 0), length, &written); up(&sisusb->lock); return 0;}/* interface routine */static voidsisusbcon_save_screen(struct vc_data *c){ struct sisusb_usb_data *sisusb; int length; /* Save the current screen contents to vc's private * buffer. */ if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num))) return; /* sisusb->lock is down */ if (sisusb_is_inactive(c, sisusb)) { up(&sisusb->lock); return; } /* Check that we don't copy too much */ length = min((int)c->vc_screenbuf_size, (int)(sisusb->scrbuf + sisusb->scrbuf_size - c->vc_origin)); /* Save the screen contents to vc's private buffer */ sisusbcon_memcpyw((u16 *)c->vc_screenbuf, (u16 *)c->vc_origin, length); up(&sisusb->lock);}/* interface routine */static intsisusbcon_set_palette(struct vc_data *c, unsigned char *table){ struct sisusb_usb_data *sisusb; int i, j; /* Return value not used by vt */ if (!CON_IS_VISIBLE(c)) return -EINVAL; if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num))) return -EINVAL; /* sisusb->lock is down */ if (sisusb_is_inactive(c, sisusb)) { up(&sisusb->lock); return -EINVAL; } for (i = j = 0; i < 16; i++) { if (sisusb_setreg(sisusb, SISCOLIDX, table[i])) break; if (sisusb_setreg(sisusb, SISCOLDATA, c->vc_palette[j++] >> 2)) break; if (sisusb_setreg(sisusb, SISCOLDATA, c->vc_palette[j++] >> 2)) break; if (sisusb_setreg(sisusb, SISCOLDATA, c->vc_palette[j++] >> 2)) break; } up(&sisusb->lock); return 0;}/* interface routine */static intsisusbcon_blank(struct vc_data *c, int blank, int mode_switch){ struct sisusb_usb_data *sisusb; u8 sr1, cr17, pmreg, cr63; ssize_t written; int ret = 0; if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num))) return 0; /* sisusb->lock is down */ if (mode_switch) sisusb->is_gfx = blank ? 1 : 0; if (sisusb_is_inactive(c, sisusb)) { up(&sisusb->lock); return 0; } switch (blank) { case 1: /* Normal blanking: Clear screen */ case -1: sisusbcon_memsetw((u16 *)c->vc_origin, c->vc_video_erase_char, c->vc_screenbuf_size); sisusb_copy_memory(sisusb, (unsigned char *)c->vc_origin, (u32)(sisusb->vrambase + (c->vc_origin - sisusb->scrbuf)), c->vc_screenbuf_size, &written); sisusb->con_blanked = 1; ret = 1; break; default: /* VESA blanking */ switch (blank) { case 0: /* Unblank */ sr1 = 0x00; cr17 = 0x80; pmreg = 0x00; cr63 = 0x00; ret = 1; sisusb->con_blanked = 0; break; case VESA_VSYNC_SUSPEND + 1: sr1 = 0x20; cr17 = 0x80; pmreg = 0x80; cr63 = 0x40; break; case VESA_HSYNC_SUSPEND + 1: sr1 = 0x20; cr17 = 0x80; pmreg = 0x40; cr63 = 0x40; break; case VESA_POWERDOWN + 1: sr1 = 0x20; cr17 = 0x00; pmreg = 0xc0; cr63 = 0x40; break; default: up(&sisusb->lock); return -EINVAL; } sisusb_setidxregandor(sisusb, SISSR, 0x01, ~0x20, sr1); sisusb_setidxregandor(sisusb, SISCR, 0x17, 0x7f, cr17); sisusb_setidxregandor(sisusb, SISSR, 0x1f, 0x3f, pmreg); sisusb_setidxregandor(sisusb, SISCR, 0x63, 0xbf, cr63); } up(&sisusb->lock); return ret;}/* interface routine */static intsisusbcon_scrolldelta(struct vc_data *c, int lines){ struct sisusb_usb_data *sisusb; int margin = c->vc_size_row * 4; int ul, we, p, st; /* The return value does not seem to be used */ if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num))) return 0; /* sisusb->lock is down */ if (sisusb_is_inactive(c, sisusb)) { up(&sisusb->lock); return 0; } if (!lines) /* Turn scrollback off */ c->vc_visible_origin = c->vc_origin; else { if (sisusb->con_rolled_over > (c->vc_scr_end - sisusb->scrbuf) + margin) { ul = c->vc_scr_end - sisusb->scrbuf; we = sisusb->con_rolled_over + c->vc_size_row; } else { ul = 0; we = sisusb->scrbuf_size; } p = (c->vc_visible_origin - sisusb->scrbuf - ul + we) % we + lines * c->vc_size_row; st = (c->vc_origin - sisusb->scrbuf - ul + we) % we; if (st < 2 * margin) margin = 0; if (p < margin) p = 0; if (p > st - margin) p = st; c->vc_visible_origin = sisusb->scrbuf + (p + ul) % we; } sisusbcon_set_start_address(sisusb, c); up(&sisusb->lock); return 1;}/* Interface routine */static voidsisusbcon_cursor(struct vc_data *c, int mode){ struct sisusb_usb_data *sisusb; int from, to, baseline; if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num))) return; /* sisusb->lock is down */ if (sisusb_is_inactive(c, sisusb)) { up(&sisusb->lock); return; } if (c->vc_origin != c->vc_visible_origin) { c->vc_visible_origin = c->vc_origin; sisusbcon_set_start_address(sisusb, c); } if (mode == CM_ERASE) { sisusb_setidxregor(sisusb, SISCR, 0x0a, 0x20); sisusb->sisusb_cursor_size_to = -1; up(&sisusb->lock); return; } sisusb_set_cursor(sisusb, (c->vc_pos - sisusb->scrbuf) / 2); baseline = c->vc_font.height - (c->vc_font.height < 10 ? 1 : 2); switch (c->vc_cursor_type & 0x0f) { case CUR_BLOCK: from = 1; to = c->vc_font.height; break; case CUR_TWO_THIRDS: from = c->vc_font.height / 3; to = baseline; break; case CUR_LOWER_HALF: from = c->vc_font.height / 2; to = baseline; break; case CUR_LOWER_THIRD: from = (c->vc_font.height * 2) / 3; to = baseline; break; case CUR_NONE: from = 31; to = 30; break; default: case CUR_UNDERLINE: from = baseline - 1; to = baseline; break; } if (sisusb->sisusb_cursor_size_from != from || sisusb->sisusb_cursor_size_to != to) { sisusb_setidxreg(sisusb, SISCR, 0x0a, from); sisusb_setidxregandor(sisusb, SISCR, 0x0b, 0xe0, to); sisusb->sisusb_cursor_size_from = from; sisusb->sisusb_cursor_size_to = to; } up(&sisusb->lock);}static intsisusbcon_scroll_area(struct vc_data *c, struct sisusb_usb_data *sisusb, int t, int b, int dir, int lines){ int cols = sisusb->sisusb_num_columns; int length = ((b - t) * cols) * 2; u16 eattr = c->vc_video_erase_char; ssize_t written; /* sisusb->lock is down */ /* Scroll an area which does not match the * visible screen's dimensions. This needs * to be done separately, as it does not * use hardware panning. */ switch (dir) { case SM_UP: sisusbcon_memmovew(SISUSB_VADDR(0, t), SISUSB_VADDR(0, t + lines), (b - t - lines) * cols * 2); sisusbcon_memsetw(SISUSB_VADDR(0, b - lines), eattr, lines * cols * 2); break; case SM_DOWN: sisusbcon_memmovew(SISUSB_VADDR(0, t + lines), SISUSB_VADDR(0, t), (b - t - lines) * cols * 2); sisusbcon_memsetw(SISUSB_VADDR(0, t), eattr, lines * cols * 2); break; } sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(0, t), (u32)SISUSB_HADDR(0, t), length, &written); up(&sisusb->lock); return 1;}/* Interface routine */static intsisusbcon_scroll(struct vc_data *c, int t, int b, int dir, int lines){ struct sisusb_usb_data *sisusb; u16 eattr = c->vc_video_erase_char; ssize_t written; int copyall = 0; unsigned long oldorigin; unsigned int delta = lines * c->vc_size_row; u32 originoffset; /* Returning != 0 means we have done the scrolling successfully. * Returning 0 makes vt do the scrolling on its own. * Note that con_scroll is only called if the console is * visible. In that case, the origin should be our buffer, * not the vt's private one. */ if (!lines) return 1; if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num))) return 0; /* sisusb->lock is down */ if (sisusb_is_inactive(c, sisusb)) { up(&sisusb->lock); return 0; } /* Special case */ if (t || b != c->vc_rows) return sisusbcon_scroll_area(c, sisusb, t, b, dir, lines); if (c->vc_origin != c->vc_visible_origin) { c->vc_visible_origin = c->vc_origin; sisusbcon_set_start_address(sisusb, c); } /* limit amount to maximum realistic size */ if (lines > c->vc_rows) lines = c->vc_rows; oldorigin = c->vc_origin; switch (dir) { case SM_UP: if (c->vc_scr_end + delta >= sisusb->scrbuf + sisusb->scrbuf_size) { sisusbcon_memcpyw((u16 *)sisusb->scrbuf, (u16 *)(oldorigin + delta), c->vc_screenbuf_size - delta); c->vc_origin = sisusb->scrbuf; sisusb->con_rolled_over = oldorigin - sisusb->scrbuf; copyall = 1; } else c->vc_origin += delta; sisusbcon_memsetw( (u16 *)(c->vc_origin + c->vc_screenbuf_size - delta), eattr, delta); break; case SM_DOWN: if (oldorigin - delta < sisusb->scrbuf) { sisusbcon_memmovew((u16 *)(sisusb->scrbuf + sisusb->scrbuf_size - c->vc_screenbuf_size + delta), (u16 *)oldorigin, c->vc_screenbuf_size - delta); c->vc_origin = sisusb->scrbuf + sisusb->scrbuf_size - c->vc_screenbuf_size; sisusb->con_rolled_over = 0; copyall = 1; } else c->vc_origin -= delta; c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size; scr_memsetw((u16 *)(c->vc_origin), eattr, delta); break; } originoffset = (u32)(c->vc_origin - sisusb->scrbuf); if (copyall) sisusb_copy_memory(sisusb, (char *)c->vc_origin, (u32)(sisusb->vrambase + originoffset), c->vc_screenbuf_size, &written); else if (dir == SM_UP) sisusb_copy_memory(sisusb, (char *)c->vc_origin + c->vc_screenbuf_size - delta, (u32)sisusb->vrambase + originoffset + c->vc_screenbuf_size - delta, delta, &written); else sisusb_copy_memory(sisusb, (char *)c->vc_origin, (u32)(sisusb->vrambase + originoffset), delta, &written); c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size; c->vc_visible_origin = c->vc_origin; sisusbcon_set_start_address(sisusb, c); c->vc_pos = c->vc_pos - oldorigin + c->vc_origin; up(&sisusb->lock); return 1;}/* Interface routine */static intsisusbcon_set_origin(struct vc_data *c){ struct sisusb_usb_data *sisusb; /* Returning != 0 means we were successful. * Returning 0 will vt make to use its own * screenbuffer as the origin. */ if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num))) return 0; /* sisusb->lock is down */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -