mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-02 03:00:23 +03:00
Android build fixes and improvements.
Updated jpeg-compressor. eterm: More clean up and improvements.
This commit is contained in:
@@ -5,7 +5,7 @@ EE::Window::Window* win = NULL;
|
||||
std::shared_ptr<TerminalDisplay> terminal = nullptr;
|
||||
|
||||
void inputCallback( InputEvent* event ) {
|
||||
if ( !terminal )
|
||||
if ( !terminal || event->Type == InputEvent::EventsSent )
|
||||
return;
|
||||
|
||||
switch ( event->Type ) {
|
||||
@@ -17,6 +17,9 @@ void inputCallback( InputEvent* event ) {
|
||||
case InputEvent::MouseButtonDown: {
|
||||
terminal->onMouseDown( win->getInput()->getMousePos(),
|
||||
win->getInput()->getPressTrigger() );
|
||||
#if EE_PLATFORM == EE_PLATFORM_ANDROID
|
||||
win->startTextInput();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case InputEvent::MouseButtonUp: {
|
||||
@@ -31,6 +34,13 @@ void inputCallback( InputEvent* event ) {
|
||||
break;
|
||||
}
|
||||
case InputEvent::Window: {
|
||||
switch ( event->window.type ) {
|
||||
case InputEvent::WindowKeyboardFocusLost:
|
||||
case InputEvent::WindowKeyboardFocusGain: {
|
||||
terminal->setFocus( win->hasFocus() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case InputEvent::KeyUp: {
|
||||
@@ -39,6 +49,12 @@ void inputCallback( InputEvent* event ) {
|
||||
case InputEvent::KeyDown: {
|
||||
terminal->onKeyDown( event->key.keysym.sym, event->key.keysym.unicode,
|
||||
event->key.keysym.mod, event->key.keysym.scancode );
|
||||
#if EE_PLATFORM == EE_PLATFORM_ANDROID
|
||||
if ( event->key.keysym.sym == KEY_RETURN ||
|
||||
event->key.keysym.scancode == SCANCODE_RETURN ) {
|
||||
win->startTextInput();
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case InputEvent::TextInput: {
|
||||
@@ -73,6 +89,10 @@ void mainLoop() {
|
||||
}
|
||||
|
||||
EE_MAIN_FUNC int main( int, char*[] ) {
|
||||
#ifdef EE_DEBUG
|
||||
Log::instance()->setConsoleOutput( true );
|
||||
Log::instance()->setLiveWrite( true );
|
||||
#endif
|
||||
DisplayManager* displayManager = Engine::instance()->getDisplayManager();
|
||||
Display* currentDisplay = displayManager->getDisplayIndex( 0 );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
@@ -108,6 +128,8 @@ EE_MAIN_FUNC int main( int, char*[] ) {
|
||||
if ( event.type == TerminalDisplay::EventType::TITLE )
|
||||
win->setTitle( "eterm - " + event.eventData );
|
||||
} );
|
||||
|
||||
win->startTextInput();
|
||||
}
|
||||
|
||||
win->getInput()->pushCallback( &inputCallback );
|
||||
|
||||
@@ -27,56 +27,56 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
EE::AutoHandle::AutoHandle() : m_hHandle( invalid_value() ) {}
|
||||
EE::AutoHandle::AutoHandle( AutoHandle&& other ) : m_hHandle( other.m_hHandle ) {
|
||||
other.m_hHandle = invalid_value();
|
||||
EE::AutoHandle::AutoHandle() : mHandle( invalid_value() ) {}
|
||||
EE::AutoHandle::AutoHandle( AutoHandle&& other ) : mHandle( other.mHandle ) {
|
||||
other.mHandle = invalid_value();
|
||||
}
|
||||
EE::AutoHandle::~AutoHandle() {
|
||||
release();
|
||||
}
|
||||
|
||||
EE::AutoHandle& EE::AutoHandle::operator=( AutoHandle&& other ) {
|
||||
if ( m_hHandle == other.m_hHandle )
|
||||
if ( mHandle == other.mHandle )
|
||||
return *this;
|
||||
release();
|
||||
m_hHandle = other.m_hHandle;
|
||||
other.m_hHandle = invalid_value();
|
||||
mHandle = other.mHandle;
|
||||
other.mHandle = invalid_value();
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
EE::AutoHandle::AutoHandle( HANDLE handle ) : m_hHandle( handle ) {}
|
||||
EE::AutoHandle::AutoHandle( HANDLE handle ) : mHandle( handle ) {}
|
||||
|
||||
void EE::AutoHandle::release() const {
|
||||
if ( m_hHandle != INVALID_HANDLE_VALUE ) {
|
||||
CloseHandle( m_hHandle );
|
||||
m_hHandle = INVALID_HANDLE_VALUE;
|
||||
if ( mHandle != INVALID_HANDLE_VALUE ) {
|
||||
CloseHandle( mHandle );
|
||||
mHandle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
#else
|
||||
EE::AutoHandle::AutoHandle( int fd ) : m_hHandle( fd ) {}
|
||||
EE::AutoHandle::AutoHandle( int fd ) : mHandle( fd ) {}
|
||||
|
||||
void EE::AutoHandle::release() const {
|
||||
if ( m_hHandle != -1 ) {
|
||||
close( m_hHandle );
|
||||
if ( mHandle != -1 ) {
|
||||
close( mHandle );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
EE::AutoHandle::operator bool() const noexcept {
|
||||
return m_hHandle != invalid_value();
|
||||
return mHandle != invalid_value();
|
||||
}
|
||||
|
||||
EE::AutoHandle::type* EE::AutoHandle::get() {
|
||||
return &m_hHandle;
|
||||
return &mHandle;
|
||||
}
|
||||
|
||||
const EE::AutoHandle::type* EE::AutoHandle::get() const {
|
||||
return &m_hHandle;
|
||||
return &mHandle;
|
||||
}
|
||||
|
||||
EE::AutoHandle::operator EE::AutoHandle::type() const noexcept {
|
||||
return m_hHandle;
|
||||
return mHandle;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
@@ -59,13 +59,13 @@ class AutoHandle final {
|
||||
const type* get() const;
|
||||
|
||||
type handle() const {
|
||||
return m_hHandle;
|
||||
return mHandle;
|
||||
}
|
||||
|
||||
void release() const;
|
||||
|
||||
private:
|
||||
mutable type m_hHandle;
|
||||
mutable type mHandle;
|
||||
};
|
||||
|
||||
} // namespace EE
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
using namespace EE::System;
|
||||
|
||||
Pipe::Pipe( AutoHandle&& readHandle, AutoHandle&& writeHandle ) :
|
||||
m_hInput( std::move( readHandle ) ), m_hOutput( std::move( writeHandle ) ) {}
|
||||
mInputHandle( std::move( readHandle ) ), mOutputHandle( std::move( writeHandle ) ) {}
|
||||
|
||||
bool Pipe::isTTY() const {
|
||||
return false;
|
||||
@@ -18,7 +18,7 @@ int Pipe::write( const char* s, size_t n ) {
|
||||
DWORD c = (DWORD)n;
|
||||
DWORD r = 0;
|
||||
while ( n > 0 ) {
|
||||
if ( !WriteFile( (HANDLE)m_hOutput, s, (DWORD)( n > lim ? lim : n ), &r, nullptr ) ) {
|
||||
if ( !WriteFile( (HANDLE)mOutputHandle, s, (DWORD)( n > lim ? lim : n ), &r, nullptr ) ) {
|
||||
PrintLastWinApiError();
|
||||
return -1;
|
||||
}
|
||||
@@ -34,7 +34,7 @@ int Pipe::read( char* buf, size_t n, bool block ) {
|
||||
DWORD read;
|
||||
|
||||
if ( !block ) {
|
||||
if ( !PeekNamedPipe( m_hInput.handle(), nullptr, 0, nullptr, &available, nullptr ) ) {
|
||||
if ( !PeekNamedPipe( mInputHandle.handle(), nullptr, 0, nullptr, &available, nullptr ) ) {
|
||||
PrintLastWinApiError();
|
||||
return -1;
|
||||
}
|
||||
@@ -42,7 +42,7 @@ int Pipe::read( char* buf, size_t n, bool block ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( !ReadFile( m_hInput.handle(), buf, (DWORD)n, &read, nullptr ) ) {
|
||||
if ( !ReadFile( mInputHandle.handle(), buf, (DWORD)n, &read, nullptr ) ) {
|
||||
PrintLastWinApiError();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -52,12 +52,12 @@ class Pipe : public IPipe {
|
||||
private:
|
||||
friend class Process;
|
||||
#ifdef _WIN32
|
||||
AutoHandle m_hInput;
|
||||
AutoHandle m_hOutput;
|
||||
AutoHandle mInputHandle;
|
||||
AutoHandle mOutputHandle;
|
||||
|
||||
Pipe( AutoHandle&& readHandle, AutoHandle&& writeHandle );
|
||||
#else
|
||||
AutoHandle m_handle;
|
||||
AutoHandle mHandle;
|
||||
|
||||
Pipe( AutoHandle&& handle );
|
||||
#endif
|
||||
|
||||
@@ -45,61 +45,61 @@
|
||||
using namespace EE::System;
|
||||
|
||||
Process::~Process() {
|
||||
if ( m_pid != -1 ) {
|
||||
kill( m_pid, SIGHUP );
|
||||
if ( mPID != -1 ) {
|
||||
kill( mPID, SIGHUP );
|
||||
}
|
||||
}
|
||||
|
||||
void Process::checkExitStatus() {
|
||||
if ( m_status == ProcessStatus::EXITED ) {
|
||||
if ( mStatus == ProcessStatus::EXITED ) {
|
||||
return;
|
||||
}
|
||||
int status = 0;
|
||||
int p = waitpid( m_pid, &status, WNOHANG );
|
||||
int p = waitpid( mPID, &status, WNOHANG );
|
||||
if ( p < 0 ) {
|
||||
perror( "Process::checkExitStatus(waitpid)" );
|
||||
}
|
||||
if ( p == 0 ) {
|
||||
return;
|
||||
}
|
||||
m_status = ProcessStatus::EXITED;
|
||||
m_exitCode = WEXITSTATUS( status );
|
||||
mStatus = ProcessStatus::EXITED;
|
||||
mExitCode = WEXITSTATUS( status );
|
||||
}
|
||||
|
||||
void Process::terminate() {
|
||||
if ( m_status == ProcessStatus::EXITED ) {
|
||||
if ( mStatus == ProcessStatus::EXITED ) {
|
||||
return;
|
||||
}
|
||||
if ( m_pid != -1 ) {
|
||||
kill( m_pid, SIGHUP );
|
||||
m_exitCode = 1;
|
||||
m_status = ProcessStatus::EXITED;
|
||||
if ( mPID != -1 ) {
|
||||
kill( mPID, SIGHUP );
|
||||
mExitCode = 1;
|
||||
mStatus = ProcessStatus::EXITED;
|
||||
}
|
||||
}
|
||||
|
||||
void Process::waitForExit() {
|
||||
if ( m_status == ProcessStatus::EXITED ) {
|
||||
if ( mStatus == ProcessStatus::EXITED ) {
|
||||
return;
|
||||
}
|
||||
int status = 0;
|
||||
int p = waitpid( m_pid, &status, 0 );
|
||||
int p = waitpid( mPID, &status, 0 );
|
||||
if ( p < 0 ) {
|
||||
perror( "Process::waitForExit(waitpid)" );
|
||||
return;
|
||||
}
|
||||
m_status = ProcessStatus::EXITED;
|
||||
m_exitCode = WEXITSTATUS( status );
|
||||
mStatus = ProcessStatus::EXITED;
|
||||
mExitCode = WEXITSTATUS( status );
|
||||
}
|
||||
|
||||
bool Process::hasExited() const {
|
||||
return m_status == EE::System::ProcessStatus::EXITED;
|
||||
return mStatus == EE::System::ProcessStatus::EXITED;
|
||||
}
|
||||
|
||||
int Process::getExitCode() const {
|
||||
return m_status == ProcessStatus::EXITED ? m_exitCode : 255;
|
||||
return mStatus == ProcessStatus::EXITED ? mExitCode : 255;
|
||||
}
|
||||
|
||||
Process::Process( int pid ) : m_pid( pid ) {}
|
||||
Process::Process( int pid ) : mPID( pid ) {}
|
||||
|
||||
static void execshell( const char* cmd, const char* const* args, std::string workingDirectory ) {
|
||||
const struct passwd* pw;
|
||||
@@ -163,11 +163,11 @@ Process::createWithPseudoTerminal( const std::string& program, const std::vector
|
||||
return nullptr;
|
||||
} else if ( pid == 0 ) {
|
||||
setsid();
|
||||
dup2( (int)pseudoTerminal.m_slave, 0 );
|
||||
dup2( (int)pseudoTerminal.m_slave, 1 );
|
||||
dup2( (int)pseudoTerminal.m_slave, 2 );
|
||||
dup2( (int)pseudoTerminal.mSlave, 0 );
|
||||
dup2( (int)pseudoTerminal.mSlave, 1 );
|
||||
dup2( (int)pseudoTerminal.mSlave, 2 );
|
||||
|
||||
if ( ioctl( (int)pseudoTerminal.m_slave, TIOCSCTTY, NULL ) < 0 ) {
|
||||
if ( ioctl( (int)pseudoTerminal.mSlave, TIOCSCTTY, NULL ) < 0 ) {
|
||||
fprintf( stderr, "ioctl TIOCSCTTY failed: %s", strerror( errno ) );
|
||||
exit( 1 );
|
||||
}
|
||||
@@ -191,7 +191,7 @@ Process::createWithPseudoTerminal( const std::string& program, const std::vector
|
||||
argsV.push_back( nullptr );
|
||||
execshell( program.c_str(), argsV.data(), workingDirectory );
|
||||
} else {
|
||||
pseudoTerminal.m_slave.release();
|
||||
pseudoTerminal.mSlave.release();
|
||||
return std::unique_ptr<Process>( new Process( pid ) );
|
||||
}
|
||||
return nullptr;
|
||||
@@ -205,6 +205,8 @@ Process::createWithPseudoTerminal( const std::string& program, const std::vector
|
||||
#include <assert.h>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#define NTDDI_VERSION NTDDI_WIN10_RS5
|
||||
#include <windows.h>
|
||||
|
||||
using namespace EE::System;
|
||||
using namespace EE;
|
||||
@@ -221,14 +223,14 @@ static std::wstring stringToWideString( const std::string& str ) {
|
||||
#define HANDLE_WIN_ERR( err ) HRESULT_FROM_WIN32( err ), PrintWinApiError( err )
|
||||
|
||||
static HRESULT InitializeStartupInfoAttachedToPseudoConsole( STARTUPINFOEXW* pStartupInfo,
|
||||
HPCON hPC ) {
|
||||
HPCON hPC ) {
|
||||
HRESULT hr{ E_UNEXPECTED };
|
||||
|
||||
if ( pStartupInfo ) {
|
||||
SIZE_T attrListSize{};
|
||||
|
||||
pStartupInfo->StartupInfo.cb = sizeof( STARTUPINFOEXW );
|
||||
//pStartupInfo->StartupInfo.dwFlags = STARTF_USESTDHANDLES;
|
||||
// pStartupInfo->StartupInfo.dwFlags = STARTF_USESTDHANDLES;
|
||||
|
||||
// Get the size of the thread attribute list.
|
||||
InitializeProcThreadAttributeList( NULL, 1, 0, &attrListSize );
|
||||
@@ -255,55 +257,55 @@ static HRESULT InitializeStartupInfoAttachedToPseudoConsole( STARTUPINFOEXW* pSt
|
||||
return hr;
|
||||
}
|
||||
|
||||
Process::Process( AutoHandle&& hProcess, LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList ) :
|
||||
m_status( ProcessStatus::RUNNING ),
|
||||
m_leaveRunning( false ),
|
||||
m_exitCode( 1 ),
|
||||
m_hProcess( std::move( hProcess ) ),
|
||||
m_lpAttributeList( lpAttributeList ) {}
|
||||
Process::Process( AutoHandle&& hProcess, void* lpAttributeList ) :
|
||||
mStatus( ProcessStatus::RUNNING ),
|
||||
mLeaveRunning( false ),
|
||||
mExitCode( 1 ),
|
||||
mProcessHandle( std::move( hProcess ) ),
|
||||
mLpAttributeList( lpAttributeList ) {}
|
||||
|
||||
Process::~Process() {
|
||||
if ( m_lpAttributeList ) {
|
||||
DeleteProcThreadAttributeList( m_lpAttributeList );
|
||||
HeapFree( GetProcessHeap(), 0, m_lpAttributeList );
|
||||
if ( mLpAttributeList ) {
|
||||
DeleteProcThreadAttributeList( (LPPROC_THREAD_ATTRIBUTE_LIST)mLpAttributeList );
|
||||
HeapFree( GetProcessHeap(), 0, mLpAttributeList );
|
||||
}
|
||||
if ( !m_leaveRunning ) {
|
||||
if ( !mLeaveRunning ) {
|
||||
terminate();
|
||||
}
|
||||
}
|
||||
|
||||
void Process::checkExitStatus() {
|
||||
if ( m_status == ProcessStatus::RUNNING ) {
|
||||
if ( mStatus == ProcessStatus::RUNNING ) {
|
||||
DWORD exitCode;
|
||||
if ( GetExitCodeProcess( (HANDLE)m_hProcess, &exitCode ) && exitCode != STILL_ACTIVE ) {
|
||||
m_status = ProcessStatus::EXITED;
|
||||
m_exitCode = (int)exitCode;
|
||||
if ( GetExitCodeProcess( (HANDLE)mProcessHandle, &exitCode ) && exitCode != STILL_ACTIVE ) {
|
||||
mStatus = ProcessStatus::EXITED;
|
||||
mExitCode = (int)exitCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Process::hasExited() const {
|
||||
return m_status == ProcessStatus::EXITED;
|
||||
return mStatus == ProcessStatus::EXITED;
|
||||
}
|
||||
|
||||
int Process::getExitCode() const {
|
||||
return m_status == ProcessStatus::EXITED ? m_exitCode : STILL_ACTIVE;
|
||||
return mStatus == ProcessStatus::EXITED ? mExitCode : STILL_ACTIVE;
|
||||
}
|
||||
|
||||
void Process::terminate() {
|
||||
if ( m_status == ProcessStatus::RUNNING ) {
|
||||
TerminateProcess( (HANDLE)m_hProcess, EXIT_FAILURE );
|
||||
m_exitCode = EXIT_FAILURE;
|
||||
m_status = ProcessStatus::EXITED;
|
||||
m_hProcess.release();
|
||||
if ( mStatus == ProcessStatus::RUNNING ) {
|
||||
TerminateProcess( (HANDLE)mProcessHandle, EXIT_FAILURE );
|
||||
mExitCode = EXIT_FAILURE;
|
||||
mStatus = ProcessStatus::EXITED;
|
||||
mProcessHandle.release();
|
||||
}
|
||||
}
|
||||
|
||||
void Process::waitForExit() {
|
||||
checkExitStatus();
|
||||
|
||||
if ( m_status == ProcessStatus::RUNNING ) {
|
||||
WaitForSingleObject( (HANDLE)m_hProcess, INFINITE );
|
||||
if ( mStatus == ProcessStatus::RUNNING ) {
|
||||
WaitForSingleObject( (HANDLE)mProcessHandle, INFINITE );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -411,7 +413,7 @@ Process::createWithPseudoTerminal( const std::string& program, const std::vector
|
||||
std::wstring workingDir = stringToWideString( workingDirectory );
|
||||
|
||||
if ( ( hr = InitializeStartupInfoAttachedToPseudoConsole( &startupInfo,
|
||||
pseudoTerminal.m_phPC ) ) != S_OK ) {
|
||||
pseudoTerminal.mPHPC ) ) != S_OK ) {
|
||||
printf( "InitializeStartupInfoAttachedToPseudoConsole failed\n" );
|
||||
PrintErrorResult( hr );
|
||||
goto fail;
|
||||
@@ -439,7 +441,7 @@ Process::createWithPseudoTerminal( const std::string& program, const std::vector
|
||||
hProcess = AutoHandle( piClient.hProcess );
|
||||
hThread = AutoHandle( piClient.hThread );
|
||||
|
||||
pseudoTerminal.m_attached = true;
|
||||
pseudoTerminal.mAttached = true;
|
||||
|
||||
return std::unique_ptr<Process>(
|
||||
new Process( std::move( hProcess ), startupInfo.lpAttributeList ) );
|
||||
|
||||
@@ -28,14 +28,6 @@
|
||||
#include "../terminal/pseudoterminal.hpp"
|
||||
#include "iprocess.hpp"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#define NTDDI_VERSION NTDDI_WIN10_RS5
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace EE { namespace System {
|
||||
|
||||
class Process final : public IProcess {
|
||||
@@ -72,16 +64,16 @@ class Process final : public IProcess {
|
||||
Terminal::PseudoTerminal& pseudoTerminal );
|
||||
|
||||
private:
|
||||
ProcessStatus m_status{ ProcessStatus::RUNNING };
|
||||
bool m_leaveRunning{ false };
|
||||
int m_exitCode{ 1 };
|
||||
ProcessStatus mStatus{ ProcessStatus::RUNNING };
|
||||
int mExitCode{ 1 };
|
||||
#ifdef _WIN32
|
||||
AutoHandle m_hProcess;
|
||||
LPPROC_THREAD_ATTRIBUTE_LIST m_lpAttributeList;
|
||||
bool mLeaveRunning{ false };
|
||||
AutoHandle mProcessHandle;
|
||||
void* mLpAttributeList;
|
||||
|
||||
Process( AutoHandle&& processHandle, LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList );
|
||||
Process( AutoHandle&& processHandle, void* lpAttributeList );
|
||||
#else
|
||||
int m_pid;
|
||||
int mPID;
|
||||
|
||||
Process( int pid );
|
||||
#endif
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 Avi Halachmi (:avih) avihpit@yahoo.com https://github.com/avih
|
||||
* MIT/X Consortium License
|
||||
*/
|
||||
/* Each shape is encoded as 16-bits. Higher bits are category, lower are data */
|
||||
/* Categories (mutually exclusive except BDB): */
|
||||
/* For convenience, BDL/BDA/BBS/BDB are 1 bit each, the rest are enums */
|
||||
#define BDL ( 1 << 8 ) /* Box Draw Lines (light/double/heavy) */
|
||||
#define BDA ( 1 << 9 ) /* Box Draw Arc (light) */
|
||||
|
||||
#define BBD ( 1 << 10 ) /* Box Block Down (lower) X/8 */
|
||||
#define BBL ( 2 << 10 ) /* Box Block Left X/8 */
|
||||
#define BBU ( 3 << 10 ) /* Box Block Upper X/8 */
|
||||
#define BBR ( 4 << 10 ) /* Box Block Right X/8 */
|
||||
#define BBQ ( 5 << 10 ) /* Box Block Quadrants */
|
||||
#define BRL ( 6 << 10 ) /* Box Braille (data is lower byte of U28XX) */
|
||||
|
||||
#define BBS ( 1 << 14 ) /* Box Block Shades */
|
||||
#define BDB ( 1 << 15 ) /* Box Draw is Bold */
|
||||
|
||||
/* (BDL/BDA) Light/Double/Heavy x Left/Up/Right/Down/Horizontal/Vertical */
|
||||
/* Heavy is light+double (literally drawing light+double align to form heavy) */
|
||||
#define LL ( 1 << 0 )
|
||||
#define LU ( 1 << 1 )
|
||||
#define LR ( 1 << 2 )
|
||||
#define LD ( 1 << 3 )
|
||||
#define LH ( LL + LR )
|
||||
#define LV ( LU + LD )
|
||||
|
||||
#define DL ( 1 << 4 )
|
||||
#define DU ( 1 << 5 )
|
||||
#define DR ( 1 << 6 )
|
||||
#define DD ( 1 << 7 )
|
||||
#define DH ( DL + DR )
|
||||
#define DV ( DU + DD )
|
||||
|
||||
#define HL ( LL + DL )
|
||||
#define HU ( LU + DU )
|
||||
#define HR ( LR + DR )
|
||||
#define HD ( LD + DD )
|
||||
#define HH ( HL + HR )
|
||||
#define HV ( HU + HD )
|
||||
|
||||
/* (BBQ) Quadrants Top/Bottom x Left/Right */
|
||||
#define TL ( 1 << 0 )
|
||||
#define TR ( 1 << 1 )
|
||||
#define BL ( 1 << 2 )
|
||||
#define BR ( 1 << 3 )
|
||||
@@ -14,7 +14,54 @@
|
||||
* https://github.com/GNOME/vte/blob/master/doc/boxes.txt
|
||||
*/
|
||||
|
||||
#include "../terminal/boxdraw.hpp"
|
||||
/*
|
||||
* Copyright 2018 Avi Halachmi (:avih) avihpit@yahoo.com https://github.com/avih
|
||||
* MIT/X Consortium License
|
||||
*/
|
||||
/* Each shape is encoded as 16-bits. Higher bits are category, lower are data */
|
||||
/* Categories (mutually exclusive except BDB): */
|
||||
/* For convenience, BDL/BDA/BBS/BDB are 1 bit each, the rest are enums */
|
||||
#define BDL ( 1 << 8 ) /* Box Draw Lines (light/double/heavy) */
|
||||
#define BDA ( 1 << 9 ) /* Box Draw Arc (light) */
|
||||
|
||||
#define BBD ( 1 << 10 ) /* Box Block Down (lower) X/8 */
|
||||
#define BBL ( 2 << 10 ) /* Box Block Left X/8 */
|
||||
#define BBU ( 3 << 10 ) /* Box Block Upper X/8 */
|
||||
#define BBR ( 4 << 10 ) /* Box Block Right X/8 */
|
||||
#define BBQ ( 5 << 10 ) /* Box Block Quadrants */
|
||||
#define BRL ( 6 << 10 ) /* Box Braille (data is lower byte of U28XX) */
|
||||
|
||||
#define BBS ( 1 << 14 ) /* Box Block Shades */
|
||||
#define BDB ( 1 << 15 ) /* Box Draw is Bold */
|
||||
|
||||
/* (BDL/BDA) Light/Double/Heavy x Left/Up/Right/Down/Horizontal/Vertical */
|
||||
/* Heavy is light+double (literally drawing light+double align to form heavy) */
|
||||
#define LL ( 1 << 0 )
|
||||
#define LU ( 1 << 1 )
|
||||
#define LR ( 1 << 2 )
|
||||
#define LD ( 1 << 3 )
|
||||
#define LH ( LL + LR )
|
||||
#define LV ( LU + LD )
|
||||
|
||||
#define DL ( 1 << 4 )
|
||||
#define DU ( 1 << 5 )
|
||||
#define DR ( 1 << 6 )
|
||||
#define DD ( 1 << 7 )
|
||||
#define DH ( DL + DR )
|
||||
#define DV ( DU + DD )
|
||||
|
||||
#define HL ( LL + DL )
|
||||
#define HU ( LU + DU )
|
||||
#define HR ( LR + DR )
|
||||
#define HD ( LD + DD )
|
||||
#define HH ( HL + HR )
|
||||
#define HV ( HU + HD )
|
||||
|
||||
/* (BBQ) Quadrants Top/Bottom x Left/Right */
|
||||
#define TL ( 1 << 0 )
|
||||
#define TR ( 1 << 1 )
|
||||
#define BL ( 1 << 2 )
|
||||
#define BR ( 1 << 3 )
|
||||
|
||||
/* Data for U+2500 - U+259F except dashes/diagonals */
|
||||
static const unsigned short boxdata[256] = {
|
||||
|
||||
@@ -35,20 +35,70 @@
|
||||
#define _DEFAULT_SOURCE
|
||||
#include <bsd/pty.h>
|
||||
#endif
|
||||
#include <eepp/system/log.hpp>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/poll.h>
|
||||
#include <unistd.h>
|
||||
using namespace EE::System;
|
||||
|
||||
#if EE_PLATFORM == EE_PLATFORM_ANDROID
|
||||
#include <fcntl.h>
|
||||
|
||||
int openpty( int* amaster, int* aslave, char* name, struct termios* termp, struct winsize* winp ) {
|
||||
int master, slave;
|
||||
char* name_slave;
|
||||
|
||||
master = open( "/dev/ptmx", O_RDWR | O_NONBLOCK );
|
||||
if ( master == -1 ) {
|
||||
Log::error( "openpty: Fail to open master" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( grantpt( master ) ) {
|
||||
Log::error( "openpty: grantpt failed" );
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ( unlockpt( master ) ) {
|
||||
Log::error( "openpty: unlockpt failed" );
|
||||
goto fail;
|
||||
}
|
||||
|
||||
name_slave = ptsname( master );
|
||||
slave = open( name_slave, O_RDWR | O_NOCTTY );
|
||||
if ( slave == -1 ) {
|
||||
Log::error( "openpty: failed to open slave name %s", name_slave );
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ( termp )
|
||||
tcsetattr( slave, TCSAFLUSH, termp );
|
||||
if ( winp )
|
||||
ioctl( slave, TIOCSWINSZ, winp );
|
||||
|
||||
*amaster = master;
|
||||
*aslave = slave;
|
||||
if ( name != NULL )
|
||||
strcpy( name, name_slave );
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
close( master );
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
using namespace EE::Terminal;
|
||||
|
||||
PseudoTerminal::~PseudoTerminal() {}
|
||||
|
||||
PseudoTerminal::PseudoTerminal( int columns, int rows, AutoHandle&& master, AutoHandle&& slave ) :
|
||||
m_columns( columns ),
|
||||
m_rows( rows ),
|
||||
m_master( std::move( master ) ),
|
||||
m_slave( std::move( slave ) ) {}
|
||||
mColumns( columns ),
|
||||
mRows( rows ),
|
||||
mMaster( std::move( master ) ),
|
||||
mSlave( std::move( slave ) ) {}
|
||||
|
||||
bool PseudoTerminal::isTTY() const {
|
||||
return true;
|
||||
@@ -62,7 +112,7 @@ bool PseudoTerminal::resize( int columns, int rows ) {
|
||||
w.ws_xpixel = 0;
|
||||
w.ws_ypixel = 0;
|
||||
|
||||
if ( ioctl( (int)m_master, TIOCSWINSZ, &w ) < 0 ) {
|
||||
if ( ioctl( (int)mMaster, TIOCSWINSZ, &w ) < 0 ) {
|
||||
perror( "PseudoTerminal::Resize" );
|
||||
return false;
|
||||
}
|
||||
@@ -71,17 +121,17 @@ bool PseudoTerminal::resize( int columns, int rows ) {
|
||||
}
|
||||
|
||||
int PseudoTerminal::getNumColumns() const {
|
||||
return m_columns;
|
||||
return mColumns;
|
||||
}
|
||||
|
||||
int PseudoTerminal::getNumRows() const {
|
||||
return m_rows;
|
||||
return mRows;
|
||||
}
|
||||
|
||||
int PseudoTerminal::write( const char* s, size_t n ) {
|
||||
size_t c = n;
|
||||
while ( n > 0 ) {
|
||||
ssize_t r = ::write( (int)m_master, s, n );
|
||||
ssize_t r = ::write( (int)mMaster, s, n );
|
||||
if ( r < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
@@ -93,7 +143,7 @@ int PseudoTerminal::write( const char* s, size_t n ) {
|
||||
|
||||
int PseudoTerminal::read( char* s, size_t n, bool block ) {
|
||||
struct pollfd pfd;
|
||||
pfd.fd = (int)m_master;
|
||||
pfd.fd = (int)mMaster;
|
||||
pfd.events = POLLIN;
|
||||
pfd.revents = 0;
|
||||
|
||||
@@ -107,7 +157,7 @@ int PseudoTerminal::read( char* s, size_t n, bool block ) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ssize_t r = ::read( (int)m_master, s, n );
|
||||
ssize_t r = ::read( (int)mMaster, s, n );
|
||||
return (int)r;
|
||||
}
|
||||
|
||||
@@ -126,7 +176,8 @@ std::unique_ptr<PseudoTerminal> PseudoTerminal::create( int columns, int rows )
|
||||
return nullptr;
|
||||
#else
|
||||
if ( openpty( master.get(), slave.get(), nullptr, NULL, &win ) != 0 ) {
|
||||
perror( "PseudoTerminal::Create(openpty)" );
|
||||
perror( "PseudoTerminal::create(openpty)" );
|
||||
Log::error( "PseudoTerminal::create(openpty)" );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -145,17 +196,17 @@ std::unique_ptr<PseudoTerminal> PseudoTerminal::create( int columns, int rows )
|
||||
using namespace EE::Terminal;
|
||||
|
||||
PseudoTerminal::~PseudoTerminal() {
|
||||
ClosePseudoConsole( m_phPC );
|
||||
ClosePseudoConsole( mPHPC );
|
||||
}
|
||||
|
||||
PseudoTerminal::PseudoTerminal( int columns, int rows, AutoHandle&& hInput, AutoHandle&& hOutput,
|
||||
void* hPC ) :
|
||||
m_hInput( std::move( hInput ) ),
|
||||
m_hOutput( std::move( hOutput ) ),
|
||||
m_phPC( hPC ),
|
||||
m_attached( false ) {
|
||||
m_size.x = (SHORT)columns;
|
||||
m_size.y = (SHORT)rows;
|
||||
mInputHandle( std::move( hInput ) ),
|
||||
mOutputHandle( std::move( hOutput ) ),
|
||||
mPHPC( hPC ),
|
||||
mAttached( false ) {
|
||||
mSize.x = (SHORT)columns;
|
||||
mSize.y = (SHORT)rows;
|
||||
}
|
||||
|
||||
bool PseudoTerminal::isTTY() const {
|
||||
@@ -163,13 +214,13 @@ bool PseudoTerminal::isTTY() const {
|
||||
}
|
||||
|
||||
bool PseudoTerminal::resize( int columns, int rows ) {
|
||||
HRESULT hr = ResizePseudoConsole( m_phPC, { (SHORT)columns, (SHORT)rows } );
|
||||
HRESULT hr = ResizePseudoConsole( mPHPC, { (SHORT)columns, (SHORT)rows } );
|
||||
if ( hr != S_OK ) {
|
||||
PrintErrorResult( hr );
|
||||
return false;
|
||||
}
|
||||
m_size.x = (SHORT)columns;
|
||||
m_size.y = (SHORT)rows;
|
||||
mSize.x = (SHORT)columns;
|
||||
mSize.y = (SHORT)rows;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -179,7 +230,7 @@ int PseudoTerminal::write( const char* s, size_t n ) {
|
||||
DWORD c = (DWORD)n;
|
||||
DWORD r = 0;
|
||||
while ( n > 0 ) {
|
||||
if ( !WriteFile( (HANDLE)m_hOutput, s, (DWORD)( n > lim ? lim : n ), &r, nullptr ) ) {
|
||||
if ( !WriteFile( (HANDLE)mOutputHandle, s, (DWORD)( n > lim ? lim : n ), &r, nullptr ) ) {
|
||||
PrintLastWinApiError();
|
||||
return -1;
|
||||
}
|
||||
@@ -195,7 +246,7 @@ int PseudoTerminal::read( char* buf, size_t n, bool block ) {
|
||||
DWORD read;
|
||||
|
||||
if ( !block ) {
|
||||
if ( !PeekNamedPipe( m_hInput.handle(), nullptr, 0, nullptr, &available, nullptr ) ) {
|
||||
if ( !PeekNamedPipe( mInputHandle.handle(), nullptr, 0, nullptr, &available, nullptr ) ) {
|
||||
PrintLastWinApiError();
|
||||
return -1;
|
||||
}
|
||||
@@ -203,7 +254,7 @@ int PseudoTerminal::read( char* buf, size_t n, bool block ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( !ReadFile( m_hInput.handle(), buf, available, &read, nullptr ) ) {
|
||||
if ( !ReadFile( mInputHandle.handle(), buf, available, &read, nullptr ) ) {
|
||||
PrintLastWinApiError();
|
||||
return -1;
|
||||
}
|
||||
@@ -211,11 +262,11 @@ int PseudoTerminal::read( char* buf, size_t n, bool block ) {
|
||||
}
|
||||
|
||||
int PseudoTerminal::getNumColumns() const {
|
||||
return m_size.x;
|
||||
return mSize.x;
|
||||
}
|
||||
|
||||
int PseudoTerminal::getNumRows() const {
|
||||
return m_size.y;
|
||||
return mSize.y;
|
||||
}
|
||||
|
||||
std::unique_ptr<PseudoTerminal> PseudoTerminal::create( int columns, int rows ) {
|
||||
|
||||
@@ -60,21 +60,21 @@ class PseudoTerminal final : public IPseudoTerminal {
|
||||
private:
|
||||
friend class ::EE::System::Process;
|
||||
#ifdef _WIN32
|
||||
Vector2i m_size;
|
||||
Vector2i mSize;
|
||||
|
||||
AutoHandle m_hInput;
|
||||
AutoHandle m_hOutput;
|
||||
void* m_phPC;
|
||||
AutoHandle mInputHandle;
|
||||
AutoHandle mOutputHandle;
|
||||
void* mPHPC;
|
||||
|
||||
bool m_attached;
|
||||
bool mAttached;
|
||||
|
||||
PseudoTerminal( int columns, int rows, AutoHandle&& hInput, AutoHandle&& hOutput, void* hPC );
|
||||
#else
|
||||
int m_columns;
|
||||
int m_rows;
|
||||
int mColumns;
|
||||
int mRows;
|
||||
|
||||
AutoHandle m_master;
|
||||
AutoHandle m_slave;
|
||||
AutoHandle mMaster;
|
||||
AutoHandle mSlave;
|
||||
|
||||
PseudoTerminal( int columns, int rows, AutoHandle&& master, AutoHandle&& slave );
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "terminaldisplay.hpp"
|
||||
#include "../system/processfactory.hpp"
|
||||
#include "boxdraw.hpp"
|
||||
#include "boxdrawdata.hpp"
|
||||
#include "eepp/graphics/fonttruetype.hpp"
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/primitives.hpp>
|
||||
@@ -153,6 +153,7 @@ static TerminalKey keys[] = {
|
||||
};
|
||||
|
||||
static TerminalScancode platformKeys[] = {
|
||||
{ SCANCODE_RETURN, KEYMOD_CTRL_SHIFT_ALT_META, "\r", 0, 0 },
|
||||
{ SCANCODE_PRIOR, KEYMOD_CTRL, "\033[5;5~", 0, 0 },
|
||||
|
||||
{ SCANCODE_PRIOR, KEYMOD_CTRL, "\033[5;5~", 0, 0 },
|
||||
@@ -389,7 +390,12 @@ TerminalDisplay::create( EE::Window::Window* window, Font* font, const Float& fo
|
||||
program = "cmd.exe";
|
||||
#else
|
||||
const char* shellenv = getenv( "SHELL" );
|
||||
#if EE_PLATFORM == EE_PLATFORM_ANDROID
|
||||
program = shellenv != nullptr ? shellenv : "/bin/sh";
|
||||
#else
|
||||
program = shellenv != nullptr ? shellenv : "/bin/bash";
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -405,6 +411,7 @@ TerminalDisplay::create( EE::Window::Window* window, Font* font, const Float& fo
|
||||
|
||||
if ( !pseudoTerminal ) {
|
||||
fprintf( stderr, "Failed to create pseudo terminal\n" );
|
||||
Log::error( "Failed to create pseudo terminal" );
|
||||
if ( freeProcessFactory )
|
||||
eeSAFE_DELETE( processFactory );
|
||||
return nullptr;
|
||||
@@ -412,6 +419,7 @@ TerminalDisplay::create( EE::Window::Window* window, Font* font, const Float& fo
|
||||
|
||||
if ( !process ) {
|
||||
fprintf( stderr, "Failed to spawn process\n" );
|
||||
Log::error( "Failed to spawn process" );
|
||||
if ( freeProcessFactory )
|
||||
eeSAFE_DELETE( processFactory );
|
||||
return nullptr;
|
||||
@@ -539,7 +547,7 @@ void TerminalDisplay::action( TerminalShortcutAction action ) {
|
||||
auto clipboard = getClipboard();
|
||||
auto clipboardLen = strlen( clipboard );
|
||||
if ( clipboardLen > 0 ) {
|
||||
mTerminal->write( clipboard, clipboardLen );
|
||||
mTerminal->ttywrite( clipboard, clipboardLen, 1 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1119,10 +1127,12 @@ void TerminalDisplay::draw( const Vector2f& pos ) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
p.setFillMode( PrimitiveFillMode::DRAW_LINE );
|
||||
p.drawRectangle(
|
||||
Rectf( { pos.x + mCursor.x * spaceCharAdvanceX, pos.y + mCursor.y * lineHeight },
|
||||
{ spaceCharAdvanceX, lineHeight } ) );
|
||||
Vector2f cpos{ pos.x + mCursor.x * spaceCharAdvanceX, pos.y + mCursor.y * lineHeight };
|
||||
drawrect( drawcol, cpos.x, cpos.y, spaceCharAdvanceX, cursorThickness, p );
|
||||
drawrect( drawcol, cpos.x, cpos.y, cursorThickness, lineHeight, p );
|
||||
drawrect( drawcol, cpos.x + spaceCharAdvanceX, cpos.y, cursorThickness, lineHeight, p );
|
||||
drawrect( drawcol, cpos.x, cpos.y + lineHeight - cursorThickness, spaceCharAdvanceX,
|
||||
cursorThickness, p );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1167,10 +1177,13 @@ void TerminalDisplay::onSizeChange() {
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalDisplay::onProcessExit( int ) {
|
||||
void TerminalDisplay::onProcessExit( int exitCode ) {
|
||||
if ( !mTerminal || mProgram.empty() )
|
||||
return;
|
||||
|
||||
if ( exitCode != 0 )
|
||||
return;
|
||||
|
||||
auto processFactory = eeNew( ProcessFactory, () );
|
||||
|
||||
Sizei termSize( mColumns, mRows );
|
||||
@@ -1241,7 +1254,7 @@ void TerminalDisplay::onKeyDown( const Keycode& keyCode, const Uint32& /*chr*/,
|
||||
}
|
||||
}
|
||||
|
||||
mTerminal->write( &tmp, 1 );
|
||||
mTerminal->ttywrite( &tmp, 1, 1 );
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1260,7 +1273,7 @@ void TerminalDisplay::onKeyDown( const Keycode& keyCode, const Uint32& /*chr*/,
|
||||
continue;
|
||||
|
||||
if ( k.string.size() > 0 ) {
|
||||
mTerminal->write( k.string.c_str(), k.string.size() );
|
||||
mTerminal->ttywrite( k.string.c_str(), k.string.size(), 1 );
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@@ -1282,7 +1295,7 @@ void TerminalDisplay::onKeyDown( const Keycode& keyCode, const Uint32& /*chr*/,
|
||||
continue;
|
||||
|
||||
if ( k.string.size() > 0 ) {
|
||||
mTerminal->write( k.string.c_str(), k.string.size() );
|
||||
mTerminal->ttywrite( k.string.c_str(), k.string.size(), 1 );
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@@ -1335,6 +1348,7 @@ void TerminalDisplay::setFocus( bool focus ) {
|
||||
if ( mFocus != modeFocus ) {
|
||||
if ( mFocus ) {
|
||||
mMode |= MODE_FOCUSED | MODE_FOCUS;
|
||||
mWindow->startTextInput();
|
||||
} else {
|
||||
mMode ^= MODE_FOCUS | MODE_FOCUSED;
|
||||
}
|
||||
|
||||
@@ -307,17 +307,18 @@ size_t utf8validate( Rune* u, size_t i ) {
|
||||
}
|
||||
|
||||
static const char base64_digits[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63,
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, -1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0,
|
||||
0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
|
||||
49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62,
|
||||
0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, (char)-1, 0, 0, 0, 0,
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
|
||||
23, 24, 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
|
||||
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
char base64dec_getc( const char** src ) {
|
||||
while ( **src && !isprint( **src ) )
|
||||
@@ -621,6 +622,9 @@ size_t TerminalEmulator::ttyread( void ) {
|
||||
_die( "couldn't read from shell: %s\n", strerror( errno ) );
|
||||
return 0;
|
||||
default:
|
||||
TerminalArg arg = { (int)mTerm.scr };
|
||||
kscrolldown( &arg );
|
||||
|
||||
mBuflen += ret;
|
||||
written = twrite( mBuf, mBuflen, 0 );
|
||||
mBuflen -= written;
|
||||
|
||||
@@ -195,7 +195,7 @@ class TerminalEmulator final {
|
||||
|
||||
bool isScrolling() const;
|
||||
|
||||
void ttywrite( const char*, size_t, int );
|
||||
void ttywrite( const char* s, size_t n, int may_echo );
|
||||
|
||||
int tisaltscr();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user