first init of 0.9

This commit is contained in:
cnjinhao
2014-12-11 03:32:35 +08:00
commit d0a317bd45
206 changed files with 69773 additions and 0 deletions

173
source/system/dataexch.cpp Normal file
View 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
View 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

View 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

View 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