feat: add WebAssembly (Emscripten) build support
- Platform detection: EMSCRIPTEN/WASM macros in piplatform.h - CMake: PIP_WASM option, auto-detect, STATIC lib, pthread flags, disable incompatible modules (console, usb, fftw, opencl, lua, http_server, http_client, mqtt_client) - Macros: environ, SHUT_RDWR, HAS_LOCALE off, PIP_MIN_MSLEEP=10ms - System stubs: process, signals, library, systeminfo, hidevice - IO stubs: serial, ethernet, can, sharedmemory - Thread: gettid() fallback via pthread_self() - Core: locale/init adjustments, console.log routing via EM_ASM - Fix: toDecimal precision loss, unreachable code in createPipe
This commit is contained in:
+2
-5
@@ -74,7 +74,6 @@ option(PIP_FFTW_F "Support fftw module for float" ON)
|
||||
option(PIP_FFTW_L "Support fftw module for long double" ON)
|
||||
option(PIP_FFTW_Q "Support fftw module for quad double" OFF)
|
||||
option(PIP_MANUAL_TEST "Build dev test (main.cpp)" OFF)
|
||||
option(PIP_WASM "Build for WebAssembly (Emscripten)" OFF)
|
||||
set(PIP_UTILS 1)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
@@ -230,10 +229,8 @@ if(PIP_FREERTOS)
|
||||
set(LOCAL ON)
|
||||
endif()
|
||||
|
||||
if(NOT PIP_WASM)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten" OR DEFINED CMAKE_Emscripten)
|
||||
set(PIP_WASM ON)
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten" OR DEFINED CMAKE_Emscripten)
|
||||
set(PIP_WASM ON)
|
||||
endif()
|
||||
|
||||
if(PIP_WASM)
|
||||
|
||||
@@ -195,7 +195,7 @@ extern long long __pi_perf_freq;
|
||||
# ifndef SHUT_RDWR
|
||||
# define SHUT_RDWR 2
|
||||
# endif
|
||||
#endif
|
||||
#endif //EMSCRIPTEN
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
@@ -210,13 +210,9 @@ extern long long __pi_perf_freq;
|
||||
typedef long time_t;
|
||||
# endif
|
||||
|
||||
# ifdef LINUX
|
||||
# if defined(LINUX) || defined(EMSCRIPTEN)
|
||||
# define environ __environ
|
||||
# endif
|
||||
|
||||
# ifdef EMSCRIPTEN
|
||||
# define environ __environ
|
||||
# endif
|
||||
# endif //EMSCRIPTEN
|
||||
|
||||
# ifdef FREE_BSD
|
||||
extern char ** environ;
|
||||
@@ -248,7 +244,7 @@ extern char ** environ;
|
||||
# pragma GCC diagnostic warning "-Wdeprecated-declarations"
|
||||
# if defined(LINUX) && !defined(EMSCRIPTEN)
|
||||
# define HAS_LOCALE
|
||||
# endif
|
||||
# endif //EMSCRIPTEN
|
||||
# ifdef MAC_OS
|
||||
# pragma GCC diagnostic ignored "-Wundefined-bool-conversion"
|
||||
# pragma GCC diagnostic ignored "-Wc++11-extensions"
|
||||
@@ -405,9 +401,9 @@ typedef long long ssize_t;
|
||||
#ifndef PIP_MIN_MSLEEP
|
||||
# if defined(MICRO_PIP) || defined(EMSCRIPTEN)
|
||||
# define PIP_MIN_MSLEEP 10.
|
||||
# else
|
||||
# else //EMSCRIPTEN
|
||||
# define PIP_MIN_MSLEEP 1.
|
||||
# endif
|
||||
# endif //EMSCRIPTEN
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
+34
-21
@@ -236,9 +236,11 @@ PICout & PICout::operator<<(PICoutAction v) {
|
||||
SetConsoleCursorPosition(__Private__::hOut, coord);
|
||||
printf(" ");
|
||||
SetConsoleCursorPosition(__Private__::hOut, coord);
|
||||
#elif !defined(EMSCRIPTEN)
|
||||
#else //EMSCRIPTEN
|
||||
# ifndef EMSCRIPTEN
|
||||
printf("\e[1D \e[1D");
|
||||
#endif
|
||||
# endif //EMSCRIPTEN
|
||||
#endif //EMSCRIPTEN
|
||||
}
|
||||
break;
|
||||
case PICoutManipulators::ShowCursor:
|
||||
@@ -247,9 +249,11 @@ PICout & PICout::operator<<(PICoutAction v) {
|
||||
GetConsoleCursorInfo(__Private__::hOut, &curinfo);
|
||||
curinfo.bVisible = true;
|
||||
SetConsoleCursorInfo(__Private__::hOut, &curinfo);
|
||||
#elif !defined(EMSCRIPTEN)
|
||||
#else //EMSCRIPTEN
|
||||
# ifndef EMSCRIPTEN
|
||||
printf("\e[?25h");
|
||||
#endif
|
||||
# endif //EMSCRIPTEN
|
||||
#endif //EMSCRIPTEN
|
||||
}
|
||||
break;
|
||||
case PICoutManipulators::HideCursor:
|
||||
@@ -258,9 +262,11 @@ PICout & PICout::operator<<(PICoutAction v) {
|
||||
GetConsoleCursorInfo(__Private__::hOut, &curinfo);
|
||||
curinfo.bVisible = false;
|
||||
SetConsoleCursorInfo(__Private__::hOut, &curinfo);
|
||||
#elif !defined(EMSCRIPTEN)
|
||||
#else //EMSCRIPTEN
|
||||
# ifndef EMSCRIPTEN
|
||||
printf("\e[?25l");
|
||||
#endif
|
||||
# endif //EMSCRIPTEN
|
||||
#endif //EMSCRIPTEN
|
||||
}
|
||||
break;
|
||||
case PICoutManipulators::ClearLine:
|
||||
@@ -279,18 +285,22 @@ PICout & PICout::operator<<(PICoutAction v) {
|
||||
delete[] line;
|
||||
}
|
||||
SetConsoleCursorPosition(__Private__::hOut, coord);
|
||||
#elif !defined(EMSCRIPTEN)
|
||||
#else //EMSCRIPTEN
|
||||
# ifndef EMSCRIPTEN
|
||||
printf("\e[0G\e[K");
|
||||
#endif
|
||||
# endif //EMSCRIPTEN
|
||||
#endif //EMSCRIPTEN
|
||||
}
|
||||
break;
|
||||
case PICoutManipulators::ClearScreen:
|
||||
if (isOutputDeviceActive(Console)) {
|
||||
#ifdef WINDOWS
|
||||
/// TODO : wondows ClearScreen !!!
|
||||
#elif !defined(EMSCRIPTEN)
|
||||
#else //EMSCRIPTEN
|
||||
# ifndef EMSCRIPTEN
|
||||
printf("\e[H\e[J");
|
||||
#endif
|
||||
# endif //EMSCRIPTEN
|
||||
#endif //EMSCRIPTEN
|
||||
}
|
||||
break;
|
||||
case PICoutManipulators::SaveContol: saveControls(); break;
|
||||
@@ -378,14 +388,16 @@ void PICout::stdoutPIString(const PIString & str, PICoutStdStream s) {
|
||||
},
|
||||
buf,
|
||||
(int)s);
|
||||
#elif defined(HAS_LOCALE)
|
||||
#else //EMSCRIPTEN
|
||||
# ifdef HAS_LOCALE
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> utf8conv;
|
||||
getStdStream(s) << utf8conv.to_bytes((char16_t *)&(const_cast<PIString &>(str).front()),
|
||||
(char16_t *)&(const_cast<PIString &>(str).front()) + str.size());
|
||||
#else
|
||||
# else // HAS_LOCALE
|
||||
for (PIChar c: str)
|
||||
getStdWStream(s).put(c.toWChar());
|
||||
#endif
|
||||
# endif // HAS_LOCALE
|
||||
#endif //EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -410,9 +422,9 @@ PICout & PICout::write(const char * str, int len) {
|
||||
0,
|
||||
(int)stream_);
|
||||
}
|
||||
#else
|
||||
#else //EMSCRIPTEN
|
||||
if (isOutputDeviceActive(Console)) getStdStream(stream_).write(str, len);
|
||||
#endif
|
||||
#endif //EMSCRIPTEN
|
||||
if (isOutputDeviceActive(Buffer)) PICout::__string__().append(PIString(str, len));
|
||||
}
|
||||
return *this;
|
||||
@@ -437,9 +449,9 @@ void PICout::writeChar(char c) {
|
||||
} else {
|
||||
#ifdef EMSCRIPTEN
|
||||
if (isOutputDeviceActive(Console)) fputc(c, stream_ == PICoutStdStream::StdErr ? stderr : stdout);
|
||||
#else
|
||||
#else //EMSCRIPTEN
|
||||
if (isOutputDeviceActive(Console)) getStdStream(stream_) << c;
|
||||
#endif
|
||||
#endif //EMSCRIPTEN
|
||||
if (isOutputDeviceActive(Buffer)) PICout::__string__().append(c);
|
||||
}
|
||||
}
|
||||
@@ -682,9 +694,9 @@ void PICout::applyFormat(PICoutFormat f) {
|
||||
if (buffer_ || !isOutputDeviceActive(Console)) return;
|
||||
#ifdef EMSCRIPTEN
|
||||
return;
|
||||
#endif
|
||||
#else //EMSCRIPTEN
|
||||
format_changed_ = true;
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
static int mask_fore = ~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
static int mask_back = ~(BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
|
||||
switch (f) {
|
||||
@@ -714,7 +726,7 @@ void PICout::applyFormat(PICoutFormat f) {
|
||||
default: break;
|
||||
}
|
||||
SetConsoleTextAttribute(__Private__::hOut, win_attr_);
|
||||
#else
|
||||
# else
|
||||
switch (f) {
|
||||
case Bin:
|
||||
case Oct:
|
||||
@@ -744,7 +756,8 @@ void PICout::applyFormat(PICoutFormat f) {
|
||||
case PICoutManipulators::Default: printf("\e[0m"); break;
|
||||
default: break;
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
#endif //EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -40,9 +40,9 @@ double piMountInfoRefreshIntervalMs = 10000.;
|
||||
lconv * currentLocale =
|
||||
#if defined(ANDROID) || defined(EMSCRIPTEN)
|
||||
0;
|
||||
#else
|
||||
#else //EMSCRIPTEN
|
||||
std::localeconv();
|
||||
#endif
|
||||
#endif //EMSCRIPTEN
|
||||
|
||||
#ifdef MAC_OS
|
||||
clock_serv_t __pi_mac_clock;
|
||||
|
||||
@@ -58,7 +58,7 @@ typedef LONG(NTAPI * PINtSetTimerResolution)(ULONG, BOOLEAN, PULONG);
|
||||
#ifdef EMSCRIPTEN
|
||||
# include <emscripten.h>
|
||||
# include <emscripten/html5.h>
|
||||
#endif
|
||||
#endif //EMSCRIPTEN
|
||||
|
||||
// clang-format on
|
||||
|
||||
|
||||
+10
-10
@@ -50,7 +50,7 @@ void __PISetTimerResolution() {
|
||||
# include <pthread.h>
|
||||
# ifndef EMSCRIPTEN
|
||||
# include <pwd.h>
|
||||
# endif
|
||||
# endif //EMSCRIPTEN
|
||||
# include <sys/utsname.h>
|
||||
# ifdef BLACKBERRY
|
||||
# include <signal.h>
|
||||
@@ -116,8 +116,8 @@ PIInit::PIInit() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
# else // WINDOWS
|
||||
# endif //EMSCRIPTEN
|
||||
# else // WINDOWS
|
||||
// OS version
|
||||
DWORD dwVersion = GetVersion();
|
||||
DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
|
||||
@@ -143,7 +143,7 @@ PIInit::PIInit() {
|
||||
setTimerResolutionAddr = (PINtSetTimerResolution)GetProcAddress(PRIVATE->ntlib, "NtSetTimerResolution");
|
||||
__PISetTimerResolution();
|
||||
}
|
||||
# endif // WINDOWS
|
||||
# endif // WINDOWS
|
||||
# ifdef HAS_LOCALE
|
||||
// std::cout << "has locale" << std::endl;
|
||||
if (currentLocale_t != 0) {
|
||||
@@ -156,9 +156,9 @@ PIInit::PIInit() {
|
||||
# ifndef EMSCRIPTEN
|
||||
setlocale(LC_ALL, "");
|
||||
setlocale(LC_NUMERIC, "C");
|
||||
# endif
|
||||
# endif // HAS_LOCALE
|
||||
# endif // ANDROID
|
||||
# endif //EMSCRIPTEN
|
||||
# endif // HAS_LOCALE
|
||||
# endif // ANDROID
|
||||
PRIVATE->delete_locs = false;
|
||||
__syslocname__ = __sysoemname__ = 0;
|
||||
__utf8name__ = const_cast<char *>("UTF-8");
|
||||
@@ -235,12 +235,12 @@ PIInit::PIInit() {
|
||||
sinfo->OS_version = uns.release;
|
||||
sinfo->architecture = uns.machine;
|
||||
}
|
||||
# else
|
||||
# else //EMSCRIPTEN
|
||||
sinfo->processorsCount = 1;
|
||||
sinfo->OS_version = PIStringAscii("WASM");
|
||||
sinfo->architecture = PIStringAscii("wasm32");
|
||||
# endif
|
||||
# endif // WINDOWS
|
||||
# endif //EMSCRIPTEN
|
||||
# endif // WINDOWS
|
||||
|
||||
# ifdef ESP_PLATFORM
|
||||
esp_chip_info_t chip_info;
|
||||
|
||||
+102
-111
@@ -73,7 +73,7 @@
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
#endif //EMSCRIPTEN
|
||||
// clang-format on
|
||||
#include "piwaitevent_p.h"
|
||||
|
||||
@@ -110,7 +110,7 @@ PIString getSockAddr(sockaddr * s) {
|
||||
const char * r = inet_ntop(AF_INET, &((sockaddr_in *)s)->sin_addr, buf, sizeof(buf));
|
||||
return r ? PIStringAscii(r) : PIString();
|
||||
}
|
||||
#endif
|
||||
#endif // WINDOWS, EMSCRIPTEN
|
||||
|
||||
|
||||
REGISTER_DEVICE(PIEthernet)
|
||||
@@ -121,7 +121,7 @@ PRIVATE_DEFINITION_START(PIEthernet)
|
||||
sockaddr_in addr_;
|
||||
sockaddr_in saddr_;
|
||||
sockaddr_in raddr_;
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
PIWaitEvent event;
|
||||
PRIVATE_DEFINITION_END(PIEthernet)
|
||||
|
||||
@@ -158,7 +158,7 @@ PIEthernet::PIEthernet(int sock_, PIString ip_port): PIIODevice("", ReadWrite) {
|
||||
setPath(ip_port);
|
||||
#ifndef EMSCRIPTEN
|
||||
ethNonblocking(sock);
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
PRIVATE->event.create();
|
||||
// piCoutObj << "new tcp client" << sock_;
|
||||
}
|
||||
@@ -218,8 +218,7 @@ void PIEthernet::construct() {
|
||||
void PIEthernet::init() {
|
||||
#ifdef EMSCRIPTEN
|
||||
return;
|
||||
#endif
|
||||
#ifndef EMSCRIPTEN
|
||||
#else // EMSCRIPTEN
|
||||
if (isOpened() || is_server_client) return;
|
||||
if (sock != -1) return;
|
||||
// piCout << "init " << type();
|
||||
@@ -252,7 +251,7 @@ void PIEthernet::init() {
|
||||
applyBuffers();
|
||||
applyOptInt(IPPROTO_IP, IP_TTL, TTL());
|
||||
// piCoutObj << "inited" << path();
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -278,11 +277,11 @@ PIByteArray PIEthernet::macToBytes(const PIString & mac) {
|
||||
PIString PIEthernet::applyMask(const PIString & ip, const PIString & mask) {
|
||||
#ifdef EMSCRIPTEN
|
||||
return PIString();
|
||||
#else
|
||||
#else // EMSCRIPTEN
|
||||
struct in_addr ia;
|
||||
ia.s_addr = inet_addr(ip.dataAscii()) & inet_addr(mask.dataAscii());
|
||||
return PIStringAscii(inet_ntoa(ia));
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -296,11 +295,11 @@ PINetworkAddress PIEthernet::applyMask(const PINetworkAddress & ip, const PINetw
|
||||
PIString PIEthernet::getBroadcast(const PIString & ip, const PIString & mask) {
|
||||
#ifdef EMSCRIPTEN
|
||||
return PIString();
|
||||
#else
|
||||
#else // EMSCRIPTEN
|
||||
struct in_addr ia;
|
||||
ia.s_addr = inet_addr(ip.dataAscii()) | ~inet_addr(mask.dataAscii());
|
||||
return PIStringAscii(inet_ntoa(ia));
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -314,8 +313,7 @@ PINetworkAddress PIEthernet::getBroadcast(const PINetworkAddress & ip, const PIN
|
||||
bool PIEthernet::openDevice() {
|
||||
#ifdef EMSCRIPTEN
|
||||
return false;
|
||||
#endif
|
||||
#ifndef EMSCRIPTEN
|
||||
#else // EMSCRIPTEN
|
||||
if (connected_) return true;
|
||||
// piCoutObj << "open";
|
||||
init();
|
||||
@@ -335,7 +333,7 @@ bool PIEthernet::openDevice() {
|
||||
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
|
||||
# endif
|
||||
// piCout << "bind to" << (params[PIEthernet::Broadcast] ? "255.255.255.255" : ip_) << ":" << port_ << " ...";
|
||||
int tries = 0;
|
||||
int tries = 0;
|
||||
while ((bind(sock, (sockaddr *)&PRIVATE->addr_, sizeof(PRIVATE->addr_)) == -1) && (tries < 2)) {
|
||||
init();
|
||||
tries++;
|
||||
@@ -352,7 +350,7 @@ bool PIEthernet::openDevice() {
|
||||
applyOptInt(IPPROTO_IP, IP_TTL, TTL());
|
||||
addr_lr.clear();
|
||||
return true;
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -383,8 +381,7 @@ void PIEthernet::closeSocket(int & sd) {
|
||||
void PIEthernet::applyTimeouts() {
|
||||
#ifdef EMSCRIPTEN
|
||||
return;
|
||||
#endif
|
||||
#ifndef EMSCRIPTEN
|
||||
#else // EMSCRIPTEN
|
||||
if (sock < 0) return;
|
||||
PISystemTime rtm = readTimeout(), wtm = writeTimeout();
|
||||
applyTimeout(sock, SO_RCVTIMEO, rtm);
|
||||
@@ -393,7 +390,7 @@ void PIEthernet::applyTimeouts() {
|
||||
applyTimeout(sock_s, SO_RCVTIMEO, rtm);
|
||||
applyTimeout(sock_s, SO_SNDTIMEO, wtm);
|
||||
}
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -408,7 +405,7 @@ void PIEthernet::applyBuffers() {
|
||||
ethSetsockoptInt(sock, SOL_SOCKET, SO_SNDBUF, snd_buf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -416,9 +413,8 @@ void PIEthernet::applyTimeout(int fd, int opt, PISystemTime tm) {
|
||||
if (fd == 0) return;
|
||||
#ifdef EMSCRIPTEN
|
||||
return;
|
||||
#endif
|
||||
#ifndef EMSCRIPTEN
|
||||
// piCoutObj << "setReadIsBlocking" << yes;
|
||||
#else // EMSCRIPTEN
|
||||
// piCoutObj << "setReadIsBlocking" << yes;
|
||||
# ifdef WINDOWS
|
||||
DWORD _tm = tm.toMilliseconds();
|
||||
# else
|
||||
@@ -427,7 +423,7 @@ void PIEthernet::applyTimeout(int fd, int opt, PISystemTime tm) {
|
||||
_tm.tv_usec = tm.nanoseconds / 1000;
|
||||
# endif
|
||||
ethSetsockopt(fd, SOL_SOCKET, opt, &_tm, sizeof(_tm));
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -440,8 +436,7 @@ void PIEthernet::applyOptInt(int level, int opt, int val) {
|
||||
bool PIEthernet::joinMulticastGroup(const PIString & group) {
|
||||
#ifdef EMSCRIPTEN
|
||||
return false;
|
||||
#endif
|
||||
#ifndef EMSCRIPTEN
|
||||
#else // EMSCRIPTEN
|
||||
if (sock == -1) init();
|
||||
if (sock == -1) return false;
|
||||
if (type() != UDP) {
|
||||
@@ -490,15 +485,14 @@ bool PIEthernet::joinMulticastGroup(const PIString & group) {
|
||||
applyOptInt(IPPROTO_IP, IP_MULTICAST_TTL, multicastTTL());
|
||||
if (!mcast_groups.contains(group)) mcast_groups << group;
|
||||
return true;
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
bool PIEthernet::leaveMulticastGroup(const PIString & group) {
|
||||
#ifdef EMSCRIPTEN
|
||||
return false;
|
||||
#endif
|
||||
#ifndef EMSCRIPTEN
|
||||
#else // EMSCRIPTEN
|
||||
if (sock == -1) init();
|
||||
if (sock == -1) return false;
|
||||
if (type() != UDP) {
|
||||
@@ -531,15 +525,14 @@ bool PIEthernet::leaveMulticastGroup(const PIString & group) {
|
||||
}
|
||||
mcast_groups.removeAll(group);
|
||||
return true;
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
bool PIEthernet::connect(bool threaded) {
|
||||
#ifdef EMSCRIPTEN
|
||||
return false;
|
||||
#endif
|
||||
#ifndef EMSCRIPTEN
|
||||
#else // EMSCRIPTEN
|
||||
if (threaded) {
|
||||
connecting_ = true;
|
||||
return true;
|
||||
@@ -553,11 +546,11 @@ bool PIEthernet::connect(bool threaded) {
|
||||
PRIVATE->addr_.sin_addr.s_addr = addr_r.ip();
|
||||
PRIVATE->addr_.sin_family = AF_INET;
|
||||
# ifdef QNX
|
||||
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
|
||||
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
|
||||
# endif
|
||||
connecting_ = true;
|
||||
connected_ = connectTCP();
|
||||
connecting_ = false;
|
||||
connecting_ = true;
|
||||
connected_ = connectTCP();
|
||||
connecting_ = false;
|
||||
if (!connected_) {
|
||||
piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString();
|
||||
}
|
||||
@@ -566,15 +559,14 @@ bool PIEthernet::connect(bool threaded) {
|
||||
connected();
|
||||
}
|
||||
return connected_;
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
bool PIEthernet::listen(bool threaded) {
|
||||
#ifdef EMSCRIPTEN
|
||||
return false;
|
||||
#endif
|
||||
#ifndef EMSCRIPTEN
|
||||
#else // EMSCRIPTEN
|
||||
if (sock == -1) init();
|
||||
if (sock == -1) return false;
|
||||
if (threaded) {
|
||||
@@ -596,10 +588,10 @@ bool PIEthernet::listen(bool threaded) {
|
||||
PRIVATE->addr_.sin_addr.s_addr = addr_r.ip();
|
||||
PRIVATE->addr_.sin_family = AF_INET;
|
||||
# ifdef QNX
|
||||
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
|
||||
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
|
||||
# endif
|
||||
opened_ = false;
|
||||
int tries = 0;
|
||||
opened_ = false;
|
||||
int tries = 0;
|
||||
while ((bind(sock, (sockaddr *)&PRIVATE->addr_, sizeof(PRIVATE->addr_)) == -1) && (tries < 2)) {
|
||||
init();
|
||||
tries++;
|
||||
@@ -616,7 +608,7 @@ bool PIEthernet::listen(bool threaded) {
|
||||
piCoutObj << "listen on" << path();
|
||||
server_thread_.start(server_func);
|
||||
return true;
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -711,8 +703,7 @@ void PIEthernet::interrupt() {
|
||||
ssize_t PIEthernet::readDevice(void * read_to, ssize_t max_size) {
|
||||
#ifdef EMSCRIPTEN
|
||||
return -1;
|
||||
#endif
|
||||
#ifndef EMSCRIPTEN
|
||||
#else // EMSCRIPTEN
|
||||
// piCout << "read" << sock;
|
||||
if (sock == -1) init();
|
||||
if (sock == -1 || read_to == 0) return -1;
|
||||
@@ -727,10 +718,10 @@ ssize_t PIEthernet::readDevice(void * read_to, ssize_t max_size) {
|
||||
PRIVATE->addr_.sin_addr.s_addr = addr_r.ip();
|
||||
PRIVATE->addr_.sin_family = AF_INET;
|
||||
# ifdef QNX
|
||||
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
|
||||
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
|
||||
# endif
|
||||
// piCoutObj << "connect to " << path() << "...";
|
||||
connected_ = connectTCP();
|
||||
connected_ = connectTCP();
|
||||
// piCoutObj << "connect to " << path() << connected_;
|
||||
if (!connected_) piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString();
|
||||
opened_.exchange(connected_);
|
||||
@@ -838,15 +829,14 @@ ssize_t PIEthernet::readDevice(void * read_to, ssize_t max_size) {
|
||||
default: break;
|
||||
}
|
||||
return -1;
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
ssize_t PIEthernet::writeDevice(const void * data, ssize_t max_size) {
|
||||
#ifdef EMSCRIPTEN
|
||||
return -1;
|
||||
#endif
|
||||
#ifndef EMSCRIPTEN
|
||||
#else // EMSCRIPTEN
|
||||
if (sock == -1) init();
|
||||
if (sock == -1 || !isWriteable()) {
|
||||
// piCoutObj << "Can`t send to uninitialized socket";
|
||||
@@ -880,10 +870,10 @@ ssize_t PIEthernet::writeDevice(const void * data, ssize_t max_size) {
|
||||
PRIVATE->addr_.sin_addr.s_addr = addr_r.ip();
|
||||
PRIVATE->addr_.sin_family = AF_INET;
|
||||
# ifdef QNX
|
||||
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
|
||||
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
|
||||
# endif
|
||||
// piCoutObj << "connect to " << ip << ":" << port_;
|
||||
connected_ = connectTCP();
|
||||
connected_ = connectTCP();
|
||||
if (!connected_) piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString();
|
||||
opened_.exchange(connected_);
|
||||
if (connected_) {
|
||||
@@ -940,7 +930,7 @@ ssize_t PIEthernet::writeDevice(const void * data, ssize_t max_size) {
|
||||
default: break;
|
||||
}
|
||||
return -1;
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -961,7 +951,7 @@ void PIEthernet::applyParameters() {
|
||||
if (params[PIEthernet::ReuseAddress]) ethSetsockoptBool(sock, SOL_SOCKET, SO_REUSEADDR);
|
||||
if (params[PIEthernet::Broadcast]) ethSetsockoptBool(sock, SOL_SOCKET, SO_BROADCAST);
|
||||
if (params[PIEthernet::NoDelay] && (type() == TCP_Client)) ethSetsockoptBool(sock, IPPROTO_TCP, TCP_NODELAY, true);
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -974,8 +964,7 @@ void PIEthernet::clientDeleted(PIObject * o) {
|
||||
void PIEthernet::server_func(void * eth) {
|
||||
#ifdef EMSCRIPTEN
|
||||
return;
|
||||
#endif
|
||||
#ifndef EMSCRIPTEN
|
||||
#else // EMSCRIPTEN
|
||||
PIEthernet * ce = (PIEthernet *)eth;
|
||||
if (ce->listen_threaded) {
|
||||
if (!ce->server_bounded) {
|
||||
@@ -989,7 +978,7 @@ void PIEthernet::server_func(void * eth) {
|
||||
sockaddr_in client_addr;
|
||||
socklen_t slen = sizeof(client_addr);
|
||||
# ifdef WINDOWS
|
||||
long wr = ce->waitForEvent(ce->PRIVATEWB->event, FD_ACCEPT | FD_CLOSE);
|
||||
long wr = ce->waitForEvent(ce->PRIVATEWB->event, FD_ACCEPT | FD_CLOSE);
|
||||
if (wr != FD_ACCEPT) {
|
||||
piMSleep(10);
|
||||
return;
|
||||
@@ -1030,7 +1019,7 @@ void PIEthernet::server_func(void * eth) {
|
||||
ce->clients_mutex.unlock();
|
||||
ce->newConnection(e);
|
||||
// cout << "connected " << ip << endl;
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -1048,8 +1037,7 @@ void PIEthernet::setType(Type t, bool reopen) {
|
||||
bool PIEthernet::connectTCP() {
|
||||
#ifdef EMSCRIPTEN
|
||||
return false;
|
||||
#endif
|
||||
#ifndef EMSCRIPTEN
|
||||
#else // EMSCRIPTEN
|
||||
::connect(sock, (sockaddr *)&(PRIVATE->addr_), sizeof(PRIVATE->addr_));
|
||||
// piCout << errorString();
|
||||
# ifdef WINDOWS
|
||||
@@ -1071,7 +1059,7 @@ bool PIEthernet::connectTCP() {
|
||||
}
|
||||
# endif
|
||||
return false;
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -1109,13 +1097,12 @@ bool PIEthernet::configureDevice(const void * e_main, const void * e_parent) {
|
||||
void PIEthernet::propertyChanged(const char * name) {
|
||||
#ifdef EMSCRIPTEN
|
||||
return;
|
||||
#endif
|
||||
#ifndef EMSCRIPTEN
|
||||
#else // EMSCRIPTEN
|
||||
PIConstChars pn(name);
|
||||
if (pn.endsWith("Timeout")) applyTimeouts();
|
||||
if (pn == "TTL") applyOptInt(IPPROTO_IP, IP_TTL, TTL());
|
||||
if (pn == "MulticastTTL") applyOptInt(IPPROTO_IP, IP_MULTICAST_TTL, multicastTTL());
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -1204,13 +1191,13 @@ void PIEthernet::configureFromVariantDevice(const PIPropertyStorage & d) {
|
||||
PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
#ifdef EMSCRIPTEN
|
||||
return {};
|
||||
#endif
|
||||
#else // EMSCRIPTEN
|
||||
// piCout << "PIEthernet::interfaces()";
|
||||
PIEthernet::InterfaceList il;
|
||||
Interface ci;
|
||||
ci.index = -1;
|
||||
ci.mtu = 1500;
|
||||
#ifdef WINDOWS
|
||||
ci.index = -1;
|
||||
ci.mtu = 1500;
|
||||
# ifdef WINDOWS
|
||||
int ret = 0;
|
||||
ulong ulOutBufLen = sizeof(IP_ADAPTER_INFO);
|
||||
PIP_ADAPTER_INFO pAdapterInfo = (PIP_ADAPTER_INFO)HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO));
|
||||
@@ -1261,10 +1248,10 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
}
|
||||
}
|
||||
if (pAdapterInfo) HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
#elif !defined(EMSCRIPTEN)
|
||||
# ifdef MICRO_PIP
|
||||
# else
|
||||
# ifdef ANDROID
|
||||
# else // WINDOWS
|
||||
# ifdef MICRO_PIP
|
||||
# else
|
||||
# ifdef ANDROID
|
||||
struct ifconf ifc;
|
||||
int s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
||||
if (s == -1) {
|
||||
@@ -1301,7 +1288,7 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
}
|
||||
delete[] ifc.ifc_buf;
|
||||
::close(s);
|
||||
# else
|
||||
# else
|
||||
struct ifaddrs *ret, *cif = 0;
|
||||
int s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
||||
if (getifaddrs(&ret) == 0) {
|
||||
@@ -1319,8 +1306,8 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
ci.address = getSockAddr(cif->ifa_addr);
|
||||
ci.netmask = getSockAddr(cif->ifa_netmask);
|
||||
ci.mac.clear();
|
||||
# ifdef QNX
|
||||
# ifndef BLACKBERRY
|
||||
# ifdef QNX
|
||||
# ifndef BLACKBERRY
|
||||
int fd = ::open((PIString("/dev/io-net/") + ci.name).dataAscii(), O_RDONLY);
|
||||
if (fd >= 0) {
|
||||
nic_config_t nic;
|
||||
@@ -1328,9 +1315,9 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
::close(fd);
|
||||
ci.mac = macFromBytes(PIByteArray(nic.permanent_address, 6));
|
||||
}
|
||||
# endif
|
||||
# else
|
||||
# ifdef MAC_OS
|
||||
# endif
|
||||
# else
|
||||
# ifdef MAC_OS
|
||||
PIString req = PISystemInfo::instance()->ifconfigPath + " " + ci.name + " | grep ether";
|
||||
FILE * fp = popen(req.dataAscii(), "r");
|
||||
if (fp != 0) {
|
||||
@@ -1341,7 +1328,7 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
}
|
||||
pclose(fp);
|
||||
}
|
||||
# else
|
||||
# else
|
||||
if (s != -1) {
|
||||
struct ifreq ir;
|
||||
memset(&ir, 0, sizeof(ir));
|
||||
@@ -1353,8 +1340,8 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
ci.mtu = ir.ifr_mtu;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
ci.flags = 0;
|
||||
if (cif->ifa_flags & IFF_UP) ci.flags |= PIEthernet::ifActive;
|
||||
if (cif->ifa_flags & IFF_RUNNING) ci.flags |= PIEthernet::ifRunning;
|
||||
@@ -1375,10 +1362,11 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
piCout << "[PIEthernet]"
|
||||
<< "Can`t get interfaces: %1"_tr("PIEthernet").arg(errorString());
|
||||
if (s != -1) ::close(s);
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
# endif // WINDOWS
|
||||
return il;
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -1397,7 +1385,7 @@ PINetworkAddress PIEthernet::interfaceAddress(const PIString & interface_) {
|
||||
}
|
||||
struct sockaddr_in * sa = (struct sockaddr_in *)&ifr.ifr_addr;
|
||||
return PINetworkAddress(uint(sa->sin_addr.s_addr));
|
||||
#endif
|
||||
#endif // WINDOWS, MICRO_PIP, EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -1422,11 +1410,13 @@ PIVector<PINetworkAddress> PIEthernet::allAddresses() {
|
||||
int PIEthernet::ethErrorCore() {
|
||||
#ifdef WINDOWS
|
||||
return WSAGetLastError();
|
||||
#elif !defined(EMSCRIPTEN)
|
||||
return errno;
|
||||
#else
|
||||
#else // WINDOWS
|
||||
# ifdef EMSCRIPTEN
|
||||
return -1;
|
||||
#endif
|
||||
# else // EMSCRIPTEN
|
||||
return errno;
|
||||
# endif // EMSCRIPTEN
|
||||
#endif // WINDOWS
|
||||
}
|
||||
|
||||
|
||||
@@ -1448,11 +1438,13 @@ PIString PIEthernet::ethErrorString() {
|
||||
} else
|
||||
ret += '?';
|
||||
return ret;
|
||||
#elif !defined(EMSCRIPTEN)
|
||||
return errorString();
|
||||
#else
|
||||
#else // WINDOWS
|
||||
# ifdef EMSCRIPTEN
|
||||
return PIString();
|
||||
#endif
|
||||
# else // EMSCRIPTEN
|
||||
return errorString();
|
||||
# endif // EMSCRIPTEN
|
||||
#endif // WINDOWS
|
||||
}
|
||||
|
||||
|
||||
@@ -1460,8 +1452,7 @@ int PIEthernet::ethRecv(int sock, void * buf, int size, int flags) {
|
||||
if (sock < 0) return -1;
|
||||
#ifdef EMSCRIPTEN
|
||||
return -1;
|
||||
#endif
|
||||
#ifndef EMSCRIPTEN
|
||||
#else // EMSCRIPTEN
|
||||
return recv(sock,
|
||||
# ifdef WINDOWS
|
||||
(char *)
|
||||
@@ -1469,7 +1460,7 @@ int PIEthernet::ethRecv(int sock, void * buf, int size, int flags) {
|
||||
buf,
|
||||
size,
|
||||
flags);
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -1477,8 +1468,7 @@ int PIEthernet::ethRecvfrom(int sock, void * buf, int size, int flags, sockaddr
|
||||
if (sock < 0) return -1;
|
||||
#ifdef EMSCRIPTEN
|
||||
return -1;
|
||||
#endif
|
||||
#ifndef EMSCRIPTEN
|
||||
#else // EMSCRIPTEN
|
||||
# ifdef QNX
|
||||
return recv(sock, buf, size, flags);
|
||||
# else
|
||||
@@ -1493,7 +1483,7 @@ int PIEthernet::ethRecvfrom(int sock, void * buf, int size, int flags, sockaddr
|
||||
addr,
|
||||
&len);
|
||||
# endif
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -1501,8 +1491,7 @@ int PIEthernet::ethSendto(int sock, const void * buf, int size, int flags, socka
|
||||
if (sock < 0) return -1;
|
||||
#ifdef EMSCRIPTEN
|
||||
return -1;
|
||||
#endif
|
||||
#ifndef EMSCRIPTEN
|
||||
#else // EMSCRIPTEN
|
||||
return sendto(sock,
|
||||
# ifdef WINDOWS
|
||||
(const char *)
|
||||
@@ -1512,15 +1501,14 @@ int PIEthernet::ethSendto(int sock, const void * buf, int size, int flags, socka
|
||||
flags,
|
||||
addr,
|
||||
addr_len);
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
void PIEthernet::ethClosesocket(int sock, bool shutdown) {
|
||||
#ifdef EMSCRIPTEN
|
||||
return;
|
||||
#endif
|
||||
#ifndef EMSCRIPTEN
|
||||
#else // EMSCRIPTEN
|
||||
// piCout << "close socket" << sock << shutdown;
|
||||
if (sock < 0) return;
|
||||
if (shutdown)
|
||||
@@ -1532,7 +1520,7 @@ void PIEthernet::ethClosesocket(int sock, bool shutdown) {
|
||||
SHUT_RDWR);
|
||||
::close(sock);
|
||||
# endif
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -1540,8 +1528,7 @@ int PIEthernet::ethSetsockopt(int sock, int level, int optname, const void * opt
|
||||
if (sock < 0) return -1;
|
||||
#ifdef EMSCRIPTEN
|
||||
return -1;
|
||||
#endif
|
||||
#ifndef EMSCRIPTEN
|
||||
#else // EMSCRIPTEN
|
||||
auto ret = setsockopt(sock,
|
||||
level,
|
||||
optname,
|
||||
@@ -1552,7 +1539,7 @@ int PIEthernet::ethSetsockopt(int sock, int level, int optname, const void * opt
|
||||
optlen);
|
||||
if (ret != 0) piCout << "setsockopt error:" << ethErrorString();
|
||||
return ret;
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -1585,16 +1572,19 @@ void PIEthernet::ethNonblocking(int sock) {
|
||||
#ifdef WINDOWS
|
||||
u_long mode = 1;
|
||||
ioctlsocket(sock, FIONBIO, &mode);
|
||||
#elif !defined(EMSCRIPTEN)
|
||||
#else // WINDOWS
|
||||
# ifdef EMSCRIPTEN
|
||||
# else // EMSCRIPTEN
|
||||
fcntl(sock, F_SETFL, O_NONBLOCK);
|
||||
#endif
|
||||
# endif // EMSCRIPTEN
|
||||
#endif // WINDOWS
|
||||
}
|
||||
|
||||
|
||||
bool PIEthernet::ethIsWriteable(int sock) {
|
||||
#ifdef EMSCRIPTEN
|
||||
return false;
|
||||
#endif
|
||||
#else // EMSCRIPTEN
|
||||
/* fd_set fd_test;
|
||||
FD_ZERO(&fd_test);
|
||||
FD_SET(sock, &fd_test);
|
||||
@@ -1606,7 +1596,7 @@ bool PIEthernet::ethIsWriteable(int sock) {
|
||||
timeout.tv_sec = timeout.tv_usec = 0;
|
||||
::select(fds, nullptr, &fd_test, nullptr, &timeout);
|
||||
return FD_ISSET(sock, &fd_test);*/
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
fd_set fd_test;
|
||||
FD_ZERO(&fd_test);
|
||||
FD_SET(sock, &fd_test);
|
||||
@@ -1614,10 +1604,11 @@ bool PIEthernet::ethIsWriteable(int sock) {
|
||||
timeout.tv_sec = timeout.tv_usec = 0;
|
||||
::select(0, nullptr, &fd_test, nullptr, &timeout);
|
||||
return FD_ISSET(sock, &fd_test);
|
||||
#elif !defined(EMSCRIPTEN)
|
||||
# else // WINDOWS
|
||||
int ret = 0;
|
||||
socklen_t len = sizeof(ret);
|
||||
getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&ret, &len);
|
||||
return ret == 0;
|
||||
#endif
|
||||
# endif // WINDOWS
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
# include <fcntl.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <termios.h>
|
||||
# endif
|
||||
# endif // EMSCRIPTEN
|
||||
# ifndef B50
|
||||
# define B50 0000001
|
||||
# endif
|
||||
@@ -176,7 +176,7 @@
|
||||
#endif
|
||||
#if defined(LINUX) && !defined(EMSCRIPTEN)
|
||||
# include <linux/serial.h>
|
||||
#endif
|
||||
#endif // LINUX && !EMSCRIPTEN
|
||||
|
||||
|
||||
//! \class PISerial piserial.h
|
||||
@@ -218,10 +218,13 @@ PRIVATE_DEFINITION_START(PISerial)
|
||||
HANDLE hCom = nullptr;
|
||||
DWORD readed = 0, mask = 0;
|
||||
OVERLAPPED overlap, overlap_write;
|
||||
#elif !defined(EMSCRIPTEN)
|
||||
#else // WINDOWS
|
||||
# ifdef EMSCRIPTEN
|
||||
# else // EMSCRIPTEN
|
||||
termios desc, sdesc;
|
||||
uint readed = 0;
|
||||
#endif
|
||||
# endif // EMSCRIPTEN
|
||||
#endif // WINDOWS
|
||||
PRIVATE_DEFINITION_END(PISerial)
|
||||
|
||||
|
||||
@@ -398,14 +401,17 @@ bool PISerial::setBreak(bool enabled) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#elif !defined(EMSCRIPTEN)
|
||||
#else // WINDOWS
|
||||
# ifdef EMSCRIPTEN
|
||||
# else // EMSCRIPTEN
|
||||
if (ioctl(fd, enabled ? TIOCSBRK : TIOCCBRK) < 0) {
|
||||
piCoutObj << "setBreak error: " << errorString();
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
# endif // EMSCRIPTEN
|
||||
#endif // WINDOWS
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -427,13 +433,16 @@ bool PISerial::setBit(int bit, bool on, const PIString & bname) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
# elif !defined(EMSCRIPTEN)
|
||||
# else // WINDOWS
|
||||
# ifdef EMSCRIPTEN
|
||||
# else // EMSCRIPTEN
|
||||
if (ioctl(fd, on ? TIOCMBIS : TIOCMBIC, &bit) < 0) {
|
||||
piCoutObj << "setBit" << bname << " error: " << errorString();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
# endif
|
||||
# endif // EMSCRIPTEN
|
||||
# endif // WINDOWS
|
||||
#endif
|
||||
piCoutObj << "setBit" << bname << " doesn`t implemented, sorry :-(";
|
||||
return false;
|
||||
@@ -447,11 +456,14 @@ bool PISerial::isBit(int bit, const PIString & bname) const {
|
||||
}
|
||||
#ifndef PISERIAL_NO_PINS
|
||||
# ifdef WINDOWS
|
||||
# elif !defined(EMSCRIPTEN)
|
||||
# else // WINDOWS
|
||||
# ifdef EMSCRIPTEN
|
||||
# else // EMSCRIPTEN
|
||||
int ret = 0;
|
||||
if (ioctl(fd, TIOCMGET, &ret) < 0) piCoutObj << "isBit" << bname << " error: " << errorString();
|
||||
return ret & bit;
|
||||
# endif
|
||||
# endif // EMSCRIPTEN
|
||||
# endif // WINDOWS
|
||||
#endif
|
||||
piCoutObj << "isBit" << bname << " doesn`t implemented, sorry :-(";
|
||||
return false;
|
||||
@@ -461,7 +473,7 @@ bool PISerial::isBit(int bit, const PIString & bname) const {
|
||||
void PISerial::flush() {
|
||||
#if !defined(WINDOWS) && !defined(EMSCRIPTEN)
|
||||
if (fd != -1) tcflush(fd, TCIOFLUSH);
|
||||
#endif
|
||||
#endif // WINDOWS && EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -752,7 +764,9 @@ bool PISerial::openDevice() {
|
||||
return false;
|
||||
}
|
||||
fd = 0;
|
||||
#elif !defined(EMSCRIPTEN)
|
||||
#else // WINDOWS
|
||||
# ifdef EMSCRIPTEN
|
||||
# else // EMSCRIPTEN
|
||||
int om = 0;
|
||||
switch (mode()) {
|
||||
case PIIODevice::ReadOnly: om = O_RDONLY; break;
|
||||
@@ -767,7 +781,8 @@ bool PISerial::openDevice() {
|
||||
tcgetattr(fd, &PRIVATE->desc);
|
||||
PRIVATE->sdesc = PRIVATE->desc;
|
||||
// piCoutObj << "Initialized " << p;
|
||||
#endif
|
||||
# endif // EMSCRIPTEN
|
||||
#endif // WINDOWS
|
||||
applySettings();
|
||||
PRIVATE->event.create();
|
||||
#ifdef WINDOWS
|
||||
@@ -789,10 +804,13 @@ bool PISerial::closeDevice() {
|
||||
// piCoutObj << "close" <<
|
||||
CloseHandle(PRIVATE->hCom);
|
||||
PRIVATE->hCom = 0;
|
||||
#elif !defined(EMSCRIPTEN)
|
||||
#else // WINDOWS
|
||||
# ifdef EMSCRIPTEN
|
||||
# else // EMSCRIPTEN
|
||||
tcsetattr(fd, TCSANOW, &PRIVATE->sdesc);
|
||||
::close(fd);
|
||||
#endif
|
||||
# endif // EMSCRIPTEN
|
||||
#endif // WINDOWS
|
||||
fd = -1;
|
||||
}
|
||||
PRIVATE->event.destroy();
|
||||
@@ -830,7 +848,9 @@ void PISerial::applySettings() {
|
||||
piCoutObj << "Unable to set comm state for \"%1\""_tr("PISerial").arg(path());
|
||||
return;
|
||||
}
|
||||
#elif !defined(EMSCRIPTEN)
|
||||
#else // WINDOWS
|
||||
# ifdef EMSCRIPTEN
|
||||
# else // EMSCRIPTEN
|
||||
if (fd == -1) return;
|
||||
tcgetattr(fd, &PRIVATE->desc);
|
||||
PRIVATE->desc.c_oflag = PRIVATE->desc.c_lflag = PRIVATE->desc.c_cflag = 0;
|
||||
@@ -864,7 +884,8 @@ void PISerial::applySettings() {
|
||||
piCoutObj << "Can`t set attributes for \"%1\""_tr("PISerial").arg(path());
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
# endif // EMSCRIPTEN
|
||||
#endif // WINDOWS
|
||||
}
|
||||
|
||||
|
||||
@@ -883,9 +904,12 @@ void PISerial::setTimeouts() {
|
||||
times.WriteTotalTimeoutConstant = isOptionSet(BlockingWrite) ? 0 : 1;
|
||||
times.WriteTotalTimeoutMultiplier = 0;
|
||||
if (SetCommTimeouts(PRIVATE->hCom, ×) == -1) piCoutObj << "Unable to set timeouts for \"" << path() << "\"";
|
||||
#elif !defined(EMSCRIPTEN)
|
||||
#else // WINDOWS
|
||||
# ifdef EMSCRIPTEN
|
||||
# else // EMSCRIPTEN
|
||||
fcntl(fd, F_SETFL, isOptionSet(BlockingRead) ? 0 : O_NONBLOCK);
|
||||
#endif
|
||||
# endif // EMSCRIPTEN
|
||||
#endif // WINDOWS
|
||||
}
|
||||
|
||||
|
||||
@@ -934,7 +958,10 @@ ssize_t PISerial::readDevice(void * read_to, ssize_t max_size) {
|
||||
return -1;
|
||||
// piCoutObj << "read" << (PRIVATE->readed) << errorString();
|
||||
return PRIVATE->readed;
|
||||
#elif !defined(EMSCRIPTEN)
|
||||
#else // WINDOWS
|
||||
# ifdef EMSCRIPTEN
|
||||
return -1;
|
||||
# else // EMSCRIPTEN
|
||||
if (!canRead()) return -1;
|
||||
if (isOptionSet(PIIODevice::BlockingRead)) {
|
||||
if (!PRIVATE->event.wait(fd)) return -1;
|
||||
@@ -949,9 +976,8 @@ ssize_t PISerial::readDevice(void * read_to, ssize_t max_size) {
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
# endif // EMSCRIPTEN
|
||||
#endif // WINDOWS
|
||||
}
|
||||
|
||||
|
||||
@@ -974,12 +1000,14 @@ ssize_t PISerial::writeDevice(const void * data, ssize_t max_size) {
|
||||
sending = false;
|
||||
// piCoutObj << "send ok" << dwrote;// << " bytes in " << path();
|
||||
wrote = (ssize_t)dwrote;
|
||||
#elif !defined(EMSCRIPTEN)
|
||||
#else // WINDOWS
|
||||
# ifdef EMSCRIPTEN
|
||||
return -1;
|
||||
# else // EMSCRIPTEN
|
||||
wrote = ::write(fd, data, max_size);
|
||||
if (isOptionSet(BlockingWrite)) tcdrain(fd);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
# endif // EMSCRIPTEN
|
||||
#endif // WINDOWS
|
||||
return wrote;
|
||||
// piCoutObj << "Error while sending";
|
||||
}
|
||||
@@ -1196,10 +1224,10 @@ bool parseID(PIString str, PISerial::DeviceInfo & di) {
|
||||
PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
||||
#ifdef EMSCRIPTEN
|
||||
return {};
|
||||
#endif
|
||||
#else // EMSCRIPTEN
|
||||
PIVector<DeviceInfo> ret;
|
||||
DeviceInfo di;
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
static const GUID guids[] = {GUID_DEVINTERFACE_MODEM, GUID_DEVINTERFACE_COMPORT};
|
||||
static const int guids_cnt = sizeof(guids) / sizeof(GUID);
|
||||
for (int i = 0; i < guids_cnt; ++i) {
|
||||
@@ -1228,12 +1256,12 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
||||
}
|
||||
SetupDiDestroyDeviceInfoList(dis);
|
||||
}
|
||||
#elif !defined(EMSCRIPTEN)
|
||||
# ifndef ANDROID
|
||||
# else // WINDOWS
|
||||
# ifndef ANDROID
|
||||
PIStringList prefixes;
|
||||
# ifdef QNX
|
||||
# ifdef QNX
|
||||
prefixes << "ser";
|
||||
# else
|
||||
# else
|
||||
prefixes << "ttyS"
|
||||
<< "ttyO"
|
||||
<< "ttyUSB"
|
||||
@@ -1244,14 +1272,14 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
||||
<< "ttyAMA"
|
||||
<< "rfcomm"
|
||||
<< "ircomm";
|
||||
# ifdef FREE_BSD
|
||||
# ifdef FREE_BSD
|
||||
prefixes << "cu";
|
||||
# endif
|
||||
# ifdef MAC_OS
|
||||
# endif
|
||||
# ifdef MAC_OS
|
||||
prefixes.clear();
|
||||
prefixes << "cu."
|
||||
<< "tty.";
|
||||
# endif
|
||||
# endif
|
||||
PIFile file_prefixes("/proc/tty/drivers", PIIODevice::ReadOnly);
|
||||
if (file_prefixes.open()) {
|
||||
PIString fc = PIString::fromAscii(file_prefixes.readAll()), line, cpref;
|
||||
@@ -1272,18 +1300,18 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
||||
}
|
||||
prefixes.removeDuplicates();
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
PIDir dir("/dev");
|
||||
PIVector<PIFile::FileInfo> de = dir.entries();
|
||||
# ifdef LINUX
|
||||
# ifdef LINUX
|
||||
char linkbuf[1024];
|
||||
# endif
|
||||
# endif
|
||||
for (const auto & e: de) { // TODO changes in FileInfo
|
||||
for (const auto & p: prefixes) {
|
||||
if (e.name().startsWith(p)) {
|
||||
di = DeviceInfo();
|
||||
di.path = e.path;
|
||||
# ifdef LINUX
|
||||
# ifdef LINUX
|
||||
ssize_t lsz = readlink(("/sys/class/tty/" + e.name()).dataAscii(), linkbuf, 1024);
|
||||
if (lsz > 0) {
|
||||
PIString fpath = "/sys/class/tty/" + PIString(linkbuf, lsz) + "/";
|
||||
@@ -1299,16 +1327,16 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
||||
if (di.pID > 0) break;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
ret << di;
|
||||
}
|
||||
}
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
# endif
|
||||
# endif // WINDOWS
|
||||
if (test) {
|
||||
for (int i = 0; i < ret.size_s(); ++i) {
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
void * hComm = CreateFileA(ret[i].path.dataAscii(),
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
@@ -1329,7 +1357,7 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
||||
continue;
|
||||
}
|
||||
CloseHandle(hComm);
|
||||
#elif !defined(EMSCRIPTEN)
|
||||
# else // WINDOWS
|
||||
int fd = ::open(ret[i].path.dataAscii(), O_NOCTTY | O_RDONLY);
|
||||
if (fd == -1) {
|
||||
ret.remove(i);
|
||||
@@ -1347,10 +1375,11 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
||||
continue;
|
||||
}
|
||||
::close(fd);
|
||||
#endif
|
||||
# endif // WINDOWS
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -1368,5 +1397,5 @@ void PISerial::threadedReadBufferSizeChanged() {
|
||||
ss.xmit_fifo_size = piMaxi(threadedReadBufferSize(), 4096);
|
||||
ioctl(fd, TIOCSSERIAL, &ss);
|
||||
// piCoutObj << "a" << ss.xmit_fifo_size;
|
||||
#endif
|
||||
#endif // LINUX && !EMSCRIPTEN
|
||||
}
|
||||
|
||||
@@ -98,10 +98,10 @@ PISharedMemory::~PISharedMemory() {
|
||||
bool PISharedMemory::openDevice() {
|
||||
#ifdef EMSCRIPTEN
|
||||
return false;
|
||||
#endif
|
||||
#else // EMSCRIPTEN
|
||||
close();
|
||||
// piCoutObj << "try open" << path() << dsize;
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
PRIVATE->name = ("PIP_SHM_" + path()).toByteArray();
|
||||
PRIVATE->name.push_back(0);
|
||||
const char * nm = (const char *)PRIVATE->name.data();
|
||||
@@ -122,8 +122,8 @@ bool PISharedMemory::openDevice() {
|
||||
return false;
|
||||
}
|
||||
// piCout << PRIVATE->map << PRIVATE->data;
|
||||
#endif
|
||||
#ifdef SHM_POSIX
|
||||
# endif
|
||||
# ifdef SHM_POSIX
|
||||
PRIVATE->name = ("/pip_shm_" + path()).toByteArray();
|
||||
PRIVATE->name.push_back(0);
|
||||
int fd = shm_open((const char *)PRIVATE->name.data(), O_RDWR, 0777);
|
||||
@@ -153,8 +153,9 @@ bool PISharedMemory::openDevice() {
|
||||
return false;
|
||||
}
|
||||
// piCoutObj << "opened" << PRIVATE->data;
|
||||
#endif
|
||||
# endif
|
||||
return true;
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -226,17 +227,18 @@ void PISharedMemory::initPrivate() {
|
||||
PIByteArray PISharedMemory::readAll() {
|
||||
#ifdef EMSCRIPTEN
|
||||
return PIByteArray();
|
||||
#endif
|
||||
#else // EMSCRIPTEN
|
||||
if (dsize <= 0) return PIByteArray();
|
||||
#ifdef WINDOWS
|
||||
# ifdef WINDOWS
|
||||
if (!PRIVATE->data) return PIByteArray();
|
||||
#endif
|
||||
#ifdef SHM_POSIX
|
||||
# endif
|
||||
# ifdef SHM_POSIX
|
||||
if (!PRIVATE->data) return PIByteArray();
|
||||
#endif
|
||||
# endif
|
||||
PIByteArray a(dsize);
|
||||
read(a.data(), a.size_s());
|
||||
return a;
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -168,7 +168,8 @@ inline double pow10(const double & e) {return pow (10. , e);}
|
||||
//! \~english Returns `10` raised to the specified power.
|
||||
//! \~russian Возвращает `10` в указанной степени.
|
||||
inline ldouble pow10(const ldouble & e) {return powl(10.L, e);}
|
||||
#endif
|
||||
#else //EMSCRIPTEN
|
||||
#endif //EMSCRIPTEN
|
||||
// clang-format on
|
||||
|
||||
|
||||
|
||||
@@ -76,16 +76,10 @@
|
||||
|
||||
//! \~\ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english Defined for Emscripten/WASM targets.
|
||||
//! \~russian Определяется для целевых сборок Emscripten/WASM.
|
||||
//! \~english Defined for Emscripten targets.
|
||||
//! \~russian Определяется для целевых сборок Emscripten.
|
||||
# define EMSCRIPTEN
|
||||
|
||||
//! \~\ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english Defined for WebAssembly targets.
|
||||
//! \~russian Определяется для целевых сборок WebAssembly.
|
||||
# define WASM
|
||||
|
||||
//! \~\ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english Defined for reduced embedded PIP builds.
|
||||
@@ -170,7 +164,6 @@
|
||||
#endif
|
||||
#ifdef __EMSCRIPTEN__
|
||||
# define EMSCRIPTEN
|
||||
# define WASM
|
||||
# ifdef __wasm64__
|
||||
# define ARCH_BITS_64
|
||||
# else
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
#include "piliterals_string.h"
|
||||
#include "piliterals_time.h"
|
||||
#ifndef EMSCRIPTEN
|
||||
#ifdef EMSCRIPTEN
|
||||
#else // EMSCRIPTEN
|
||||
# ifndef WINDOWS
|
||||
# include "pidir.h"
|
||||
# include "pifile.h"
|
||||
@@ -25,7 +26,7 @@ extern "C" {
|
||||
}
|
||||
// clang-format on
|
||||
# endif
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
|
||||
|
||||
bool PIHIDeviceInfo::match(const PIString & str) const {
|
||||
@@ -63,15 +64,17 @@ void PIHIDeviceInfo::prepare() {
|
||||
|
||||
PICout operator<<(PICout s, const PIHIDeviceInfo & v) {
|
||||
s.saveAndSetControls(0);
|
||||
s << "PIHIDeviceInfo(" << v.product << " (" << v.manufacturer << "), " << v.VID << ":" << v.PID << ", " << v.axesAbsoluteCount()
|
||||
<< " abs axes, " << v.axesRelativeCount() << " rel axes, " << v.buttonsCount() << " buttons)";
|
||||
s << "PIHIDeviceInfo(" << v.product << " (" << v.manufacturer << "), " << v.VID << ":" << v.PID
|
||||
<< ", " //<< "path \"" << v.path << "\", "
|
||||
<< v.axesAbsoluteCount() << " abs axes, " << v.axesRelativeCount() << " rel axes, " << v.buttonsCount() << " buttons)";
|
||||
s.restoreControls();
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
PRIVATE_DEFINITION_START(PIHIDevice)
|
||||
#ifndef EMSCRIPTEN
|
||||
#ifdef EMSCRIPTEN
|
||||
#else // EMSCRIPTEN
|
||||
# ifndef WINDOWS
|
||||
PIFile file;
|
||||
bool is_js = false;
|
||||
@@ -80,7 +83,7 @@ PRIVATE_DEFINITION_START(PIHIDevice)
|
||||
HANDLE deviceHandle = nullptr;
|
||||
PHIDP_PREPARSED_DATA preparsed = nullptr;
|
||||
# endif
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
PRIVATE_DEFINITION_END(PIHIDevice)
|
||||
|
||||
|
||||
@@ -91,13 +94,13 @@ PIHIDevice::~PIHIDevice() {
|
||||
bool PIHIDevice::isOpened() const {
|
||||
#ifdef EMSCRIPTEN
|
||||
return false;
|
||||
#else
|
||||
#else // EMSCRIPTEN
|
||||
# ifndef WINDOWS
|
||||
return PRIVATE->file.isOpened();
|
||||
# else
|
||||
return PRIVATE->deviceHandle;
|
||||
# endif
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +113,7 @@ bool PIHIDevice::open(const PIHIDeviceInfo & device) {
|
||||
if (device.isNull()) return false;
|
||||
#ifdef EMSCRIPTEN
|
||||
return false;
|
||||
#else
|
||||
#else // EMSCRIPTEN
|
||||
# ifndef WINDOWS
|
||||
if (!PRIVATE->file.open(di.path, PIIODevice::ReadOnly)) {
|
||||
piCout << "PIHIDevice::open" << di.path << "error:" << errorString();
|
||||
@@ -138,7 +141,7 @@ bool PIHIDevice::open(const PIHIDeviceInfo & device) {
|
||||
}
|
||||
return true;
|
||||
# endif
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -151,7 +154,7 @@ void PIHIDevice::close() {
|
||||
stop();
|
||||
#ifdef EMSCRIPTEN
|
||||
return;
|
||||
#else
|
||||
#else // EMSCRIPTEN
|
||||
# ifndef WINDOWS
|
||||
PRIVATE->file.close();
|
||||
# else
|
||||
@@ -164,13 +167,16 @@ void PIHIDevice::close() {
|
||||
PRIVATE->preparsed = nullptr;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
void PIHIDevice::start() {
|
||||
if (!isOpened()) return;
|
||||
PIThread::start(200_Hz);
|
||||
#ifndef WINDOWS
|
||||
#else // WINDOWS
|
||||
#endif // WINDOWS
|
||||
}
|
||||
|
||||
|
||||
@@ -188,7 +194,7 @@ void PIHIDevice::stop() {
|
||||
void PIHIDevice::run() {
|
||||
#ifdef EMSCRIPTEN
|
||||
return;
|
||||
#else
|
||||
#else // EMSCRIPTEN
|
||||
Event e;
|
||||
# ifndef WINDOWS
|
||||
# pragma pack(push, 1)
|
||||
@@ -199,10 +205,10 @@ void PIHIDevice::run() {
|
||||
uint value;
|
||||
};
|
||||
struct js_event {
|
||||
uint time;
|
||||
short value;
|
||||
uchar type;
|
||||
uchar number;
|
||||
uint time; /* event timestamp in milliseconds */
|
||||
short value; /* value */
|
||||
uchar type; /* event type */
|
||||
uchar number; /* axis/button number */
|
||||
};
|
||||
# pragma pack(pop)
|
||||
if (PRIVATE->is_js) {
|
||||
@@ -212,15 +218,18 @@ void PIHIDevice::run() {
|
||||
bool ok = false;
|
||||
switch (ie.type) {
|
||||
case 2: {
|
||||
// piCout << ie.value;
|
||||
cur_axes[ie.number] = procDeadZone(ie.value / 32767. / 2. + 0.5);
|
||||
ok = true;
|
||||
} break;
|
||||
case 1:
|
||||
// piCout << ie.code;
|
||||
cur_buttons[ie.number] = ie.value;
|
||||
ok = true;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
// piCout << ok << ie.type << ie.code << ie.value;
|
||||
if (!ok) continue;
|
||||
}
|
||||
} else {
|
||||
@@ -229,7 +238,7 @@ void PIHIDevice::run() {
|
||||
if (ie.type == 0) continue;
|
||||
bool ok = false;
|
||||
switch (ie.type) {
|
||||
case 2: {
|
||||
case 2: { // rel axis
|
||||
auto vi = di.axis_by_dataindex.value(ie.code);
|
||||
if (vi.isValid()) {
|
||||
e.type = Event::tAxisMove;
|
||||
@@ -239,35 +248,41 @@ void PIHIDevice::run() {
|
||||
}
|
||||
ok = true;
|
||||
} break;
|
||||
case 3: {
|
||||
case 3: { // abs axis
|
||||
auto vi = di.axis_by_dataindex.value(ie.code);
|
||||
float fv = (ie.value - vi.min) / piMaxf(1.f, (float)(vi.max - vi.min));
|
||||
cur_axes[ie.code] = procDeadZone(fv);
|
||||
ok = true;
|
||||
} break;
|
||||
case 1:
|
||||
case 1: // button
|
||||
// piCout << ie.code;
|
||||
cur_buttons[ie.code] = ie.value;
|
||||
ok = true;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
// piCout << ok << ie.type << ie.code << ie.value;
|
||||
if (!ok) continue;
|
||||
}
|
||||
}
|
||||
# else
|
||||
PRIVATE->buffer.resize(di.input_report_size).fill(0);
|
||||
DWORD readed = 0;
|
||||
// piCout << "read" << PRIVATE->deviceHandle << PRIVATE->buffer.size();
|
||||
HIDP_DATA gdd[256];
|
||||
ULONG gdd_len = 256;
|
||||
if (ReadFile(PRIVATE->deviceHandle, PRIVATE->buffer.data(), PRIVATE->buffer.size_s(), &readed, nullptr) != TRUE) return;
|
||||
// piCout << readed << PRIVATE->buffer.size();
|
||||
if (readed != PRIVATE->buffer.size()) return;
|
||||
auto gd = HidP_GetData(HidP_Input, gdd, &gdd_len, PRIVATE->preparsed, (PCHAR)PRIVATE->buffer.data(), PRIVATE->buffer.size_s());
|
||||
NO_UNUSED(gd);
|
||||
// piCout << "readed" << PRIVATE->buffer << gdd_len;
|
||||
auto cbit = cur_buttons.makeIterator();
|
||||
while (cbit.next())
|
||||
cbit.value() = 0;
|
||||
for (ULONG i = 0; i < gdd_len; ++i) {
|
||||
const auto & cd(gdd[i]);
|
||||
// piCout << cd.DataIndex << cd.RawValue;
|
||||
auto vi = di.axis_by_dataindex.value(cd.DataIndex);
|
||||
if (vi.isValid()) {
|
||||
if (vi.is_relative) {
|
||||
@@ -276,14 +291,17 @@ void PIHIDevice::run() {
|
||||
e.value = static_cast<LONG>(cd.RawValue);
|
||||
event(e);
|
||||
} else {
|
||||
// auto & axis(cur_axes[cd.DataIndex]);
|
||||
float fv = (cd.RawValue - vi.min) / piMaxf(1.f, (float)(vi.max - vi.min));
|
||||
cur_axes[vi.data_index] = procDeadZone(fv);
|
||||
}
|
||||
// piCout << "axis" << vi.data_index << "->" << cur_axes[vi.data_index];
|
||||
continue;
|
||||
}
|
||||
auto bi = di.button_by_dataindex.value(cd.DataIndex);
|
||||
if (bi.isValid()) {
|
||||
cur_buttons[bi.data_index] = 1;
|
||||
// piCout << "button" << bi.data_index << "-> 1";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -310,7 +328,7 @@ void PIHIDevice::run() {
|
||||
}
|
||||
}
|
||||
prev_buttons = cur_buttons;
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -331,10 +349,9 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
|
||||
#ifdef EMSCRIPTEN
|
||||
(void)try_open;
|
||||
return ret;
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
|
||||
#ifndef WINDOWS
|
||||
# ifndef EMSCRIPTEN
|
||||
#if !defined(WINDOWS) && !defined(EMSCRIPTEN)
|
||||
|
||||
auto readFile = [](const PIString & path) {
|
||||
auto ba = PIFile::readAll(path);
|
||||
@@ -353,18 +370,23 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
|
||||
PIDir hid_dir("/sys/bus/hid/devices"_a);
|
||||
auto hid_devs = hid_dir.entries();
|
||||
for (const auto & hd: hid_devs) {
|
||||
// piCout << d.path;
|
||||
if (!isDir(hd)) continue;
|
||||
PIDir dir_input(hd.path + "/input"_a);
|
||||
auto hid_inputs = dir_input.entries();
|
||||
for (const auto & hd_i: hid_inputs) {
|
||||
if (!isDir(hd_i)) continue;
|
||||
// now in /sys/bus/hid/devices/<dev>/input/input<N>
|
||||
// piCout << hd_i.path;
|
||||
PIHIDeviceInfo dev;
|
||||
dev.product = readFile(hd_i.path + "/name"_a);
|
||||
// piCout << readFile(hd_i.path + "/name"_a);
|
||||
dev.VID = readFile(hd_i.path + "/id/vendor"_a);
|
||||
dev.PID = readFile(hd_i.path + "/id/product"_a);
|
||||
dev.version = readFile(hd_i.path + "/id/version"_a);
|
||||
dev.manufacturer = readFile(hd_i.path + "/id/manufacturer"_a);
|
||||
|
||||
// piCout << dev.product;
|
||||
dev.input_report_size = 24;
|
||||
PIDir dir_e(hd_i.path);
|
||||
PIStringList devs;
|
||||
@@ -373,6 +395,16 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
|
||||
if (!d_e.isDir() || d_e.flags[PIFile::FileInfo::Dot] || d_e.flags[PIFile::FileInfo::DotDot]) continue;
|
||||
devs << d_e.name();
|
||||
}
|
||||
/*bool dev_found = false;
|
||||
for (const auto & d: devs) {
|
||||
if (d.startsWith("js"_a)) {
|
||||
dev.path = "/dev/input/"_a + d;
|
||||
dev_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!dev_found) {*/
|
||||
// search for event<N> dir
|
||||
for (const auto & d: devs) {
|
||||
if (d.startsWith("event"_a)) {
|
||||
dev.path = "/dev/input/"_a + d;
|
||||
@@ -387,12 +419,17 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
|
||||
if (test_f.isClosed()) continue;
|
||||
}
|
||||
|
||||
// ullong ev = readFile(hd_i.path + "/capabilities/ev"_a).toULLong(16);
|
||||
|
||||
auto readAxes = [readFile, checkBit, &hd_i, &dev](const PIString & file, bool is_relative) {
|
||||
PIVector<PIHIDeviceInfo::AxisInfo> ret;
|
||||
ullong bits = readFile(hd_i.path + file).toULLong(16);
|
||||
// piCout<< PICoutManipulators::Bin << abs;
|
||||
if (bits > 0) {
|
||||
int fd = ::open(dev.path.dataAscii(), O_RDONLY);
|
||||
if (fd < 0) {}
|
||||
if (fd < 0) {
|
||||
// piCout << "Warning: can`t open" << dev.path << errorString();
|
||||
}
|
||||
PIHIDeviceInfo::AxisInfo ai;
|
||||
ai.is_relative = is_relative;
|
||||
for (int bit = 0; bit < 64; ++bit) {
|
||||
@@ -403,6 +440,7 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
|
||||
if (ioctl(fd, EVIOCGABS(bit), &abs_info) != -1) {
|
||||
ai.min = abs_info.minimum;
|
||||
ai.max = abs_info.maximum;
|
||||
// piCout << "axis" << bit << abs_info.minimum << abs_info.maximum << abs_info.flat << abs_info.fuzz;
|
||||
} else {
|
||||
ai.min = 0;
|
||||
ai.max = 1024;
|
||||
@@ -442,6 +480,7 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
|
||||
for (const auto * hwp: {"/usr/share/hwdata/usb.ids", "/var/lib/usbutils/usb.ids"}) {
|
||||
PIFile hwf(hwp, PIIODevice::ReadOnly);
|
||||
if (hwf.isClosed()) continue;
|
||||
// piCout << "search" << dev.VID << "in" << hwp;
|
||||
PIString line;
|
||||
PIIOTextStream ts(&hwf);
|
||||
while (!hwf.isEnd()) {
|
||||
@@ -461,8 +500,7 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
|
||||
}
|
||||
}
|
||||
|
||||
# endif
|
||||
#else
|
||||
#elif defined(WINDOWS)
|
||||
|
||||
GUID guid;
|
||||
HidD_GetHidGuid(&guid);
|
||||
@@ -512,12 +550,18 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// piCout << i << deviceHandle;
|
||||
|
||||
PHIDP_PREPARSED_DATA preparsed = nullptr;
|
||||
if (HidD_GetPreparsedData(deviceHandle, &preparsed) == FALSE) {
|
||||
piCout << "HidD_GetPreparsedData error:" << errorString();
|
||||
CloseHandle(deviceHandle);
|
||||
continue;
|
||||
}
|
||||
// auto pp = PIByteArray(preparsed, 64);
|
||||
// piCout << piChangedEndian(pp.dataAs<ushort>(7)) << piChangedEndian(pp.dataAs<ushort>(8)) <<
|
||||
// piChangedEndian(pp.dataAs<ushort>(9));
|
||||
// piCout << pp;
|
||||
|
||||
dev.path = deviceInterfaceDetailData->DevicePath;
|
||||
|
||||
@@ -575,6 +619,7 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
|
||||
else
|
||||
axes_abs << vi;
|
||||
}
|
||||
// piCout << vc.LinkCollection << vc.LinkUsage << vc.LinkUsagePage;
|
||||
}
|
||||
dev.axes << axes_abs << axes_rel;
|
||||
for (int i = 0; i < dev.axes.size_s(); ++i)
|
||||
@@ -587,6 +632,7 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
|
||||
for (int i = 0; i < _cnt; ++i) {
|
||||
const auto & bc(button_caps[i]);
|
||||
PIHIDeviceInfo::ButtonInfo bi;
|
||||
// dev.values.append(PIHIDeviceInfo::ValueInfo{value_caps[i].BitSize, value_caps[i].LogicalMin, value_caps[i].LogicalMax});
|
||||
if (bc.IsRange == 1) {
|
||||
int count = bc.Range.UsageMax - bc.Range.UsageMin + 1;
|
||||
int cur_index = bc.Range.DataIndexMin;
|
||||
@@ -595,12 +641,16 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
|
||||
bi.data_index = cur_index;
|
||||
dev.buttons << bi;
|
||||
++cur_index;
|
||||
// piCout << b << (start_bit / 8) << (start_bit % 8);
|
||||
}
|
||||
} else {
|
||||
bi.index = dev.buttons.size_s();
|
||||
bi.data_index = bc.NotRange.DataIndex;
|
||||
dev.buttons << bi;
|
||||
// piCout << (bi.bit / 8) << (bi.bit % 8);
|
||||
}
|
||||
// piCout << bc.IsRange << bc.Range.UsageMin << bc.Range.UsageMax
|
||||
// << bc.Range.DataIndexMin << bc.Range.DataIndexMax;
|
||||
}
|
||||
|
||||
HidD_FreePreparsedData(preparsed);
|
||||
|
||||
+134
-14
@@ -27,14 +27,109 @@
|
||||
# endif
|
||||
|
||||
|
||||
//! \class PILibrary pilibrary.h
|
||||
//! \~\details
|
||||
//! \~english \section _sec0 Synopsis
|
||||
//! \~russian \section _sec0 Краткий обзор
|
||||
//! \~english
|
||||
//! %PILibrary allow you dynamically load external library and use
|
||||
//! some methods from it. %PILibrary instance contains library
|
||||
//! pointer and unload library on destructor, so recommended
|
||||
//! to use it with \b new creation.
|
||||
//!
|
||||
//! Main method of %PILibrary is \a resolve(const char *), which returns
|
||||
//! \c void* pointer to requested method. One should test it
|
||||
//! to \c nullptr and convert it in pointer to the required method.
|
||||
//!
|
||||
//! In case of C++ libraries it`s very important to use [C-linkage](https://en.cppreference.com/w/cpp/language/language_linkage)
|
||||
//! of exported methods! You may also need to mark methods for
|
||||
//! export, e.g. \c __declspec(dllexport). You can include \c <piplugin.h>
|
||||
//! and use \a PIP_PLUGIN_EXPORT to mark exports with PIP.
|
||||
//!
|
||||
//! \~russian
|
||||
//! %PILibrary позволяет динамически загружать стороннюю библиотеку
|
||||
//! и использовать оттуда методы. Экземпляр %PILibrary содержит
|
||||
//! указатель на библиотеку и выгружает её в деструкторе, поэтому
|
||||
//! рекомендуется создавать её с помощью \b new.
|
||||
//!
|
||||
//! Основной метод %PILibrary - это \a resolve(const char *), который возвращает
|
||||
//! \c void* указатель на запрошенный метод. Необходимо проверить его
|
||||
//! на \c nullptr и преобразовать в указатель на нужный метод.
|
||||
//!
|
||||
//! В случае C++ библиотеки очень важно использовать [C-linkage](https://en.cppreference.com/w/cpp/language/language_linkage)
|
||||
//! для экспортируемых методов! Также может понадобиться пометить
|
||||
//! методы на экспорт, например, \c __declspec(dllexport). Можно включить \c <piplugin.h>
|
||||
//! и использовать \a PIP_PLUGIN_EXPORT, чтобы пометить экспорт с помощью PIP.
|
||||
//!
|
||||
//! \~\code
|
||||
//! extern "C" {
|
||||
//! __declspec(dllexport) int exportedSum(int,int);
|
||||
//! __declspec(dllexport) int exportedMul(int,int);
|
||||
//! }
|
||||
//! \endcode
|
||||
//!
|
||||
//! \~english \section _sec1 Usage
|
||||
//! \~russian \section _sec1 Использование
|
||||
//!
|
||||
//! \~english Library:
|
||||
//! \~russian Библиотека:
|
||||
//! \~\code
|
||||
//! #include <piplugin.h>
|
||||
//!
|
||||
//! extern "C" {
|
||||
//! PIP_PLUGIN_EXPORT int exportedSum(int,int);
|
||||
//! PIP_PLUGIN_EXPORT int exportedMul(int,int);
|
||||
//! }
|
||||
//!
|
||||
//! int exportedSum(int a, int b) {
|
||||
//! return a + b;
|
||||
//! }
|
||||
//! int exportedMul(int a, int b) {
|
||||
//! return a * b;
|
||||
//! }
|
||||
//! \endcode
|
||||
//!
|
||||
//! \~english Program:
|
||||
//! \~russian Программа:
|
||||
//! \~\code
|
||||
//! int main(int argc, char * argv[]) {
|
||||
//! typedef int(*MyFunc)(int,int);
|
||||
//! PILibrary * lib = new PILibrary();
|
||||
//! if (lib->load("mylib.dll")) {
|
||||
//! MyFunc fadd = (MyFunc)lib->resolve("exportedSum");
|
||||
//! MyFunc fmul = (MyFunc)lib->resolve("exportedMul");
|
||||
//! if (fadd) {
|
||||
//! int sum = fadd(1, 2);
|
||||
//! piCout << "sum =" << sum;
|
||||
//! } else {
|
||||
//! piCout << "Can`t resolve" << "exportedSum";
|
||||
//! }
|
||||
//! if (fmul) {
|
||||
//! int mul = fadd(10, 20);
|
||||
//! piCout << "mul =" << mul;
|
||||
//! } else {
|
||||
//! piCout << "Can`t resolve" << "exportedMul";
|
||||
//! }
|
||||
//! } else {
|
||||
//! piCout << lib->lastError();
|
||||
//! }
|
||||
//! delete lib;
|
||||
//! }
|
||||
//!
|
||||
//! // sum = 3
|
||||
//! // mul = 30
|
||||
//! \endcode
|
||||
//!
|
||||
|
||||
|
||||
PRIVATE_DEFINITION_START(PILibrary)
|
||||
# ifdef WINDOWS
|
||||
HMODULE
|
||||
# elif defined(EMSCRIPTEN)
|
||||
void *
|
||||
# else
|
||||
# else // EMSCRIPTEN
|
||||
void *
|
||||
# endif
|
||||
# endif // EMSCRIPTEN
|
||||
hLib;
|
||||
PRIVATE_DEFINITION_END(PILibrary)
|
||||
|
||||
@@ -67,9 +162,9 @@ void PILibrary::unload() {
|
||||
FreeLibrary(PRIVATE->hLib);
|
||||
# elif defined(EMSCRIPTEN)
|
||||
PRIVATE->hLib = 0;
|
||||
# else
|
||||
# else // EMSCRIPTEN
|
||||
dlclose(PRIVATE->hLib);
|
||||
# endif
|
||||
# endif // EMSCRIPTEN
|
||||
PRIVATE->hLib = 0;
|
||||
}
|
||||
|
||||
@@ -79,22 +174,47 @@ bool PILibrary::isLoaded() const {
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! Returns exported method with name "symbol" from
|
||||
//! loaded library. Method have to use [C-linkage](https://en.cppreference.com/w/cpp/language/language_linkage) and
|
||||
//! marked to export, according to compiler specification.\n
|
||||
//! C-linkage doesn`t provide information about return type
|
||||
//! and arguments, so you should manually convert obtained
|
||||
//! pointer to required method format before call.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Возвращает экспортированный метод с именем "symbol"
|
||||
//! из загруженной библиотеки. Метод должен иметь [C-linkage](https://en.cppreference.com/w/cpp/language/language_linkage)
|
||||
//! и помечен для экспорта, согласно спецификации компилятора.\n
|
||||
//! C-linkage не предоставляет информации о возвращаемом типе
|
||||
//! и аргументах, поэтому необходимо вручную преобразовать
|
||||
//! полученный указатель к формату требуемого метода перед вызовом.
|
||||
//!
|
||||
//! \~\return
|
||||
//! \~english
|
||||
//! \b void* pointer to method or\n
|
||||
//! \b nullptr if method doesn`t exists or library not loaded
|
||||
//!
|
||||
//! \~russian
|
||||
//! \b void* указатель на метод или\n
|
||||
//! \b nullptr если метод не существует или библиотека не загружена
|
||||
void * PILibrary::resolve(const char * symbol) {
|
||||
if (!isLoaded()) return 0;
|
||||
# ifdef EMSCRIPTEN
|
||||
(void)symbol;
|
||||
liberror = "dlsym not available on Emscripten";
|
||||
return 0;
|
||||
# else
|
||||
# else // EMSCRIPTEN
|
||||
void * ret;
|
||||
# ifdef WINDOWS
|
||||
ret = (void *)GetProcAddress(PRIVATE->hLib, symbol);
|
||||
# else
|
||||
# else // WINDOWS
|
||||
ret = dlsym(PRIVATE->hLib, symbol);
|
||||
# endif
|
||||
# endif // WINDOWS
|
||||
getLastError();
|
||||
return ret;
|
||||
# endif
|
||||
# endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -104,15 +224,15 @@ bool PILibrary::loadInternal() {
|
||||
# ifdef EMSCRIPTEN
|
||||
liberror = "dlopen not available on Emscripten";
|
||||
return false;
|
||||
# else
|
||||
# else // EMSCRIPTEN
|
||||
# ifdef WINDOWS
|
||||
PRIVATE->hLib = LoadLibraryA(libpath.data());
|
||||
# else
|
||||
# else // WINDOWS
|
||||
PRIVATE->hLib = dlopen(libpath.data(), RTLD_LAZY);
|
||||
# endif
|
||||
# endif // WINDOWS
|
||||
getLastError();
|
||||
return PRIVATE->hLib;
|
||||
# endif
|
||||
# endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -121,13 +241,13 @@ void PILibrary::getLastError() {
|
||||
liberror = errorString();
|
||||
# elif defined(EMSCRIPTEN)
|
||||
liberror.clear();
|
||||
# else
|
||||
# else // EMSCRIPTEN
|
||||
const char * e = dlerror();
|
||||
if (e)
|
||||
liberror = e;
|
||||
else
|
||||
liberror.clear();
|
||||
# endif
|
||||
# endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
#endif // MICRO_PIP
|
||||
|
||||
@@ -24,16 +24,49 @@
|
||||
# include "piliterals_bytes.h"
|
||||
# include "piprocess.h"
|
||||
# include "pitranslator.h"
|
||||
# ifndef WINDOWS
|
||||
# include <csignal>
|
||||
# include <sys/wait.h>
|
||||
# include <fcntl.h>
|
||||
# endif
|
||||
# ifdef EMSCRIPTEN
|
||||
# else // EMSCRIPTEN
|
||||
# ifndef WINDOWS
|
||||
# include <csignal>
|
||||
# include <sys/wait.h>
|
||||
# include <fcntl.h>
|
||||
# endif
|
||||
# endif // EMSCRIPTEN
|
||||
# ifdef MAC_OS
|
||||
# include <crt_externs.h>
|
||||
# endif
|
||||
|
||||
|
||||
//! \class PIProcess piprocess.h
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! This class able to start external executables, watch for them,
|
||||
//! grab output and exit code.
|
||||
//!
|
||||
//! \~russian
|
||||
//!
|
||||
//!
|
||||
//! \~english \section PIProcess_sec0 Synopsis
|
||||
//! \~russian \section PIProcess_sec0 Краткий обзор
|
||||
//! \~english
|
||||
//! External executable can be started with control or fully independent
|
||||
//! from application.\n
|
||||
//! Start with control allow you to wait for finish, grab output
|
||||
//! and terminate it at any time.\n
|
||||
//! You can change working directory and environment of executable.\n
|
||||
//!
|
||||
//! \~russian
|
||||
//!
|
||||
//!
|
||||
//! \~english \section PIProcess_sec1 Usage
|
||||
//! \~russian \section PIProcess_sec1 Использование
|
||||
//! \~english
|
||||
//!
|
||||
//!
|
||||
//! \~russian
|
||||
//!
|
||||
|
||||
|
||||
namespace {
|
||||
enum PipeDirection {
|
||||
PipeRead,
|
||||
@@ -55,8 +88,8 @@ constexpr int StdFileCount = StdLast + 1;
|
||||
using PipeHandleType = HANDLE;
|
||||
using SizeType = DWORD;
|
||||
# elif defined(EMSCRIPTEN)
|
||||
using PipeHandleType = int;
|
||||
using SizeType = ssize_t;
|
||||
using PipeHandleType = int;
|
||||
# else
|
||||
using SizeType = ssize_t;
|
||||
using PipeHandleType = int;
|
||||
@@ -71,9 +104,6 @@ PIString convertWindowsCmd(PIStringList sl) {
|
||||
return sl.join(' ');
|
||||
}
|
||||
# elif defined(EMSCRIPTEN)
|
||||
char * const * convertToCharArrays(const PIStringList &) {
|
||||
return nullptr;
|
||||
}
|
||||
# else
|
||||
char * const * convertToCharArrays(const PIStringList & sl) {
|
||||
char ** cc = new char *[sl.size() + 1];
|
||||
@@ -89,6 +119,7 @@ char * const * convertToCharArrays(const PIStringList & sl) {
|
||||
|
||||
|
||||
PRIVATE_DEFINITION_START(PIProcess)
|
||||
|
||||
# ifdef WINDOWS
|
||||
PROCESS_INFORMATION pi;
|
||||
# elif defined(EMSCRIPTEN)
|
||||
@@ -120,7 +151,7 @@ PRIVATE_DEFINITION_START(PIProcess)
|
||||
# ifdef EMSCRIPTEN
|
||||
(void)pipe_type;
|
||||
return false;
|
||||
# else
|
||||
# else // EMSCRIPTEN
|
||||
const int pt = pipe_type;
|
||||
# ifdef WINDOWS
|
||||
SECURITY_ATTRIBUTES saAttr;
|
||||
@@ -133,14 +164,15 @@ PRIVATE_DEFINITION_START(PIProcess)
|
||||
int ret = pipe(pipes[pt]);
|
||||
return ret != -1;
|
||||
# endif
|
||||
# endif
|
||||
# endif // EMSCRIPTEN
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool createPipes() {
|
||||
# ifdef EMSCRIPTEN
|
||||
return false;
|
||||
# else
|
||||
# else // EMSCRIPTEN
|
||||
for (int i = 0; i < StdFileCount; ++i) {
|
||||
if (grab[i]) {
|
||||
if (!createPipe(static_cast<StdFile>(i))) {
|
||||
@@ -158,7 +190,7 @@ PRIVATE_DEFINITION_START(PIProcess)
|
||||
if (grab[StdErr]) SetHandleInformation(pipes[StdErr][PipeRead], HANDLE_FLAG_INHERIT, 0);
|
||||
# endif
|
||||
return true;
|
||||
# endif
|
||||
# endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -189,8 +221,9 @@ PRIVATE_DEFINITION_START(PIProcess)
|
||||
|
||||
PIByteArray readPipe(StdFile pipe_type) {
|
||||
# ifdef EMSCRIPTEN
|
||||
(void)pipe_type;
|
||||
return {};
|
||||
# else
|
||||
# else // EMSCRIPTEN
|
||||
if (!grab[pipe_type]) return {};
|
||||
constexpr size_t read_buffer_size = 4_KiB;
|
||||
PIByteArray read_buffer;
|
||||
@@ -222,14 +255,15 @@ PRIVATE_DEFINITION_START(PIProcess)
|
||||
}
|
||||
}
|
||||
return read_buffer;
|
||||
# endif
|
||||
# endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
bool writePipe(const PIByteArray & data) {
|
||||
# ifdef EMSCRIPTEN
|
||||
(void)data;
|
||||
return false;
|
||||
# else
|
||||
# else // EMSCRIPTEN
|
||||
SizeType sz = 0;
|
||||
# ifdef WINDOWS
|
||||
BOOL ok = WriteFile(pipes[StdIn][PipeWrite], data.data(), data.size(), &sz, NULL);
|
||||
@@ -247,7 +281,7 @@ PRIVATE_DEFINITION_START(PIProcess)
|
||||
sz = offset;
|
||||
# endif
|
||||
return sz == (SizeType)data.size_s();
|
||||
# endif
|
||||
# endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
PRIVATE_DEFINITION_END(PIProcess)
|
||||
@@ -257,6 +291,9 @@ PIProcess::PIProcess(): PIThread() {
|
||||
exit_code = -1;
|
||||
# ifdef WINDOWS
|
||||
PRIVATE->pi.dwProcessId = 0;
|
||||
# elif defined(EMSCRIPTEN)
|
||||
PRIVATE->pid = 0;
|
||||
PRIVATE->forEachPipe([](PipeHandleType & pipe) { pipe = -1; });
|
||||
# else
|
||||
PRIVATE->pid = 0;
|
||||
PRIVATE->forEachPipe([](PipeHandleType & pipe) { pipe = -1; });
|
||||
@@ -288,7 +325,7 @@ void PIProcess::startProc(bool detached) {
|
||||
exec_start = false;
|
||||
exec_finished = false;
|
||||
return;
|
||||
# else
|
||||
# else // EMSCRIPTEN
|
||||
const PIString & str = args.front();
|
||||
if (!detached) execStarted(str);
|
||||
if (!PRIVATE->createPipes()) return;
|
||||
@@ -301,16 +338,17 @@ void PIProcess::startProc(bool detached) {
|
||||
if (PRIVATE->grab[StdErr]) si.hStdError = PRIVATE->pipes[StdErr][PipeWrite];
|
||||
si.dwFlags |= STARTF_USESTDHANDLES;
|
||||
const auto cmd = convertWindowsCmd(args);
|
||||
if (CreateProcessA(0,
|
||||
(LPSTR)cmd.data(),
|
||||
0,
|
||||
0,
|
||||
true,
|
||||
detached ? DETACHED_PROCESS : 0,
|
||||
0,
|
||||
wd.isEmpty() ? 0 : wd.data(),
|
||||
&si,
|
||||
&(PRIVATE->pi))) {
|
||||
if (CreateProcessA(0, // No module name (use command line)
|
||||
(LPSTR)cmd.data(), // Command line
|
||||
0, // Process handle not inheritable
|
||||
0, // Thread handle not inheritable
|
||||
true, // Set handle inheritance to FALSE
|
||||
detached ? DETACHED_PROCESS /*CREATE_NEW_CONSOLE*/ : 0, // Creation flags
|
||||
0, // Use environment
|
||||
wd.isEmpty() ? 0 : wd.data(), // Use working directory
|
||||
&si, // Pointer to STARTUPINFO structure
|
||||
&(PRIVATE->pi))) // Pointer to PROCESS_INFORMATION structure
|
||||
{
|
||||
exec_start = true;
|
||||
if (!detached) {
|
||||
WaitForSingleObject(PRIVATE->pi.hProcess, INFINITE);
|
||||
@@ -352,6 +390,7 @@ void PIProcess::startProc(bool detached) {
|
||||
PRIVATE->closePipe(StdErr, PipeWrite);
|
||||
|
||||
execve(str.data(), largs, lenv);
|
||||
// normaly execve can't return, if it returns - error occured
|
||||
piCoutObj << "\"execve" << str << args << "\" error :" << errorString();
|
||||
exit(127);
|
||||
} else {
|
||||
@@ -377,14 +416,14 @@ void PIProcess::startProc(bool detached) {
|
||||
# endif
|
||||
if (!detached) execFinished(str, exit_code);
|
||||
exec_start = false;
|
||||
# endif
|
||||
# endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
void PIProcess::terminate() {
|
||||
# ifdef EMSCRIPTEN
|
||||
return;
|
||||
# else
|
||||
# else // EMSCRIPTEN
|
||||
# ifdef WINDOWS
|
||||
if (exec_start) {
|
||||
if (!TerminateProcess(PRIVATE->pi.hProcess, 0)) return;
|
||||
@@ -394,7 +433,7 @@ void PIProcess::terminate() {
|
||||
if (exec_start) kill(PRIVATE->pid, SIGKILL);
|
||||
PRIVATE->pid = 0;
|
||||
# endif
|
||||
# endif
|
||||
# endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -408,13 +447,13 @@ void PIProcess::execIndependent(const PIString & program, const PIStringList & a
|
||||
int PIProcess::pID() const {
|
||||
# ifdef EMSCRIPTEN
|
||||
return -1;
|
||||
# else
|
||||
# else // EMSCRIPTEN
|
||||
# ifdef WINDOWS
|
||||
return PRIVATE->pi.dwProcessId;
|
||||
# else
|
||||
return PRIVATE->pid;
|
||||
# endif
|
||||
# endif
|
||||
# endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -462,20 +501,20 @@ void PIProcess::enableReadStdErr(bool on) {
|
||||
int PIProcess::currentPID() {
|
||||
# ifdef EMSCRIPTEN
|
||||
return -1;
|
||||
# else
|
||||
# else // EMSCRIPTEN
|
||||
# ifdef WINDOWS
|
||||
return GetCurrentProcessId();
|
||||
# else
|
||||
return getpid();
|
||||
# endif
|
||||
# endif
|
||||
# endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
PIStringList PIProcess::currentEnvironment() {
|
||||
# ifdef EMSCRIPTEN
|
||||
return PIStringList();
|
||||
# else
|
||||
# else // EMSCRIPTEN
|
||||
PIStringList l;
|
||||
int i = 0;
|
||||
while (environ[i] != 0) {
|
||||
@@ -483,7 +522,7 @@ PIStringList PIProcess::currentEnvironment() {
|
||||
++i;
|
||||
}
|
||||
return l;
|
||||
# endif
|
||||
# endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
#include "pisignals.h"
|
||||
|
||||
#include "piincludes.h"
|
||||
#ifndef EMSCRIPTEN
|
||||
#ifdef EMSCRIPTEN
|
||||
#else // EMSCRIPTEN
|
||||
# ifdef BLACKBERRY
|
||||
# include <signal.h>
|
||||
# else
|
||||
@@ -30,7 +31,7 @@
|
||||
# define SIGUSR1 10
|
||||
# define SIGUSR2 12
|
||||
# endif
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
|
||||
PISignals::SignalEvent PISignals::ret_func;
|
||||
|
||||
@@ -38,7 +39,7 @@ PISignals::SignalEvent PISignals::ret_func;
|
||||
void PISignals::grabSignals(PIFlags<PISignals::Signal> signals_) {
|
||||
#ifdef EMSCRIPTEN
|
||||
(void)signals_;
|
||||
#else
|
||||
#else // EMSCRIPTEN
|
||||
if (signals_[PISignals::Interrupt]) signal(signalCode(PISignals::Interrupt), PISignals::signal_event);
|
||||
if (signals_[PISignals::Illegal]) signal(signalCode(PISignals::Illegal), PISignals::signal_event);
|
||||
if (signals_[PISignals::Abort]) signal(signalCode(PISignals::Abort), PISignals::signal_event);
|
||||
@@ -62,14 +63,14 @@ void PISignals::grabSignals(PIFlags<PISignals::Signal> signals_) {
|
||||
if (signals_[PISignals::StopTTYInput]) signal(signalCode(PISignals::StopTTYInput), PISignals::signal_event);
|
||||
if (signals_[PISignals::StopTTYOutput]) signal(signalCode(PISignals::StopTTYOutput), PISignals::signal_event);
|
||||
# endif
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
void PISignals::releaseSignals(PIFlags<Signal> signals_) {
|
||||
#ifdef EMSCRIPTEN
|
||||
(void)signals_;
|
||||
#else
|
||||
#else // EMSCRIPTEN
|
||||
if (signals_[PISignals::Interrupt]) signal(signalCode(PISignals::Interrupt), SIG_DFL);
|
||||
if (signals_[PISignals::Illegal]) signal(signalCode(PISignals::Illegal), SIG_DFL);
|
||||
if (signals_[PISignals::Abort]) signal(signalCode(PISignals::Abort), SIG_DFL);
|
||||
@@ -93,16 +94,16 @@ void PISignals::releaseSignals(PIFlags<Signal> signals_) {
|
||||
if (signals_[PISignals::StopTTYInput]) signal(signalCode(PISignals::StopTTYInput), SIG_DFL);
|
||||
if (signals_[PISignals::StopTTYOutput]) signal(signalCode(PISignals::StopTTYOutput), SIG_DFL);
|
||||
# endif
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
void PISignals::raiseSignal(PISignals::Signal signal) {
|
||||
#ifdef EMSCRIPTEN
|
||||
(void)signal;
|
||||
#else
|
||||
#else // EMSCRIPTEN
|
||||
raise(signalCode(signal));
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +111,7 @@ int PISignals::signalCode(PISignals::Signal signal) {
|
||||
#ifdef EMSCRIPTEN
|
||||
(void)signal;
|
||||
return 0;
|
||||
#else
|
||||
#else // EMSCRIPTEN
|
||||
switch (signal) {
|
||||
case PISignals::Interrupt: return SIGINT;
|
||||
case PISignals::Illegal: return SIGILL;
|
||||
@@ -138,7 +139,7 @@ int PISignals::signalCode(PISignals::Signal signal) {
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
@@ -146,7 +147,7 @@ PISignals::Signal PISignals::signalFromCode(int signal) {
|
||||
#ifdef EMSCRIPTEN
|
||||
(void)signal;
|
||||
return PISignals::Termination;
|
||||
#else
|
||||
#else // EMSCRIPTEN
|
||||
switch (signal) {
|
||||
case SIGINT: return PISignals::Interrupt;
|
||||
case SIGILL: return PISignals::Illegal;
|
||||
@@ -174,7 +175,7 @@ PISignals::Signal PISignals::signalFromCode(int signal) {
|
||||
default: break;
|
||||
}
|
||||
return PISignals::Termination;
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ PISystemInfo * PISystemInfo::instance() {
|
||||
ret.hostname = "wasm";
|
||||
ret.user = "browser";
|
||||
ret.processorsCount = 1;
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
return &ret;
|
||||
}
|
||||
@@ -66,7 +66,7 @@ PIStringList PISystemInfo::mountRoots() {
|
||||
} else
|
||||
clet += PIChar(letters[i]);
|
||||
}
|
||||
#else
|
||||
#else // WINDOWS
|
||||
# ifdef LINUX
|
||||
PIString s_df, s_m;
|
||||
char in[1024];
|
||||
@@ -87,7 +87,7 @@ PIStringList PISystemInfo::mountRoots() {
|
||||
}
|
||||
# else
|
||||
# endif
|
||||
#endif
|
||||
#endif // WINDOWS
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -146,6 +146,7 @@ PIVector<PISystemInfo::MountInfo> PISystemInfo::mountInfo(bool ignore_cache) {
|
||||
PIString s_df, s_m;
|
||||
char in[1024];
|
||||
piZeroMemory(in, 1024);
|
||||
// piCout << "mountInfo 0";
|
||||
FILE * fp = popen("df -B1", "r");
|
||||
PIStringList l_df;
|
||||
PIMap<PIString, String3> fs;
|
||||
@@ -155,6 +156,7 @@ PIVector<PISystemInfo::MountInfo> PISystemInfo::mountInfo(bool ignore_cache) {
|
||||
pclose(fp);
|
||||
fp = 0;
|
||||
}
|
||||
// piCout << "mountInfo 1";
|
||||
piZeroMemory(in, 1024);
|
||||
fp = popen("mount -l", "r");
|
||||
PIStringList tl;
|
||||
@@ -182,6 +184,7 @@ PIVector<PISystemInfo::MountInfo> PISystemInfo::mountInfo(bool ignore_cache) {
|
||||
me.label.cutLeft(1).cutRight(1);
|
||||
}
|
||||
fs[dev] = me;
|
||||
// piCout << fsmp << fstl;
|
||||
}
|
||||
pclose(fp);
|
||||
fp = 0;
|
||||
@@ -201,6 +204,7 @@ PIVector<PISystemInfo::MountInfo> PISystemInfo::mountInfo(bool ignore_cache) {
|
||||
m.mount_point = s3.mp;
|
||||
m.label = s3.label;
|
||||
ret << m;
|
||||
// piCout << ml;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -224,9 +228,9 @@ PIString confDir() {
|
||||
""
|
||||
#elif defined(EMSCRIPTEN)
|
||||
""
|
||||
#else
|
||||
#else // EMSCRIPTEN
|
||||
PIDir::home().path() + "/.config"
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
;
|
||||
}
|
||||
|
||||
@@ -250,14 +254,14 @@ PIString PISystemInfo::machineKey() {
|
||||
PIString conf = confDir() + "/.pip_machine_salt";
|
||||
#ifdef EMSCRIPTEN
|
||||
ret = si->OS_name + "_" + si->architecture;
|
||||
#else
|
||||
#else // EMSCRIPTEN
|
||||
if (PIFile::isExists(conf)) salt = PIFile::readAll(conf);
|
||||
if (salt.size_s() != SALT_SIZE) {
|
||||
salt = generateSalt();
|
||||
PIFile::writeAll(conf, salt);
|
||||
}
|
||||
ret = si->OS_name + "_" + si->architecture + "_" + si->hostname + "_" + salt.toHex();
|
||||
#endif
|
||||
#endif // EMSCRIPTEN
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -268,6 +272,7 @@ uint PISystemInfo::machineID() {
|
||||
if (ret == 0) {
|
||||
CRC_32 crc = standardCRC_32();
|
||||
ret = crc.calculate(machineKey().toByteArray());
|
||||
// piCout << "machineID \"" << machineKey() << "\" =" << PICoutManipulators::Hex << ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
#elif defined(EMSCRIPTEN)
|
||||
# include <stdint.h>
|
||||
# define gettid() (pid_t)(uintptr_t) pthread_self()
|
||||
#endif
|
||||
#endif //EMSCRIPTEN
|
||||
#if defined(MAC_OS) || defined(BLACKBERRY)
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
@@ -870,7 +870,7 @@ void PIThread::_beginThread() {
|
||||
#endif
|
||||
#if defined(LINUX) || defined(EMSCRIPTEN)
|
||||
tid_ = gettid();
|
||||
#endif
|
||||
#endif //EMSCRIPTEN
|
||||
setPriority(priority_);
|
||||
setThreadName();
|
||||
PIINTROSPECTION_THREAD_START(this);
|
||||
|
||||
Reference in New Issue
Block a user