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.
This commit is contained in:
Leroy Hopson 2021-07-16 14:31:13 +07:00
parent 88e5320a83
commit 84243cd824
No known key found for this signature in database
GPG key ID: D2747312A6DB51AA
8 changed files with 145 additions and 101 deletions

View file

@ -98,29 +98,38 @@ jobs:
cd addons/godot_xterm/native/thirdparty/godot-cpp cd addons/godot_xterm/native/thirdparty/godot-cpp
scons platform=${{ matrix.platform }} target=${{ matrix.target }} bits=${{ matrix.bits }} generate_bindings=yes -j2 scons platform=${{ matrix.platform }} target=${{ matrix.target }} bits=${{ matrix.bits }} generate_bindings=yes -j2
- name: Setup cmake
if: steps.cache-libuv.outputs.cache-hit != 'true'
uses: jwlawson/actions-setup-cmake@v1.9
with:
cmake-version: '3.15.4'
use-32bit: ${{ matrix.bits == 32 && matrix.os == 'windows-latest' }}
- name: Build libuv - name: Build libuv
if: ${{ matrix.bits == 64 && steps.cache-libuv.outputs.cache-hit != 'true' }} if: steps.cache-libuv.outputs.cache-hit != 'true'
uses: lukka/run-cmake@v3 shell: bash
with: env:
cmakeListsOrSettingsJson: CMakeListsTxtAdvanced TARGET: ${{ matrix.target }}
cmakeListsTxtPath: '${{ github.workspace }}/addons/godot_xterm/native/thirdparty/libuv/CMakeLists.txt' BITS: ${{ matrix.bits }}
useVcpkgToolchainFile: true OS: ${{ matrix.os }}
cmakeAppendedArgs: '-DCMAKE_BUILD_TYPE=${{ matrix.target }} -DBUILD_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE' run: |
buildDirectory: '${{ github.workspace }}/addons/godot_xterm/native/thirdparty/libuv/build' cd addons/godot_xterm/native/thirdparty/libuv
- name: Build libuv 32 bit args="-DCMAKE_BUILD_TYPE=$TARGET -DBUILD_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE"
if: ${{ matrix.bits == 32 && steps.cache-libuv.outputs.cache-hit != 'true' }} if [ "$BITS" -eq 32 -a "$OS" == "windows-latest" ]; then
uses: lukka/run-cmake@v3 cmake -G "Visual Studio 16 2019" -A Win32 -S $(pwd) -B "build" $args
with: else
cmakeListsOrSettingsJson: CMakeListsTxtAdvanced mkdir build || true
cmakeListsTxtPath: '${{ github.workspace }}/addons/godot_xterm/native/thirdparty/libuv/CMakeLists.txt' cd build
useVcpkgToolchainFile: true if [ "$BITS" -eq 32 ]; then args="$args -DCMAKE_SYSTEM_PROCESSOR=i686 -DCMAKE_C_FLAGS=-m32"; fi
cmakeAppendedArgs: '-DCMAKE_BUILD_TYPE=${{ matrix.target }} -DBUILD_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE -DCMAKE_SYSTEM_PROCESSOR=i686 -DCMAKE_C_FLAGS=-m32' cmake .. $args
buildDirectory: '${{ github.workspace }}/addons/godot_xterm/native/thirdparty/libuv/build' cd ..
fi
cmake --build build --config $TARGET
- name: Build libgodot-xterm - name: Build libgodot-xterm
run: | run: |
cd addons/godot_xterm/native 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 - name: Upload build artifacts
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2

View file

@ -264,14 +264,25 @@ sources.append('src/libgodotxtermnative.cpp')
sources.append('src/terminal.cpp') sources.append('src/terminal.cpp')
# PTY not supported on HTML5 or Windows (yet). # PTY not supported on HTML5.
if env['disable_pty'] or env['platform'] == 'javascript' or env['platform'] == 'windows': if env['disable_pty'] or env['platform'] == 'javascript':
env.Append(CPPDEFINES=['_PTY_DISABLED']) env.Append(CPPDEFINES=['_PTY_DISABLED'])
else: else:
sources.append('src/pipe.cpp') sources.append('src/pipe.cpp')
sources.append('src/libuv_utils.cpp') sources.append('src/libuv_utils.cpp')
if env['platform'] != 'windows':
sources.append('src/node_pty/unix/pty.cc') sources.append('src/node_pty/unix/pty.cc')
env.Append(LIBS=['util', env.File('thirdparty/libuv/build/libuv_a.a')]) 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': if env['platform'] == 'linux':
libsuffix = "a" libsuffix = "a"

View file

@ -1,9 +1,14 @@
#include "terminal.h" #include "terminal.h"
#if !defined(__EMSCRIPTEN__) && !defined(__WIN32) #if !defined(_PTY_DISABLED)
#include "libuv_utils.h" #include "libuv_utils.h"
#include "node_pty/unix/pty.h"
#include "pipe.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 #endif
extern "C" void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options *o) { 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__) #if defined(__unix__)
godot::register_tool_class<godot::PTYUnix>(); godot::register_tool_class<godot::PTYUnix>();
#endif #endif
#if defined(__WIN32)
// godot::register_tool_class<godot::ConPTY>();
#endif
#endif #endif
} }

View file

