Merge branch 'feature-freebsd-posix' into develop
This commit is contained in:
commit
c72d8e25b4
18
.travis.yml
18
.travis.yml
@ -22,24 +22,6 @@ matrix:
|
||||
- libxft-dev
|
||||
sources:
|
||||
- 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:
|
||||
- env: CXX=clang++-3.8 CC=clang-3.8
|
||||
|
@ -152,18 +152,29 @@ if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
|
||||
if(NANA_CMAKE_SHARED_LIB)
|
||||
list(APPEND NANA_LINKS -lgcc -lstdc++ -pthread)
|
||||
else()
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-static -pthread")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-s")
|
||||
endif()
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -pthread")
|
||||
# message("Setting NANA_LINKS to -static-libgcc -static-libstdc++ -pthread or ${NANA_LINKS}")
|
||||
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)
|
||||
list(APPEND NANA_LINKS -lstdc++fs)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(APPLE AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
|
||||
list(APPEND NANA_LINKS -stdlib=libstdc++)
|
||||
endif()
|
||||
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++)
|
||||
endif ()
|
||||
|
||||
|
||||
############# Optional libraries
|
||||
@ -342,26 +353,27 @@ endif()
|
||||
|
||||
|
||||
# Just for information:
|
||||
message("")
|
||||
message("CMAKE_CXX_COMPILER_ID = " ${CMAKE_CXX_COMPILER_ID})
|
||||
message("COMPILER_IS_CLANG = " ${COMPILER_IS_CLANG})
|
||||
message("CMAKE_COMPILER_IS_GNUCXX = " ${CMAKE_COMPILER_IS_GNUCXX})
|
||||
message("CMAKE_CXX_FLAGS = " ${CMAKE_CXX_FLAGS})
|
||||
message("CMAKE_EXE_LINKER_FLAGS = " ${CMAKE_EXE_LINKER_FLAGS})
|
||||
message("CMAKE_STATIC_LINKER_FLAGS = " ${CMAKE_STATIC_LINKER_FLAGS})
|
||||
message("NANA_LINKS = " ${NANA_LINKS})
|
||||
message("DESTDIR = " ${DESTDIR})
|
||||
message("CMAKE_INSTALL_PREFIX = " ${CMAKE_INSTALL_PREFIX})
|
||||
message("NANA_INCLUDE_DIR = " ${NANA_INCLUDE_DIR})
|
||||
message("CMAKE_CURRENT_SOURCE_DIR = " ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
message("NANA_CMAKE_ENABLE_AUDIO = " ${NANA_CMAKE_ENABLE_AUDIO})
|
||||
message("NANA_CMAKE_SHARED_LIB = " ${NANA_CMAKE_SHARED_LIB})
|
||||
message("NANA_CLION = " ${NANA_CLION})
|
||||
message("CMAKE_MAKE_PROGRAM = " ${CMAKE_MAKE_PROGRAM})
|
||||
message ("")
|
||||
message ( "CMAKE_CXX_COMPILER_ID = " ${CMAKE_CXX_COMPILER_ID})
|
||||
message ( "COMPILER_IS_CLANG = " ${COMPILER_IS_CLANG})
|
||||
message ( "CMAKE_COMPILER_IS_GNUCXX = " ${CMAKE_COMPILER_IS_GNUCXX})
|
||||
message ( "CMAKE_CXX_FLAGS = " ${CMAKE_CXX_FLAGS})
|
||||
message ( "CMAKE_EXE_LINKER_FLAGS = " ${CMAKE_EXE_LINKER_FLAGS})
|
||||
message ( "CMAKE_STATIC_LINKER_FLAGS = " ${CMAKE_STATIC_LINKER_FLAGS})
|
||||
message ( "NANA_LINKS = " ${NANA_LINKS})
|
||||
message ( "DESTDIR = " ${DESTDIR})
|
||||
message ( "CMAKE_INSTALL_PREFIX = " ${CMAKE_INSTALL_PREFIX})
|
||||
message ( "NANA_INCLUDE_DIR = " ${NANA_INCLUDE_DIR})
|
||||
message ( "CMAKE_CURRENT_SOURCE_DIR = " ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
message ( "NANA_CMAKE_ENABLE_AUDIO = " ${NANA_CMAKE_ENABLE_AUDIO})
|
||||
message ( "NANA_CMAKE_SHARED_LIB = " ${NANA_CMAKE_SHARED_LIB})
|
||||
message ( "NANA_CLION = " ${NANA_CLION})
|
||||
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_BOOST_FILESYSTEM_FORCE = " ${NANA_CMAKE_BOOST_FILESYSTEM_FORCE})
|
||||
message("NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT = " ${NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT})
|
||||
message("NANA_CMAKE_BOOST_FILESYSTEM_LIB = " ${NANA_CMAKE_BOOST_FILESYSTEM_LIB})
|
||||
message("NANA_CMAKE_AUTOMATIC_GUI_TESTING = " ${NANA_CMAKE_AUTOMATIC_GUI_TESTING})
|
||||
message("NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING = " ${NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING})
|
||||
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_INCLUDE_ROOT = " ${NANA_CMAKE_BOOST_FILESYSTEM_INCLUDE_ROOT})
|
||||
message ( "NANA_CMAKE_BOOST_FILESYSTEM_LIB = " ${NANA_CMAKE_BOOST_FILESYSTEM_LIB})
|
||||
message ( "NANA_CMAKE_AUTOMATIC_GUI_TESTING = " ${NANA_CMAKE_AUTOMATIC_GUI_TESTING})
|
||||
message ( "NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING = " ${NANA_CMAKE_ADD_DEF_AUTOMATIC_GUI_TESTING})
|
||||
|
@ -10,7 +10,9 @@
|
||||
#if defined(NANA_WINDOWS)
|
||||
#include <windows.h>
|
||||
#elif defined(NANA_LINUX)
|
||||
#include <alsa/asoundlib.h>
|
||||
#include <alsa/asoundlib.h>
|
||||
#elif defined(NANA_POSIX)
|
||||
#include <sys/soundcard.h>
|
||||
#endif
|
||||
|
||||
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);
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(NANA_WINDOWS)
|
||||
HWAVEOUT handle_;
|
||||
std::recursive_mutex queue_lock_;
|
||||
@ -45,6 +46,12 @@ namespace nana{ namespace audio
|
||||
std::size_t channels_;
|
||||
std::size_t bytes_per_sample_;
|
||||
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
|
||||
buffer_preparation * buf_prep_;
|
||||
};
|
||||
@ -54,4 +61,4 @@ namespace nana{ namespace audio
|
||||
}//end namespace nana
|
||||
|
||||
#endif //NANA_ENABLE_AUDIO
|
||||
#endif
|
||||
#endif
|
||||
|
@ -33,7 +33,7 @@ namespace nana{ namespace audio{
|
||||
unsigned short wBitsPerSample;
|
||||
};
|
||||
#pragma pack()
|
||||
#elif defined(NANA_LINUX)
|
||||
#elif defined(NANA_POSIX)
|
||||
struct master_riff_chunk
|
||||
{
|
||||
unsigned ckID; //"RIFF"
|
||||
@ -83,4 +83,4 @@ namespace nana{ namespace audio{
|
||||
}//end namespace audio
|
||||
}//end namespace nana
|
||||
#endif //NANA_ENABLE_AUDIO
|
||||
#endif
|
||||
#endif
|
||||
|
@ -32,7 +32,7 @@ namespace nana{ namespace audio
|
||||
public:
|
||||
#if defined(NANA_WINDOWS)
|
||||
typedef WAVEHDR meta;
|
||||
#elif defined(NANA_LINUX)
|
||||
#elif defined(NANA_POSIX)
|
||||
struct meta
|
||||
{
|
||||
char * buf;
|
||||
@ -66,4 +66,4 @@ namespace nana{ namespace audio
|
||||
}//end namespace audio
|
||||
}//end namespace nana
|
||||
#endif //NANA_ENABLE_AUDIO
|
||||
#endif
|
||||
#endif
|
||||
|
@ -68,9 +68,16 @@
|
||||
# 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 ......
|
||||
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) //Microsoft Windows
|
||||
#define NANA_WINDOWS
|
||||
typedef DWORD_PTR thread_t;
|
||||
|
||||
// MINGW ...
|
||||
#if defined(__MINGW32__) || defined(__MINGW64__) || defined(MINGW)
|
||||
@ -79,24 +86,23 @@
|
||||
|
||||
#elif defined(APPLE) //Mac OS X
|
||||
//Symbols for MACOS
|
||||
|
||||
#define NANA_MACOS
|
||||
#define NANA_POSIX
|
||||
#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
|
||||
#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_X11
|
||||
typedef unsigned long thread_t;
|
||||
#else
|
||||
static_assert(false, "Only Windows and Linux are supported now (Mac OS and BSD are experimental)");
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Select compiler ...
|
||||
#if defined(_MSC_VER) //Microsoft Visual C++
|
||||
#define _SCL_SECURE_NO_WARNNGS
|
||||
|
@ -20,19 +20,19 @@
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace filesystem_ext
|
||||
namespace filesystem_ext
|
||||
{
|
||||
|
||||
#if defined(NANA_WINDOWS)
|
||||
constexpr auto const def_root = "C:";
|
||||
constexpr auto const def_rootstr = "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_rootstr = "/";
|
||||
constexpr auto const def_rootname = "Root/";
|
||||
#endif
|
||||
|
||||
|
||||
std::experimental::filesystem::path path_user(); ///< extention ?
|
||||
|
||||
/// workaround Boost not having path.generic_u8string() - a good point for http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0251r0.pdf
|
||||
@ -52,7 +52,7 @@ inline bool is_directory(const std::experimental::filesystem::directory_entry& d
|
||||
|
||||
//template<class DI> // DI = directory_iterator from std, boost, or nana : return directory_entry
|
||||
class directory_only_iterator : public std::experimental::filesystem::directory_iterator
|
||||
{
|
||||
{
|
||||
using directory_iterator = std::experimental::filesystem::directory_iterator;
|
||||
|
||||
directory_only_iterator& find_first()
|
||||
@ -60,7 +60,7 @@ class directory_only_iterator : public std::experimental::filesystem::directory_
|
||||
auto end = directory_only_iterator{};
|
||||
while (*this != end)
|
||||
{
|
||||
if (is_directory((**this).status()))
|
||||
if (is_directory((**this).status()))
|
||||
return *this;
|
||||
this->directory_iterator::operator++();
|
||||
}
|
||||
@ -110,7 +110,7 @@ public:
|
||||
{
|
||||
find_first();
|
||||
}
|
||||
|
||||
|
||||
regular_file_only_iterator& operator++()
|
||||
{
|
||||
this->directory_iterator::operator++();
|
||||
|
@ -3,8 +3,8 @@
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* @file nana/gui/detail/basic_window.hpp
|
||||
@ -79,7 +79,7 @@ namespace detail
|
||||
};
|
||||
|
||||
|
||||
/// a window data structure descriptor
|
||||
/// a window data structure descriptor
|
||||
struct basic_window
|
||||
: public events_holder
|
||||
{
|
||||
@ -139,7 +139,7 @@ namespace detail
|
||||
void _m_init_pos_and_size(basic_window* parent, const rectangle&);
|
||||
void _m_initialize(basic_window* parent);
|
||||
public:
|
||||
#if defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#if defined(NANA_POSIX)
|
||||
point pos_native;
|
||||
#endif
|
||||
point pos_root; ///< coordinates of the root window
|
||||
@ -202,7 +202,7 @@ namespace detail
|
||||
effects::bground_interface * bground;
|
||||
double bground_fade_rate;
|
||||
}effect;
|
||||
|
||||
|
||||
struct other_tag
|
||||
{
|
||||
#ifndef WIDGET_FRAME_DEPRECATED
|
||||
@ -248,7 +248,7 @@ namespace detail
|
||||
}other;
|
||||
|
||||
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;
|
||||
container children;
|
||||
};
|
||||
|
@ -46,10 +46,10 @@ namespace detail
|
||||
~bedrock();
|
||||
void pump_event(window, bool is_modal);
|
||||
void flush_surface(core_window_t*, bool forced, const rectangle* update_area = nullptr);
|
||||
static int inc_window(unsigned tid = 0);
|
||||
thread_context* open_thread_context(unsigned tid = 0);
|
||||
thread_context* get_thread_context(unsigned tid = 0);
|
||||
void remove_thread_context(unsigned tid = 0);
|
||||
static int inc_window(thread_t tid = 0);
|
||||
thread_context* open_thread_context(thread_t tid = 0);
|
||||
thread_context* get_thread_context(thread_t tid = 0);
|
||||
void remove_thread_context(thread_t tid = 0);
|
||||
static bedrock& instance();
|
||||
|
||||
core_window_t* focus();
|
||||
@ -73,7 +73,7 @@ namespace detail
|
||||
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
|
||||
void close_thread_window(unsigned thread_id);
|
||||
void close_thread_window(thread_t thread_id);
|
||||
|
||||
public:
|
||||
//Platform-dependent functions
|
||||
|
@ -139,7 +139,7 @@ namespace detail
|
||||
void enable_tabstop(core_window_t*);
|
||||
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);
|
||||
|
||||
@ -154,7 +154,7 @@ namespace detail
|
||||
core_window_t* find_shortkey(native_window_type, unsigned long key);
|
||||
|
||||
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:
|
||||
void _m_disengage(core_window_t*, core_window_t* for_new);
|
||||
void _m_destroy(core_window_t*);
|
||||
|
@ -26,7 +26,7 @@ namespace system
|
||||
|
||||
//this_thread_id
|
||||
//@brief: get the identifier of calling thread.
|
||||
unsigned long this_thread_id();
|
||||
thread_t this_thread_id();
|
||||
|
||||
//timestamp
|
||||
//@brief: it retrieves the timestamp at the time the function is called.
|
||||
|
@ -5,11 +5,14 @@
|
||||
|
||||
#include <nana/system/platform.hpp>
|
||||
|
||||
#if defined(NANA_LINUX)
|
||||
#if defined(NANA_POSIX)
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
static bool get_default_audio(std::string &, bool);
|
||||
#endif
|
||||
|
||||
namespace nana{namespace audio
|
||||
@ -47,6 +50,8 @@ namespace nana{namespace audio
|
||||
audio_device::audio_device()
|
||||
#if defined(NANA_WINDOWS)
|
||||
: handle_(nullptr), buf_prep_(nullptr)
|
||||
#elif defined(NANA_POSIX)
|
||||
: handle_(-1), buf_prep_(nullptr)
|
||||
#elif defined(NANA_LINUX)
|
||||
: handle_(nullptr), buf_prep_(nullptr)
|
||||
#endif
|
||||
@ -59,7 +64,11 @@ namespace nana{namespace audio
|
||||
|
||||
bool audio_device::empty() const
|
||||
{
|
||||
#ifdef NANA_POSIX
|
||||
return (-1 == handle_);
|
||||
#else
|
||||
return (nullptr == handle_);
|
||||
#endif
|
||||
}
|
||||
|
||||
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);
|
||||
return (mmr == MMSYSERR_NOERROR);
|
||||
#elif defined(NANA_LINUX)
|
||||
// assumes ALSA sub-system
|
||||
if(nullptr == handle_)
|
||||
{
|
||||
if(::snd_pcm_open(&handle_, "plughw:0,0", SND_PCM_STREAM_PLAYBACK, 0) < 0)
|
||||
@ -158,7 +168,52 @@ namespace nana{namespace audio
|
||||
::snd_pcm_prepare(handle_);
|
||||
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
|
||||
}
|
||||
|
||||
@ -168,10 +223,14 @@ namespace nana{namespace audio
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
wave_native_if.out_close(handle_);
|
||||
handle_ = nullptr;
|
||||
#elif defined(__FreeBSD__)
|
||||
::close(handle_);
|
||||
handle_ = 0;
|
||||
#elif defined(NANA_LINUX)
|
||||
::snd_pcm_close(handle_);
|
||||
#endif
|
||||
handle_ = nullptr;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,6 +249,11 @@ namespace nana{namespace audio
|
||||
|
||||
wave_native_if.out_prepare(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)
|
||||
std::size_t frames = m->bufsize / bytes_per_frame_;
|
||||
std::size_t buffered = 0; //in bytes
|
||||
@ -240,4 +304,144 @@ namespace nana{namespace audio
|
||||
}//end namespace audio
|
||||
}//end namespace nana
|
||||
|
||||
#endif //NANA_ENABLE_AUDIO
|
||||
#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
|
||||
|
@ -26,6 +26,7 @@ namespace nana{ namespace audio
|
||||
memset(m, 0, sizeof(meta));
|
||||
m->dwBufferLength = static_cast<unsigned long>(block_size_);
|
||||
m->lpData = rawbuf + sizeof(meta);
|
||||
#elif defined(__FreeBSD__)
|
||||
#elif defined(NANA_LINUX)
|
||||
m->bufsize = ck.nAvgBytesPerSec;
|
||||
m->buf = rawbuf + sizeof(meta);
|
||||
@ -124,6 +125,7 @@ namespace nana{ namespace audio
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
memcpy(m->lpData + buffered, buf, read_bytes);
|
||||
#elif defined(__FreeBSD__)
|
||||
#elif defined(NANA_LINUX)
|
||||
memcpy(m->buf + buffered, buf, read_bytes);
|
||||
#endif
|
||||
@ -144,6 +146,7 @@ namespace nana{ namespace audio
|
||||
}
|
||||
#if defined(NANA_WINDOWS)
|
||||
m->dwBufferLength = static_cast<unsigned long>(buffered);
|
||||
#elif defined(__FreeBSD__)
|
||||
#elif defined(NANA_LINUX)
|
||||
m->bufsize = buffered;
|
||||
#endif
|
||||
@ -163,4 +166,4 @@ namespace nana{ namespace audio
|
||||
}//end namespace audio
|
||||
}//end namespace nana
|
||||
|
||||
#endif //NANA_ENABLE_AUDIO
|
||||
#endif //NANA_ENABLE_AUDIO
|
||||
|
@ -42,7 +42,7 @@ namespace nana
|
||||
{
|
||||
auto ustr = reinterpret_cast<const unsigned char*>(text);
|
||||
auto const end = ustr + std::strlen(text);
|
||||
|
||||
|
||||
for (unsigned i = 0; i != pos; ++i)
|
||||
{
|
||||
const auto uch = *ustr;
|
||||
@ -55,7 +55,7 @@ namespace nana
|
||||
if (uch < 0xC0) // use police ?
|
||||
return nullptr;
|
||||
|
||||
if ((uch < 0xE0) && (ustr + 1 < end)) //? *(ustr + 1) < 0xE0
|
||||
if ((uch < 0xE0) && (ustr + 1 < end)) //? *(ustr + 1) < 0xE0
|
||||
ustr += 2;
|
||||
else if (uch < 0xF0 && (ustr + 2 <= end))
|
||||
ustr += 3;
|
||||
@ -217,7 +217,7 @@ namespace nana
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
{
|
||||
/// candidate to be more general??
|
||||
class locale_initializer
|
||||
{
|
||||
@ -226,7 +226,7 @@ namespace nana
|
||||
{
|
||||
static bool initialized = false;
|
||||
if (initialized) return;
|
||||
|
||||
|
||||
initialized = true;
|
||||
//Only set the C library locale
|
||||
std::setlocale(LC_CTYPE, "");
|
||||
@ -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
|
||||
bool wc2mb(std::string& mbstr, const wchar_t * s)
|
||||
static bool wc2mb(std::string& mbstr, const wchar_t * s)
|
||||
{
|
||||
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
|
||||
bool mb2wc(std::wstring& wcstr, const char* s)
|
||||
static bool mb2wc(std::wstring& wcstr, const char* s)
|
||||
{
|
||||
if(nullptr == s || *s == 0)
|
||||
{
|
||||
@ -288,7 +288,7 @@ namespace nana
|
||||
std::size_t len = std::mbsrtowcs(nullptr, &s, 0, &mbstate);
|
||||
if(len == static_cast<std::size_t>(-1))
|
||||
return false;
|
||||
|
||||
|
||||
if(len)
|
||||
{
|
||||
wcstr.resize(len);
|
||||
@ -322,7 +322,7 @@ namespace nana
|
||||
std::size_t len = std::mbsrtowcs(nullptr, &s, 0, &mbstate);
|
||||
if(len == static_cast<std::size_t>(-1))
|
||||
return false;
|
||||
|
||||
|
||||
if(len)
|
||||
{
|
||||
wcstr.resize(sizeof(wchar_t) * len);
|
||||
@ -367,7 +367,7 @@ namespace nana
|
||||
|
||||
};
|
||||
|
||||
///
|
||||
///
|
||||
struct utf8_error_police_def_char : public encoding_error_police
|
||||
{
|
||||
static unsigned long def_error_mark ;
|
||||
@ -386,13 +386,13 @@ namespace nana
|
||||
|
||||
unsigned long utf8_error_police_def_char::def_error_mark{ '*' };
|
||||
|
||||
///
|
||||
///
|
||||
struct utf8_error_police_throw : public encoding_error_police
|
||||
{
|
||||
unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override
|
||||
{
|
||||
//utf8_Error::use_throw = true;
|
||||
utf8_Error(std::string("The text is not encoded in UTF8: ") +
|
||||
utf8_Error(std::string("The text is not encoded in UTF8: ") +
|
||||
reinterpret_cast<const char*>( current_code_unit) ).emit();;
|
||||
current_code_unit = end;
|
||||
return 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());
|
||||
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());
|
||||
#else
|
||||
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());
|
||||
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));
|
||||
#else
|
||||
throw std::runtime_error("Bad charset");
|
||||
@ -689,7 +689,7 @@ namespace nana
|
||||
}
|
||||
unsigned ch = *p;
|
||||
unsigned long code;
|
||||
if(ch < 0xC0) // error? - move to end. Posible ANSI or ISO code-page
|
||||
if(ch < 0xC0) // error? - move to end. Posible ANSI or ISO code-page
|
||||
{
|
||||
//return *(p++); // temp: assume equal
|
||||
//p = end;
|
||||
@ -809,7 +809,7 @@ namespace nana
|
||||
s += static_cast<char>(0x80 | ((code >> 12) & 0x3F));
|
||||
s += static_cast<char>(0x80 | ((code >> 6) & 0x3F));
|
||||
s += static_cast<char>(0x80 | (code & 0x3F));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//le_or_be, true = le, false = be
|
||||
|
@ -19,12 +19,11 @@
|
||||
|
||||
#if defined(NANA_WINDOWS)
|
||||
#include <windows.h>
|
||||
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#elif defined(NANA_POSIX)
|
||||
#include <string.h>
|
||||
#include "detail/platform_spec_selector.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace nana
|
||||
@ -76,7 +75,7 @@ namespace nana
|
||||
std::cerr << what();
|
||||
}
|
||||
|
||||
//bool utf8_Error::use_throw{true};
|
||||
//bool utf8_Error::use_throw{true};
|
||||
bool utf8_Error::use_throw{ false };
|
||||
//end class utf8_Error
|
||||
|
||||
@ -240,4 +239,4 @@ namespace nana
|
||||
|
||||
#if defined(VERBOSE_PREPROCESSOR)
|
||||
# include <nana/verbose_preprocessor.hpp>
|
||||
#endif
|
||||
#endif
|
||||
|
@ -206,7 +206,7 @@ namespace detail
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class timer_runner
|
||||
{
|
||||
typedef void (*timer_proc_t)(std::size_t id);
|
||||
@ -214,7 +214,7 @@ namespace detail
|
||||
struct timer_tag
|
||||
{
|
||||
std::size_t id;
|
||||
unsigned tid;
|
||||
thread_t tid;
|
||||
std::size_t interval;
|
||||
std::size_t timestamp;
|
||||
timer_proc_t proc;
|
||||
@ -250,7 +250,7 @@ namespace detail
|
||||
i->second.proc = proc;
|
||||
return;
|
||||
}
|
||||
unsigned tid = nana::system::this_thread_id();
|
||||
auto tid = nana::system::this_thread_id();
|
||||
threadmap_[tid].timers.insert(id);
|
||||
|
||||
timer_tag & tag = holder_[id];
|
||||
@ -272,7 +272,7 @@ namespace detail
|
||||
if(i != holder_.end())
|
||||
{
|
||||
auto tid = i->second.tid;
|
||||
|
||||
|
||||
auto ig = threadmap_.find(tid);
|
||||
if(ig != threadmap_.end()) //Generally, the ig should not be the end of threadmap_
|
||||
{
|
||||
@ -295,7 +295,7 @@ namespace detail
|
||||
return (holder_.empty());
|
||||
}
|
||||
|
||||
void timer_proc(unsigned tid)
|
||||
void timer_proc(thread_t tid)
|
||||
{
|
||||
is_proc_handling_ = true;
|
||||
auto i = threadmap_.find(tid);
|
||||
@ -329,7 +329,7 @@ namespace detail
|
||||
}
|
||||
private:
|
||||
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_;
|
||||
};
|
||||
|
||||
@ -339,8 +339,8 @@ namespace detail
|
||||
string.tab_pixels = 0;
|
||||
string.whitespace_pixels = 0;
|
||||
#if defined(NANA_USE_XFT)
|
||||
conv_.handle = ::iconv_open("UTF-8", "UTF-32");
|
||||
conv_.code = "UTF-32";
|
||||
conv_.handle = ::iconv_open("UTF-8", NANA_UNICODE);
|
||||
conv_.code = NANA_UNICODE;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -723,7 +723,7 @@ namespace detail
|
||||
::XFree(attr);
|
||||
}
|
||||
else
|
||||
addr->input_context = ::XCreateIC(addr->input_method,
|
||||
addr->input_context = ::XCreateIC(addr->input_method,
|
||||
XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
|
||||
XNClientWindow, reinterpret_cast<Window>(wd),
|
||||
XNFocusWindow, reinterpret_cast<Window>(wd), nullptr);
|
||||
@ -794,7 +794,7 @@ namespace detail
|
||||
XSetWindowAttributes new_attr;
|
||||
|
||||
//Don't remove the KeyPress and KeyRelease mask(0x3), otherwise the window will not receive
|
||||
//Keyboard events after destroying caret
|
||||
//Keyboard events after destroying caret
|
||||
new_attr.event_mask = (attr.your_event_mask & ~(addr->input_context_event_mask & (~0x3)));
|
||||
::XChangeWindowAttributes(display_, reinterpret_cast<Window>(wd), CWEventMask, &new_attr);
|
||||
}
|
||||
@ -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);
|
||||
if(timer_.runner)
|
||||
@ -1066,7 +1066,7 @@ namespace detail
|
||||
// 2 = msg_dispatcher should ignore the msg, because the XEvent is processed by _m_msg_filter
|
||||
int platform_spec::_m_msg_filter(XEvent& evt, msg_packet_tag& msg)
|
||||
{
|
||||
auto & bedrock = detail::bedrock::instance();
|
||||
auto & bedrock = detail::bedrock::instance();
|
||||
|
||||
platform_spec & self = instance();
|
||||
if(KeyPress == evt.type || KeyRelease == evt.type)
|
||||
|
@ -16,6 +16,6 @@
|
||||
|
||||
#if defined(NANA_WINDOWS)
|
||||
#include "mswin/platform_spec.hpp"
|
||||
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#elif defined(NANA_POSIX)
|
||||
#include "posix/platform_spec.hpp"
|
||||
#endif
|
||||
#endif
|
||||
|
@ -2,8 +2,8 @@
|
||||
* Message Dispatcher Implementation
|
||||
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* @file: nana/detail/msg_dispatcher.hpp
|
||||
@ -35,7 +35,7 @@ namespace detail
|
||||
{
|
||||
struct thread_binder
|
||||
{
|
||||
unsigned tid;
|
||||
thread_t tid;
|
||||
std::mutex mutex;
|
||||
std::condition_variable cond;
|
||||
std::list<msg_packet_tag> msg_queue;
|
||||
@ -44,7 +44,7 @@ namespace detail
|
||||
|
||||
public:
|
||||
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 int (*event_filter_type)(XEvent&, msg_packet_tag&);
|
||||
|
||||
@ -76,7 +76,7 @@ namespace detail
|
||||
|
||||
void insert(Window wd)
|
||||
{
|
||||
unsigned tid = nana::system::this_thread_id();
|
||||
auto tid = nana::system::this_thread_id();
|
||||
|
||||
bool start_driver;
|
||||
|
||||
@ -87,7 +87,7 @@ namespace detail
|
||||
start_driver = (0 == table_.thr_table.size());
|
||||
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())
|
||||
{
|
||||
thr = new thread_binder;
|
||||
@ -100,7 +100,7 @@ namespace detail
|
||||
thr->mutex.lock();
|
||||
thr->window.insert(wd);
|
||||
thr->mutex.unlock();
|
||||
|
||||
|
||||
table_.wnd_table[wd] = thr;
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ namespace detail
|
||||
void erase(Window wd)
|
||||
{
|
||||
std::lock_guard<decltype(table_.mutex)> lock(table_.mutex);
|
||||
|
||||
|
||||
auto i = table_.wnd_table.find(wd);
|
||||
if(i != table_.wnd_table.end())
|
||||
{
|
||||
@ -136,7 +136,7 @@ namespace detail
|
||||
|
||||
table_.wnd_table.erase(i);
|
||||
thr->window.erase(wd);
|
||||
|
||||
|
||||
//There still is at least one window alive.
|
||||
if(thr->window.size())
|
||||
{
|
||||
@ -151,10 +151,10 @@ namespace detail
|
||||
|
||||
void dispatch(Window modal)
|
||||
{
|
||||
unsigned tid = nana::system::this_thread_id();
|
||||
auto tid = nana::system::this_thread_id();
|
||||
msg_packet_tag msg;
|
||||
int qstate;
|
||||
|
||||
|
||||
//Test whether the thread is registered for window, and retrieve the queue state for event
|
||||
while((qstate = _m_read_queue(tid, msg, modal)))
|
||||
{
|
||||
@ -186,7 +186,7 @@ namespace detail
|
||||
if(pending)
|
||||
{
|
||||
::XNextEvent(display_, &event);
|
||||
|
||||
|
||||
if(KeyRelease == event.type)
|
||||
{
|
||||
//Check whether the key is pressed, because X will send KeyRelease when pressing and
|
||||
@ -260,7 +260,7 @@ namespace detail
|
||||
if(i != table_.wnd_table.end())
|
||||
{
|
||||
thread_binder * const thr = i->second;
|
||||
|
||||
|
||||
std::lock_guard<decltype(thr->mutex)> lock(thr->mutex);
|
||||
thr->msg_queue.push_back(msg);
|
||||
thr->cond.notify_one();
|
||||
@ -270,7 +270,7 @@ namespace detail
|
||||
//_m_read_queue
|
||||
//@brief:Read the event from a specified thread queue.
|
||||
//@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;
|
||||
|
||||
@ -317,7 +317,7 @@ namespace detail
|
||||
//_m_wait_for_queue
|
||||
// wait for the insertion of queue.
|
||||
//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;
|
||||
{
|
||||
@ -330,12 +330,12 @@ namespace detail
|
||||
thr = i->second;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Waits for notifying the condition variable, it indicates a new msg is pushing into the queue.
|
||||
std::unique_lock<decltype(thr->mutex)> lock(thr->mutex);
|
||||
return (thr->cond.wait_for(lock, std::chrono::milliseconds(10)) != std::cv_status::timeout);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
Display * display_;
|
||||
volatile bool is_work_{ false };
|
||||
@ -344,7 +344,7 @@ namespace detail
|
||||
struct table_tag
|
||||
{
|
||||
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;
|
||||
}table_;
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
* 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
|
||||
#define NANA_DETAIL_PLATFORM_SPEC_HPP
|
||||
@ -186,7 +186,7 @@ namespace detail
|
||||
public:
|
||||
int error_code;
|
||||
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 ::nana::event_code event_code;
|
||||
typedef ::nana::native_window_type native_window_type;
|
||||
@ -235,7 +235,7 @@ namespace detail
|
||||
Window grab(Window);
|
||||
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 timer_proc(unsigned tid);
|
||||
void timer_proc(thread_t tid);
|
||||
|
||||
//Message dispatcher
|
||||
void msg_insert(native_window_type);
|
||||
@ -319,6 +319,5 @@ namespace detail
|
||||
// .h ward
|
||||
#endif
|
||||
|
||||
//#if defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#endif
|
||||
|
||||
|
@ -58,7 +58,7 @@ namespace nana
|
||||
wchar_t pstr[MAX_PATH];
|
||||
if (SUCCEEDED(SHGetFolderPath(0, CSIDL_PROFILE, 0, SHGFP_TYPE_CURRENT, pstr)))
|
||||
return pstr;
|
||||
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#elif defined(NANA_POSIX)
|
||||
const char * pstr = ::getenv("HOME");
|
||||
if (pstr)
|
||||
return pstr;
|
||||
@ -66,7 +66,7 @@ namespace nana
|
||||
return fs::path();
|
||||
}
|
||||
|
||||
std::string pretty_file_size(const fs::path& path)
|
||||
std::string pretty_file_size(const fs::path& path)
|
||||
{
|
||||
try {
|
||||
auto bytes = fs::file_size(path);
|
||||
@ -118,7 +118,7 @@ namespace nana
|
||||
if (ftime == ((fs::file_time_type::min)())) return{};
|
||||
|
||||
//std::time_t cftime = decltype(ftime)::clock::to_time_t(ftime);
|
||||
|
||||
|
||||
//A workaround for VC2013
|
||||
using time_point = decltype(ftime);
|
||||
|
||||
@ -169,7 +169,7 @@ namespace nana
|
||||
}
|
||||
}
|
||||
|
||||
#if NANA_USING_NANA_FILESYSTEM
|
||||
#if NANA_USING_NANA_FILESYSTEM
|
||||
|
||||
namespace nana_fs = nana::experimental::filesystem;
|
||||
|
||||
@ -208,7 +208,7 @@ namespace nana { namespace experimental { namespace filesystem
|
||||
|
||||
|
||||
//Because of No wide character version of POSIX
|
||||
#if defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#if defined(NANA_POSIX)
|
||||
const char* splstr = "/";
|
||||
#else
|
||||
const wchar_t* splstr = L"/\\";
|
||||
@ -251,7 +251,7 @@ namespace nana { namespace experimental { namespace filesystem
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
return (::GetFileAttributes(pathstr_.c_str()) == INVALID_FILE_ATTRIBUTES);
|
||||
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#elif defined(NANA_POSIX)
|
||||
struct stat sta;
|
||||
return (::stat(pathstr_.c_str(), &sta) == -1);
|
||||
#endif
|
||||
@ -293,7 +293,7 @@ namespace nana { namespace experimental { namespace filesystem
|
||||
return file_type::directory;
|
||||
|
||||
return file_type::regular;
|
||||
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#elif defined(NANA_POSIX)
|
||||
struct stat sta;
|
||||
if (-1 == ::stat(pathstr_.c_str(), &sta))
|
||||
return file_type::not_found; //??
|
||||
@ -372,7 +372,7 @@ namespace nana { namespace experimental { namespace filesystem
|
||||
{
|
||||
return pathstr_;
|
||||
}
|
||||
|
||||
|
||||
path::operator string_type() const
|
||||
{
|
||||
return native();
|
||||
@ -392,7 +392,7 @@ namespace nana { namespace experimental { namespace filesystem
|
||||
{
|
||||
return to_utf8(pathstr_);
|
||||
}
|
||||
std::string path::generic_string() const
|
||||
std::string path::generic_string() const
|
||||
{
|
||||
auto str = string();
|
||||
std::replace(str.begin(), str.end(), '\\', '/');
|
||||
@ -404,7 +404,7 @@ namespace nana { namespace experimental { namespace filesystem
|
||||
std::replace(str.begin(), str.end(), L'\\', L'/');
|
||||
return str;
|
||||
}
|
||||
std::string path::generic_u8string() const // uppss ...
|
||||
std::string path::generic_u8string() const // uppss ...
|
||||
{
|
||||
auto str = pathstr_;
|
||||
std::replace(str.begin(), str.end(), '\\', '/'); // uppss ... revise this !!!!!
|
||||
@ -447,7 +447,7 @@ namespace nana { namespace experimental { namespace filesystem
|
||||
|
||||
void path::_m_assign(const std::wstring& source)
|
||||
{
|
||||
pathstr_ = to_nstring(source);
|
||||
pathstr_ = to_nstring(source);
|
||||
}
|
||||
//end class path
|
||||
|
||||
@ -517,9 +517,9 @@ namespace nana { namespace experimental { namespace filesystem
|
||||
void operator()(void** handle)
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
::FindClose(*handle);
|
||||
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
::closedir(*reinterpret_cast<DIR**>(handle));
|
||||
::FindClose(*handle);
|
||||
#elif defined(NANA_POSIX)
|
||||
::closedir(*reinterpret_cast<DIR**>(handle));
|
||||
#endif
|
||||
}
|
||||
};
|
||||
@ -554,7 +554,7 @@ namespace nana { namespace experimental { namespace filesystem
|
||||
bool directory_iterator::equal(const directory_iterator& x) const
|
||||
{
|
||||
if (end_ && (end_ == x.end_)) return true;
|
||||
return (value_.path().filename() == x.value_.path().filename());
|
||||
return (value_.path().filename() == x.value_.path().filename());
|
||||
}
|
||||
|
||||
|
||||
@ -695,11 +695,11 @@ namespace nana { namespace experimental { namespace filesystem
|
||||
{
|
||||
if (p.empty())
|
||||
return false;
|
||||
#if defined(NANA_WINDOWS)
|
||||
#if defined(NANA_WINDOWS)
|
||||
return (FALSE != ::DeleteFileW(p.c_str()));
|
||||
#elif defined(NANA_POSIX)
|
||||
return (!std::remove(p.c_str()));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
bool rm_dir(const path& p)
|
||||
@ -708,7 +708,7 @@ namespace nana { namespace experimental { namespace filesystem
|
||||
return (FALSE != ::RemoveDirectoryW(p.c_str())) || not_found_error(static_cast<int>(::GetLastError()));
|
||||
#elif defined(NANA_POSIX)
|
||||
return (!::rmdir(p.c_str())) || not_found_error(errno);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
bool rm_dir(const path& p, bool fails_if_not_empty);
|
||||
@ -841,7 +841,7 @@ namespace nana { namespace experimental { namespace filesystem
|
||||
return file_status{ file_type::socket, prms };
|
||||
|
||||
return file_status{ file_type::unknown };
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
bool is_directory(const path& p)
|
||||
@ -877,7 +877,7 @@ namespace nana { namespace experimental { namespace filesystem
|
||||
# if defined(NANA_LINUX)
|
||||
fseeko64(stream, 0, SEEK_END);
|
||||
size = ftello64(stream);
|
||||
# elif defined(NANA_MACOS)
|
||||
# elif defined(NANA_POSIX)
|
||||
fseeko(stream, 0, SEEK_END);
|
||||
size = ftello(stream);
|
||||
# endif
|
||||
@ -891,7 +891,7 @@ namespace nana { namespace experimental { namespace filesystem
|
||||
file_time_type last_write_time(const path& p)
|
||||
{
|
||||
struct tm t;
|
||||
nana::filesystem_ext::modified_file_time(p, t);
|
||||
nana::filesystem_ext::modified_file_time(p, t);
|
||||
std::chrono::system_clock::time_point dateTime =std::chrono::system_clock::from_time_t( mktime(&t) );
|
||||
return dateTime;
|
||||
}
|
||||
@ -946,7 +946,7 @@ namespace nana { namespace experimental { namespace filesystem
|
||||
auto pstr = ::getcwd(buf, 260);
|
||||
if (pstr)
|
||||
return pstr;
|
||||
|
||||
|
||||
int bytes = 260 + 260;
|
||||
while (ERANGE == errno)
|
||||
{
|
||||
|
@ -37,7 +37,7 @@ namespace nana
|
||||
detail::bedrock::instance().wd_manager().internal_lock().unlock();
|
||||
}
|
||||
//end class internal_scope_guard
|
||||
|
||||
|
||||
//class internal_revert_guard
|
||||
internal_revert_guard::internal_revert_guard()
|
||||
{
|
||||
@ -55,7 +55,7 @@ namespace nana
|
||||
{
|
||||
stop_propagation_ = true;
|
||||
}
|
||||
|
||||
|
||||
bool event_arg::propagation_stopped() const
|
||||
{
|
||||
return stop_propagation_;
|
||||
@ -111,7 +111,7 @@ namespace nana
|
||||
pi_data_->auto_form_set.insert(wd);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (pi_data_->auto_form_set.erase(wd))
|
||||
{
|
||||
auto p = wd->widget_notifier->widget_ptr();
|
||||
@ -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;
|
||||
wd_manager().all_handles(v);
|
||||
@ -321,7 +321,7 @@ namespace nana
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void bedrock::set_menu(native_window_type menu_wd, bool has_keyboard)
|
||||
{
|
||||
if(menu_wd && pi_data_->menu.window != menu_wd)
|
||||
@ -453,7 +453,7 @@ namespace nana
|
||||
flag_guard fguard(this, wd);
|
||||
(wd->drawer.*drawer_event_fn)(*arg, bForce__EmitInternal);
|
||||
}
|
||||
|
||||
|
||||
if (bProcess__External_event)
|
||||
evt_addr->emit(*arg, reinterpret_cast<window>(wd));
|
||||
break;
|
||||
@ -610,4 +610,4 @@ namespace nana
|
||||
}
|
||||
}
|
||||
}//end namespace detail
|
||||
}//end namespace nana
|
||||
}//end namespace nana
|
||||
|
@ -80,26 +80,26 @@ namespace detail
|
||||
cursor.handle = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct bedrock::private_impl
|
||||
{
|
||||
typedef std::map<unsigned, thread_context> thr_context_container;
|
||||
std::recursive_mutex mutex;
|
||||
thr_context_container thr_contexts;
|
||||
|
||||
|
||||
element_store estore;
|
||||
|
||||
struct cache_type
|
||||
{
|
||||
struct thread_context_cache
|
||||
{
|
||||
unsigned tid{ 0 };
|
||||
thread_t tid{ 0 };
|
||||
thread_context *object{ nullptr };
|
||||
}tcontext;
|
||||
}cache;
|
||||
};
|
||||
|
||||
void timer_proc(unsigned);
|
||||
void timer_proc(thread_t);
|
||||
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_xevent(Display*, XEvent&);
|
||||
@ -175,7 +175,7 @@ namespace detail
|
||||
|
||||
//inc_window
|
||||
//@biref: increament the number of windows
|
||||
int bedrock::inc_window(unsigned tid)
|
||||
int bedrock::inc_window(thread_t tid)
|
||||
{
|
||||
private_impl * impl = instance().impl_;
|
||||
std::lock_guard<decltype(impl->mutex)> lock(impl->mutex);
|
||||
@ -184,7 +184,7 @@ namespace detail
|
||||
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();
|
||||
|
||||
@ -205,7 +205,7 @@ namespace detail
|
||||
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();
|
||||
|
||||
@ -224,7 +224,7 @@ namespace detail
|
||||
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();
|
||||
|
||||
@ -320,7 +320,7 @@ namespace detail
|
||||
|
||||
good_wd = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(thrd) thrd->event_window = prev_wd;
|
||||
return good_wd;
|
||||
@ -403,10 +403,10 @@ namespace detail
|
||||
arg.distance = 120;
|
||||
arg.which = arg_wheel::wheel::vertical;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void timer_proc(unsigned tid)
|
||||
void timer_proc(thread_t tid)
|
||||
{
|
||||
nana::detail::platform_spec::instance().timer_proc(tid);
|
||||
}
|
||||
@ -616,7 +616,7 @@ namespace detail
|
||||
|
||||
arg.evt_code = event_code::mouse_move;
|
||||
brock.emit(event_code::mouse_move, msgwnd, arg, true, &context);
|
||||
|
||||
|
||||
if (!wd_manager.available(hovered_wd))
|
||||
hovered_wd = nullptr;
|
||||
}
|
||||
@ -643,7 +643,7 @@ namespace detail
|
||||
auto & cf = xevent.xconfigure;
|
||||
wd_manager.size(msgwnd, nana::size{static_cast<unsigned>(cf.width), static_cast<unsigned>(cf.height)}, true, true);
|
||||
}
|
||||
|
||||
|
||||
if(msgwnd->pos_native.x != xevent.xconfigure.x || msgwnd->pos_native.y != xevent.xconfigure.y)
|
||||
{
|
||||
msgwnd->pos_native.x = xevent.xconfigure.x;
|
||||
@ -664,7 +664,7 @@ namespace detail
|
||||
pressed_wd = nullptr;
|
||||
if(nullptr == msgwnd)
|
||||
break;
|
||||
|
||||
|
||||
if ((msgwnd == msgwnd->root_widget->other.attribute.root->menubar) && brock.get_menu(msgwnd->root, true))
|
||||
brock.erase_menu(true);
|
||||
else
|
||||
@ -752,7 +752,7 @@ namespace detail
|
||||
arg.which = arg_wheel::wheel::vertical;
|
||||
assign_arg(arg, msgwnd, xevent);
|
||||
draw_invoker(&drawer::mouse_wheel, msgwnd, arg, &context);
|
||||
wd_manager.do_lazy_refresh(msgwnd, false);
|
||||
wd_manager.do_lazy_refresh(msgwnd, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -782,13 +782,13 @@ namespace detail
|
||||
draw_invoker(&drawer::click, msgwnd, click_arg, &context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Do mouse_up, this handle may be closed by click handler.
|
||||
if(wd_manager.available(msgwnd) && msgwnd->flags.enabled)
|
||||
{
|
||||
if(hit)
|
||||
msgwnd->set_action(mouse_action::hovered);
|
||||
|
||||
|
||||
auto retain = msgwnd->annex.events_ptr;
|
||||
auto evt_ptr = retain.get();
|
||||
|
||||
@ -886,7 +886,7 @@ namespace detail
|
||||
{
|
||||
arg_mouse arg;
|
||||
assign_arg(arg, msgwnd, message, xevent);
|
||||
|
||||
|
||||
if (mouse_action::pressed != msgwnd->flags.action)
|
||||
msgwnd->set_action(mouse_action::hovered);
|
||||
|
||||
@ -1069,10 +1069,10 @@ namespace detail
|
||||
{
|
||||
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));
|
||||
charbuf = reinterpret_cast<const wchar_t*>(str.c_str()) + 1;
|
||||
len = str.size() / sizeof(wchar_t) - 1;
|
||||
charbuf = reinterpret_cast<const wchar_t*>(str.c_str());
|
||||
len = str.size() / sizeof(wchar_t);
|
||||
|
||||
for(int i = 0; i < len; ++i)
|
||||
{
|
||||
@ -1080,6 +1080,9 @@ namespace detail
|
||||
arg.ignore = false;
|
||||
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.
|
||||
if ((keyboard::tab == arg.key) && root_runtime->condition.ignore_tab)
|
||||
continue;
|
||||
@ -1126,12 +1129,12 @@ namespace detail
|
||||
context.is_ctrl_pressed = false;
|
||||
|
||||
if (('\t' == os_code) && root_runtime->condition.ignore_tab)
|
||||
{
|
||||
{
|
||||
root_runtime->condition.ignore_tab = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
msgwnd = brock.focus();
|
||||
if(msgwnd)
|
||||
{
|
||||
@ -1165,7 +1168,7 @@ namespace detail
|
||||
else
|
||||
{
|
||||
arg_keyboard arg;
|
||||
|
||||
|
||||
arg.evt_code = event_code::key_release;
|
||||
arg.window_handle = reinterpret_cast<window>(msgwnd);
|
||||
arg.ignore = false;
|
||||
@ -1264,7 +1267,7 @@ namespace detail
|
||||
|
||||
auto & lock = wd_manager().internal_lock();
|
||||
lock.revert();
|
||||
|
||||
|
||||
native_window_type owner_native{};
|
||||
core_window_t * owner = 0;
|
||||
if(condition_wd && is_modal)
|
||||
@ -1277,9 +1280,9 @@ namespace detail
|
||||
owner = wd_manager().root(owner_native);
|
||||
if(owner)
|
||||
owner->flags.enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nana::detail::platform_spec::instance().msg_dispatch(condition_wd ? reinterpret_cast<core_window_t*>(condition_wd)->root : 0);
|
||||
|
||||
if(owner_native)
|
||||
@ -1291,7 +1294,7 @@ namespace detail
|
||||
|
||||
//Before exit of pump_event, it should call the remove_trash_handle.
|
||||
//Under Linux, if the windows are closed in other threads, all the widgets handles
|
||||
//will be marked as deleted after exit of the event loop and in other threads. So the
|
||||
//will be marked as deleted after exit of the event loop and in other threads. So the
|
||||
//handle should be deleted from trash before exit the pump_event.
|
||||
auto thread_id = ::nana::system::this_thread_id();
|
||||
wd_manager().call_safe_place(thread_id);
|
||||
@ -1376,7 +1379,7 @@ namespace detail
|
||||
{
|
||||
if (!wd_manager().available(wd))
|
||||
return;
|
||||
|
||||
|
||||
wd->root_widget->other.attribute.root->state_cursor = nana::cursor::arrow;
|
||||
wd->root_widget->other.attribute.root->state_cursor_window = nullptr;
|
||||
|
||||
|
@ -176,7 +176,7 @@ namespace detail
|
||||
{
|
||||
struct thread_context_cache
|
||||
{
|
||||
unsigned tid{ 0 };
|
||||
thread_t tid{ 0 };
|
||||
thread_context *object{ nullptr };
|
||||
}tcontext;
|
||||
}cache;
|
||||
@ -251,7 +251,7 @@ namespace detail
|
||||
|
||||
|
||||
/// @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.
|
||||
private_impl * impl = instance().impl_;
|
||||
@ -261,7 +261,7 @@ namespace detail
|
||||
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();
|
||||
std::lock_guard<decltype(impl_->mutex)> lock(impl_->mutex);
|
||||
@ -275,7 +275,7 @@ namespace detail
|
||||
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();
|
||||
|
||||
@ -295,7 +295,7 @@ namespace detail
|
||||
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();
|
||||
|
||||
@ -372,7 +372,7 @@ namespace detail
|
||||
|
||||
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);
|
||||
if(0 == context->window_count)
|
||||
{
|
||||
|
@ -263,7 +263,7 @@ namespace detail
|
||||
std::vector<key_value_rep> table_;
|
||||
};
|
||||
|
||||
//class window_manager
|
||||
//class window_manager
|
||||
//struct wdm_private_impl
|
||||
struct window_manager::wdm_private_impl
|
||||
{
|
||||
@ -280,10 +280,10 @@ namespace detail
|
||||
//class revertible_mutex
|
||||
struct thread_refcount
|
||||
{
|
||||
unsigned tid; //Thread ID
|
||||
thread_t tid; //Thread ID
|
||||
std::vector<unsigned> callstack_refs;
|
||||
|
||||
thread_refcount(unsigned thread_id, unsigned refs)
|
||||
thread_refcount(thread_t thread_id, unsigned refs)
|
||||
: tid(thread_id)
|
||||
{
|
||||
callstack_refs.push_back(refs);
|
||||
@ -294,7 +294,7 @@ namespace detail
|
||||
{
|
||||
std::recursive_mutex mutex;
|
||||
|
||||
unsigned thread_id; //Thread ID
|
||||
thread_t thread_id; //Thread ID
|
||||
unsigned refs; //Ref count
|
||||
|
||||
std::vector<thread_refcount> records;
|
||||
@ -842,7 +842,7 @@ namespace detail
|
||||
std::lock_guard<mutex_type> lock(mutex_);
|
||||
if (!impl_->wd_register.available(wd))
|
||||
return false;
|
||||
|
||||
|
||||
auto & brock = bedrock::instance();
|
||||
bool moved = false;
|
||||
const bool size_changed = (r.width != wd->dimension.width || r.height != wd->dimension.height);
|
||||
@ -913,12 +913,12 @@ namespace detail
|
||||
// window again, otherwise, it causes an infinite loop, because when a root_widget is resized,
|
||||
// window_manager will call the function.
|
||||
bool window_manager::size(core_window_t* wd, nana::size sz, bool passive, bool ask_update)
|
||||
{
|
||||
{
|
||||
//Thread-Safe Required!
|
||||
std::lock_guard<mutex_type> lock(mutex_);
|
||||
if (!impl_->wd_register.available(wd))
|
||||
return false;
|
||||
|
||||
|
||||
auto & brock = bedrock::instance();
|
||||
if (sz != wd->dimension)
|
||||
{
|
||||
@ -1175,7 +1175,7 @@ namespace detail
|
||||
}
|
||||
|
||||
bool window_manager::set_parent(core_window_t* wd, core_window_t* newpa)
|
||||
{
|
||||
{
|
||||
//Thread-Safe Required!
|
||||
std::lock_guard<mutex_type> lock(mutex_);
|
||||
if (!impl_->wd_register.available(wd))
|
||||
@ -1255,7 +1255,7 @@ namespace detail
|
||||
//The menubar token window will be redirected to the prev focus window when the new
|
||||
//focus window is a menubar.
|
||||
//The focus window will be restored to the prev focus which losts the focus becuase of
|
||||
//memberbar.
|
||||
//memberbar.
|
||||
if (prev_focus && (wd == wd->root_widget->other.attribute.root->menubar))
|
||||
wd = prev_focus;
|
||||
|
||||
@ -1403,7 +1403,7 @@ namespace detail
|
||||
return tabs.front();
|
||||
}
|
||||
}
|
||||
else if (tabs.size() > 1) //at least 2 elments in tabs are required when moving backward.
|
||||
else if (tabs.size() > 1) //at least 2 elments in tabs are required when moving backward.
|
||||
{
|
||||
auto i = std::find(tabs.begin(), end, wd);
|
||||
if (i != end)
|
||||
@ -1449,7 +1449,7 @@ namespace detail
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void window_manager::remove_trash_handle(unsigned tid)
|
||||
void window_manager::remove_trash_handle(thread_t tid)
|
||||
{
|
||||
//Thread-Safe Required!
|
||||
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_);
|
||||
|
||||
@ -1608,7 +1608,7 @@ namespace detail
|
||||
|
||||
bool established = (for_new && (wdpa != for_new));
|
||||
decltype(for_new->root_widget->other.attribute.root) pa_root_attr = nullptr;
|
||||
|
||||
|
||||
if (established)
|
||||
pa_root_attr = for_new->root_widget->other.attribute.root;
|
||||
|
||||
@ -1743,7 +1743,7 @@ namespace detail
|
||||
wd->root = for_new->root;
|
||||
wd->root_graph = for_new->root_graph;
|
||||
wd->root_widget = for_new->root_widget;
|
||||
|
||||
|
||||
wd->pos_owner.x = wd->pos_owner.y = 0;
|
||||
|
||||
auto delta_pos = wd->pos_root - for_new->pos_root;
|
||||
|
@ -153,7 +153,7 @@ namespace nana
|
||||
}
|
||||
}
|
||||
|
||||
void delete_trash(unsigned thread_id)
|
||||
void delete_trash(thread_t thread_id)
|
||||
{
|
||||
if (0 == thread_id)
|
||||
{
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#include "../detail/platform_spec_selector.hpp"
|
||||
|
||||
#if defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#if defined(NANA_POSIX)
|
||||
#include <nana/system/platform.hpp>
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
#if defined(NANA_WINDOWS)
|
||||
#include <windows.h>
|
||||
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#elif defined(NANA_POSIX)
|
||||
#include "../detail/platform_spec_selector.hpp"
|
||||
#include <nana/system/platform.hpp>
|
||||
#endif
|
||||
|
@ -440,7 +440,7 @@ namespace paint
|
||||
#endif
|
||||
impl_->handle->string.tab_pixels = detail::raw_text_extent_size(impl_->handle, L"\t", 1).width;
|
||||
impl_->handle->string.whitespace_pixels = detail::raw_text_extent_size(impl_->handle, L" ", 1).width;
|
||||
|
||||
|
||||
if (impl_->changed == false)
|
||||
impl_->changed = true;
|
||||
}
|
||||
@ -833,11 +833,11 @@ namespace paint
|
||||
}
|
||||
#elif defined(NANA_X11)
|
||||
auto & spec = nana::detail::platform_spec::instance();
|
||||
|
||||
|
||||
Display * display = spec.open_display();
|
||||
|
||||
|
||||
nana::detail::platform_scope_guard lock;
|
||||
|
||||
|
||||
::XCopyArea(display,
|
||||
impl_->handle->pixmap, reinterpret_cast<Window>(dst), impl_->handle->context,
|
||||
sx, sy, width, height, dx, dy);
|
||||
@ -847,7 +847,7 @@ namespace paint
|
||||
::XGetWindowAttributes(display, reinterpret_cast<Window>(dst), &attr);
|
||||
if(BadWindow != spec.rev_error_handler() && attr.map_state != IsUnmapped)
|
||||
::XMapWindow(display, reinterpret_cast<Window>(dst));
|
||||
|
||||
|
||||
::XFlush(display);
|
||||
#endif
|
||||
}
|
||||
@ -1063,7 +1063,7 @@ namespace paint
|
||||
{
|
||||
auto const end = str + len;
|
||||
auto i = std::find(str, end, '\t');
|
||||
#if defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#if defined(NANA_POSIX)
|
||||
impl_->handle->update_text_color();
|
||||
#endif
|
||||
if (i != end)
|
||||
|
@ -17,12 +17,49 @@
|
||||
#if defined(NANA_WINDOWS)
|
||||
#include <windows.h>
|
||||
#include "../detail/mswin/platform_spec.hpp"
|
||||
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#elif defined(NANA_POSIX)
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.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
|
||||
|
||||
namespace nana
|
||||
@ -36,7 +73,7 @@ namespace system
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
::Sleep(milliseconds);
|
||||
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#elif defined(NANA_POSIX)
|
||||
struct timespec timeOut, remains;
|
||||
timeOut.tv_sec = milliseconds / 1000;
|
||||
timeOut.tv_nsec = (milliseconds % 1000) * 1000000;
|
||||
@ -52,14 +89,16 @@ namespace system
|
||||
|
||||
//this_thread_id
|
||||
//@brief: get the identifier of calling thread.
|
||||
unsigned long this_thread_id()
|
||||
thread_t this_thread_id()
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
return ::GetCurrentThreadId();
|
||||
return (thread_t)::GetCurrentThreadId();
|
||||
#elif defined(NANA_LINUX)
|
||||
return ::syscall(__NR_gettid);
|
||||
return (thread_t)::syscall(__NR_gettid);
|
||||
#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
|
||||
}
|
||||
|
||||
@ -67,7 +106,7 @@ namespace system
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
return ::GetTickCount();
|
||||
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#elif defined(NANA_POSIX)
|
||||
struct timeval tv;
|
||||
::gettimeofday(&tv, 0);
|
||||
return (tv.tv_sec * 1000 + tv.tv_usec / 1000);
|
||||
@ -92,7 +131,7 @@ namespace system
|
||||
}
|
||||
|
||||
return (::GetAsyncKeyState(button) != 0);
|
||||
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#elif defined(NANA_POSIX)
|
||||
static_cast<void>(button); //eliminate unused parameter compiler warning.
|
||||
return false;
|
||||
#endif
|
||||
@ -105,7 +144,6 @@ namespace system
|
||||
return;
|
||||
|
||||
#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))
|
||||
{
|
||||
//Because ShellExecute can delegate execution to Shell extensions (data sources, context menu handlers,
|
||||
@ -115,8 +153,9 @@ namespace system
|
||||
nana::detail::platform_spec::co_initializer co_init;
|
||||
::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
|
||||
}
|
||||
}
|
||||
}//end namespace system
|
||||
}//end namespace nana
|
||||
|
@ -2,8 +2,8 @@
|
||||
* Operation System Shared Linkage Library Wrapper Implementation
|
||||
* Copyright(C) 2003 Jinhao
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* @file: nana/system/shared_wrapper.cpp
|
||||
@ -12,7 +12,7 @@
|
||||
#include <nana/system/shared_wrapper.hpp>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#if defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#if defined(NANA_POSIX)
|
||||
#include <dlfcn.h>
|
||||
#else
|
||||
#include <windows.h>
|
||||
@ -30,7 +30,7 @@ namespace system
|
||||
|
||||
module_t open(const char* filename)
|
||||
{
|
||||
#if defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#if defined(NANA_POSIX)
|
||||
return ::dlopen(filename, RTLD_LAZY);
|
||||
#else
|
||||
return ::LoadLibraryA(filename);
|
||||
@ -39,7 +39,7 @@ namespace system
|
||||
|
||||
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));
|
||||
#else
|
||||
return (void*)(::GetProcAddress(reinterpret_cast<HMODULE>(handle), symbol));
|
||||
@ -48,7 +48,7 @@ namespace system
|
||||
|
||||
void close(module_t handle)
|
||||
{
|
||||
#if defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#if defined(NANA_POSIX)
|
||||
::dlclose(handle);
|
||||
#else
|
||||
::FreeLibrary(reinterpret_cast<HMODULE>(handle));
|
||||
@ -90,7 +90,7 @@ namespace system
|
||||
std::transform(filename + length - 13, filename + length , std::back_inserter(file), tolower);
|
||||
if(file == ".nana_shared")
|
||||
{
|
||||
#if defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#if defined(NANA_POSIX)
|
||||
ofn.replace(length - 13, 13, ".so");
|
||||
#else
|
||||
ofn.replace(length - 13, 13, ".DLL");
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include <nana/config.hpp>
|
||||
#ifdef NANA_WINDOWS
|
||||
#include <windows.h>
|
||||
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#elif defined(NANA_POSIX)
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
@ -15,7 +15,7 @@ namespace system
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
LARGE_INTEGER beg_timestamp;
|
||||
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#elif defined(NANA_POSIX)
|
||||
struct timeval beg_timestamp;
|
||||
#endif
|
||||
};
|
||||
@ -45,7 +45,7 @@ namespace system
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
::QueryPerformanceCounter(&impl_->beg_timestamp);
|
||||
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#elif defined(NANA_POSIX)
|
||||
struct timezone tz;
|
||||
::gettimeofday(&impl_->beg_timestamp, &tz);
|
||||
#endif
|
||||
@ -63,7 +63,7 @@ namespace system
|
||||
::QueryPerformanceFrequency(&freq);
|
||||
|
||||
return double(diff)/double(freq.QuadPart) * 1000;
|
||||
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#elif defined(NANA_POSIX)
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
gettimeofday(&tv, &tz);
|
||||
|
@ -29,7 +29,7 @@
|
||||
#if defined(NANA_WINDOWS)
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#elif defined(NANA_POSIX)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user