⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 console.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (s != active_console)         return;    vga_fill_rect(s->ds, 0, 0, s->ds->width, s->ds->height,                  color_table[0][COLOR_BLACK]);    y1 = s->y_displayed;    for(y = 0; y < s->height; y++) {        c = s->cells + y1 * s->width;        for(x = 0; x < s->width; x++) {            vga_putcharxy(s->ds, x, y, c->ch,                           &(c->t_attrib));            c++;        }        if (++y1 == s->total_height)            y1 = 0;    }    dpy_update(s->ds, 0, 0, s->ds->width, s->ds->height);    console_show_cursor(s, 1);}static void console_scroll(int ydelta){    TextConsole *s;    int i, y1;        s = active_console;    if (!s || !s->text_console)        return;    if (ydelta > 0) {        for(i = 0; i < ydelta; i++) {            if (s->y_displayed == s->y_base)                break;            if (++s->y_displayed == s->total_height)                s->y_displayed = 0;        }    } else {        ydelta = -ydelta;        i = s->backscroll_height;        if (i > s->total_height - s->height)            i = s->total_height - s->height;        y1 = s->y_base - i;        if (y1 < 0)            y1 += s->total_height;        for(i = 0; i < ydelta; i++) {            if (s->y_displayed == y1)                break;            if (--s->y_displayed < 0)                s->y_displayed = s->total_height - 1;        }    }    console_refresh(s);}static void console_put_lf(TextConsole *s){    TextCell *c;    int x, y1;    s->x = 0;    s->y++;    if (s->y >= s->height) {        s->y = s->height - 1;        if (s->y_displayed == s->y_base) {            if (++s->y_displayed == s->total_height)                s->y_displayed = 0;        }        if (++s->y_base == s->total_height)            s->y_base = 0;        if (s->backscroll_height < s->total_height)            s->backscroll_height++;        y1 = (s->y_base + s->height - 1) % s->total_height;        c = &s->cells[y1 * s->width];        for(x = 0; x < s->width; x++) {            c->ch = ' ';            c->t_attrib = s->t_attrib_default;            c++;        }        if (s == active_console && s->y_displayed == s->y_base) {            vga_bitblt(s->ds, 0, FONT_HEIGHT, 0, 0,                        s->width * FONT_WIDTH,                        (s->height - 1) * FONT_HEIGHT);            vga_fill_rect(s->ds, 0, (s->height - 1) * FONT_HEIGHT,                          s->width * FONT_WIDTH, FONT_HEIGHT,                           color_table[0][s->t_attrib_default.bgcol]);            dpy_update(s->ds, 0, 0,                        s->width * FONT_WIDTH, s->height * FONT_HEIGHT);        }    }}/* Set console attributes depending on the current escape codes. * NOTE: I know this code is not very efficient (checking every color for it * self) but it is more readable and better maintainable. */static void console_handle_escape(TextConsole *s){    int i;    if (s->nb_esc_params == 0) { /* ESC[m sets all attributes to default */        s->t_attrib = s->t_attrib_default;        return;    }    for (i=0; i<s->nb_esc_params; i++) {        switch (s->esc_params[i]) {            case 0: /* reset all console attributes to default */                s->t_attrib = s->t_attrib_default;                break;            case 1:                s->t_attrib.bold = 1;                break;            case 4:                s->t_attrib.uline = 1;                break;            case 5:                s->t_attrib.blink = 1;                break;            case 7:                s->t_attrib.invers = 1;                break;            case 8:                s->t_attrib.unvisible = 1;                break;            case 22:                s->t_attrib.bold = 0;                break;            case 24:                s->t_attrib.uline = 0;                break;            case 25:                s->t_attrib.blink = 0;                break;            case 27:                s->t_attrib.invers = 0;                break;            case 28:                s->t_attrib.unvisible = 0;                break;            /* set foreground color */            case 30:                s->t_attrib.fgcol=COLOR_BLACK;                break;            case 31:                s->t_attrib.fgcol=COLOR_RED;                break;            case 32:                s->t_attrib.fgcol=COLOR_GREEN;                break;            case 33:                s->t_attrib.fgcol=COLOR_YELLOW;                break;            case 34:                s->t_attrib.fgcol=COLOR_BLUE;                break;            case 35:                s->t_attrib.fgcol=COLOR_MAGENTA;                break;            case 36:                s->t_attrib.fgcol=COLOR_CYAN;                break;            case 37:                s->t_attrib.fgcol=COLOR_WHITE;                break;            /* set background color */            case 40:                s->t_attrib.bgcol=COLOR_BLACK;                break;            case 41:                s->t_attrib.bgcol=COLOR_RED;                break;            case 42:                s->t_attrib.bgcol=COLOR_GREEN;                break;            case 43:                s->t_attrib.bgcol=COLOR_YELLOW;                break;            case 44:                s->t_attrib.bgcol=COLOR_BLUE;                break;            case 45:                s->t_attrib.bgcol=COLOR_MAGENTA;                break;            case 46:                s->t_attrib.bgcol=COLOR_CYAN;                break;            case 47:                s->t_attrib.bgcol=COLOR_WHITE;                break;        }    }}static void console_putchar(TextConsole *s, int ch){    TextCell *c;    int y1, i, x;    switch(s->state) {    case TTY_STATE_NORM:        switch(ch) {        case '\r':  /* carriage return */            s->x = 0;            break;        case '\n':  /* newline */            console_put_lf(s);            break;        case '\b':  /* backspace */            if(s->x > 0) s->x--;            y1 = (s->y_base + s->y) % s->total_height;            c = &s->cells[y1 * s->width + s->x];            c->ch = ' ';            c->t_attrib = s->t_attrib;            update_xy(s, s->x, s->y);            break;        case '\t':  /* tabspace */            if (s->x + (8 - (s->x % 8)) > s->width) {                console_put_lf(s);            } else {                s->x = s->x + (8 - (s->x % 8));            }            break;        case '\a':  /* alert aka. bell */            /* TODO: has to be implemented */            break;        case 27:    /* esc (introducing an escape sequence) */            s->state = TTY_STATE_ESC;            break;        default:            y1 = (s->y_base + s->y) % s->total_height;            c = &s->cells[y1 * s->width + s->x];            c->ch = ch;            c->t_attrib = s->t_attrib;            update_xy(s, s->x, s->y);            s->x++;            if (s->x >= s->width)                console_put_lf(s);            break;        }        break;    case TTY_STATE_ESC: /* check if it is a terminal escape sequence */        if (ch == '[') {            for(i=0;i<MAX_ESC_PARAMS;i++)                s->esc_params[i] = 0;            s->nb_esc_params = 0;            s->state = TTY_STATE_CSI;        } else {            s->state = TTY_STATE_NORM;        }        break;    case TTY_STATE_CSI: /* handle escape sequence parameters */        if (ch >= '0' && ch <= '9') {            if (s->nb_esc_params < MAX_ESC_PARAMS) {                s->esc_params[s->nb_esc_params] =                     s->esc_params[s->nb_esc_params] * 10 + ch - '0';            }        } else {            s->nb_esc_params++;            if (ch == ';')                break;            s->state = TTY_STATE_NORM;            switch(ch) {            case 'D':                if (s->x > 0)                    s->x--;                break;            case 'C':                if (s->x < (s->width - 1))                    s->x++;                break;            case 'K':                /* clear to eol */                y1 = (s->y_base + s->y) % s->total_height;                for(x = s->x; x < s->width; x++) {                    c = &s->cells[y1 * s->width + x];                    c->ch = ' ';                    c->t_attrib = s->t_attrib_default;                    c++;                    update_xy(s, x, s->y);                }                break;            default:                break;            }            console_handle_escape(s);            break;        }    }}void console_select(unsigned int index){    TextConsole *s;    if (index >= MAX_CONSOLES)        return;    s = consoles[index];    if (s) {        active_console = s;        if (s->text_console) {            if (s->g_width != s->ds->width ||                s->g_height != s->ds->height) {                s->g_width = s->ds->width;                s->g_height = s->ds->height;                text_console_resize(s);            }            console_refresh(s);        } else {            vga_hw_invalidate();        }    }}static int console_puts(CharDriverState *chr, const uint8_t *buf, int len){    TextConsole *s = chr->opaque;    int i;    console_show_cursor(s, 0);    for(i = 0; i < len; i++) {        console_putchar(s, buf[i]);    }    console_show_cursor(s, 1);    return len;}static void console_chr_add_read_handler(CharDriverState *chr,                                          IOCanRWHandler *fd_can_read,                                          IOReadHandler *fd_read, void *opaque){    TextConsole *s = chr->opaque;    s->fd_read = fd_read;    s->fd_opaque = opaque;}static void console_send_event(CharDriverState *chr, int event){    TextConsole *s = chr->opaque;    int i;    if (event == CHR_EVENT_FOCUS) {        for(i = 0; i < nb_consoles; i++) {            if (consoles[i] == s) {                console_select(i);                break;            }        }    }}/* called when an ascii key is pressed */void kbd_put_keysym(int keysym){    TextConsole *s;    uint8_t buf[16], *q;    int c;    s = active_console;    if (!s || !s->text_console)        return;    switch(keysym) {    case QEMU_KEY_CTRL_UP:        console_scroll(-1);        break;    case QEMU_KEY_CTRL_DOWN:        console_scroll(1);        break;    case QEMU_KEY_CTRL_PAGEUP:        console_scroll(-10);        break;    case QEMU_KEY_CTRL_PAGEDOWN:        console_scroll(10);        break;    default:        if (s->fd_read) {            /* convert the QEMU keysym to VT100 key string */            q = buf;            if (keysym >= 0xe100 && keysym <= 0xe11f) {                *q++ = '\033';                *q++ = '[';                c = keysym - 0xe100;                if (c >= 10)                    *q++ = '0' + (c / 10);                *q++ = '0' + (c % 10);                *q++ = '~';            } else if (keysym >= 0xe120 && keysym <= 0xe17f) {                *q++ = '\033';                *q++ = '[';                *q++ = keysym & 0xff;            } else {                *q++ = keysym;            }            s->fd_read(s->fd_opaque, buf, q - buf);        }        break;    }}static TextConsole *new_console(DisplayState *ds, int text){    TextConsole *s;    int i;    if (nb_consoles >= MAX_CONSOLES)        return NULL;    s = qemu_mallocz(sizeof(TextConsole));    if (!s) {        return NULL;    }    if (!active_console || (active_console->text_console && !text))        active_console = s;    s->ds = ds;    s->text_console = text;    if (text) {        consoles[nb_consoles++] = s;    } else {        /* HACK: Put graphical consoles before text consoles.  */        for (i = nb_consoles; i > 0; i--) {            if (!consoles[i - 1]->text_console)                break;            consoles[i] = consoles[i - 1];        }        consoles[i] = s;    }    return s;}TextConsole *graphic_console_init(DisplayState *ds, vga_hw_update_ptr update,                                  vga_hw_invalidate_ptr invalidate,                                  vga_hw_screen_dump_ptr screen_dump,                                  void *opaque){    TextConsole *s;    s = new_console(ds, 0);    if (!s)      return NULL;    s->hw_update = update;    s->hw_invalidate = invalidate;    s->hw_screen_dump = screen_dump;    s->hw = opaque;    return s;}int is_graphic_console(void){    return !active_console->text_console;}CharDriverState *text_console_init(DisplayState *ds){    CharDriverState *chr;    TextConsole *s;    int i,j;    static int color_inited;    chr = qemu_mallocz(sizeof(CharDriverState));    if (!chr)        return NULL;    s = new_console(ds, 1);    if (!s) {        free(chr);        return NULL;    }    chr->opaque = s;    chr->chr_write = console_puts;    chr->chr_add_read_handler = console_chr_add_read_handler;    chr->chr_send_event = console_send_event;    if (!color_inited) {        color_inited = 1;        for(j = 0; j < 2; j++) {            for(i = 0; i < 8; i++) {                color_table[j][i] = col_expand(s->ds,                         vga_get_color(s->ds, color_table_rgb[j][i]));            }        }    }    s->y_displayed = 0;    s->y_base = 0;    s->total_height = DEFAULT_BACKSCROLL;    s->x = 0;    s->y = 0;    s->g_width = s->ds->width;    s->g_height = s->ds->height;    /* Set text attribute defaults */    s->t_attrib_default.bold = 0;    s->t_attrib_default.uline = 0;    s->t_attrib_default.blink = 0;    s->t_attrib_default.invers = 0;    s->t_attrib_default.unvisible = 0;    s->t_attrib_default.fgcol = COLOR_WHITE;    s->t_attrib_default.bgcol = COLOR_BLACK;    /* set current text attributes to default */    s->t_attrib = s->t_attrib_default;    text_console_resize(s);    return chr;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -