From 84243cd8240c7d852a3b6021d1b0fbd5dc9a6385 Mon Sep 17 00:00:00 2001 From: Leroy Hopson Date: Fri, 16 Jul 2021 14:31:13 +0700 Subject: [PATCH] Enable compiling Pipe and LibuvUtils on Windows Currently only works when building with debug target. On GitHub actions target release results in linking errors. So disable PTY for release builds. Part of #25. --- .github/workflows/main.yml | 45 ++++++++------ addons/godot_xterm/native/SConstruct | 19 ++++-- .../native/src/libgodotxtermnative.cpp | 12 +++- .../native/src/node_pty/win/conpty.cc | 43 ++++--------- .../native/src/node_pty/win/conpty.h | 33 ++++++++++ addons/godot_xterm/native/src/pipe.cpp | 10 ++- addons/godot_xterm/native/src/pipe.h | 22 +------ addons/godot_xterm/native/src/terminal.cpp | 62 ++++++++++++------- 8 files changed, 145 insertions(+), 101 deletions(-) create mode 100644 addons/godot_xterm/native/src/node_pty/win/conpty.h diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 08013dc..da80fe1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -98,29 +98,38 @@ jobs: cd addons/godot_xterm/native/thirdparty/godot-cpp scons platform=${{ matrix.platform }} target=${{ matrix.target }} bits=${{ matrix.bits }} generate_bindings=yes -j2 - - name: Build libuv - if: ${{ matrix.bits == 64 && steps.cache-libuv.outputs.cache-hit != 'true' }} - uses: lukka/run-cmake@v3 + - name: Setup cmake + if: steps.cache-libuv.outputs.cache-hit != 'true' + uses: jwlawson/actions-setup-cmake@v1.9 with: - cmakeListsOrSettingsJson: CMakeListsTxtAdvanced - cmakeListsTxtPath: '${{ github.workspace }}/addons/godot_xterm/native/thirdparty/libuv/CMakeLists.txt' - useVcpkgToolchainFile: true - cmakeAppendedArgs: '-DCMAKE_BUILD_TYPE=${{ matrix.target }} -DBUILD_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE' - buildDirectory: '${{ github.workspace }}/addons/godot_xterm/native/thirdparty/libuv/build' - - name: Build libuv 32 bit - if: ${{ matrix.bits == 32 && steps.cache-libuv.outputs.cache-hit != 'true' }} - uses: lukka/run-cmake@v3 - with: - cmakeListsOrSettingsJson: CMakeListsTxtAdvanced - cmakeListsTxtPath: '${{ github.workspace }}/addons/godot_xterm/native/thirdparty/libuv/CMakeLists.txt' - useVcpkgToolchainFile: true - cmakeAppendedArgs: '-DCMAKE_BUILD_TYPE=${{ matrix.target }} -DBUILD_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE -DCMAKE_SYSTEM_PROCESSOR=i686 -DCMAKE_C_FLAGS=-m32' - buildDirectory: '${{ github.workspace }}/addons/godot_xterm/native/thirdparty/libuv/build' + cmake-version: '3.15.4' + use-32bit: ${{ matrix.bits == 32 && matrix.os == 'windows-latest' }} + - name: Build libuv + if: steps.cache-libuv.outputs.cache-hit != 'true' + shell: bash + env: + TARGET: ${{ matrix.target }} + BITS: ${{ matrix.bits }} + OS: ${{ matrix.os }} + run: | + cd addons/godot_xterm/native/thirdparty/libuv + args="-DCMAKE_BUILD_TYPE=$TARGET -DBUILD_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE" + if [ "$BITS" -eq 32 -a "$OS" == "windows-latest" ]; then + cmake -G "Visual Studio 16 2019" -A Win32 -S $(pwd) -B "build" $args + else + mkdir build || true + cd build + if [ "$BITS" -eq 32 ]; then args="$args -DCMAKE_SYSTEM_PROCESSOR=i686 -DCMAKE_C_FLAGS=-m32"; fi + cmake .. $args + cd .. + fi + cmake --build build --config $TARGET - name: Build libgodot-xterm run: | cd addons/godot_xterm/native - scons platform=${{ matrix.platform }} target=${{ matrix.target }} bits=${{ matrix.bits }} -j2 + # Disable PTY on release windows builds as it has linking errors when built on GithHub actions. + scons platform=${{ matrix.platform }} target=${{ matrix.target }} bits=${{ matrix.bits }} disable_pty=${{ matrix.target == 'release' && matrix.platform == 'windows' && 'yes' || 'no' }} -j2 - name: Upload build artifacts uses: actions/upload-artifact@v2 diff --git a/addons/godot_xterm/native/SConstruct b/addons/godot_xterm/native/SConstruct index 824df1c..6312e86 100644 --- a/addons/godot_xterm/native/SConstruct +++ b/addons/godot_xterm/native/SConstruct @@ -264,14 +264,25 @@ sources.append('src/libgodotxtermnative.cpp') sources.append('src/terminal.cpp') -# PTY not supported on HTML5 or Windows (yet). -if env['disable_pty'] or env['platform'] == 'javascript' or env['platform'] == 'windows': +# PTY not supported on HTML5. +if env['disable_pty'] or env['platform'] == 'javascript': env.Append(CPPDEFINES=['_PTY_DISABLED']) else: sources.append('src/pipe.cpp') sources.append('src/libuv_utils.cpp') - sources.append('src/node_pty/unix/pty.cc') - env.Append(LIBS=['util', env.File('thirdparty/libuv/build/libuv_a.a')]) + if env['platform'] != 'windows': + sources.append('src/node_pty/unix/pty.cc') + env.Append(LIBS=['util', env.File('thirdparty/libuv/build/libuv_a.a')]) + else: + #sources.append('src/node_pty/win/conpty.cc') + env.Append(LIBS=[ + env.File(f'thirdparty/libuv/build/{env["target"].capitalize()}/uv_a.lib'), + 'Advapi32.lib', + 'Iphlpapi.lib', + 'user32.lib', + 'userenv.lib', + 'Ws2_32.lib', + ]) if env['platform'] == 'linux': libsuffix = "a" diff --git a/addons/godot_xterm/native/src/libgodotxtermnative.cpp b/addons/godot_xterm/native/src/libgodotxtermnative.cpp index 7ff414a..7d249c2 100644 --- a/addons/godot_xterm/native/src/libgodotxtermnative.cpp +++ b/addons/godot_xterm/native/src/libgodotxtermnative.cpp @@ -1,9 +1,14 @@ #include "terminal.h" -#if !defined(__EMSCRIPTEN__) && !defined(__WIN32) +#if !defined(_PTY_DISABLED) #include "libuv_utils.h" -#include "node_pty/unix/pty.h" #include "pipe.h" +#if defined(__unix__) +#include "node_pty/unix/pty.h" +#endif +#if defined(__WIN32) +//#include "node_pty/win/conpty.h" +#endif #endif extern "C" void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options *o) { @@ -24,5 +29,8 @@ extern "C" void GDN_EXPORT godot_nativescript_init(void *handle) { #if defined(__unix__) godot::register_tool_class(); #endif +#if defined(__WIN32) + // godot::register_tool_class(); +#endif #endif } diff --git a/addons/godot_xterm/native/src/node_pty/win/conpty.cc b/addons/godot_xterm/native/src/node_pty/win/conpty.cc index 65128a3..ef45707 100644 --- a/addons/godot_xterm/native/src/node_pty/win/conpty.cc +++ b/addons/godot_xterm/native/src/node_pty/win/conpty.cc @@ -2,6 +2,7 @@ * Copyright (c) 2013-2015, Christopher Jeffrey, Peter Sunde (MIT License) * Copyright (c) 2016, Daniel Imms (MIT License). * Copyright (c) 2018, Microsoft Corporation (MIT License). + * Copyright (c) 2021, Leroy Hopson (MIT License). * * pty.cc: * This file is responsible for starting processes @@ -379,18 +380,9 @@ static NAN_METHOD(PtyConnect) { info.GetReturnValue().Set(marshal); } -static NAN_METHOD(PtyResize) { - Nan::HandleScope scope; - - if (info.Length() != 3 || !info[0]->IsNumber() || !info[1]->IsNumber() || - !info[2]->IsNumber()) { - Nan::ThrowError("Usage: pty.resize(id, cols, rows)"); - return; - } - - int id = info[0]->Int32Value(Nan::GetCurrentContext()).FromJust(); - SHORT cols = info[1]->Uint32Value(Nan::GetCurrentContext()).FromJust(); - SHORT rows = info[2]->Uint32Value(Nan::GetCurrentContext()).FromJust(); +void ConPTY::resize(int id, int cols, int rows) { + // SHORT cols = info[1]->Uint32Value(Nan::GetCurrentContext()).FromJust(); + // SHORT rows = info[2]->Uint32Value(Nan::GetCurrentContext()).FromJust(); const pty_baton *handle = get_pty_baton(id); @@ -405,20 +397,9 @@ static NAN_METHOD(PtyResize) { pfnResizePseudoConsole(handle->hpc, size); } } - - return info.GetReturnValue().SetUndefined(); } -static NAN_METHOD(PtyKill) { - Nan::HandleScope scope; - - if (info.Length() != 1 || !info[0]->IsNumber()) { - Nan::ThrowError("Usage: pty.kill(id)"); - return; - } - - int id = info[0]->Int32Value(Nan::GetCurrentContext()).FromJust(); - +void ConPTY::kill(int id) { const pty_baton *handle = get_pty_baton(id); HANDLE hLibrary = LoadLibraryExW(L"kernel32.dll", 0, 0); @@ -441,12 +422,12 @@ static NAN_METHOD(PtyKill) { * Init */ -extern "C" void init(v8::Local target) { - Nan::HandleScope scope; - Nan::SetMethod(target, "startProcess", PtyStartProcess); - Nan::SetMethod(target, "connect", PtyConnect); - Nan::SetMethod(target, "resize", PtyResize); - Nan::SetMethod(target, "kill", PtyKill); +void ConPTY::_register_methods() { + register_method("_init", &ConPTY::_init); + register_method("start_process", &ConPTY::start_process); + register_method("connect_to_named_pipe", &ConPTY::connect_to_named_pipe); + register_method("resize", &ConPTY::resize); + register_method("kill", &ConPTY::kill); }; -NODE_MODULE(pty, init); +void ConPTY::_init() {} diff --git a/addons/godot_xterm/native/src/node_pty/win/conpty.h b/addons/godot_xterm/native/src/node_pty/win/conpty.h new file mode 100644 index 0000000..be66641 --- /dev/null +++ b/addons/godot_xterm/native/src/node_pty/win/conpty.h @@ -0,0 +1,33 @@ +// Copyright (c) 2021, Leroy Hopson (MIT License). + +#ifndef GODOT_XTERM_CONPTY_H +#define GODOT_XTERM_CONPTY_H + +#include +#include + +namespace godot { + +class ConPTY : public Reference { + GODOT_CLASS(ConPTY, Reference) + +public: + // Array fork(String file, + // int _ignored, /* FIXME: For some reason Pipe throws + // ENOTSOCK in read callback if args (or another + // non-empty, non-zero) value is in this position. */ + // PoolStringArray args, PoolStringArray env, String cwd, int + // cols, int rows, int uid, int gid, bool utf8, Ref + // on_exit); + // Array open(int cols, int rows); + void resize(int id, int cols, int rows); + void kill(int id); + // String process(int fd, String tty); + + void _init(); + static void _register_methods(); +}; + +} // namespace godot + +#endif // GODOT_XTERM_CONPTY_H \ No newline at end of file diff --git a/addons/godot_xterm/native/src/pipe.cpp b/addons/godot_xterm/native/src/pipe.cpp index 7bb2241..361b195 100644 --- a/addons/godot_xterm/native/src/pipe.cpp +++ b/addons/godot_xterm/native/src/pipe.cpp @@ -13,6 +13,10 @@ #include #include +#ifndef ULONG +#define ULONG size_t +#endif + using namespace godot; void Pipe::_register_methods() { @@ -54,9 +58,11 @@ godot_error Pipe::open(int fd, bool ipc = false) { godot_error Pipe::write(String p_data) { char *s = p_data.alloc_c_string(); - size_t len = strlen(s); + ULONG len = strlen(s); - uv_buf_t bufs[] = {{.base = s, .len = len}}; + uv_buf_t bufs[1]; + bufs[0].base = s; + bufs[0].len = len; uv_write_t req; diff --git a/addons/godot_xterm/native/src/pipe.h b/addons/godot_xterm/native/src/pipe.h index 395b063..e893361 100644 --- a/addons/godot_xterm/native/src/pipe.h +++ b/addons/godot_xterm/native/src/pipe.h @@ -3,13 +3,8 @@ #ifndef GODOT_XTERM_PIPE_H #define GODOT_XTERM_PIPE_H -#include -#include #include #include -#include -#include -#include #include namespace godot { @@ -22,18 +17,6 @@ public: static void _register_methods(); - enum Status { - NONE, - CONNECTING, - CONNECTED, - ERROR, - }; - - int STATUS_NONE = Status::NONE; - int STATUS_CONNECTING = Status::CONNECTING; - int STATUS_CONNECTED = Status::CONNECTING; - int STATUS_ERROR = Status::ERROR; - Pipe(); ~Pipe(); @@ -47,11 +30,8 @@ public: void pause(); void resume(); -protected: - const godot_net_stream_peer *interface; - public: - Status status; + int status; private: void _poll_connection(); diff --git a/addons/godot_xterm/native/src/terminal.cpp b/addons/godot_xterm/native/src/terminal.cpp index ce3c9a3..ca1b352 100644 --- a/addons/godot_xterm/native/src/terminal.cpp +++ b/addons/godot_xterm/native/src/terminal.cpp @@ -425,30 +425,46 @@ void Terminal::update_theme() { palette[color] = c; }; - set_pallete_color(TSM_COLOR_BLACK, "Black", Color(0, 0, 0, 1)); - set_pallete_color(TSM_COLOR_RED, "Red", Color(0.501961, 0, 0, 1)); - set_pallete_color(TSM_COLOR_GREEN, "Green", Color(0, 0.501961, 0, 1)); - set_pallete_color(TSM_COLOR_YELLOW, "Yellow", - Color(0.501961, 0.501961, 0, 1)); - set_pallete_color(TSM_COLOR_BLUE, "Blue", Color(0, 0, 0.501961, 1)); - set_pallete_color(TSM_COLOR_MAGENTA, "Magenta", - Color(0.501961, 0, 0.501961, 1)); - set_pallete_color(TSM_COLOR_CYAN, "Cyan", Color(0, 0.501961, 0.501961, 1)); - set_pallete_color(TSM_COLOR_DARK_GREY, "Dark Grey", - Color(0.501961, 0.501961, 0.501961, 1)); - set_pallete_color(TSM_COLOR_LIGHT_GREY, "Light Grey", - Color(0.752941, 0.752941, 0.752941, 1)); - set_pallete_color(TSM_COLOR_LIGHT_RED, "Light Red", Color(1, 0, 0, 1)); - set_pallete_color(TSM_COLOR_LIGHT_GREEN, "Light Green", Color(0, 1, 0, 1)); - set_pallete_color(TSM_COLOR_LIGHT_YELLOW, "Light Yellow", Color(1, 1, 0, 1)); - set_pallete_color(TSM_COLOR_LIGHT_BLUE, "Light Blue", Color(0, 0, 1, 1)); - set_pallete_color(TSM_COLOR_LIGHT_MAGENTA, "Light Magenta", - Color(1, 0, 1, 1)); - set_pallete_color(TSM_COLOR_LIGHT_CYAN, "Light Cyan", Color(0, 1, 1, 1)); - set_pallete_color(TSM_COLOR_WHITE, "White", Color(1, 1, 1, 1)); + /* Default to Xterm colors */ - set_pallete_color(TSM_COLOR_BACKGROUND, "Background", Color(0, 0, 0, 1)); - set_pallete_color(TSM_COLOR_FOREGROUND, "Foreground", Color(1, 1, 1, 1)); + /* ANSI 0 */ + set_pallete_color(TSM_COLOR_BLACK, "Black", Color::html("#000000")); + /* ANSI 1 */ + set_pallete_color(TSM_COLOR_RED, "Red", Color::html("#CD0000")); + /* ANSI 2 */ + set_pallete_color(TSM_COLOR_GREEN, "Green", Color::html("#00CD00")); + /* ANSI 3 */ + set_pallete_color(TSM_COLOR_YELLOW, "Yellow", Color::html("#CDCD00")); + /* ANSI 4 */ + set_pallete_color(TSM_COLOR_BLUE, "Blue", Color::html("#0000EE")); + /* ANSI 5 */ + set_pallete_color(TSM_COLOR_MAGENTA, "Magenta", Color::html("#CD00CD")); + /* ANSI 6 */ + set_pallete_color(TSM_COLOR_CYAN, "Cyan", Color::html("#00CDCD")); + /* ANSI 7 (White) */ + set_pallete_color(TSM_COLOR_LIGHT_GREY, "Light Grey", Color::html("#E5E5E5")); + /* ANSI 8 (Bright Black) */ + set_pallete_color(TSM_COLOR_DARK_GREY, "Dark Grey", Color::html("#7F7F7F")); + /* ANSI 9 */ + set_pallete_color(TSM_COLOR_LIGHT_RED, "Light Red", Color::html("#FF0000")); + /* ANSI 10 */ + set_pallete_color(TSM_COLOR_LIGHT_GREEN, "Light Green", + Color::html("#00FF00")); + /* ANSI 11 */ + set_pallete_color(TSM_COLOR_LIGHT_YELLOW, "Light Yellow", + Color::html("#FFFF00")); + /* ANSI 12 */ + set_pallete_color(TSM_COLOR_LIGHT_BLUE, "Light Blue", Color::html("#0000FC")); + /* ANSI 13 */ + set_pallete_color(TSM_COLOR_LIGHT_MAGENTA, "Light Magenta", + Color::html("#FF00FF")); + /* ANSI 14 */ + set_pallete_color(TSM_COLOR_LIGHT_CYAN, "Light Cyan", Color::html("#00FFFF")); + /* ANSI 15 (Bright White) */ + set_pallete_color(TSM_COLOR_WHITE, "White", Color::html("#FFFFFF")); + + set_pallete_color(TSM_COLOR_FOREGROUND, "Foreground", Color::html("#000000")); + set_pallete_color(TSM_COLOR_BACKGROUND, "Background", Color::html("#FFFFFF")); if (tsm_vte_set_custom_palette(vte, color_palette)) { ERR_PRINT("Error setting custom palette");