Compare commits
7 commits
4d27325d25
...
840ffdd3bf
Author | SHA1 | Date | |
---|---|---|---|
Christian Burger | 840ffdd3bf | ||
Christian Burger | 6ce6bcdace | ||
Christian Burger | 45beee33a8 | ||
Christian Burger | 0a916fe01a | ||
Christian Burger | 8273da4ada | ||
Christian Burger | 33e05f058c | ||
Christian Burger | ab0525cc6f |
6
App.cpp
6
App.cpp
|
@ -19,8 +19,10 @@ namespace krikkel::NCursesPtyWindow
|
||||||
|
|
||||||
int App::run()
|
int App::run()
|
||||||
{
|
{
|
||||||
Window *ptyWindow = new Window(
|
std::mutex writeMutex;
|
||||||
Root_Window->lines()
|
|
||||||
|
Window *ptyWindow = new Window(&writeMutex
|
||||||
|
, Root_Window->lines()
|
||||||
, Root_Window->cols()
|
, Root_Window->cols()
|
||||||
, 0
|
, 0
|
||||||
, 0);
|
, 0);
|
||||||
|
|
2
App.hpp
2
App.hpp
|
@ -6,7 +6,7 @@
|
||||||
#ifndef A3B2AE4E_0A39_468C_8CCA_E6508166702A
|
#ifndef A3B2AE4E_0A39_468C_8CCA_E6508166702A
|
||||||
#define A3B2AE4E_0A39_468C_8CCA_E6508166702A
|
#define A3B2AE4E_0A39_468C_8CCA_E6508166702A
|
||||||
|
|
||||||
#include <cursesapp.h>
|
#include <ncursesw/cursesapp.h>
|
||||||
|
|
||||||
namespace krikkel::NCursesPtyWindow
|
namespace krikkel::NCursesPtyWindow
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,6 +34,15 @@ target_link_libraries(NCursesPtyWindow Threads::Threads)
|
||||||
add_executable(NCursesPtyApp main.cpp App.cpp)
|
add_executable(NCursesPtyApp main.cpp App.cpp)
|
||||||
target_link_libraries(NCursesPtyApp ${CURSES_LIBRARIES} NCursesPtyWindow)
|
target_link_libraries(NCursesPtyApp ${CURSES_LIBRARIES} NCursesPtyWindow)
|
||||||
|
|
||||||
|
### installation and packaging
|
||||||
|
set_target_properties(NCursesPtyWindow PROPERTIES PUBLIC_HEADER "Window.hpp;SingleUserInput.hpp")
|
||||||
|
install(TARGETS NCursesPtyWindow ARCHIVE PUBLIC_HEADER)
|
||||||
|
|
||||||
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
|
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
|
||||||
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
|
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
|
||||||
|
set(CPACK_PACKAGE_CONTACT "Christian Burger <christian@krikkel.de>")
|
||||||
|
set(CPACK_PACKAGE_DESCRIPTION "Library for a pseudo terminal where the host end is a ncurses window")
|
||||||
|
|
||||||
|
set(CPACK_GENERATOR "DEB" "TGZ")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libncursesw6 (>=6.2), libvterm-dev (>= 0.1.2)")
|
||||||
include(CPack)
|
include(CPack)
|
||||||
|
|
160
Debug.cpp
160
Debug.cpp
|
@ -14,9 +14,14 @@
|
||||||
|
|
||||||
#include "Debug.hpp"
|
#include "Debug.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <syscall.h>
|
||||||
|
#include <sys/ptrace.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
#define BUFFER_SIZE 128
|
#define BUFFER_SIZE 128
|
||||||
|
|
||||||
|
@ -29,6 +34,7 @@ namespace krikkel
|
||||||
using std::time;
|
using std::time;
|
||||||
using std::localtime;
|
using std::localtime;
|
||||||
using std::strftime;
|
using std::strftime;
|
||||||
|
using std::min;
|
||||||
|
|
||||||
Debug::Debug()
|
Debug::Debug()
|
||||||
{
|
{
|
||||||
|
@ -87,6 +93,160 @@ namespace krikkel
|
||||||
logFile.flush();
|
logFile.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Debug::peekData(pid_t shellPid, void *data, size_t length)
|
||||||
|
{
|
||||||
|
std::string result;
|
||||||
|
|
||||||
|
for(int index = 0; index < length / sizeof(long); ++index)
|
||||||
|
{
|
||||||
|
long datum = ptrace(PTRACE_PEEKDATA, shellPid, ((char *) data) + index * sizeof(long));
|
||||||
|
if(length == -1)
|
||||||
|
{
|
||||||
|
size_t datumLength = strnlen((char *) &datum, sizeof(long));
|
||||||
|
result += string((char *) &datum, datumLength);
|
||||||
|
if(datumLength < sizeof(long))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result += string((char *) &datum, sizeof(long));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Debug::formatToAddress(unsigned long long address)
|
||||||
|
{
|
||||||
|
char addressString[17];
|
||||||
|
|
||||||
|
snprintf(addressString, 17, "%016llx", address);
|
||||||
|
|
||||||
|
return string("0x") + addressString;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Debug::logPtraceSysCall(pid_t shellPid, uint16_t sysCallId, bool returnedFromSysCall, unsigned long long result, unsigned long long firstArgument, unsigned long long secondArgument, unsigned long long thirdArgument, unsigned long long fourthArgument, std::string fileName, int lineNo, std::string functionName)
|
||||||
|
{
|
||||||
|
const static uint8_t maxStringLength = 32;
|
||||||
|
string message = "syscall: ";
|
||||||
|
|
||||||
|
string sysCallName;
|
||||||
|
if(sysCallId < MAX_NUMBER_OF_SYSCALLS)
|
||||||
|
sysCallName = syscalls[sysCallId];
|
||||||
|
if(sysCallName.empty())
|
||||||
|
sysCallName = "syscall" + std::to_string(sysCallId);
|
||||||
|
|
||||||
|
|
||||||
|
switch(sysCallId)
|
||||||
|
{
|
||||||
|
case SYS_read:
|
||||||
|
if(returnedFromSysCall)
|
||||||
|
message += (result == -1 ? "-1" : std::to_string((size_t) result)) + " = ";
|
||||||
|
message += sysCallName
|
||||||
|
+ "(" + std::to_string((int) firstArgument)
|
||||||
|
+ ", \"" + (returnedFromSysCall ? __debug_make_bytes_printable(peekData(shellPid, (char *) secondArgument, (size_t) min<unsigned long long>(thirdArgument, maxStringLength))) : "")
|
||||||
|
+ (maxStringLength < thirdArgument || returnedFromSysCall == true ? "[…]" : "") + "\""
|
||||||
|
+ ", " + std::to_string((size_t) thirdArgument)
|
||||||
|
+ ")";
|
||||||
|
break;
|
||||||
|
case SYS_write:
|
||||||
|
if(returnedFromSysCall)
|
||||||
|
message += (result == -1 ? "-1" : std::to_string((size_t) result)) + " = ";
|
||||||
|
message += sysCallName
|
||||||
|
+ "(" + std::to_string((int) firstArgument)
|
||||||
|
+ ", \"" + __debug_make_bytes_printable(peekData(shellPid, (char *) secondArgument, (size_t) min<unsigned long long>(thirdArgument, maxStringLength)))
|
||||||
|
+ (maxStringLength < thirdArgument || returnedFromSysCall == true ? "[…]" : "") + "\""
|
||||||
|
+ ", " + std::to_string((size_t) thirdArgument)
|
||||||
|
+ ")";
|
||||||
|
break;
|
||||||
|
case SYS_close:
|
||||||
|
if(returnedFromSysCall)
|
||||||
|
message += std::to_string((int) result) + " = ";
|
||||||
|
message += sysCallName
|
||||||
|
+ "(" + std::to_string((int) firstArgument)
|
||||||
|
+ ")";
|
||||||
|
break;
|
||||||
|
case SYS_stat:
|
||||||
|
if(returnedFromSysCall)
|
||||||
|
message += std::to_string((int) result) + " = ";
|
||||||
|
message += sysCallName
|
||||||
|
+ "(\"" + peekData(shellPid, (char *) firstArgument, -1) + "\""
|
||||||
|
+ ", " + formatToAddress(secondArgument)
|
||||||
|
+ ")";
|
||||||
|
break;
|
||||||
|
case SYS_fstat:
|
||||||
|
if(returnedFromSysCall)
|
||||||
|
message += std::to_string((int) result) + " = ";
|
||||||
|
message += sysCallName
|
||||||
|
+ "(" + std::to_string((int) firstArgument)
|
||||||
|
+ ", " + formatToAddress(secondArgument)
|
||||||
|
+ ")";
|
||||||
|
break;
|
||||||
|
case SYS_openat:
|
||||||
|
if(returnedFromSysCall)
|
||||||
|
message += std::to_string((int) result) + " = ";
|
||||||
|
message += sysCallName
|
||||||
|
+ "(" + ((int) firstArgument == AT_FDCWD ? string("AT_FDCWD") : std::to_string((int) firstArgument))
|
||||||
|
+ ", \"" + __debug_make_bytes_printable(peekData(shellPid, (char *) secondArgument, -1)) + "\""
|
||||||
|
+ ", " + std::to_string((int) thirdArgument)
|
||||||
|
+ ")";
|
||||||
|
break;
|
||||||
|
case SYS_rt_sigprocmask:
|
||||||
|
if(returnedFromSysCall)
|
||||||
|
message += std::to_string((int) result) + " = ";
|
||||||
|
message += sysCallName
|
||||||
|
+ "(" + std::to_string((int) firstArgument)
|
||||||
|
+ ", " + formatToAddress(secondArgument)
|
||||||
|
+ ", " + formatToAddress(thirdArgument)
|
||||||
|
+ ", " + std::to_string((size_t) fourthArgument)
|
||||||
|
+ ")";
|
||||||
|
break;
|
||||||
|
case SYS_access:
|
||||||
|
if(returnedFromSysCall)
|
||||||
|
message += std::to_string((int) result) + " = ";
|
||||||
|
message += sysCallName
|
||||||
|
+ "(" + peekData(shellPid, (char *) firstArgument, -1)
|
||||||
|
+ ", " + std::to_string((int) secondArgument)
|
||||||
|
+ ")";
|
||||||
|
break;
|
||||||
|
case SYS_dup2:
|
||||||
|
if(returnedFromSysCall)
|
||||||
|
message += std::to_string((int) result) + " = ";
|
||||||
|
message += sysCallName
|
||||||
|
+ "(" + std::to_string((int) firstArgument)
|
||||||
|
+ ", " + std::to_string((int) secondArgument)
|
||||||
|
+ ")";
|
||||||
|
break;
|
||||||
|
case SYS_fcntl:
|
||||||
|
if(returnedFromSysCall)
|
||||||
|
message += std::to_string((int) result) + " = ";
|
||||||
|
message += sysCallName
|
||||||
|
+ "(" + std::to_string((int) firstArgument)
|
||||||
|
+ ", " + (secondArgument == 0 ? string("F_DUP_FD") : std::to_string((int) secondArgument))
|
||||||
|
+ ", …"
|
||||||
|
+ ")";
|
||||||
|
break;
|
||||||
|
/* case SYS_fstat:
|
||||||
|
struct stat statbuf;
|
||||||
|
message += "(" + std::to_string(firstArgument)
|
||||||
|
+ ", \"" + __debug_make_bytes_printable(peekData(shellPid, (char *) secondArgument, (size_t) min<unsigned long long>(thirdArgument, maxStringLength)))
|
||||||
|
+ (maxStringLength < thirdArgument ? "[…]" : "") + "\""
|
||||||
|
+ ", " + std::to_string((size_t) thirdArgument)
|
||||||
|
+ ")";
|
||||||
|
break;
|
||||||
|
*/ default:
|
||||||
|
if(returnedFromSysCall)
|
||||||
|
message += (result == -1 ? "-1" : std::to_string(result)) + " = ";
|
||||||
|
message += sysCallName
|
||||||
|
+ "(" + formatToAddress(firstArgument)
|
||||||
|
+ ", " + formatToAddress(secondArgument)
|
||||||
|
+ ", " + formatToAddress(thirdArgument)
|
||||||
|
+ ", " + formatToAddress(fourthArgument)
|
||||||
|
+ ")";
|
||||||
|
}
|
||||||
|
// source: https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/
|
||||||
|
|
||||||
|
log(message, fileName, lineNo, functionName);
|
||||||
|
}
|
||||||
|
|
||||||
Debug *Debug::getInstance()
|
Debug *Debug::getInstance()
|
||||||
{
|
{
|
||||||
static Debug *debug = new Debug();
|
static Debug *debug = new Debug();
|
||||||
|
|
11
Debug.hpp
11
Debug.hpp
|
@ -26,17 +26,22 @@ namespace krikkel
|
||||||
Debug();
|
Debug();
|
||||||
std::string getTimestamp();
|
std::string getTimestamp();
|
||||||
std::string getUname();
|
std::string getUname();
|
||||||
|
std::string peekData(pid_t shellPid, void *data, size_t length);
|
||||||
|
std::string formatToAddress(unsigned long long address);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void log(std::string message, std::string fileName, int lineNo
|
void log(std::string message, std::string fileName, int lineNo
|
||||||
, std::string functionName);
|
, std::string functionName);
|
||||||
|
void logPtraceSysCall(pid_t shellPid, uint16_t sysCallId, bool returnedFromSysCall, unsigned long long result, unsigned long long firstArgument, unsigned long long secondArgument, unsigned long long thirdArgument, unsigned long long fourthArgument, std::string fileName, int lineNo, std::string functionName);
|
||||||
static Debug *getInstance();
|
static Debug *getInstance();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#define __debug_log(message) krikkel::Debug::getInstance()\
|
#define __debug_log(message) \
|
||||||
->log(message, __FILE__, __LINE__, __func__)
|
krikkel::Debug::getInstance()->log(message, __FILE__, __LINE__, __func__)
|
||||||
|
|
||||||
|
#define __debug_log_ptrace_syscall(shellPid, sysCallId, returnedFromSysCall, result, firstArgument, secondArgument, thirdArgument, fourthArgument) \
|
||||||
|
krikkel::Debug::getInstance()->logPtraceSysCall(shellPid, sysCallId, returnedFromSysCall, result, firstArgument, secondArgument, thirdArgument, fourthArgument, __FILE__, __LINE__, __func__);
|
||||||
|
|
||||||
/// @todo need an explanation on why and how to use this
|
/// @todo need an explanation on why and how to use this
|
||||||
/// this is the complete opposite of self-explanatory
|
/// this is the complete opposite of self-explanatory
|
||||||
|
@ -104,7 +109,7 @@ namespace krikkel
|
||||||
if(std::isprint(character, loc) && character != '<') \
|
if(std::isprint(character, loc) && character != '<') \
|
||||||
result += character; \
|
result += character; \
|
||||||
else \
|
else \
|
||||||
result += '<' + std::to_string(character) + '>'; \
|
result += '<' + std::to_string((unsigned char) character) + '>'; \
|
||||||
} \
|
} \
|
||||||
return result; \
|
return result; \
|
||||||
})(__bytes)
|
})(__bytes)
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include "SingleUserInput.hpp"
|
#include "SingleUserInput.hpp"
|
||||||
#include "Debug.hpp"
|
#include "Debug.hpp"
|
||||||
|
|
||||||
#include <ncurses.h>
|
|
||||||
#include <vterm.h>
|
#include <vterm.h>
|
||||||
|
|
||||||
#define KEY_TAB '\t'
|
#define KEY_TAB '\t'
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
|
/**
|
||||||
|
* @brief stores a single user input (printable and function keys)
|
||||||
|
* @author Christian Burger (christian@krikkel.de)
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef F0E30ED4_3883_40D6_A6EE_08BA4DF9E92E
|
#ifndef F0E30ED4_3883_40D6_A6EE_08BA4DF9E92E
|
||||||
#define F0E30ED4_3883_40D6_A6EE_08BA4DF9E92E
|
#define F0E30ED4_3883_40D6_A6EE_08BA4DF9E92E
|
||||||
|
|
||||||
#include <cursesw.h>
|
#include <ncursesw/cursesw.h>
|
||||||
#include <vterm_keycodes.h>
|
#include <vterm_keycodes.h>
|
||||||
|
|
||||||
namespace krikkel::NCursesPtyWindow
|
namespace krikkel::NCursesPtyWindow
|
||||||
|
|
19
Window.cpp
19
Window.cpp
|
@ -18,8 +18,8 @@ namespace krikkel::NCursesPtyWindow
|
||||||
using gsl::narrow;
|
using gsl::narrow;
|
||||||
using std::lock_guard;
|
using std::lock_guard;
|
||||||
|
|
||||||
Window::Window(int lines, int columns, int y, int x)
|
Window::Window(std::mutex *writeToNCursesMutex, int lines, int columns, int y, int x)
|
||||||
: NCursesWindow(lines, columns, y, x)
|
: writeToNCursesMutex(writeToNCursesMutex), NCursesWindow(lines, columns, y, x)
|
||||||
{
|
{
|
||||||
// to get the original terminal we need to shutdown ncurses for a moment
|
// to get the original terminal we need to shutdown ncurses for a moment
|
||||||
/// @todo maybe try `reset_prog_mode()` and `reset_shell_mode()` instead
|
/// @todo maybe try `reset_prog_mode()` and `reset_shell_mode()` instead
|
||||||
|
@ -245,10 +245,13 @@ namespace krikkel::NCursesPtyWindow
|
||||||
else
|
else
|
||||||
character = *vTermCell.chars;
|
character = *vTermCell.chars;
|
||||||
|
|
||||||
setcchar(&converted, &character, formatting, colorPair, NULL);
|
{
|
||||||
move(cellPosition.row, cellPosition.col);
|
lock_guard nCursesLock(*writeToNCursesMutex);
|
||||||
chgat(1, formatting, colorPair, NULL);
|
setcchar(&converted, &character, formatting, colorPair, NULL);
|
||||||
add_wch(&converted);
|
move(cellPosition.row, cellPosition.col);
|
||||||
|
chgat(1, formatting, colorPair, NULL);
|
||||||
|
add_wch(&converted);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Window::add_wch(const cchar_t *character)
|
int Window::add_wch(const cchar_t *character)
|
||||||
|
@ -263,6 +266,7 @@ namespace krikkel::NCursesPtyWindow
|
||||||
|
|
||||||
int Window::refresh()
|
int Window::refresh()
|
||||||
{
|
{
|
||||||
|
lock_guard nCursesLock(*writeToNCursesMutex);
|
||||||
move(cursorY, cursorX);
|
move(cursorY, cursorX);
|
||||||
return NCursesWindow::refresh();
|
return NCursesWindow::refresh();
|
||||||
}
|
}
|
||||||
|
@ -271,7 +275,8 @@ namespace krikkel::NCursesPtyWindow
|
||||||
/// resizing?
|
/// resizing?
|
||||||
int Window::wresize(int rows, int cols)
|
int Window::wresize(int rows, int cols)
|
||||||
{
|
{
|
||||||
std::lock_guard writeLock(writeToPseudoTerminalMutex);
|
lock_guard nCursesLock(*writeToNCursesMutex);
|
||||||
|
lock_guard writeLock(writeToPseudoTerminalMutex);
|
||||||
winsize windowSize =
|
winsize windowSize =
|
||||||
{
|
{
|
||||||
.ws_row = narrow<unsigned short>(rows)
|
.ws_row = narrow<unsigned short>(rows)
|
||||||
|
|
|
@ -3,9 +3,12 @@
|
||||||
* @author Christian Burger (christian@krikkel.de)
|
* @author Christian Burger (christian@krikkel.de)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef __WINDOW_H__
|
||||||
|
#define __WINDOW_H__
|
||||||
|
|
||||||
#include "SingleUserInput.hpp"
|
#include "SingleUserInput.hpp"
|
||||||
|
|
||||||
#include <cursesw.h>
|
#include <ncursesw/cursesw.h>
|
||||||
#include <pty.h>
|
#include <pty.h>
|
||||||
#include <vterm.h>
|
#include <vterm.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -29,7 +32,7 @@ namespace krikkel::NCursesPtyWindow
|
||||||
class Window : public NCursesWindow
|
class Window : public NCursesWindow
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Window(int lines, int columns, int y, int x);
|
Window(std::mutex *writeToNCursesMutex, int lines, int columns, int y, int x);
|
||||||
~Window();
|
~Window();
|
||||||
|
|
||||||
int getFdPtyClient() const;
|
int getFdPtyClient() const;
|
||||||
|
@ -49,6 +52,7 @@ namespace krikkel::NCursesPtyWindow
|
||||||
struct termios terminalParameters;
|
struct termios terminalParameters;
|
||||||
VTerm *pseudoTerminal;
|
VTerm *pseudoTerminal;
|
||||||
std::mutex writeToPseudoTerminalMutex;
|
std::mutex writeToPseudoTerminalMutex;
|
||||||
|
std::mutex *writeToNCursesMutex;
|
||||||
VTermScreen *pseudoTerminalScreen;
|
VTermScreen *pseudoTerminalScreen;
|
||||||
static VTermScreenCallbacks screenCallbacks;
|
static VTermScreenCallbacks screenCallbacks;
|
||||||
/// @todo one line is at most 4096 chars long
|
/// @todo one line is at most 4096 chars long
|
||||||
|
@ -84,3 +88,4 @@ namespace krikkel::NCursesPtyWindow
|
||||||
static void staticHandlerOutput(const char *s, size_t len, void *user);
|
static void staticHandlerOutput(const char *s, size_t len, void *user);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
#endif // __WINDOW_H__
|
|
@ -1,6 +1,6 @@
|
||||||
# @author Christian Burger <christian@krikkel.de>
|
# @author Christian Burger <christian@krikkel.de>
|
||||||
|
|
||||||
find_path(GSL_INCLUDE_DIR "gsl")
|
find_path(GSL_INCLUDE_DIR "gsl/gsl")
|
||||||
if(GSL_INCLUDE_DIR STREQUAL "GSL_INCLUDE_DIR-NOTFOUND")
|
if(GSL_INCLUDE_DIR STREQUAL "GSL_INCLUDE_DIR-NOTFOUND")
|
||||||
message(SEND_ERROR "Microsoft GSL not found.")
|
message(SEND_ERROR "Microsoft GSL not found.")
|
||||||
else()
|
else()
|
||||||
|
|
|
@ -22,4 +22,6 @@ if(LIBVTERM_LIBRARY STREQUAL "LIBVTERM_LIBRARY-NOTFOUND")
|
||||||
ExternalProject_Get_property(libvtermProject SOURCE_DIR)
|
ExternalProject_Get_property(libvtermProject SOURCE_DIR)
|
||||||
set(LIBVTERM_LIBRARY "${SOURCE_DIR}/.libs/libvterm.a")
|
set(LIBVTERM_LIBRARY "${SOURCE_DIR}/.libs/libvterm.a")
|
||||||
include_directories(SYSTEM "${SOURCE_DIR}/include")
|
include_directories(SYSTEM "${SOURCE_DIR}/include")
|
||||||
|
else()
|
||||||
|
message(WARNING "libvterm found — hopefully the right version")
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
# @author Christian Burger <christian@krikkel.de>
|
# @author Christian Burger <christian@krikkel.de>
|
||||||
|
|
||||||
### ncurses
|
|
||||||
set(CURSES_NEED_NCURSES TRUE)
|
set(CURSES_NEED_NCURSES TRUE)
|
||||||
set(CURSES_NEED_WIDE TRUE)
|
set(CURSES_NEED_WIDE TRUE)
|
||||||
find_package(Curses 6.2 REQUIRED)
|
find_package(Curses 6.2 REQUIRED)
|
||||||
include_directories(${CURSES_INCLUDE_DIRS})
|
include_directories(SYSTEM ${CURSES_INCLUDE_DIRS})
|
||||||
|
|
||||||
# find C++ interface for ncurses with unicode support
|
# find C++ interface for ncurses with unicode support
|
||||||
find_library(CURSES_CPP_WIDE_LIBRARY NAMES ncurses++w REQUIRED)
|
find_library(CURSES_CPP_WIDE_LIBRARY NAMES ncurses++w REQUIRED)
|
||||||
|
|
Loading…
Reference in a new issue