send correctly long key sequences on slow terminals - fixes backspace handling
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2012 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									be995c2764
								
							
						
					
					
						commit
						e15d737181
					
				
							
								
								
									
										96
									
								
								console.c
								
								
								
								
							
							
						
						
									
										96
									
								
								console.c
								
								
								
								
							| 
						 | 
				
			
			@ -53,6 +53,57 @@ enum TTYState {
 | 
			
		|||
    TTY_STATE_CSI,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct QEMUFIFO {
 | 
			
		||||
    uint8_t *buf;
 | 
			
		||||
    int buf_size;
 | 
			
		||||
    int count, wptr, rptr;
 | 
			
		||||
} QEMUFIFO;
 | 
			
		||||
 | 
			
		||||
int qemu_fifo_write(QEMUFIFO *f, const uint8_t *buf, int len1)
 | 
			
		||||
{
 | 
			
		||||
    int l, len;
 | 
			
		||||
 | 
			
		||||
    l = f->buf_size - f->count;
 | 
			
		||||
    if (len1 > l)
 | 
			
		||||
        len1 = l;
 | 
			
		||||
    len = len1;
 | 
			
		||||
    while (len > 0) {
 | 
			
		||||
        l = f->buf_size - f->wptr;
 | 
			
		||||
        if (l > len)
 | 
			
		||||
            l = len;
 | 
			
		||||
        memcpy(f->buf + f->wptr, buf, l);
 | 
			
		||||
        f->wptr += l;
 | 
			
		||||
        if (f->wptr >= f->buf_size)
 | 
			
		||||
            f->wptr = 0;
 | 
			
		||||
        buf += l;
 | 
			
		||||
        len -= l;
 | 
			
		||||
    }
 | 
			
		||||
    f->count += len1;
 | 
			
		||||
    return len1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int qemu_fifo_read(QEMUFIFO *f, uint8_t *buf, int len1)
 | 
			
		||||
{
 | 
			
		||||
    int l, len;
 | 
			
		||||
 | 
			
		||||
    if (len1 > f->count)
 | 
			
		||||
        len1 = f->count;
 | 
			
		||||
    len = len1;
 | 
			
		||||
    while (len > 0) {
 | 
			
		||||
        l = f->buf_size - f->rptr;
 | 
			
		||||
        if (l > len)
 | 
			
		||||
            l = len;
 | 
			
		||||
        memcpy(buf, f->buf + f->rptr, l);
 | 
			
		||||
        f->rptr += l;
 | 
			
		||||
        if (f->rptr >= f->buf_size)
 | 
			
		||||
            f->rptr = 0;
 | 
			
		||||
        buf += l;
 | 
			
		||||
        len -= l;
 | 
			
		||||
    }
 | 
			
		||||
    f->count -= len1;
 | 
			
		||||
    return len1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ??? This is mis-named.
 | 
			
		||||
   It is used for both text and graphical consoles.  */
 | 
			
		||||
struct TextConsole {
 | 
			
		||||
| 
						 | 
				
			
			@ -81,8 +132,13 @@ struct TextConsole {
 | 
			
		|||
    int nb_esc_params;
 | 
			
		||||
 | 
			
		||||
    /* kbd read handler */
 | 
			
		||||
    IOCanRWHandler *fd_can_read; 
 | 
			
		||||
    IOReadHandler *fd_read;
 | 
			
		||||
    void *fd_opaque;
 | 
			
		||||
    /* fifo for key pressed */
 | 
			
		||||
    QEMUFIFO out_fifo;
 | 
			
		||||
    uint8_t out_fifo_buf[16];
 | 
			
		||||
    QEMUTimer *kbd_timer;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static TextConsole *active_console;
 | 
			
		||||
| 
						 | 
				
			
			@ -712,12 +768,8 @@ static void console_putchar(TextConsole *s, int ch)
 | 
			
		|||
            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);
 | 
			
		||||
            if (s->x > 0) 
 | 
			
		||||
                s->x--;
 | 
			
		||||
            break;
 | 
			
		||||
        case '\t':  /* tabspace */
 | 
			
		||||
            if (s->x + (8 - (s->x % 8)) > s->width) {
 | 
			
		||||
| 
						 | 
				
			
			@ -835,6 +887,7 @@ static void console_chr_add_read_handler(CharDriverState *chr,
 | 
			
		|||
                                         IOReadHandler *fd_read, void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    TextConsole *s = chr->opaque;
 | 
			
		||||
    s->fd_can_read = fd_can_read;
 | 
			
		||||
    s->fd_read = fd_read;
 | 
			
		||||
    s->fd_opaque = opaque;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -854,6 +907,28 @@ static void console_send_event(CharDriverState *chr, int event)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void kbd_send_chars(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    TextConsole *s = opaque;
 | 
			
		||||
    int len;
 | 
			
		||||
    uint8_t buf[16];
 | 
			
		||||
    
 | 
			
		||||
    len = s->fd_can_read(s->fd_opaque);
 | 
			
		||||
    if (len > s->out_fifo.count)
 | 
			
		||||
        len = s->out_fifo.count;
 | 
			
		||||
    if (len > 0) {
 | 
			
		||||
        if (len > sizeof(buf))
 | 
			
		||||
            len = sizeof(buf);
 | 
			
		||||
        qemu_fifo_read(&s->out_fifo, buf, len);
 | 
			
		||||
        s->fd_read(s->fd_opaque, buf, len);
 | 
			
		||||
    }
 | 
			
		||||
    /* characters are pending: we send them a bit later (XXX:
 | 
			
		||||
       horrible, should change char device API) */
 | 
			
		||||
    if (s->out_fifo.count > 0) {
 | 
			
		||||
        qemu_mod_timer(s->kbd_timer, qemu_get_clock(rt_clock) + 1);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* called when an ascii key is pressed */
 | 
			
		||||
void kbd_put_keysym(int keysym)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -879,7 +954,6 @@ void kbd_put_keysym(int keysym)
 | 
			
		|||
        console_scroll(10);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        if (s->fd_read) {
 | 
			
		||||
        /* convert the QEMU keysym to VT100 key string */
 | 
			
		||||
        q = buf;
 | 
			
		||||
        if (keysym >= 0xe100 && keysym <= 0xe11f) {
 | 
			
		||||
| 
						 | 
				
			
			@ -897,7 +971,9 @@ void kbd_put_keysym(int keysym)
 | 
			
		|||
        } else {
 | 
			
		||||
                *q++ = keysym;
 | 
			
		||||
        }
 | 
			
		||||
            s->fd_read(s->fd_opaque, buf, q - buf);
 | 
			
		||||
        if (s->fd_read) {
 | 
			
		||||
            qemu_fifo_write(&s->out_fifo, buf, q - buf);
 | 
			
		||||
            kbd_send_chars(s);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -974,6 +1050,10 @@ CharDriverState *text_console_init(DisplayState *ds)
 | 
			
		|||
    chr->chr_add_read_handler = console_chr_add_read_handler;
 | 
			
		||||
    chr->chr_send_event = console_send_event;
 | 
			
		||||
 | 
			
		||||
    s->out_fifo.buf = s->out_fifo_buf;
 | 
			
		||||
    s->out_fifo.buf_size = sizeof(s->out_fifo_buf);
 | 
			
		||||
    s->kbd_timer = qemu_new_timer(rt_clock, kbd_send_chars, s);
 | 
			
		||||
    
 | 
			
		||||
    if (!color_inited) {
 | 
			
		||||
        color_inited = 1;
 | 
			
		||||
        for(j = 0; j < 2; j++) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue