first init of 0.9
This commit is contained in:
173
source/system/dataexch.cpp
Normal file
173
source/system/dataexch.cpp
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Data Exchanger Implementation
|
||||
* Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* 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/dataexch.cpp
|
||||
* @description: An implementation of a data exchange mechanism through Windows Clipboard, X11 Selection.
|
||||
*/
|
||||
|
||||
#include <nana/system/dataexch.hpp>
|
||||
#include <nana/traits.hpp>
|
||||
#if defined(NANA_WINDOWS)
|
||||
#include <windows.h>
|
||||
#elif defined(NANA_X11)
|
||||
#include PLATFORM_SPEC_HPP
|
||||
#include GUI_BEDROCK_HPP
|
||||
#include <nana/gui/detail/basic_window.hpp>
|
||||
#endif
|
||||
|
||||
namespace nana{ namespace system{
|
||||
|
||||
//class dataexch
|
||||
void dataexch::set(const nana::char_t* text)
|
||||
{
|
||||
_m_set(std::is_same<char, nana::char_t>::value ? format::text : format::unicode, text, (nana::strlen(text) + 1) * sizeof(nana::char_t));
|
||||
}
|
||||
|
||||
void dataexch::set(const nana::string& text)
|
||||
{
|
||||
_m_set(std::is_same<char, nana::char_t>::value ? format::text : format::unicode, text.c_str(), (text.length() + 1) * sizeof(nana::char_t));
|
||||
}
|
||||
|
||||
void dataexch::get(nana::string& str)
|
||||
{
|
||||
std::size_t size;
|
||||
void* res = _m_get(std::is_same<char, nana::char_t>::value ? format::text : format::unicode, size);
|
||||
if(res)
|
||||
{
|
||||
#if defined(NANA_X11) && defined(NANA_UNICODE)
|
||||
nana::detail::charset_conv conv("UTF-32", "UTF-8");
|
||||
const std::string & utf32str = conv.charset(reinterpret_cast<char*>(res), size);
|
||||
const nana::char_t * utf32ptr = reinterpret_cast<const nana::char_t*>(utf32str.c_str());
|
||||
str.append(utf32ptr + 1, utf32ptr + utf32str.size() / sizeof(nana::char_t));
|
||||
#else
|
||||
str.reserve(size / sizeof(nana::char_t));
|
||||
str.append(reinterpret_cast<nana::char_t*>(res), reinterpret_cast<nana::char_t*>(res) + size / sizeof(nana::char_t));
|
||||
nana::string::size_type pos = str.find_last_not_of(nana::char_t(0));
|
||||
if(pos != str.npos)
|
||||
str.erase(pos + 1);
|
||||
#endif
|
||||
|
||||
#if defined(NANA_X11)
|
||||
::XFree(res);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
//private:
|
||||
bool dataexch::_m_set(unsigned type, const void* buf, std::size_t size)
|
||||
{
|
||||
bool res = false;
|
||||
#if defined(NANA_WINDOWS)
|
||||
if(type < format::end && ::OpenClipboard(::GetFocus()))
|
||||
{
|
||||
if(::EmptyClipboard())
|
||||
{
|
||||
HGLOBAL g = ::GlobalAlloc(GHND | GMEM_SHARE, size);
|
||||
void * addr = ::GlobalLock(g);
|
||||
|
||||
memcpy(addr, buf, size);
|
||||
::GlobalUnlock(g);
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case format::text: type = CF_TEXT; break;
|
||||
case format::unicode: type = CF_UNICODETEXT; break;
|
||||
case format::pixmap: type = CF_BITMAP; break;
|
||||
}
|
||||
::SetClipboardData(type, g);
|
||||
res = true;
|
||||
}
|
||||
::CloseClipboard();
|
||||
}
|
||||
#elif defined(NANA_X11)
|
||||
auto & spec = ::nana::detail::platform_spec::instance();
|
||||
native_window_type owner = nullptr;
|
||||
{
|
||||
internal_scope_guard lock;
|
||||
auto wd = detail::bedrock::instance().focus();
|
||||
if(wd) owner = wd->root;
|
||||
}
|
||||
|
||||
if(owner)
|
||||
{
|
||||
Atom atom_type;
|
||||
switch(type)
|
||||
{
|
||||
case format::text: atom_type = XA_STRING; break;
|
||||
case format::unicode: atom_type = spec.atombase().utf8_string; break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
#if defined(NANA_UNICODE)
|
||||
//The internal clipboard stores UTF8_STRING, the parameter string should be converted from utf32 to utf8.
|
||||
nana::detail::charset_conv conv("UTF-8", "UTF-32");
|
||||
std::string utf8str = conv.charset(reinterpret_cast<const char*>(buf), size);
|
||||
buf = utf8str.c_str();
|
||||
size = utf8str.size();
|
||||
#endif
|
||||
spec.write_selection(owner, atom_type, buf, size);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
void* dataexch::_m_get(unsigned type, size_t& size)
|
||||
{
|
||||
void* res = 0;
|
||||
#if defined(NANA_WINDOWS)
|
||||
if(type < format::end && ::OpenClipboard(::GetFocus()))
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case format::text: type = CF_TEXT; break;
|
||||
case format::unicode: type = CF_UNICODETEXT; break;
|
||||
case format::pixmap: type = CF_BITMAP; break;
|
||||
}
|
||||
HANDLE handle = ::GetClipboardData(type);
|
||||
if(handle)
|
||||
{
|
||||
res = reinterpret_cast<HGLOBAL>(::GlobalLock(handle));
|
||||
if(res)
|
||||
size = ::GlobalSize(handle);
|
||||
}
|
||||
|
||||
::CloseClipboard();
|
||||
}
|
||||
#elif defined(NANA_X11)
|
||||
nana::detail::platform_spec & spec = nana::detail::platform_spec::instance();
|
||||
native_window_type requester = nullptr;
|
||||
spec.lock_xlib();
|
||||
|
||||
{
|
||||
internal_scope_guard isg;
|
||||
detail::bedrock::core_window_t * wd = detail::bedrock::instance().focus();
|
||||
if(wd) requester = wd->root;
|
||||
}
|
||||
spec.unlock_xlib();
|
||||
|
||||
if(requester)
|
||||
{
|
||||
Atom atom;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case format::text: atom = XA_STRING; break;
|
||||
case format::unicode: atom = spec.atombase().utf8_string; break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
res = spec.request_selection(requester, atom, size);
|
||||
}
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
//end class dataexch
|
||||
|
||||
}//end namespace system
|
||||
}//end namespace nana
|
||||
|
||||
116
source/system/platform.cpp
Normal file
116
source/system/platform.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* A platform API implementation
|
||||
* Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* 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/platform.cpp
|
||||
* @description:
|
||||
* this implements some API for platform-independent programming
|
||||
*/
|
||||
#include <nana/deploy.hpp>
|
||||
|
||||
#if defined(NANA_WINDOWS)
|
||||
#include <windows.h>
|
||||
#include PLATFORM_SPEC_HPP
|
||||
#elif defined(NANA_LINUX)
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/syscall.h>
|
||||
#endif
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace system
|
||||
{
|
||||
//sleep
|
||||
//@brief: Suspend current thread for a specified milliseconds.
|
||||
// its precision is depended on hardware.
|
||||
void sleep(unsigned milliseconds)
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
::Sleep(milliseconds);
|
||||
#elif defined(NANA_LINUX)
|
||||
struct timespec timeOut, remains;
|
||||
timeOut.tv_sec = milliseconds / 1000;
|
||||
timeOut.tv_nsec = (milliseconds % 1000) * 1000000;
|
||||
while(-1 == ::nanosleep(&timeOut, &remains))
|
||||
{
|
||||
if(errno == EINTR)
|
||||
timeOut = remains;
|
||||
else
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//this_thread_id
|
||||
//@brief: get the identifier of calling thread.
|
||||
unsigned long this_thread_id()
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
return ::GetCurrentThreadId();
|
||||
#elif defined(NANA_LINUX)
|
||||
return ::syscall(__NR_gettid);
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned long timestamp()
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
return ::GetTickCount();
|
||||
#elif defined(NANA_LINUX)
|
||||
struct timeval tv;
|
||||
::gettimeofday(&tv, 0);
|
||||
return (tv.tv_sec * 1000 + tv.tv_usec / 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool get_async_mouse_state(int button)
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
bool swap = (::GetSystemMetrics(SM_SWAPBUTTON) != 0);
|
||||
switch(button)
|
||||
{
|
||||
case 1: //Right
|
||||
button = swap ? VK_LBUTTON : VK_RBUTTON;
|
||||
break;
|
||||
case 2:
|
||||
button = VK_MBUTTON;
|
||||
break;
|
||||
default:
|
||||
button = swap ? VK_RBUTTON : VK_LBUTTON;
|
||||
break;
|
||||
}
|
||||
|
||||
return (::GetAsyncKeyState(button) != 0);
|
||||
#elif defined(NANA_LINUX)
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
//open an url through a default browser
|
||||
void open_url(const nana::string& url)
|
||||
{
|
||||
if(url.empty())
|
||||
return;
|
||||
|
||||
#if defined(NANA_WINDOWS)
|
||||
if(::ShellExecute(0, STR("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,
|
||||
//verb implementations) that are activated using Component Object Model (COM), COM should be initialized
|
||||
//before ShellExecute is called. Some Shell extensions require the COM single-threaded apartment (STA) type.
|
||||
//In that case, COM should be initialized under WinXP.
|
||||
nana::detail::platform_spec::co_initializer co_init;
|
||||
::ShellExecute(0, STR("open"), url.c_str(), 0, 0, SW_SHOWNORMAL);
|
||||
}
|
||||
#elif defined(NANA_LINUX)
|
||||
#endif
|
||||
}
|
||||
}//end namespace system
|
||||
}//end namespace nana
|
||||
125
source/system/shared_wrapper.cpp
Normal file
125
source/system/shared_wrapper.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* @file: nana/system/shared_wrapper.cpp
|
||||
*/
|
||||
|
||||
#include <nana/system/shared_wrapper.hpp>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#ifdef NANA_LINUX
|
||||
#include <dlfcn.h>
|
||||
#else
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace system
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
namespace shared_helper
|
||||
{
|
||||
|
||||
module_t open(const char* filename)
|
||||
{
|
||||
#ifdef NANA_LINUX
|
||||
return ::dlopen(filename, RTLD_LAZY);
|
||||
#else
|
||||
return ::LoadLibraryA(filename);
|
||||
#endif
|
||||
}
|
||||
|
||||
void* symbols(module_t handle, const char* symbol)
|
||||
{
|
||||
#ifdef NANA_LINUX
|
||||
return ::dlsym(handle, const_cast<char*>(symbol));
|
||||
#else
|
||||
return (void*)(::GetProcAddress(reinterpret_cast<HMODULE>(handle), symbol));
|
||||
#endif
|
||||
}
|
||||
|
||||
void close(module_t handle)
|
||||
{
|
||||
#ifdef NANA_LINUX
|
||||
::dlclose(handle);
|
||||
#else
|
||||
::FreeLibrary(reinterpret_cast<HMODULE>(handle));
|
||||
#endif
|
||||
}
|
||||
}; //end struct shared_helper
|
||||
}//end namespace detail
|
||||
|
||||
|
||||
shared_wrapper::impl_type::impl_type()
|
||||
{}
|
||||
|
||||
//class shared_wrapper
|
||||
shared_wrapper::shared_wrapper()
|
||||
{}
|
||||
|
||||
shared_wrapper::shared_wrapper(const char* filename)
|
||||
{
|
||||
this->open(filename);
|
||||
}
|
||||
|
||||
shared_wrapper::~shared_wrapper()
|
||||
{
|
||||
this->close();
|
||||
}
|
||||
|
||||
bool shared_wrapper::open(const char* filename)
|
||||
{
|
||||
this->close();
|
||||
|
||||
if(filename)
|
||||
{
|
||||
std::string file;
|
||||
std::string ofn = filename;
|
||||
std::string::size_type length = ofn.length();
|
||||
|
||||
if(length > 13)
|
||||
{
|
||||
std::transform(filename + length - 13, filename + length , std::back_inserter(file), tolower);
|
||||
if(file == ".nana_shared")
|
||||
{
|
||||
#ifdef NANA_LINUX
|
||||
ofn.replace(length - 13, 13, ".so");
|
||||
#else
|
||||
ofn.replace(length - 13, 13, ".DLL");
|
||||
#endif
|
||||
filename = ofn.c_str();
|
||||
}
|
||||
}
|
||||
|
||||
impl_.handle = detail::shared_helper::open(filename);
|
||||
}
|
||||
|
||||
return (impl_.handle != 0);
|
||||
}
|
||||
|
||||
void shared_wrapper::close()
|
||||
{
|
||||
if(impl_.handle)
|
||||
{
|
||||
detail::shared_helper::close(impl_.handle);
|
||||
impl_.symbol = "";
|
||||
impl_.proc_address = 0;
|
||||
impl_.handle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool shared_wrapper::empty() const
|
||||
{
|
||||
return (impl_.handle == 0);
|
||||
}
|
||||
//end class shared_wrapper
|
||||
}//end namespace system
|
||||
}//end namespace nana
|
||||
76
source/system/timepiece.cpp
Normal file
76
source/system/timepiece.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
#include <nana/system/timepiece.hpp>
|
||||
#include <nana/config.hpp>
|
||||
#ifdef NANA_WINDOWS
|
||||
#include <windows.h>
|
||||
#elif defined(NANA_LINUX)
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace system
|
||||
{
|
||||
//class timepiece
|
||||
struct timepiece::impl_t
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
LARGE_INTEGER beg_timestamp;
|
||||
#elif defined(NANA_LINUX)
|
||||
struct timeval beg_timestamp;
|
||||
#endif
|
||||
};
|
||||
|
||||
timepiece::timepiece()
|
||||
: impl_(new impl_t)
|
||||
{}
|
||||
|
||||
timepiece::timepiece(const volatile timepiece& rhs)
|
||||
: impl_(new impl_t(*rhs.impl_))
|
||||
{}
|
||||
|
||||
timepiece::~timepiece()
|
||||
{
|
||||
delete impl_;
|
||||
}
|
||||
|
||||
timepiece & timepiece::operator=(const volatile timepiece & rhs)
|
||||
{
|
||||
if(this != &rhs)
|
||||
*impl_ = *rhs.impl_;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void timepiece::start() volatile
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
::QueryPerformanceCounter(&impl_->beg_timestamp);
|
||||
#elif defined(NANA_LINUX)
|
||||
struct timezone tz;
|
||||
::gettimeofday(&impl_->beg_timestamp, &tz);
|
||||
#endif
|
||||
}
|
||||
|
||||
double timepiece::calc() const volatile
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
LARGE_INTEGER li;
|
||||
::QueryPerformanceCounter(&li);
|
||||
|
||||
__int64 diff = li.QuadPart - impl_->beg_timestamp.QuadPart;
|
||||
|
||||
LARGE_INTEGER freq;
|
||||
::QueryPerformanceFrequency(&freq);
|
||||
|
||||
return double(diff)/double(freq.QuadPart) * 1000;
|
||||
#elif defined(NANA_LINUX)
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
gettimeofday(&tv, &tz);
|
||||
return static_cast<double>(tv.tv_sec - impl_->beg_timestamp.tv_sec) * 1000 + static_cast<double>(tv.tv_usec - impl_->beg_timestamp.tv_usec) / 1000;
|
||||
#endif
|
||||
}
|
||||
//end class timepiece
|
||||
|
||||
}//end namespace system
|
||||
}//end namespace nana
|
||||
Reference in New Issue
Block a user