diff --git a/Makefile.common b/Makefile.common index 2a8b41c6e2..5783c2ca3f 100644 --- a/Makefile.common +++ b/Makefile.common @@ -172,6 +172,7 @@ OBJ += frontend/frontend.o \ $(LIBRETRO_COMM_DIR)/lists/file_list.o \ $(LIBRETRO_COMM_DIR)/lists/dir_list.o \ $(LIBRETRO_COMM_DIR)/file/retro_dirent.o \ + $(LIBRETRO_COMM_DIR)/streams/stdin_stream.o \ $(LIBRETRO_COMM_DIR)/streams/file_stream.o \ $(LIBRETRO_COMM_DIR)/streams/interface_stream.o \ $(LIBRETRO_COMM_DIR)/streams/memory_stream.o \ diff --git a/command.c b/command.c index b8d134b639..696131c077 100644 --- a/command.c +++ b/command.c @@ -18,27 +18,22 @@ #include #include -#ifdef _WIN32 -#include -#else -#include -#endif - #include #include #include #include #include +#include #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_COMMAND - #ifdef HAVE_NETWORKING - #include - #include - #endif +#ifdef HAVE_NETWORKING +#include +#include +#endif #include #endif @@ -589,112 +584,6 @@ error: #ifdef HAVE_STDIN_CMD -#ifdef _WIN32 -static size_t read_stdin(char *buf, size_t size) -{ - DWORD i; - DWORD has_read = 0; - DWORD avail = 0; - bool echo = false; - HANDLE hnd = GetStdHandle(STD_INPUT_HANDLE); - - if (hnd == INVALID_HANDLE_VALUE) - return 0; - - /* Check first if we're a pipe - * (not console). */ - - /* If not a pipe, check if we're running in a console. */ - if (!PeekNamedPipe(hnd, NULL, 0, NULL, &avail, NULL)) - { - INPUT_RECORD recs[256]; - bool has_key = false; - DWORD mode = 0; - DWORD has_read = 0; - - if (!GetConsoleMode(hnd, &mode)) - return 0; - - if ((mode & (ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT)) - && !SetConsoleMode(hnd, - mode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT))) - return 0; - - /* Win32, Y U NO SANE NONBLOCK READ!? */ - if (!PeekConsoleInput(hnd, recs, - sizeof(recs) / sizeof(recs[0]), &has_read)) - return 0; - - for (i = 0; i < has_read; i++) - { - /* Very crude, but should get the job done. */ - if (recs[i].EventType == KEY_EVENT && - recs[i].Event.KeyEvent.bKeyDown && - (isgraph(recs[i].Event.KeyEvent.wVirtualKeyCode) || - recs[i].Event.KeyEvent.wVirtualKeyCode == VK_RETURN)) - { - has_key = true; - echo = true; - avail = size; - break; - } - } - - if (!has_key) - { - FlushConsoleInputBuffer(hnd); - return 0; - } - } - - if (!avail) - return 0; - - if (avail > size) - avail = size; - - if (!ReadFile(hnd, buf, avail, &has_read, NULL)) - return 0; - - for (i = 0; i < has_read; i++) - if (buf[i] == '\r') - buf[i] = '\n'; - - /* Console won't echo for us while in non-line mode, - * so do it manually ... */ - if (echo) - { - HANDLE hnd_out = GetStdHandle(STD_OUTPUT_HANDLE); - if (hnd_out != INVALID_HANDLE_VALUE) - { - DWORD has_written; - WriteConsole(hnd_out, buf, has_read, &has_written, NULL); - } - } - - return has_read; -} -#else - -static size_t read_stdin(char *buf, size_t size) -{ - size_t has_read = 0; - - while (size) - { - ssize_t ret = read(STDIN_FILENO, buf, size); - - if (ret <= 0) - break; - - buf += ret; - has_read += ret; - size -= ret; - } - - return has_read; -} -#endif static void command_stdin_poll(command_t *handle) { diff --git a/griffin/griffin.c b/griffin/griffin.c index a9f82c3a75..e03701ecd4 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -65,6 +65,7 @@ ARCHIVE FILE /*============================================================ COMPRESSION ============================================================ */ +#include "../libretro-common/streams/stdin_stream.c" #include "../libretro-common/streams/trans_stream.c" #include "../libretro-common/streams/trans_stream_pipe.c" diff --git a/libretro-common/include/streams/stdin_stream.h b/libretro-common/include/streams/stdin_stream.h new file mode 100644 index 0000000000..ce5ebe55df --- /dev/null +++ b/libretro-common/include/streams/stdin_stream.h @@ -0,0 +1,40 @@ +/* Copyright (C) 2010-2017 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (stdin_stream.h). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef LIBRETRO_SDK_STDIN_STREAM_H__ +#define LIBRETRO_SDK_STDIN_STREAM_H__ + +#include +#include + +#include + +#include + +RETRO_BEGIN_DECLS + +size_t read_stdin(char *buf, size_t size); + +RETRO_END_DECLS + +#endif + diff --git a/libretro-common/streams/stdin_stream.c b/libretro-common/streams/stdin_stream.c new file mode 100644 index 0000000000..2e39d1968f --- /dev/null +++ b/libretro-common/streams/stdin_stream.c @@ -0,0 +1,136 @@ +/* Copyright (C) 2010-2017 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (stdin_stream.c). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include +#include +#include + +#ifdef _WIN32 +#include +#else +#include +#endif + +#ifdef _WIN32 +size_t read_stdin(char *buf, size_t size) +{ + DWORD i; + DWORD has_read = 0; + DWORD avail = 0; + bool echo = false; + HANDLE hnd = GetStdHandle(STD_INPUT_HANDLE); + + if (hnd == INVALID_HANDLE_VALUE) + return 0; + + /* Check first if we're a pipe + * (not console). */ + + /* If not a pipe, check if we're running in a console. */ + if (!PeekNamedPipe(hnd, NULL, 0, NULL, &avail, NULL)) + { + INPUT_RECORD recs[256]; + bool has_key = false; + DWORD mode = 0; + DWORD has_read = 0; + + if (!GetConsoleMode(hnd, &mode)) + return 0; + + if ((mode & (ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT)) + && !SetConsoleMode(hnd, + mode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT))) + return 0; + + /* Win32, Y U NO SANE NONBLOCK READ!? */ + if (!PeekConsoleInput(hnd, recs, + sizeof(recs) / sizeof(recs[0]), &has_read)) + return 0; + + for (i = 0; i < has_read; i++) + { + /* Very crude, but should get the job done. */ + if (recs[i].EventType == KEY_EVENT && + recs[i].Event.KeyEvent.bKeyDown && + (isgraph(recs[i].Event.KeyEvent.wVirtualKeyCode) || + recs[i].Event.KeyEvent.wVirtualKeyCode == VK_RETURN)) + { + has_key = true; + echo = true; + avail = size; + break; + } + } + + if (!has_key) + { + FlushConsoleInputBuffer(hnd); + return 0; + } + } + + if (!avail) + return 0; + + if (avail > size) + avail = size; + + if (!ReadFile(hnd, buf, avail, &has_read, NULL)) + return 0; + + for (i = 0; i < has_read; i++) + if (buf[i] == '\r') + buf[i] = '\n'; + + /* Console won't echo for us while in non-line mode, + * so do it manually ... */ + if (echo) + { + HANDLE hnd_out = GetStdHandle(STD_OUTPUT_HANDLE); + if (hnd_out != INVALID_HANDLE_VALUE) + { + DWORD has_written; + WriteConsole(hnd_out, buf, has_read, &has_written, NULL); + } + } + + return has_read; +} +#else +size_t read_stdin(char *buf, size_t size) +{ + size_t has_read = 0; + + while (size) + { + ssize_t ret = read(STDIN_FILENO, buf, size); + + if (ret <= 0) + break; + + buf += ret; + has_read += ret; + size -= ret; + } + + return has_read; +} +#endif