예제 #1
0
파일: cgets.c 프로젝트: chunhualiu/OpenNT
char * __cdecl _cgets (
        char *string
        )
{
        ULONG oldstate;
        ULONG num_read;
        char *result;

        _mlock(_CONIO_LOCK);            /* lock the console */

        string[1] = 0;                  /* no chars read yet */
        result = &string[2];

	/*
	 * _coninpfh, the handle to the console input, is created the first
	 * time that either _getch() or _cgets() or _kbhit() is called.
	 */

	if ( _coninpfh == -2 )
	    __initconin();

        if ( _coninpfh == -1 ) {
            _munlock(_CONIO_LOCK);      /* unlock the console */
            return(NULL);               /* return failure */
        }

        GetConsoleMode( (HANDLE)_coninpfh, &oldstate );
        SetConsoleMode( (HANDLE)_coninpfh, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT |
                                         ENABLE_ECHO_INPUT );

        if ( !ReadConsole( (HANDLE)_coninpfh,
                           (LPVOID)result,
                           (unsigned char)string[0],
                           &num_read,
                           NULL )
           )
            result = NULL;

        if ( result != NULL ) {

            /* set length of string and null terminate it */

            if (string[num_read] == '\r') {
                string[1] = (char)(num_read - 2);
                string[num_read] = '\0';
            } else if ( (num_read == (ULONG)(unsigned char)string[0]) &&
                        (string[num_read + 1] == '\r') ) {
                /* special case 1 - \r\n straddles the boundary */
                string[1] = (char)(num_read -1);
                string[1 + num_read] = '\0';
            } else if ( (num_read == 1) && (string[2] == '\n') ) {
                /* special case 2 - read a single '\n'*/
                string[1] = string[2] = '\0';
            } else {
                string[1] = (char)num_read;
                string[2 + num_read] = '\0';
            }
        }

        SetConsoleMode( (HANDLE)_coninpfh, oldstate );

        _munlock(_CONIO_LOCK);          /* unlock the console */

        return result;
}
예제 #2
0
파일: getch.c 프로젝트: flychen50/clib
int __cdecl _kbhit_nolock (

        void
        )
{
        DWORD NumPending;
        DWORD NumPeeked;
        int ret = FALSE;
        PINPUT_RECORD pIRBuf=NULL;

        /*
         * if a character has been pushed back, return TRUE
         */
        if ( chbuf != -1 )
            return TRUE;

        /*
         * _coninpfh, the handle to the console input, is created the first
         * time that either _getch() or _cgets() or _kbhit() is called.
         */

        if ( _coninpfh == -2 )
            __initconin();

        /*
         * Peek all pending console events
         */
        if ( (_coninpfh == -1) ||

             !GetNumberOfConsoleInputEvents((HANDLE)_coninpfh, &NumPending) ||

             (NumPending == 0))
        {
            return FALSE;
        }

        pIRBuf=(PINPUT_RECORD)_calloca(NumPending, sizeof(INPUT_RECORD));
        if ( pIRBuf == NULL )
        {
            return FALSE;
        }

        if ( PeekConsoleInput( (HANDLE)_coninpfh,
                               pIRBuf,
                               NumPending,
                               &NumPeeked ) &&

             (NumPeeked != 0L) &&

             (NumPeeked <= NumPending) )
        {

            /*
             * Scan all of the peeked events to determine if any is a key event
             * which should be recognized.
             */
            PINPUT_RECORD pIR;
            for ( pIR = pIRBuf ; NumPeeked > 0 ; NumPeeked--, pIR++ ) {

                if ( (pIR->EventType == KEY_EVENT) &&

                     (pIR->Event.KeyEvent.bKeyDown) &&

                     ( pIR->Event.KeyEvent.uChar.AsciiChar ||
                       _getextendedkeycode( &(pIR->Event.KeyEvent) ) ) )
                {
                    /*
                     * Key event corresponding to an ASCII character or an
                     * extended code. In either case, success!
                     */
                    ret = TRUE;
                }
            }
        }

        _freea( pIRBuf );

        return ret;
}
예제 #3
0
파일: cgetws.c 프로젝트: jetlive/skiaming
errno_t __cdecl _cgetws_s (
        wchar_t *string,
        size_t sizeInWords,
        size_t * pSizeRead
        )
{
        ULONG oldstate;
        ULONG num_read;
        errno_t err = 0;

        _VALIDATE_CLEAR_OSSERR_RETURN_ERRCODE((string != NULL), EINVAL);
        _VALIDATE_CLEAR_OSSERR_RETURN_ERRCODE((sizeInWords > 0), EINVAL);
        _RESET_STRING(string, sizeInWords);

        _VALIDATE_CLEAR_OSSERR_RETURN_ERRCODE((pSizeRead != NULL), EINVAL);

        _mlock(_CONIO_LOCK);            /* lock the console */
        __TRY

            /*
             * We need to decrement sizeInWords because ReadConsole reads as
             * many characters as the parameter passed, doesn't null terminate
             */

            --sizeInWords;
            *pSizeRead = 0;

            /*
             * If the __console_whcar_buffer_used is set, then first fill the
             * buffered character and then proceed.
             */
            if (__console_wchar_buffer_used != 0 && sizeInWords > 0)
            {
                *string++ = __console_wchar_buffer;
                __console_wchar_buffer = 0;
                --sizeInWords;
                (*pSizeRead)++;
                if (__console_wchar_buffer == L'\0')
                    sizeInWords = 0;
            }

                        /* if the user only asked for one character, we have now filled their request
                        */
            if (sizeInWords != 0)
                        {
                                /*
                                * _coninpfh, the handle to the console input, is created the first
                                * time that either _getch() or _cgets() or _kbhit() is called.
                                */

                                if ( _coninpfh == -2 )
                                        __initconin();

                                if ( _coninpfh != -1 ) {

                                        GetConsoleMode( (HANDLE)_coninpfh, &oldstate );
                                        SetConsoleMode( (HANDLE)_coninpfh, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT );
                                        // First try usual way just as _cgets
                                        if ( bUseW)
                                        {
                                                if ( !ReadConsoleW( (HANDLE)_coninpfh,
                                                                                        (LPVOID)string,
                                                                                        (DWORD)sizeInWords,
                                                                                        &num_read,
                                                                                        NULL )
                                                        )
                                                {
                                                        if ( bUseW == 2 )
                                                        {
                                                                if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
                                                                        bUseW = FALSE;
                                                                else
                                                                        bUseW = TRUE;
                                                        }
                                                }
                                                else
                                                {
                                                        bUseW = TRUE;

                                                        /* set length of string and null terminate it */

                                                        if (string[num_read - 2] == L'\r') {
                                                                (*pSizeRead) += num_read - 2;
                                                                string[num_read - 2] = L'\0';
                                                        } else if ( (num_read == sizeInWords) &&
                                                                                (string[num_read - 1] == L'\r') ) {
                                                        /* special case 1 - \r\n straddles the boundary */
                                                                (*pSizeRead) += num_read -1;
                                                                string[num_read - 1] = L'\0';
                                                        } else if ( (num_read == 1) && (string[0] == L'\n') ) {
                                                                /* special case 2 - read a single '\n'*/
                                                                string[0] = L'\0';
                                                                (*pSizeRead) += 0;
                                                        } else {
                                                                (*pSizeRead) += num_read;
                                                                string[num_read] = L'\0';
                                                        }
                                                }
                                        }
                                        // If ReadConsoleW is not present, use ReadConsoleA and then convert
                                        // to Wide Char.
                                        if ( !bUseW)
                                        {
                                                static char AStr[BUF_MAX_LEN +1];
                                                static int in_buff = 0, was_buff_full = 0;
                                                unsigned int Copy, Sz, consoleCP;
                                                unsigned int last_read = 0, i;
                                                consoleCP = GetConsoleCP();
                                                do {
                                                        if (!in_buff)
                                                        {
                                                                if ( ReadConsoleA( (HANDLE)_coninpfh,
                                                                                                        (LPVOID)AStr,
                                                                                                        BUF_MAX_LEN,
                                                                                                        &num_read,
                                                                                   NULL) &&
                                                                     num_read <= BUF_MAX_LEN
                                                                        ) {
                                                                        if (num_read >= 2 && AStr[num_read -2] == '\r')
                                                                        {
                                                                                AStr[num_read -2] = '\0';
                                                                        }
                                                                        else if (num_read == BUF_MAX_LEN &&
                                                                                        AStr[num_read -1] == '\r')
                                                                                AStr[num_read -1] = '\0';
                                                                        else if (num_read == 1 && AStr[0] == '\n')
                                                                                AStr[0] = '\0';
                                                                        else
                                                                                AStr[num_read] = '\0';
                                                                } else {
                                                                        _dosmaperr(GetLastError());
                                                                        err = errno;
                                                                }
                                                        }
                                                        for ( i = 0; AStr[i] != '\0' &&
                                                                                i < (BUF_MAX_LEN) &&
                                                                                last_read < sizeInWords; i += Sz)
                                                        {
                                                                // Check if this character is lead byte. If yes, the size
                                                                // of this character is 2. Else 1.
                                                                if ( IsDBCSLeadByteEx( GetConsoleCP(), AStr[i]))
                                                                        Sz = 2;
                                                                else
                                                                        Sz = 1;
                                                                if ( (Copy = MultiByteToWideChar( consoleCP,
                                                                                                                                MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
                                                                                                                                &AStr[i],
                                                                                                                                Sz,
                                                                                                                                &string[last_read],
                                                                                                                                (int)sizeInWords - last_read)))
                                                                {
                                                                        last_read += Copy;
                                                                }
                                                        }
                                                        // Check if this conversion was from buffer. If yes, was
                                                        // buffer fully filled when it was first read using
                                                        // ReadConsoleA. If the buffer not fully filled, we don't need
                                                        // to read more from buffer. This is necessary to make it
                                                        // behave same as if we are reading using ReadConsoleW.
                                                        if ( in_buff && i == strlen(AStr))
                                                        {
                                                                in_buff = 0;
                                                                if ( was_buff_full)
                                                                {
                                                                        was_buff_full = 0;
                                                                        continue;
                                                                }
                                                                else
                                                                {
                                                                        break;
                                                                }
                                                        }
                                                        else if ( i < (BUF_MAX_LEN))
                                                                break;
                                                } while (last_read < sizeInWords);
                                                // We save the buffer to be used again.
                                                if ( i < strlen(AStr))
                                                {
                                                        in_buff = 1;
                                                        if ( strlen(AStr) == (BUF_MAX_LEN))
                                                                was_buff_full = 1;
                                                        memmove(AStr, &AStr[i], BUF_MAX_LEN +1 - i);
                                                }
                                                string[last_read] = '\0';
                                                (*pSizeRead) += last_read;
                                        }

                                        SetConsoleMode( (HANDLE)_coninpfh, oldstate );
                                } else {
                                        _dosmaperr(GetLastError());
                                        err = errno;
                                }
                        }

        __FINALLY
            _munlock(_CONIO_LOCK);          /* unlock the console */
        __END_TRY_FINALLY

        if (err != 0)
        {
            errno = err;
        }
        return err;
}
예제 #4
0
파일: getch.c 프로젝트: flychen50/clib
int __cdecl _getch_nolock (
        void
        )
{
        INPUT_RECORD ConInpRec;
        DWORD NumRead;
        const CharPair *pCP;
        int ch = 0;                     /* single character buffer */
        DWORD oldstate;

        /*
         * check pushback buffer (chbuf) a for character
         */
        if ( chbuf != EOF ) {
            /*
             * something there, clear buffer and return the character.
             */
            ch = (unsigned char)(chbuf & 0xFF);
            chbuf = EOF;
            return ch;
        }

        /*
         * _coninpfh, the handle to the console input, is created the first
         * time that either _getch() or _cgets() or _kbhit() is called.
         */

        if ( _coninpfh == -2 )
            __initconin();

        if (_coninpfh == -1)
            return EOF;

        /*
         * Switch to raw mode (no line input, no echo input)
         */
        GetConsoleMode( (HANDLE)_coninpfh, &oldstate );
        SetConsoleMode( (HANDLE)_coninpfh, 0L );

        for ( ; ; ) {

            /*
             * Get a console input event.
             */
            if ( !ReadConsoleInput( (HANDLE)_coninpfh,
                                    &ConInpRec,
                                    1L,
                                    &NumRead )
                 || (NumRead == 0L) )
            {
                ch = EOF;
                break;
            }

            /*
             * Look for, and decipher, key events.
             */
            if ( (ConInpRec.EventType == KEY_EVENT) &&
                 ConInpRec.Event.KeyEvent.bKeyDown ) {
                /*
                 * Easy case: if uChar.AsciiChar is non-zero, just stuff it
                 * into ch and quit.
                 */

                if ( ch = (unsigned char)ConInpRec.Event.KeyEvent.uChar.AsciiChar )
                    break;

                /*
                 * Hard case: either an extended code or an event which should
                 * not be recognized. let _getextendedkeycode() do the work...
                 */
                if ( pCP = _getextendedkeycode( &(ConInpRec.Event.KeyEvent) ) ) {
                    ch = pCP->LeadChar;
                    chbuf = pCP->SecondChar;
                    break;
                }
            }
        }


        /*
         * Restore previous console mode.
         */
        SetConsoleMode( (HANDLE)_coninpfh, oldstate );

        return ch;
}