@ -2,6 +2,7 @@
* Copyright (c) 2013-2015, Christopher Jeffrey, Peter Sunde (MIT License) * Copyright (c) 2013-2015, Christopher Jeffrey, Peter Sunde (MIT License)
* Copyright (c) 2016, Daniel Imms (MIT License). * Copyright (c) 2016, Daniel Imms (MIT License).
* Copyright (c) 2018, Microsoft Corporation (MIT License). * Copyright (c) 2018, Microsoft Corporation (MIT License).
* Copyright (c) 2021, Leroy Hopson (MIT License).
* *
* pty.cc: * pty.cc:
* This file is responsible for starting processes * This file is responsible for starting processes
@ -379,18 +380,9 @@ static NAN_METHOD(PtyConnect) {
info.GetReturnValue().Set(marshal); info.GetReturnValue().Set(marshal);
} }
static NAN_METHOD(PtyResize) { void ConPTY::resize(int id, int cols, int rows) {
Nan::HandleScope scope; // SHORT cols = info[1]->Uint32Value(Nan::GetCurrentContext()).FromJust();
// SHORT rows = info[2]->Uint32Value(Nan::GetCurrentContext()).FromJust();
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();
const pty_baton *handle = get_pty_baton(id); const pty_baton *handle = get_pty_baton(id);
@ -405,20 +397,9 @@ static NAN_METHOD(PtyResize) {
pfnResizePseudoConsole(handle->hpc, size); pfnResizePseudoConsole(handle->hpc, size);
} }
} }
return info.GetReturnValue().SetUndefined();
} }
static NAN_METHOD(PtyKill) { void ConPTY::kill(int id) {
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();
const pty_baton *handle = get_pty_baton(id); const pty_baton *handle = get_pty_baton(id);
HANDLE hLibrary = LoadLibraryExW(L"kernel32.dll", 0, 0); HANDLE hLibrary = LoadLibraryExW(L"kernel32.dll", 0, 0);
@ -441,12 +422,12 @@ static NAN_METHOD(PtyKill) {
* Init * Init
*/ */
extern "C" void init(v8::Local<v8::Object> target) { void ConPTY::_register_methods() {
Nan::HandleScope scope; register_method("_init", &ConPTY::_init);
Nan::SetMethod(target, "startProcess", PtyStartProcess); register_method("start_process", &ConPTY::start_process);
Nan::SetMethod(target, "connect", PtyConnect); register_method("connect_to_named_pipe", &ConPTY::connect_to_named_pipe);
Nan::SetMethod(target, "resize", PtyResize); register_method("resize", &ConPTY::resize);
Nan::SetMethod(target, "kill", PtyKill); register_method("kill", &ConPTY::kill);
}; };
NODE_MODULE(pty, init); void ConPTY::_init() {}

View file

@ -0,0 +1,33 @@
// Copyright (c) 2021, Leroy Hopson (MIT License).
#ifndef GODOT_XTERM_CONPTY_H
#define GODOT_XTERM_CONPTY_H
#include <FuncRef.hpp>
#include <Godot.hpp>
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<FuncRef>
// 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

View file

@ -13,6 +13,10 @@
#include <vector> #include <vector>
#include <xkbcommon/xkbcommon-keysyms.h> #include <xkbcommon/xkbcommon-keysyms.h>
#ifndef ULONG
#define ULONG size_t
#endif
using namespace godot; using namespace godot;
void Pipe::_register_methods() { void Pipe::_register_methods() {
@ -54,9 +58,11 @@ godot_error Pipe::open(int fd, bool ipc = false) {
godot_error Pipe::write(String p_data) { godot_error Pipe::write(String p_data) {
char *s = p_data.alloc_c_string(); 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; uv_write_t req;

View file

@ -3,13 +3,8 @@
#ifndef GODOT_XTERM_PIPE_H #ifndef GODOT_XTERM_PIPE_H
#define GODOT_XTERM_PIPE_H #define GODOT_XTERM_PIPE_H
#include <Array.hpp>
#include <FuncRef.hpp>
#include <Godot.hpp> #include <Godot.hpp>
#include <Reference.hpp> #include <Reference.hpp>
#include <StreamPeer.hpp>
#include <StreamPeerBuffer.hpp>
#include <StreamPeerGDNative.hpp>
#include <uv.h> #include <uv.h>
namespace godot { namespace godot {
@ -22,18 +17,6 @@ public:
static void _register_methods(); 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();
~Pipe(); ~Pipe();
@ -47,11 +30,8 @@ public:
void pause(); void pause();
void resume(); void resume();
protected:
const godot_net_stream_peer *interface;
public: public:
Status status; int status;
private: private:
void _poll_connection(); void _poll_connection();

View file

@ -425,30 +425,46 @@ void Terminal::update_theme() {
palette[color] = c; palette[color] = c;
}; };
set_pallete_color(TSM_COLOR_BLACK, "Black", Color(0, 0, 0, 1)); /* Default to Xterm colors */
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));
set_pallete_color(TSM_COLOR_BACKGROUND, "Background", Color(0, 0, 0, 1)); /* ANSI 0 */
set_pallete_color(TSM_COLOR_FOREGROUND, "Foreground", Color(1, 1, 1, 1)); 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)) { if (tsm_vte_set_custom_palette(vte, color_palette)) {
ERR_PRINT("Error setting custom palette"); ERR_PRINT("Error setting custom palette");