Revision db418a0a

b/qemu-char.c
538 538
}
539 539
#endif /* !_WIN32 */
540 540

  
541
#define STDIO_MAX_CLIENTS 1
542
static int stdio_nb_clients;
543

  
541 544
#ifndef _WIN32
542 545

  
543 546
typedef struct {
......
545 548
    int max_size;
546 549
} FDCharDriver;
547 550

  
548
#define STDIO_MAX_CLIENTS 1
549
static int stdio_nb_clients = 0;
550 551

  
551 552
static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
552 553
{
......
1451 1452

  
1452 1453
#else /* _WIN32 */
1453 1454

  
1455
static CharDriverState *stdio_clients[STDIO_MAX_CLIENTS];
1456

  
1454 1457
typedef struct {
1455 1458
    int max_size;
1456 1459
    HANDLE hcom, hrecv, hsend;
......
1459 1462
    DWORD len;
1460 1463
} WinCharState;
1461 1464

  
1465
typedef struct {
1466
    HANDLE  hStdIn;
1467
    HANDLE  hInputReadyEvent;
1468
    HANDLE  hInputDoneEvent;
1469
    HANDLE  hInputThread;
1470
    uint8_t win_stdio_buf;
1471
} WinStdioCharState;
1472

  
1462 1473
#define NSENDBUF 2048
1463 1474
#define NRECVBUF 2048
1464 1475
#define MAXCONNECT 1
......
1809 1820

  
1810 1821
    return qemu_chr_open_win_file(fd_out, _chr);
1811 1822
}
1823

  
1824
static int win_stdio_write(CharDriverState *chr, const uint8_t *buf, int len)
1825
{
1826
    HANDLE  hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
1827
    DWORD   dwSize;
1828
    int     len1;
1829

  
1830
    len1 = len;
1831

  
1832
    while (len1 > 0) {
1833
        if (!WriteFile(hStdOut, buf, len1, &dwSize, NULL)) {
1834
            break;
1835
        }
1836
        buf  += dwSize;
1837
        len1 -= dwSize;
1838
    }
1839

  
1840
    return len - len1;
1841
}
1842

  
1843
static void win_stdio_wait_func(void *opaque)
1844
{
1845
    CharDriverState   *chr   = opaque;
1846
    WinStdioCharState *stdio = chr->opaque;
1847
    INPUT_RECORD       buf[4];
1848
    int                ret;
1849
    DWORD              dwSize;
1850
    int                i;
1851

  
1852
    ret = ReadConsoleInput(stdio->hStdIn, buf, sizeof(buf) / sizeof(*buf),
1853
                           &dwSize);
1854

  
1855
    if (!ret) {
1856
        /* Avoid error storm */
1857
        qemu_del_wait_object(stdio->hStdIn, NULL, NULL);
1858
        return;
1859
    }
1860

  
1861
    for (i = 0; i < dwSize; i++) {
1862
        KEY_EVENT_RECORD *kev = &buf[i].Event.KeyEvent;
1863

  
1864
        if (buf[i].EventType == KEY_EVENT && kev->bKeyDown) {
1865
            int j;
1866
            if (kev->uChar.AsciiChar != 0) {
1867
                for (j = 0; j < kev->wRepeatCount; j++) {
1868
                    if (qemu_chr_be_can_write(chr)) {
1869
                        uint8_t c = kev->uChar.AsciiChar;
1870
                        qemu_chr_be_write(chr, &c, 1);
1871
                    }
1872
                }
1873
            }
1874
        }
1875
    }
1876
}
1877

  
1878
static DWORD WINAPI win_stdio_thread(LPVOID param)
1879
{
1880
    CharDriverState   *chr   = param;
1881
    WinStdioCharState *stdio = chr->opaque;
1882
    int                ret;
1883
    DWORD              dwSize;
1884

  
1885
    while (1) {
1886

  
1887
        /* Wait for one byte */
1888
        ret = ReadFile(stdio->hStdIn, &stdio->win_stdio_buf, 1, &dwSize, NULL);
1889

  
1890
        /* Exit in case of error, continue if nothing read */
1891
        if (!ret) {
1892
            break;
1893
        }
1894
        if (!dwSize) {
1895
            continue;
1896
        }
1897

  
1898
        /* Some terminal emulator returns \r\n for Enter, just pass \n */
1899
        if (stdio->win_stdio_buf == '\r') {
1900
            continue;
1901
        }
1902

  
1903
        /* Signal the main thread and wait until the byte was eaten */
1904
        if (!SetEvent(stdio->hInputReadyEvent)) {
1905
            break;
1906
        }
1907
        if (WaitForSingleObject(stdio->hInputDoneEvent, INFINITE)
1908
            != WAIT_OBJECT_0) {
1909
            break;
1910
        }
1911
    }
1912

  
1913
    qemu_del_wait_object(stdio->hInputReadyEvent, NULL, NULL);
1914
    return 0;
1915
}
1916

  
1917
static void win_stdio_thread_wait_func(void *opaque)
1918
{
1919
    CharDriverState   *chr   = opaque;
1920
    WinStdioCharState *stdio = chr->opaque;
1921

  
1922
    if (qemu_chr_be_can_write(chr)) {
1923
        qemu_chr_be_write(chr, &stdio->win_stdio_buf, 1);
1924
    }
1925

  
1926
    SetEvent(stdio->hInputDoneEvent);
1927
}
1928

  
1929
static void qemu_chr_set_echo_win_stdio(CharDriverState *chr, bool echo)
1930
{
1931
    WinStdioCharState *stdio  = chr->opaque;
1932
    DWORD              dwMode = 0;
1933

  
1934
    GetConsoleMode(stdio->hStdIn, &dwMode);
1935

  
1936
    if (echo) {
1937
        SetConsoleMode(stdio->hStdIn, dwMode | ENABLE_ECHO_INPUT);
1938
    } else {
1939
        SetConsoleMode(stdio->hStdIn, dwMode & ~ENABLE_ECHO_INPUT);
1940
    }
1941
}
1942

  
1943
static void win_stdio_close(CharDriverState *chr)
1944
{
1945
    WinStdioCharState *stdio = chr->opaque;
1946

  
1947
    if (stdio->hInputReadyEvent != INVALID_HANDLE_VALUE) {
1948
        CloseHandle(stdio->hInputReadyEvent);
1949
    }
1950
    if (stdio->hInputDoneEvent != INVALID_HANDLE_VALUE) {
1951
        CloseHandle(stdio->hInputDoneEvent);
1952
    }
1953
    if (stdio->hInputThread != INVALID_HANDLE_VALUE) {
1954
        TerminateThread(stdio->hInputThread, 0);
1955
    }
1956

  
1957
    g_free(chr->opaque);
1958
    g_free(chr);
1959
    stdio_nb_clients--;
1960
}
1961

  
1962
static int qemu_chr_open_win_stdio(QemuOpts *opts, CharDriverState **_chr)
1963
{
1964
    CharDriverState   *chr;
1965
    WinStdioCharState *stdio;
1966
    DWORD              dwMode;
1967
    int                is_console = 0;
1968

  
1969
    if (stdio_nb_clients >= STDIO_MAX_CLIENTS
1970
        || ((display_type != DT_NOGRAPHIC) && (stdio_nb_clients != 0))) {
1971
        return -EIO;
1972
    }
1973

  
1974
    chr   = g_malloc0(sizeof(CharDriverState));
1975
    stdio = g_malloc0(sizeof(WinStdioCharState));
1976

  
1977
    stdio->hStdIn = GetStdHandle(STD_INPUT_HANDLE);
1978
    if (stdio->hStdIn == INVALID_HANDLE_VALUE) {
1979
        fprintf(stderr, "cannot open stdio: invalid handle\n");
1980
        exit(1);
1981
    }
1982

  
1983
    is_console = GetConsoleMode(stdio->hStdIn, &dwMode) != 0;
1984

  
1985
    chr->opaque    = stdio;
1986
    chr->chr_write = win_stdio_write;
1987
    chr->chr_close = win_stdio_close;
1988

  
1989
    if (stdio_nb_clients == 0) {
1990
        if (is_console) {
1991
            if (qemu_add_wait_object(stdio->hStdIn,
1992
                                     win_stdio_wait_func, chr)) {
1993
                fprintf(stderr, "qemu_add_wait_object: failed\n");
1994
            }
1995
        } else {
1996
            DWORD   dwId;
1997

  
1998
            stdio->hInputReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
1999
            stdio->hInputDoneEvent  = CreateEvent(NULL, FALSE, FALSE, NULL);
2000
            stdio->hInputThread     = CreateThread(NULL, 0, win_stdio_thread,
2001
                                            chr, 0, &dwId);
2002

  
2003
            if (stdio->hInputThread == INVALID_HANDLE_VALUE
2004
                || stdio->hInputReadyEvent == INVALID_HANDLE_VALUE
2005
                || stdio->hInputDoneEvent == INVALID_HANDLE_VALUE) {
2006
                fprintf(stderr, "cannot create stdio thread or event\n");
2007
                exit(1);
2008
            }
2009
            if (qemu_add_wait_object(stdio->hInputReadyEvent,
2010
                                     win_stdio_thread_wait_func, chr)) {
2011
                fprintf(stderr, "qemu_add_wait_object: failed\n");
2012
            }
2013
        }
2014
    }
2015

  
2016
    dwMode |= ENABLE_LINE_INPUT;
2017

  
2018
    stdio_clients[stdio_nb_clients++] = chr;
2019
    if (stdio_nb_clients == 1 && is_console) {
2020
        /* set the terminal in raw mode */
2021
        /* ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS */
2022
        dwMode |= ENABLE_PROCESSED_INPUT;
2023
    }
2024

  
2025
    SetConsoleMode(stdio->hStdIn, dwMode);
2026

  
2027
    chr->chr_set_echo = qemu_chr_set_echo_win_stdio;
2028
    qemu_chr_fe_set_echo(chr, false);
2029

  
2030
    *_chr = chr;
2031

  
2032
    return 0;
2033
}
1812 2034
#endif /* !_WIN32 */
1813 2035

  
1814 2036
/***********************************************************/
......
2519 2741
    { .name = "pipe",      .open = qemu_chr_open_win_pipe },
2520 2742
    { .name = "console",   .open = qemu_chr_open_win_con },
2521 2743
    { .name = "serial",    .open = qemu_chr_open_win },
2744
    { .name = "stdio",     .open = qemu_chr_open_win_stdio },
2522 2745
#else
2523 2746
    { .name = "file",      .open = qemu_chr_open_file_out },
2524 2747
    { .name = "pipe",      .open = qemu_chr_open_pipe },

Also available in: Unified diff