Merge branch 'feature-freebsd-posix' into develop

This commit is contained in:
Jinhao 2018-05-08 04:52:13 +08:00
commit c72d8e25b4
32 changed files with 509 additions and 255 deletions

View File

@ -22,24 +22,6 @@ matrix:
- libxft-dev - libxft-dev
sources: sources:
- ubuntu-toolchain-r-test - ubuntu-toolchain-r-test
- env: CXX=g++-4.9 CC=gcc-4.9
addons:
apt:
packages:
- g++-4.9
- libjpeg8-dev
- libpng-dev
- libasound2-dev
- alsa-utils
- alsa-oss
- libx11-dev
- libxft-dev
- libboost-filesystem-dev
- libboost-system-dev
- libboost-thread-dev
- libboost-chrono-dev
sources:
- ubuntu-toolchain-r-test
allow_failures: allow_failures:
- env: CXX=clang++-3.8 CC=clang-3.8 - env: CXX=clang++-3.8 CC=clang-3.8

View File

@ -152,16 +152,27 @@ if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
if(NANA_CMAKE_SHARED_LIB) if(NANA_CMAKE_SHARED_LIB)
list(APPEND NANA_LINKS -lgcc -lstdc++ -pthread) list(APPEND NANA_LINKS -lgcc -lstdc++ -pthread)
else() else()
set(CMAKE_EXE_LINKER_FLAGS "-static -pthread") set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -pthread")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-s") # message("Setting NANA_LINKS to -static-libgcc -static-libstdc++ -pthread or ${NANA_LINKS}")
endif() endif(NANA_CMAKE_SHARED_LIB)
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
# GCC 4.9
list(APPEND NANA_LINKS "-lboost_system -lboost_thread")
elseif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3)
# IS_GNUCXX < 5.3
else()
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3) if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3)
list(APPEND NANA_LINKS -lstdc++fs) list(APPEND NANA_LINKS -lstdc++fs)
endif() endif()
endif()
if(APPLE AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") endif(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # AND NOT MINGW
if (APPLE AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # APPLE Clang
# set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libstdc++")
list(APPEND NANA_LINKS -stdlib=libstdc++) list(APPEND NANA_LINKS -stdlib=libstdc++)
endif () endif ()
@ -358,6 +369,7 @@ message("NANA_CMAKE_ENABLE_AUDIO = " ${NANA_CMAKE_ENABLE_AUDIO})
message ( "NANA_CMAKE_SHARED_LIB = " ${NANA_CMAKE_SHARED_LIB}) message ( "NANA_CMAKE_SHARED_LIB = " ${NANA_CMAKE_SHARED_LIB})
message ( "NANA_CLION = " ${NANA_CLION}) message ( "NANA_CLION = " ${NANA_CLION})
message ( "CMAKE_MAKE_PROGRAM = " ${CMAKE_MAKE_PROGRAM}) message ( "CMAKE_MAKE_PROGRAM = " ${CMAKE_MAKE_PROGRAM})
message ( "CMAKE_CXX_COMPILER_VERSION = " ${CMAKE_CXX_COMPILER_VERSION})
message ( "NANA_CMAKE_FIND_BOOST_FILESYSTEM = " ${NANA_CMAKE_FIND_BOOST_FILESYSTEM}) message ( "NANA_CMAKE_FIND_BOOST_FILESYSTEM = " ${NANA_CMAKE_FIND_BOOST_FILESYSTEM})
message ( "NANA_CMAKE_BOOST_FILESYSTEM_FORCE = " ${NANA_CMAKE_BOOST_FILESYSTEM_FORCE}) message ( "NANA_CMAKE_BOOST_FILESYSTEM_FORCE = " ${NANA_CMAKE_BOOST_FILESYSTEM_FORCE})

View File

@ -11,6 +11,8 @@
#include <windows.h> #include <windows.h>
#elif defined(NANA_LINUX) #elif defined(NANA_LINUX)
#include <alsa/asoundlib.h> #include <alsa/asoundlib.h>
#elif defined(NANA_POSIX)
#include <sys/soundcard.h>
#endif #endif
namespace nana{ namespace audio namespace nana{ namespace audio
@ -34,7 +36,6 @@ namespace nana{ namespace audio
static void __stdcall _m_dev_callback(HWAVEOUT handle, UINT msg, audio_device * self, DWORD_PTR, DWORD_PTR); static void __stdcall _m_dev_callback(HWAVEOUT handle, UINT msg, audio_device * self, DWORD_PTR, DWORD_PTR);
#endif #endif
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
HWAVEOUT handle_; HWAVEOUT handle_;
std::recursive_mutex queue_lock_; std::recursive_mutex queue_lock_;
@ -45,6 +46,12 @@ namespace nana{ namespace audio
std::size_t channels_; std::size_t channels_;
std::size_t bytes_per_sample_; std::size_t bytes_per_sample_;
std::size_t bytes_per_frame_; std::size_t bytes_per_frame_;
#elif defined(NANA_POSIX)
int handle_;
int rate_;
int channels_;
int bytes_per_sample_;
int bytes_per_frame_;
#endif #endif
buffer_preparation * buf_prep_; buffer_preparation * buf_prep_;
}; };

View File

@ -33,7 +33,7 @@ namespace nana{ namespace audio{
unsigned short wBitsPerSample; unsigned short wBitsPerSample;
}; };
#pragma pack() #pragma pack()
#elif defined(NANA_LINUX) #elif defined(NANA_POSIX)
struct master_riff_chunk struct master_riff_chunk
{ {
unsigned ckID; //"RIFF" unsigned ckID; //"RIFF"

View File

@ -32,7 +32,7 @@ namespace nana{ namespace audio
public: public:
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
typedef WAVEHDR meta; typedef WAVEHDR meta;
#elif defined(NANA_LINUX) #elif defined(NANA_POSIX)
struct meta struct meta
{ {
char * buf; char * buf;

View File

@ -68,9 +68,16 @@
# endif # endif
#endif #endif
// Set this to "UTF-32" at the command-line for big endian.
#ifndef NANA_UNICODE
// much of the world runs intel compatible processors so default to LE.
#define NANA_UNICODE "UTF-32LE"
#endif
// Select platform ...... // Select platform ......
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) //Microsoft Windows #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) //Microsoft Windows
#define NANA_WINDOWS #define NANA_WINDOWS
typedef DWORD_PTR thread_t;
// MINGW ... // MINGW ...
#if defined(__MINGW32__) || defined(__MINGW64__) || defined(MINGW) #if defined(__MINGW32__) || defined(__MINGW64__) || defined(MINGW)
@ -79,24 +86,23 @@
#elif defined(APPLE) //Mac OS X #elif defined(APPLE) //Mac OS X
//Symbols for MACOS //Symbols for MACOS
#define NANA_MACOS #define NANA_MACOS
#define NANA_POSIX
#define NANA_X11 #define NANA_X11
typedef unsigned long thread_t;
#elif defined(__FreeBSD__)
#define NANA_POSIX
#define NANA_X11
typedef unsigned long thread_t;
#elif (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC) //Linux #elif (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC) //Linux
#define NANA_LINUX #define NANA_LINUX
#define NANA_X11
#else
static_assert(false, "Only Windows and Unix are supported now (Mac OS is experimental)");
#endif
//Define a symbol for POSIX operating system.
#if defined(NANA_LINUX) || defined(NANA_MACOS)
#define NANA_POSIX #define NANA_POSIX
#define NANA_X11
typedef unsigned long thread_t;
#else
static_assert(false, "Only Windows and Linux are supported now (Mac OS and BSD are experimental)");
#endif #endif
// Select compiler ... // Select compiler ...
#if defined(_MSC_VER) //Microsoft Visual C++ #if defined(_MSC_VER) //Microsoft Visual C++
#define _SCL_SECURE_NO_WARNNGS #define _SCL_SECURE_NO_WARNNGS

View File

@ -27,7 +27,7 @@ namespace filesystem_ext
constexpr auto const def_root = "C:"; constexpr auto const def_root = "C:";
constexpr auto const def_rootstr = "C:\\"; constexpr auto const def_rootstr = "C:\\";
constexpr auto const def_rootname = "Local Drive(C:)"; constexpr auto const def_rootname = "Local Drive(C:)";
#elif defined(NANA_LINUX) #elif defined(NANA_POSIX)
constexpr auto const def_root = "/"; constexpr auto const def_root = "/";
constexpr auto const def_rootstr = "/"; constexpr auto const def_rootstr = "/";
constexpr auto const def_rootname = "Root/"; constexpr auto const def_rootname = "Root/";

View File

@ -139,7 +139,7 @@ namespace detail
void _m_init_pos_and_size(basic_window* parent, const rectangle&); void _m_init_pos_and_size(basic_window* parent, const rectangle&);
void _m_initialize(basic_window* parent); void _m_initialize(basic_window* parent);
public: public:
#if defined(NANA_LINUX) || defined(NANA_MACOS) #if defined(NANA_POSIX)
point pos_native; point pos_native;
#endif #endif
point pos_root; ///< coordinates of the root window point pos_root; ///< coordinates of the root window
@ -248,7 +248,7 @@ namespace detail
}other; }other;
native_window_type root; ///< root Window handle native_window_type root; ///< root Window handle
unsigned thread_id; ///< the identifier of the thread that created the window. thread_t thread_id; ///< the identifier of the thread that created the window.
unsigned index; unsigned index;
container children; container children;
}; };

View File

@ -46,10 +46,10 @@ namespace detail
~bedrock(); ~bedrock();
void pump_event(window, bool is_modal); void pump_event(window, bool is_modal);
void flush_surface(core_window_t*, bool forced, const rectangle* update_area = nullptr); void flush_surface(core_window_t*, bool forced, const rectangle* update_area = nullptr);
static int inc_window(unsigned tid = 0); static int inc_window(thread_t tid = 0);
thread_context* open_thread_context(unsigned tid = 0); thread_context* open_thread_context(thread_t tid = 0);
thread_context* get_thread_context(unsigned tid = 0); thread_context* get_thread_context(thread_t tid = 0);
void remove_thread_context(unsigned tid = 0); void remove_thread_context(thread_t tid = 0);
static bedrock& instance(); static bedrock& instance();
core_window_t* focus(); core_window_t* focus();
@ -73,7 +73,7 @@ namespace detail
void map_through_widgets(core_window_t*, native_drawable_type); void map_through_widgets(core_window_t*, native_drawable_type);
//Closes the windows which are associated with the specified thread. If the given thread_id is 0, it closes all windows //Closes the windows which are associated with the specified thread. If the given thread_id is 0, it closes all windows
void close_thread_window(unsigned thread_id); void close_thread_window(thread_t thread_id);
public: public:
//Platform-dependent functions //Platform-dependent functions

View File

@ -139,7 +139,7 @@ namespace detail
void enable_tabstop(core_window_t*); void enable_tabstop(core_window_t*);
core_window_t* tabstop(core_window_t*, bool forward) const; //forward means move to next in logic. core_window_t* tabstop(core_window_t*, bool forward) const; //forward means move to next in logic.
void remove_trash_handle(unsigned tid); void remove_trash_handle(thread_t tid);
bool enable_effects_bground(core_window_t*, bool); bool enable_effects_bground(core_window_t*, bool);
@ -154,7 +154,7 @@ namespace detail
core_window_t* find_shortkey(native_window_type, unsigned long key); core_window_t* find_shortkey(native_window_type, unsigned long key);
void set_safe_place(core_window_t* wd, std::function<void()>&& fn); void set_safe_place(core_window_t* wd, std::function<void()>&& fn);
void call_safe_place(unsigned thread_id); void call_safe_place(thread_t thread_id);
private: private:
void _m_disengage(core_window_t*, core_window_t* for_new); void _m_disengage(core_window_t*, core_window_t* for_new);
void _m_destroy(core_window_t*); void _m_destroy(core_window_t*);

View File

@ -26,7 +26,7 @@ namespace system
//this_thread_id //this_thread_id
//@brief: get the identifier of calling thread. //@brief: get the identifier of calling thread.
unsigned long this_thread_id(); thread_t this_thread_id();
//timestamp //timestamp
//@brief: it retrieves the timestamp at the time the function is called. //@brief: it retrieves the timestamp at the time the function is called.

View File

@ -5,11 +5,14 @@
#include <nana/system/platform.hpp> #include <nana/system/platform.hpp>
#if defined(NANA_LINUX) #if defined(NANA_POSIX)
#include <pthread.h> #include <pthread.h>
#include <unistd.h> #include <unistd.h>
#include <sys/time.h> #include <sys/time.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
static bool get_default_audio(std::string &, bool);
#endif #endif
namespace nana{namespace audio namespace nana{namespace audio
@ -47,6 +50,8 @@ namespace nana{namespace audio
audio_device::audio_device() audio_device::audio_device()
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
: handle_(nullptr), buf_prep_(nullptr) : handle_(nullptr), buf_prep_(nullptr)
#elif defined(NANA_POSIX)
: handle_(-1), buf_prep_(nullptr)
#elif defined(NANA_LINUX) #elif defined(NANA_LINUX)
: handle_(nullptr), buf_prep_(nullptr) : handle_(nullptr), buf_prep_(nullptr)
#endif #endif
@ -59,7 +64,11 @@ namespace nana{namespace audio
bool audio_device::empty() const bool audio_device::empty() const
{ {
#ifdef NANA_POSIX
return (-1 == handle_);
#else
return (nullptr == handle_); return (nullptr == handle_);
#endif
} }
bool audio_device::open(std::size_t channels, std::size_t rate, std::size_t bits_per_sample) bool audio_device::open(std::size_t channels, std::size_t rate, std::size_t bits_per_sample)
@ -80,6 +89,7 @@ namespace nana{namespace audio
MMRESULT mmr = wave_native_if.out_open(&handle_, WAVE_MAPPER, &wfx, reinterpret_cast<DWORD_PTR>(&audio_device::_m_dev_callback), reinterpret_cast<DWORD_PTR>(this), CALLBACK_FUNCTION); MMRESULT mmr = wave_native_if.out_open(&handle_, WAVE_MAPPER, &wfx, reinterpret_cast<DWORD_PTR>(&audio_device::_m_dev_callback), reinterpret_cast<DWORD_PTR>(this), CALLBACK_FUNCTION);
return (mmr == MMSYSERR_NOERROR); return (mmr == MMSYSERR_NOERROR);
#elif defined(NANA_LINUX) #elif defined(NANA_LINUX)
// assumes ALSA sub-system
if(nullptr == handle_) if(nullptr == handle_)
{ {
if(::snd_pcm_open(&handle_, "plughw:0,0", SND_PCM_STREAM_PLAYBACK, 0) < 0) if(::snd_pcm_open(&handle_, "plughw:0,0", SND_PCM_STREAM_PLAYBACK, 0) < 0)
@ -159,6 +169,51 @@ namespace nana{namespace audio
return true; return true;
} }
return false; return false;
#elif defined(NANA_POSIX)
std::string dsp;
if ( !get_default_audio(dsp, true) )
return false;
handle_ = ::open(dsp.c_str(), O_WRONLY);
if (handle_ == -1)
return false;
int zero = 0;
int caps = 0;
int fragment = 0x200008L;
int ok;
ok = ioctl(handle_, SNDCTL_DSP_COOKEDMODE, &zero);
if (ok >= 0)
{
ok = ioctl(handle_, SNDCTL_DSP_SETFRAGMENT, &fragment);
if (ok >= 0)
{
ok = ioctl(handle_, SNDCTL_DSP_GETCAPS, &caps);
if (ok >= 0)
{
ok = ioctl(handle_, SNDCTL_DSP_SETFMT, &bits_per_sample);
if (ok >= 0)
{
ok = ioctl(handle_, SNDCTL_DSP_CHANNELS, &channels);
if (ok >= 0)
{
ok = ioctl(handle_, SNDCTL_DSP_SPEED, &rate);
if (ok >= 0)
{
channels_ = channels;
rate_ = rate;
bytes_per_sample_ = ( (bits_per_sample + 7) >> 3 );
bytes_per_frame_ = bytes_per_sample_ * channels;
return true;
}
}
}
}
}
}
// failure so close handle.
::close(handle_);
handle_ = -1;
return false;
#endif #endif
} }
@ -168,10 +223,14 @@ namespace nana{namespace audio
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
wave_native_if.out_close(handle_); wave_native_if.out_close(handle_);
handle_ = nullptr;
#elif defined(__FreeBSD__)
::close(handle_);
handle_ = 0;
#elif defined(NANA_LINUX) #elif defined(NANA_LINUX)
::snd_pcm_close(handle_); ::snd_pcm_close(handle_);
#endif
handle_ = nullptr; handle_ = nullptr;
#endif
} }
} }
@ -190,6 +249,11 @@ namespace nana{namespace audio
wave_native_if.out_prepare(handle_, m, sizeof(WAVEHDR)); wave_native_if.out_prepare(handle_, m, sizeof(WAVEHDR));
wave_native_if.out_write(handle_, m, sizeof(WAVEHDR)); wave_native_if.out_write(handle_, m, sizeof(WAVEHDR));
#elif defined(NANA_POSIX)
// consider moving this to a background thread.
// currently this blocks calling thread.
::write(handle_, m->buf, m->bufsize);
buf_prep_->revert(m);
#elif defined(NANA_LINUX) #elif defined(NANA_LINUX)
std::size_t frames = m->bufsize / bytes_per_frame_; std::size_t frames = m->bufsize / bytes_per_frame_;
std::size_t buffered = 0; //in bytes std::size_t buffered = 0; //in bytes
@ -240,4 +304,144 @@ namespace nana{namespace audio
}//end namespace audio }//end namespace audio
}//end namespace nana }//end namespace nana
#ifdef NANA_POSIX
// parse input securely, no-overruns or overflows.
static bool match(char *&cursor, const char *pattern, const char *tail)
{
char *skim = cursor;
while (*skim != '\n' && *pattern != 0 && cursor != tail)
{
if (*pattern != *skim)
return false;
pattern++;
skim++;
}
if (*pattern == 0)
{
cursor = skim;
return true;
}
return false;
}
// parse input securely, no-overruns or overflows.
static bool skip(char *&cursor, const char stop, const char *tail)
{
char *skim = cursor;
while (*skim != '\n' && cursor != tail)
{
if (stop == *skim)
{
cursor = skim;
return true;
}
skim++;
}
return false;
}
struct audio_device
{
// pcm name
std::string device;
// /dev/dsp
std::string path;
// terse description
std::string description;
// can record eg. microphone or line-in.
bool rec;
// can play - speaker, headphone or line-out.
bool play;
// is the default device.
bool chosen;
};
static bool get_audio_devices(std::vector<audio_device> &list)
{
// read the sndstat device to get a list of audio devices.
// mostly OSS but some ALSA installs mimic this.
FILE *cat = fopen("/dev/sndstat", "r");
if (cat != 0)
{
char line[128] = {0};
const char *last = line + sizeof line;
while ( fgets(line, sizeof line, cat) != 0 )
{
// extract five things about a device: name, description, play, rec, and default.
audio_device next;
char *cursor = line;
// ignore these lines
if ( match(cursor, "Installed", last) || match(cursor, "No devices", last) )
continue;
const char *device = cursor;
if ( !skip(cursor, ':', last) )
continue;
// nul terminate device name.
*cursor++ = 0;
next.device = device;
if ( !skip(cursor, '<', last) )
continue;
const char *description = ++cursor;
if ( !skip(cursor, '>', last) )
continue;
// nul terminate description.
*cursor++ = 0;
next.description = description;
if ( !skip(cursor, '(', last) )
continue;
cursor++;
// supports play?
next.play = match(cursor, "play", last);
if (next.play)
match(cursor, "/", last);
// supports record?
next.rec = match(cursor, "rec", last);
if ( !skip(cursor, ')', last) )
continue;
cursor++;
// default ?
if ( match(cursor, " ", last) )
next.chosen = match(cursor, "default", last);
if (next.device.compare(0, 3, "pcm") == 0)
{
// proper dev path with number appended.
next.path = "/dev/dsp";
next.path += next.device.c_str() + 3;
}
list.push_back(next);
}
fclose(cat);
}
return list.size() > 0;
}
static bool get_default_audio(std::string &dsp, bool play)
{
std::vector<audio_device> list;
if ( !get_audio_devices(list) )
return false;
for (auto it = list.begin(); it != list.end(); it++)
{
if ( (it->play && play) || (it->rec && !play) )
{
if (it->chosen)
{
dsp = it->path;
return true;
}
}
}
return false;
}
#endif //NANA_POSIX
#endif //NANA_ENABLE_AUDIO #endif //NANA_ENABLE_AUDIO

View File

@ -26,6 +26,7 @@ namespace nana{ namespace audio
memset(m, 0, sizeof(meta)); memset(m, 0, sizeof(meta));
m->dwBufferLength = static_cast<unsigned long>(block_size_); m->dwBufferLength = static_cast<unsigned long>(block_size_);
m->lpData = rawbuf + sizeof(meta); m->lpData = rawbuf + sizeof(meta);
#elif defined(__FreeBSD__)
#elif defined(NANA_LINUX) #elif defined(NANA_LINUX)
m->bufsize = ck.nAvgBytesPerSec; m->bufsize = ck.nAvgBytesPerSec;
m->buf = rawbuf + sizeof(meta); m->buf = rawbuf + sizeof(meta);
@ -124,6 +125,7 @@ namespace nana{ namespace audio
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
memcpy(m->lpData + buffered, buf, read_bytes); memcpy(m->lpData + buffered, buf, read_bytes);
#elif defined(__FreeBSD__)
#elif defined(NANA_LINUX) #elif defined(NANA_LINUX)
memcpy(m->buf + buffered, buf, read_bytes); memcpy(m->buf + buffered, buf, read_bytes);
#endif #endif
@ -144,6 +146,7 @@ namespace nana{ namespace audio
} }
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
m->dwBufferLength = static_cast<unsigned long>(buffered); m->dwBufferLength = static_cast<unsigned long>(buffered);
#elif defined(__FreeBSD__)
#elif defined(NANA_LINUX) #elif defined(NANA_LINUX)
m->bufsize = buffered; m->bufsize = buffered;
#endif #endif

View File

@ -234,7 +234,7 @@ namespace nana
}; };
/// convert wchar C string from ? ANSI code page CP_ACP (windows) or LC_CTYPE c locale (-nix) into utf8 std::string /// convert wchar C string from ? ANSI code page CP_ACP (windows) or LC_CTYPE c locale (-nix) into utf8 std::string
bool wc2mb(std::string& mbstr, const wchar_t * s) static bool wc2mb(std::string& mbstr, const wchar_t * s)
{ {
if(nullptr == s || *s == 0) if(nullptr == s || *s == 0)
{ {
@ -268,7 +268,7 @@ namespace nana
} }
/// convert a char C-string from The system default Windows ANSI code page CP_ACP or from LC_CTYPE c locale (-nix) into utf16 std::wstring /// convert a char C-string from The system default Windows ANSI code page CP_ACP or from LC_CTYPE c locale (-nix) into utf16 std::wstring
bool mb2wc(std::wstring& wcstr, const char* s) static bool mb2wc(std::wstring& wcstr, const char* s)
{ {
if(nullptr == s || *s == 0) if(nullptr == s || *s == 0)
{ {
@ -561,7 +561,7 @@ namespace nana
std::u32string utf32str = std::wstring_convert<std::codecvt_utf16<char32_t>, char32_t>().from_bytes(bytes, bytes + sizeof(wchar_t) * wcstr.size()); std::u32string utf32str = std::wstring_convert<std::codecvt_utf16<char32_t>, char32_t>().from_bytes(bytes, bytes + sizeof(wchar_t) * wcstr.size());
return std::string(reinterpret_cast<const char*>(utf32str.c_str()), sizeof(char32_t) * utf32str.size()); return std::string(reinterpret_cast<const char*>(utf32str.c_str()), sizeof(char32_t) * utf32str.size());
} }
#elif defined(NANA_LINUX) || defined(NANA_MACOS) #elif defined(NANA_POSIX)
return std::string(reinterpret_cast<const char*>(wcstr.c_str()), sizeof(wchar_t) * wcstr.size()); return std::string(reinterpret_cast<const char*>(wcstr.c_str()), sizeof(wchar_t) * wcstr.size());
#else #else
throw std::runtime_error("Bad charset"); throw std::runtime_error("Bad charset");
@ -653,7 +653,7 @@ namespace nana
std::u32string utf32str = std::wstring_convert<std::codecvt_utf16<char32_t>, char32_t>().from_bytes(bytes, bytes + sizeof(wchar_t) * data_.size()); std::u32string utf32str = std::wstring_convert<std::codecvt_utf16<char32_t>, char32_t>().from_bytes(bytes, bytes + sizeof(wchar_t) * data_.size());
return std::string(reinterpret_cast<const char*>(utf32str.c_str()), sizeof(char32_t) * utf32str.size()); return std::string(reinterpret_cast<const char*>(utf32str.c_str()), sizeof(char32_t) * utf32str.size());
} }
#elif defined(NANA_LINUX) || defined(NANA_MACOS) #elif defined(NANA_POSIX)
return std::string(reinterpret_cast<const char*>(data_.c_str()), data_.size() * sizeof(wchar_t)); return std::string(reinterpret_cast<const char*>(data_.c_str()), data_.size() * sizeof(wchar_t));
#else #else
throw std::runtime_error("Bad charset"); throw std::runtime_error("Bad charset");

View File

@ -19,12 +19,11 @@
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
#include <windows.h> #include <windows.h>
#elif defined(NANA_LINUX) || defined(NANA_MACOS) #elif defined(NANA_POSIX)
#include <string.h> #include <string.h>
#include "detail/platform_spec_selector.hpp" #include "detail/platform_spec_selector.hpp"
#endif #endif
#include <iostream> #include <iostream>
namespace nana namespace nana

View File

@ -214,7 +214,7 @@ namespace detail
struct timer_tag struct timer_tag
{ {
std::size_t id; std::size_t id;
unsigned tid; thread_t tid;
std::size_t interval; std::size_t interval;
std::size_t timestamp; std::size_t timestamp;
timer_proc_t proc; timer_proc_t proc;
@ -250,7 +250,7 @@ namespace detail
i->second.proc = proc; i->second.proc = proc;
return; return;
} }
unsigned tid = nana::system::this_thread_id(); auto tid = nana::system::this_thread_id();
threadmap_[tid].timers.insert(id); threadmap_[tid].timers.insert(id);
timer_tag & tag = holder_[id]; timer_tag & tag = holder_[id];
@ -295,7 +295,7 @@ namespace detail
return (holder_.empty()); return (holder_.empty());
} }
void timer_proc(unsigned tid) void timer_proc(thread_t tid)
{ {
is_proc_handling_ = true; is_proc_handling_ = true;
auto i = threadmap_.find(tid); auto i = threadmap_.find(tid);
@ -329,7 +329,7 @@ namespace detail
} }
private: private:
bool is_proc_handling_; bool is_proc_handling_;
std::map<unsigned, timer_group> threadmap_; std::map<thread_t, timer_group> threadmap_;
std::map<std::size_t, timer_tag> holder_; std::map<std::size_t, timer_tag> holder_;
}; };
@ -339,8 +339,8 @@ namespace detail
string.tab_pixels = 0; string.tab_pixels = 0;
string.whitespace_pixels = 0; string.whitespace_pixels = 0;
#if defined(NANA_USE_XFT) #if defined(NANA_USE_XFT)
conv_.handle = ::iconv_open("UTF-8", "UTF-32"); conv_.handle = ::iconv_open("UTF-8", NANA_UNICODE);
conv_.code = "UTF-32"; conv_.code = NANA_UNICODE;
#endif #endif
} }
@ -966,7 +966,7 @@ namespace detail
} }
} }
void platform_spec::timer_proc(unsigned tid) void platform_spec::timer_proc(thread_t tid)
{ {
std::lock_guard<decltype(timer_.mutex)> lock(timer_.mutex); std::lock_guard<decltype(timer_.mutex)> lock(timer_.mutex);
if(timer_.runner) if(timer_.runner)

View File

@ -16,6 +16,6 @@
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
#include "mswin/platform_spec.hpp" #include "mswin/platform_spec.hpp"
#elif defined(NANA_LINUX) || defined(NANA_MACOS) #elif defined(NANA_POSIX)
#include "posix/platform_spec.hpp" #include "posix/platform_spec.hpp"
#endif #endif

View File

@ -35,7 +35,7 @@ namespace detail
{ {
struct thread_binder struct thread_binder
{ {
unsigned tid; thread_t tid;
std::mutex mutex; std::mutex mutex;
std::condition_variable cond; std::condition_variable cond;
std::list<msg_packet_tag> msg_queue; std::list<msg_packet_tag> msg_queue;
@ -44,7 +44,7 @@ namespace detail
public: public:
typedef msg_packet_tag msg_packet; typedef msg_packet_tag msg_packet;
typedef void (*timer_proc_type)(unsigned tid); typedef void (*timer_proc_type)(thread_t tid);
typedef void (*event_proc_type)(Display*, msg_packet_tag&); typedef void (*event_proc_type)(Display*, msg_packet_tag&);
typedef int (*event_filter_type)(XEvent&, msg_packet_tag&); typedef int (*event_filter_type)(XEvent&, msg_packet_tag&);
@ -76,7 +76,7 @@ namespace detail
void insert(Window wd) void insert(Window wd)
{ {
unsigned tid = nana::system::this_thread_id(); auto tid = nana::system::this_thread_id();
bool start_driver; bool start_driver;
@ -87,7 +87,7 @@ namespace detail
start_driver = (0 == table_.thr_table.size()); start_driver = (0 == table_.thr_table.size());
thread_binder * thr; thread_binder * thr;
std::map<unsigned, thread_binder*>::iterator i = table_.thr_table.find(tid); std::map<thread_t, thread_binder*>::iterator i = table_.thr_table.find(tid);
if(i == table_.thr_table.end()) if(i == table_.thr_table.end())
{ {
thr = new thread_binder; thr = new thread_binder;
@ -151,7 +151,7 @@ namespace detail
void dispatch(Window modal) void dispatch(Window modal)
{ {
unsigned tid = nana::system::this_thread_id(); auto tid = nana::system::this_thread_id();
msg_packet_tag msg; msg_packet_tag msg;
int qstate; int qstate;
@ -270,7 +270,7 @@ namespace detail
//_m_read_queue //_m_read_queue
//@brief:Read the event from a specified thread queue. //@brief:Read the event from a specified thread queue.
//@return: 0 = exit the queue, 1 = fetch the msg, -1 = no msg //@return: 0 = exit the queue, 1 = fetch the msg, -1 = no msg
int _m_read_queue(unsigned tid, msg_packet_tag& msg, Window modal) int _m_read_queue(thread_t tid, msg_packet_tag& msg, Window modal)
{ {
bool stop_driver = false; bool stop_driver = false;
@ -317,7 +317,7 @@ namespace detail
//_m_wait_for_queue //_m_wait_for_queue
// wait for the insertion of queue. // wait for the insertion of queue.
//return@ it returns true if the queue is not empty, otherwise the wait is timeout. //return@ it returns true if the queue is not empty, otherwise the wait is timeout.
bool _m_wait_for_queue(unsigned tid) bool _m_wait_for_queue(thread_t tid)
{ {
thread_binder * thr = nullptr; thread_binder * thr = nullptr;
{ {
@ -344,7 +344,7 @@ namespace detail
struct table_tag struct table_tag
{ {
std::recursive_mutex mutex; std::recursive_mutex mutex;
std::map<unsigned, thread_binder*> thr_table; std::map<thread_t, thread_binder*> thr_table;
std::map<Window, thread_binder*> wnd_table; std::map<Window, thread_binder*> wnd_table;
}table_; }table_;

View File

@ -13,7 +13,7 @@
* This file should not be included by any header files. * This file should not be included by any header files.
*/ */
#if defined(NANA_LINUX) || defined(NANA_MACOS) #if defined(NANA_POSIX)
#ifndef NANA_DETAIL_PLATFORM_SPEC_HPP #ifndef NANA_DETAIL_PLATFORM_SPEC_HPP
#define NANA_DETAIL_PLATFORM_SPEC_HPP #define NANA_DETAIL_PLATFORM_SPEC_HPP
@ -186,7 +186,7 @@ namespace detail
public: public:
int error_code; int error_code;
public: public:
typedef void (*timer_proc_type)(unsigned tid); typedef void (*timer_proc_type)(thread_t tid);
typedef void (*event_proc_type)(Display*, msg_packet_tag&); typedef void (*event_proc_type)(Display*, msg_packet_tag&);
typedef ::nana::event_code event_code; typedef ::nana::event_code event_code;
typedef ::nana::native_window_type native_window_type; typedef ::nana::native_window_type native_window_type;
@ -235,7 +235,7 @@ namespace detail
Window grab(Window); Window grab(Window);
void set_timer(std::size_t id, std::size_t interval, void (*timer_proc)(std::size_t id)); void set_timer(std::size_t id, std::size_t interval, void (*timer_proc)(std::size_t id));
void kill_timer(std::size_t id); void kill_timer(std::size_t id);
void timer_proc(unsigned tid); void timer_proc(thread_t tid);
//Message dispatcher //Message dispatcher
void msg_insert(native_window_type); void msg_insert(native_window_type);
@ -319,6 +319,5 @@ namespace detail
// .h ward // .h ward
#endif #endif
//#if defined(NANA_LINUX) || defined(NANA_MACOS)
#endif #endif

View File

@ -58,7 +58,7 @@ namespace nana
wchar_t pstr[MAX_PATH]; wchar_t pstr[MAX_PATH];
if (SUCCEEDED(SHGetFolderPath(0, CSIDL_PROFILE, 0, SHGFP_TYPE_CURRENT, pstr))) if (SUCCEEDED(SHGetFolderPath(0, CSIDL_PROFILE, 0, SHGFP_TYPE_CURRENT, pstr)))
return pstr; return pstr;
#elif defined(NANA_LINUX) || defined(NANA_MACOS) #elif defined(NANA_POSIX)
const char * pstr = ::getenv("HOME"); const char * pstr = ::getenv("HOME");
if (pstr) if (pstr)
return pstr; return pstr;
@ -208,7 +208,7 @@ namespace nana { namespace experimental { namespace filesystem
//Because of No wide character version of POSIX //Because of No wide character version of POSIX
#if defined(NANA_LINUX) || defined(NANA_MACOS) #if defined(NANA_POSIX)
const char* splstr = "/"; const char* splstr = "/";
#else #else
const wchar_t* splstr = L"/\\"; const wchar_t* splstr = L"/\\";
@ -251,7 +251,7 @@ namespace nana { namespace experimental { namespace filesystem
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
return (::GetFileAttributes(pathstr_.c_str()) == INVALID_FILE_ATTRIBUTES); return (::GetFileAttributes(pathstr_.c_str()) == INVALID_FILE_ATTRIBUTES);
#elif defined(NANA_LINUX) || defined(NANA_MACOS) #elif defined(NANA_POSIX)
struct stat sta; struct stat sta;
return (::stat(pathstr_.c_str(), &sta) == -1); return (::stat(pathstr_.c_str(), &sta) == -1);
#endif #endif
@ -293,7 +293,7 @@ namespace nana { namespace experimental { namespace filesystem
return file_type::directory; return file_type::directory;
return file_type::regular; return file_type::regular;
#elif defined(NANA_LINUX) || defined(NANA_MACOS) #elif defined(NANA_POSIX)
struct stat sta; struct stat sta;
if (-1 == ::stat(pathstr_.c_str(), &sta)) if (-1 == ::stat(pathstr_.c_str(), &sta))
return file_type::not_found; //?? return file_type::not_found; //??
@ -518,7 +518,7 @@ namespace nana { namespace experimental { namespace filesystem
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
::FindClose(*handle); ::FindClose(*handle);
#elif defined(NANA_LINUX) || defined(NANA_MACOS) #elif defined(NANA_POSIX)
::closedir(*reinterpret_cast<DIR**>(handle)); ::closedir(*reinterpret_cast<DIR**>(handle));
#endif #endif
} }
@ -877,7 +877,7 @@ namespace nana { namespace experimental { namespace filesystem
# if defined(NANA_LINUX) # if defined(NANA_LINUX)
fseeko64(stream, 0, SEEK_END); fseeko64(stream, 0, SEEK_END);
size = ftello64(stream); size = ftello64(stream);
# elif defined(NANA_MACOS) # elif defined(NANA_POSIX)
fseeko(stream, 0, SEEK_END); fseeko(stream, 0, SEEK_END);
size = ftello(stream); size = ftello(stream);
# endif # endif

View File

@ -119,7 +119,7 @@ namespace nana
} }
} }
void bedrock::close_thread_window(unsigned thread_id) void bedrock::close_thread_window(thread_t thread_id)
{ {
std::vector<core_window_t*> v; std::vector<core_window_t*> v;
wd_manager().all_handles(v); wd_manager().all_handles(v);

View File

@ -93,13 +93,13 @@ namespace detail
{ {
struct thread_context_cache struct thread_context_cache
{ {
unsigned tid{ 0 }; thread_t tid{ 0 };
thread_context *object{ nullptr }; thread_context *object{ nullptr };
}tcontext; }tcontext;
}cache; }cache;
}; };
void timer_proc(unsigned); void timer_proc(thread_t);
void window_proc_dispatcher(Display*, nana::detail::msg_packet_tag&); void window_proc_dispatcher(Display*, nana::detail::msg_packet_tag&);
void window_proc_for_packet(Display *, nana::detail::msg_packet_tag&); void window_proc_for_packet(Display *, nana::detail::msg_packet_tag&);
void window_proc_for_xevent(Display*, XEvent&); void window_proc_for_xevent(Display*, XEvent&);
@ -175,7 +175,7 @@ namespace detail
//inc_window //inc_window
//@biref: increament the number of windows //@biref: increament the number of windows
int bedrock::inc_window(unsigned tid) int bedrock::inc_window(thread_t tid)
{ {
private_impl * impl = instance().impl_; private_impl * impl = instance().impl_;
std::lock_guard<decltype(impl->mutex)> lock(impl->mutex); std::lock_guard<decltype(impl->mutex)> lock(impl->mutex);
@ -184,7 +184,7 @@ namespace detail
return (cnt < 0 ? cnt = 1 : ++cnt); return (cnt < 0 ? cnt = 1 : ++cnt);
} }
bedrock::thread_context* bedrock::open_thread_context(unsigned tid) bedrock::thread_context* bedrock::open_thread_context(thread_t tid)
{ {
if(0 == tid) tid = nana::system::this_thread_id(); if(0 == tid) tid = nana::system::this_thread_id();
@ -205,7 +205,7 @@ namespace detail
return context; return context;
} }
bedrock::thread_context* bedrock::get_thread_context(unsigned tid) bedrock::thread_context* bedrock::get_thread_context(thread_t tid)
{ {
if(0 == tid) tid = nana::system::this_thread_id(); if(0 == tid) tid = nana::system::this_thread_id();
@ -224,7 +224,7 @@ namespace detail
return 0; return 0;
} }
void bedrock::remove_thread_context(unsigned tid) void bedrock::remove_thread_context(thread_t tid)
{ {
if(0 == tid) tid = nana::system::this_thread_id(); if(0 == tid) tid = nana::system::this_thread_id();
@ -406,7 +406,7 @@ namespace detail
} }
void timer_proc(unsigned tid) void timer_proc(thread_t tid)
{ {
nana::detail::platform_spec::instance().timer_proc(tid); nana::detail::platform_spec::instance().timer_proc(tid);
} }
@ -1069,10 +1069,10 @@ namespace detail
{ {
const wchar_t* charbuf; const wchar_t* charbuf;
nana::detail::charset_conv charset("UTF-32", "UTF-8"); nana::detail::charset_conv charset(NANA_UNICODE, "UTF-8");
const std::string& str = charset.charset(std::string(keybuf, keybuf + len)); const std::string& str = charset.charset(std::string(keybuf, keybuf + len));
charbuf = reinterpret_cast<const wchar_t*>(str.c_str()) + 1; charbuf = reinterpret_cast<const wchar_t*>(str.c_str());
len = str.size() / sizeof(wchar_t) - 1; len = str.size() / sizeof(wchar_t);
for(int i = 0; i < len; ++i) for(int i = 0; i < len; ++i)
{ {
@ -1080,6 +1080,9 @@ namespace detail
arg.ignore = false; arg.ignore = false;
arg.key = charbuf[i]; arg.key = charbuf[i];
// ignore Unicode BOM (it may or may not appear)
if (arg.key == 0xFEFF) continue;
//Only accept tab when it is not ignored. //Only accept tab when it is not ignored.
if ((keyboard::tab == arg.key) && root_runtime->condition.ignore_tab) if ((keyboard::tab == arg.key) && root_runtime->condition.ignore_tab)
continue; continue;

View File

@ -176,7 +176,7 @@ namespace detail
{ {
struct thread_context_cache struct thread_context_cache
{ {
unsigned tid{ 0 }; thread_t tid{ 0 };
thread_context *object{ nullptr }; thread_context *object{ nullptr };
}tcontext; }tcontext;
}cache; }cache;
@ -251,7 +251,7 @@ namespace detail
/// @brief increament the number of windows in the thread id /// @brief increament the number of windows in the thread id
int bedrock::inc_window(unsigned tid) int bedrock::inc_window(thread_t tid)
{ {
//impl refers to the object of private_impl, the object is created when bedrock is creating. //impl refers to the object of private_impl, the object is created when bedrock is creating.
private_impl * impl = instance().impl_; private_impl * impl = instance().impl_;
@ -261,7 +261,7 @@ namespace detail
return (cnt < 0 ? cnt = 1 : ++cnt); return (cnt < 0 ? cnt = 1 : ++cnt);
} }
auto bedrock::open_thread_context(unsigned tid) -> thread_context* auto bedrock::open_thread_context(thread_t tid) -> thread_context*
{ {
if(0 == tid) tid = nana::system::this_thread_id(); if(0 == tid) tid = nana::system::this_thread_id();
std::lock_guard<decltype(impl_->mutex)> lock(impl_->mutex); std::lock_guard<decltype(impl_->mutex)> lock(impl_->mutex);
@ -275,7 +275,7 @@ namespace detail
return context; return context;
} }
auto bedrock::get_thread_context(unsigned tid) -> thread_context * auto bedrock::get_thread_context(thread_t tid) -> thread_context *
{ {
if(0 == tid) tid = nana::system::this_thread_id(); if(0 == tid) tid = nana::system::this_thread_id();
@ -295,7 +295,7 @@ namespace detail
return nullptr; return nullptr;
} }
void bedrock::remove_thread_context(unsigned tid) void bedrock::remove_thread_context(thread_t tid)
{ {
if(0 == tid) tid = nana::system::this_thread_id(); if(0 == tid) tid = nana::system::this_thread_id();
@ -372,7 +372,7 @@ namespace detail
void bedrock::pump_event(window condition_wd, bool is_modal) void bedrock::pump_event(window condition_wd, bool is_modal)
{ {
const unsigned tid = ::GetCurrentThreadId(); thread_t tid = ::GetCurrentThreadId();
auto context = this->open_thread_context(tid); auto context = this->open_thread_context(tid);
if(0 == context->window_count) if(0 == context->window_count)
{ {

View File

@ -280,10 +280,10 @@ namespace detail
//class revertible_mutex //class revertible_mutex
struct thread_refcount struct thread_refcount
{ {
unsigned tid; //Thread ID thread_t tid; //Thread ID
std::vector<unsigned> callstack_refs; std::vector<unsigned> callstack_refs;
thread_refcount(unsigned thread_id, unsigned refs) thread_refcount(thread_t thread_id, unsigned refs)
: tid(thread_id) : tid(thread_id)
{ {
callstack_refs.push_back(refs); callstack_refs.push_back(refs);
@ -294,7 +294,7 @@ namespace detail
{ {
std::recursive_mutex mutex; std::recursive_mutex mutex;
unsigned thread_id; //Thread ID thread_t thread_id; //Thread ID
unsigned refs; //Ref count unsigned refs; //Ref count
std::vector<thread_refcount> records; std::vector<thread_refcount> records;
@ -1449,7 +1449,7 @@ namespace detail
return nullptr; return nullptr;
} }
void window_manager::remove_trash_handle(unsigned tid) void window_manager::remove_trash_handle(thread_t tid)
{ {
//Thread-Safe Required! //Thread-Safe Required!
std::lock_guard<mutex_type> lock(mutex_); std::lock_guard<mutex_type> lock(mutex_);
@ -1571,7 +1571,7 @@ namespace detail
} }
} }
void window_manager::call_safe_place(unsigned thread_id) void window_manager::call_safe_place(thread_t thread_id)
{ {
std::lock_guard<mutex_type> lock(mutex_); std::lock_guard<mutex_type> lock(mutex_);

View File

@ -153,7 +153,7 @@ namespace nana
} }
} }
void delete_trash(unsigned thread_id) void delete_trash(thread_t thread_id)
{ {
if (0 == thread_id) if (0 == thread_id)
{ {

View File

@ -28,7 +28,7 @@
#include "../detail/platform_spec_selector.hpp" #include "../detail/platform_spec_selector.hpp"
#if defined(NANA_LINUX) || defined(NANA_MACOS) #if defined(NANA_POSIX)
#include <nana/system/platform.hpp> #include <nana/system/platform.hpp>
#include <iostream> #include <iostream>
#endif #endif

View File

@ -27,7 +27,7 @@
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
#include <windows.h> #include <windows.h>
#elif defined(NANA_LINUX) || defined(NANA_MACOS) #elif defined(NANA_POSIX)
#include "../detail/platform_spec_selector.hpp" #include "../detail/platform_spec_selector.hpp"
#include <nana/system/platform.hpp> #include <nana/system/platform.hpp>
#endif #endif

View File

@ -1063,7 +1063,7 @@ namespace paint
{ {
auto const end = str + len; auto const end = str + len;
auto i = std::find(str, end, '\t'); auto i = std::find(str, end, '\t');
#if defined(NANA_LINUX) || defined(NANA_MACOS) #if defined(NANA_POSIX)
impl_->handle->update_text_color(); impl_->handle->update_text_color();
#endif #endif
if (i != end) if (i != end)

View File

@ -17,12 +17,49 @@
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
#include <windows.h> #include <windows.h>
#include "../detail/mswin/platform_spec.hpp" #include "../detail/mswin/platform_spec.hpp"
#elif defined(NANA_LINUX) || defined(NANA_MACOS) #elif defined(NANA_POSIX)
#include <time.h> #include <time.h>
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/syscall.h> #include <sys/syscall.h>
#include <pthread.h>
#include <sys/stat.h>
#include <spawn.h>
#include <string.h>
static void posix_open_url(const char *url_utf8)
{
extern char **environ;
const char *home = getenv("HOME");
std::string cheat(home);
cheat += "/.mozilla";
struct stat exists{};
// TODO: generalize this for chromium, opera, waterfox, etc.
// Most desktop environments (KDE, Gnome, Lumina etc.) provide a way to set
// your preferred browser - but there are more desktops than browsers.
// Look for $HOME/.mozilla directory as strong evidence they use firefox.
if ( stat(cheat.c_str(), &exists) == 0 && S_ISDIR(exists.st_mode))
{
const char *path = "";
static const char *likely[2] = { "/usr/local/bin/firefox", "/usr/bin/firefox"};
if ( stat(likely[0], &exists) == 0 && S_ISREG(exists.st_mode))
path = likely[0];
else if ( stat(likely[1], &exists) == 0 && S_ISREG(exists.st_mode) )
path = likely[1];
else return;
pid_t pid = 0;
static const char firefox[] = "firefox";
char name[sizeof firefox]{};
// argv does not like const-literals so make a copy.
strcpy(name, firefox);
char *argv[3] = {name, const_cast<char *>(url_utf8), nullptr};
posix_spawn(&pid, path, NULL, NULL, argv, environ);
}
}
#endif #endif
namespace nana namespace nana
@ -36,7 +73,7 @@ namespace system
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
::Sleep(milliseconds); ::Sleep(milliseconds);
#elif defined(NANA_LINUX) || defined(NANA_MACOS) #elif defined(NANA_POSIX)
struct timespec timeOut, remains; struct timespec timeOut, remains;
timeOut.tv_sec = milliseconds / 1000; timeOut.tv_sec = milliseconds / 1000;
timeOut.tv_nsec = (milliseconds % 1000) * 1000000; timeOut.tv_nsec = (milliseconds % 1000) * 1000000;
@ -52,14 +89,16 @@ namespace system
//this_thread_id //this_thread_id
//@brief: get the identifier of calling thread. //@brief: get the identifier of calling thread.
unsigned long this_thread_id() thread_t this_thread_id()
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
return ::GetCurrentThreadId(); return (thread_t)::GetCurrentThreadId();
#elif defined(NANA_LINUX) #elif defined(NANA_LINUX)
return ::syscall(__NR_gettid); return (thread_t)::syscall(__NR_gettid);
#elif defined(NANA_MACOS) #elif defined(NANA_MACOS)
return ::syscall(SYS_thread_selfid); return (thread_t)::syscall(SYS_thread_selfid);
#elif defined(NANA_POSIX)
return (thread_t)pthread_self();
#endif #endif
} }
@ -67,7 +106,7 @@ namespace system
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
return ::GetTickCount(); return ::GetTickCount();
#elif defined(NANA_LINUX) || defined(NANA_MACOS) #elif defined(NANA_POSIX)
struct timeval tv; struct timeval tv;
::gettimeofday(&tv, 0); ::gettimeofday(&tv, 0);
return (tv.tv_sec * 1000 + tv.tv_usec / 1000); return (tv.tv_sec * 1000 + tv.tv_usec / 1000);
@ -92,7 +131,7 @@ namespace system
} }
return (::GetAsyncKeyState(button) != 0); return (::GetAsyncKeyState(button) != 0);
#elif defined(NANA_LINUX) || defined(NANA_MACOS) #elif defined(NANA_POSIX)
static_cast<void>(button); //eliminate unused parameter compiler warning. static_cast<void>(button); //eliminate unused parameter compiler warning.
return false; return false;
#endif #endif
@ -105,7 +144,6 @@ namespace system
return; return;
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
std::wstring url = to_wstring(url_utf8);
if(::ShellExecute(0, L"open", url.c_str(), 0, 0, SW_SHOWNORMAL) < reinterpret_cast<HINSTANCE>(32)) if(::ShellExecute(0, L"open", url.c_str(), 0, 0, SW_SHOWNORMAL) < reinterpret_cast<HINSTANCE>(32))
{ {
//Because ShellExecute can delegate execution to Shell extensions (data sources, context menu handlers, //Because ShellExecute can delegate execution to Shell extensions (data sources, context menu handlers,
@ -115,7 +153,8 @@ namespace system
nana::detail::platform_spec::co_initializer co_init; nana::detail::platform_spec::co_initializer co_init;
::ShellExecute(0, L"open", url.c_str(), 0, 0, SW_SHOWNORMAL); ::ShellExecute(0, L"open", url.c_str(), 0, 0, SW_SHOWNORMAL);
} }
#elif defined(NANA_LINUX) || defined(NANA_MACOS) #elif defined(NANA_POSIX)
posix_open_url(url_utf8.c_str());
#endif #endif
} }
}//end namespace system }//end namespace system

View File

@ -12,7 +12,7 @@
#include <nana/system/shared_wrapper.hpp> #include <nana/system/shared_wrapper.hpp>
#include <algorithm> #include <algorithm>
#include <iterator> #include <iterator>
#if defined(NANA_LINUX) || defined(NANA_MACOS) #if defined(NANA_POSIX)
#include <dlfcn.h> #include <dlfcn.h>
#else #else
#include <windows.h> #include <windows.h>
@ -30,7 +30,7 @@ namespace system
module_t open(const char* filename) module_t open(const char* filename)
{ {
#if defined(NANA_LINUX) || defined(NANA_MACOS) #if defined(NANA_POSIX)
return ::dlopen(filename, RTLD_LAZY); return ::dlopen(filename, RTLD_LAZY);
#else #else
return ::LoadLibraryA(filename); return ::LoadLibraryA(filename);
@ -39,7 +39,7 @@ namespace system
void* symbols(module_t handle, const char* symbol) void* symbols(module_t handle, const char* symbol)
{ {
#if defined(NANA_LINUX) || defined(NANA_MACOS) #if defined(NANA_POSIX)
return ::dlsym(handle, const_cast<char*>(symbol)); return ::dlsym(handle, const_cast<char*>(symbol));
#else #else
return (void*)(::GetProcAddress(reinterpret_cast<HMODULE>(handle), symbol)); return (void*)(::GetProcAddress(reinterpret_cast<HMODULE>(handle), symbol));
@ -48,7 +48,7 @@ namespace system
void close(module_t handle) void close(module_t handle)
{ {
#if defined(NANA_LINUX) || defined(NANA_MACOS) #if defined(NANA_POSIX)
::dlclose(handle); ::dlclose(handle);
#else #else
::FreeLibrary(reinterpret_cast<HMODULE>(handle)); ::FreeLibrary(reinterpret_cast<HMODULE>(handle));
@ -90,7 +90,7 @@ namespace system
std::transform(filename + length - 13, filename + length , std::back_inserter(file), tolower); std::transform(filename + length - 13, filename + length , std::back_inserter(file), tolower);
if(file == ".nana_shared") if(file == ".nana_shared")
{ {
#if defined(NANA_LINUX) || defined(NANA_MACOS) #if defined(NANA_POSIX)
ofn.replace(length - 13, 13, ".so"); ofn.replace(length - 13, 13, ".so");
#else #else
ofn.replace(length - 13, 13, ".DLL"); ofn.replace(length - 13, 13, ".DLL");

View File

@ -2,7 +2,7 @@
#include <nana/config.hpp> #include <nana/config.hpp>
#ifdef NANA_WINDOWS #ifdef NANA_WINDOWS
#include <windows.h> #include <windows.h>
#elif defined(NANA_LINUX) || defined(NANA_MACOS) #elif defined(NANA_POSIX)
#include <sys/time.h> #include <sys/time.h>
#endif #endif
@ -15,7 +15,7 @@ namespace system
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
LARGE_INTEGER beg_timestamp; LARGE_INTEGER beg_timestamp;
#elif defined(NANA_LINUX) || defined(NANA_MACOS) #elif defined(NANA_POSIX)
struct timeval beg_timestamp; struct timeval beg_timestamp;
#endif #endif
}; };
@ -45,7 +45,7 @@ namespace system
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
::QueryPerformanceCounter(&impl_->beg_timestamp); ::QueryPerformanceCounter(&impl_->beg_timestamp);
#elif defined(NANA_LINUX) || defined(NANA_MACOS) #elif defined(NANA_POSIX)
struct timezone tz; struct timezone tz;
::gettimeofday(&impl_->beg_timestamp, &tz); ::gettimeofday(&impl_->beg_timestamp, &tz);
#endif #endif
@ -63,7 +63,7 @@ namespace system
::QueryPerformanceFrequency(&freq); ::QueryPerformanceFrequency(&freq);
return double(diff)/double(freq.QuadPart) * 1000; return double(diff)/double(freq.QuadPart) * 1000;
#elif defined(NANA_LINUX) || defined(NANA_MACOS) #elif defined(NANA_POSIX)
struct timeval tv; struct timeval tv;
struct timezone tz; struct timezone tz;
gettimeofday(&tv, &tz); gettimeofday(&tv, &tz);

View File

@ -29,7 +29,7 @@
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
#include <windows.h> #include <windows.h>
#include <process.h> #include <process.h>
#elif defined(NANA_LINUX) || defined(NANA_MACOS) #elif defined(NANA_POSIX)
#include <pthread.h> #include <pthread.h>
#endif #endif