reuse some linux implementations for Mac OS
This commit is contained in:
parent
e0765bbf97
commit
41f7545822
@ -1,32 +0,0 @@
|
||||
#ifndef NANA_DETAIL_MSG_PACKET_HPP
|
||||
#define NANA_DETAIL_MSG_PACKET_HPP
|
||||
#include <X11/Xlib.h>
|
||||
#include <vector>
|
||||
#include <nana/deploy.hpp>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct msg_packet_tag
|
||||
{
|
||||
enum kind_t{kind_xevent, kind_mouse_drop, kind_cleanup};
|
||||
kind_t kind;
|
||||
union
|
||||
{
|
||||
XEvent xevent;
|
||||
|
||||
Window packet_window; //Avaiable if the packet is not kind_xevent
|
||||
struct mouse_drop_tag
|
||||
{
|
||||
Window window;
|
||||
int x;
|
||||
int y;
|
||||
std::vector<nana::string> * files;
|
||||
}mouse_drop;
|
||||
}u;
|
||||
};
|
||||
}//end namespace detail
|
||||
}//end namespace nana
|
||||
#endif
|
||||
|
||||
@ -1,325 +0,0 @@
|
||||
/*
|
||||
* Platform Specification Implementation
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2014 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/detail/platform_spec.hpp
|
||||
*
|
||||
* This file provides basis class and data structrue that required by nana
|
||||
* This file should not be included by any header files.
|
||||
*/
|
||||
|
||||
#ifndef NANA_DETAIL_PLATFORM_SPEC_HPP
|
||||
#define NANA_DETAIL_PLATFORM_SPEC_HPP
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
#include <condition_variable>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xos.h>
|
||||
#include <nana/gui/basis.hpp>
|
||||
#include <nana/paint/image.hpp>
|
||||
#include <nana/paint/graphics.hpp>
|
||||
#include <nana/gui/detail/event_code.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "msg_packet.hpp"
|
||||
#if defined(NANA_UNICODE)
|
||||
#include <X11/Xft/Xft.h>
|
||||
#include <iconv.h>
|
||||
#include <fstream>
|
||||
#endif
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class msg_dispatcher;
|
||||
#if defined(NANA_UNICODE)
|
||||
class conf
|
||||
{
|
||||
public:
|
||||
conf(const char * file);
|
||||
bool open(const char* file);
|
||||
std::string value(const char* key);
|
||||
private:
|
||||
std::ifstream ifs_;
|
||||
};
|
||||
|
||||
class charset_conv
|
||||
{
|
||||
public:
|
||||
charset_conv(const char* tocode, const char* fromcode);
|
||||
~charset_conv();
|
||||
std::string charset(const std::string& str) const;
|
||||
std::string charset(const char * buf, std::size_t len) const;
|
||||
private:
|
||||
iconv_t handle_;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct font_tag
|
||||
{
|
||||
nana::string name;
|
||||
unsigned height;
|
||||
unsigned weight;
|
||||
bool italic;
|
||||
bool underline;
|
||||
bool strikeout;
|
||||
#if defined(NANA_UNICODE)
|
||||
XftFont * handle;
|
||||
#else
|
||||
XFontSet handle;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct drawable_impl_type
|
||||
{
|
||||
typedef std::shared_ptr<font_tag> font_ptr_t;
|
||||
|
||||
Pixmap pixmap;
|
||||
GC context;
|
||||
font_ptr_t font;
|
||||
|
||||
nana::point line_begin_pos;
|
||||
|
||||
struct string_spec
|
||||
{
|
||||
unsigned tab_length;
|
||||
unsigned tab_pixels;
|
||||
unsigned whitespace_pixels;
|
||||
}string;
|
||||
#if defined(NANA_UNICODE)
|
||||
XftDraw * xftdraw{nullptr};
|
||||
XftColor xft_fgcolor;
|
||||
const std::string charset(const nana::string& str, const std::string& strcode);
|
||||
#endif
|
||||
drawable_impl_type();
|
||||
~drawable_impl_type();
|
||||
|
||||
void fgcolor(const ::nana::color&); //deprecated
|
||||
void set_color(const ::nana::color&);
|
||||
void set_text_color(const ::nana::color&);
|
||||
|
||||
void update_color();
|
||||
void update_text_color();
|
||||
private:
|
||||
unsigned current_color_{ 0xFFFFFF };
|
||||
unsigned color_{ 0xFFFFFFFF };
|
||||
unsigned text_color_{ 0xFFFFFFFF };
|
||||
|
||||
#if defined(NANA_UNICODE)
|
||||
struct conv_tag
|
||||
{
|
||||
iconv_t handle;
|
||||
std::string code;
|
||||
}conv_;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct atombase_tag
|
||||
{
|
||||
Atom wm_protocols;
|
||||
//window manager support
|
||||
Atom wm_change_state;
|
||||
Atom wm_delete_window;
|
||||
//ext
|
||||
Atom net_wm_state;
|
||||
Atom net_wm_state_skip_taskbar;
|
||||
Atom net_wm_state_fullscreen;
|
||||
Atom net_wm_state_maximized_horz;
|
||||
Atom net_wm_state_maximized_vert;
|
||||
Atom net_wm_state_modal;
|
||||
Atom net_wm_name;
|
||||
Atom net_wm_window_type;
|
||||
Atom net_wm_window_type_normal;
|
||||
Atom net_wm_window_type_utility;
|
||||
Atom net_wm_window_type_dialog;
|
||||
Atom motif_wm_hints;
|
||||
|
||||
Atom clipboard;
|
||||
Atom text;
|
||||
Atom text_uri_list;
|
||||
Atom utf8_string;
|
||||
Atom targets;
|
||||
|
||||
Atom xdnd_aware;
|
||||
Atom xdnd_enter;
|
||||
Atom xdnd_position;
|
||||
Atom xdnd_status;
|
||||
Atom xdnd_action_copy;
|
||||
Atom xdnd_drop;
|
||||
Atom xdnd_selection;
|
||||
Atom xdnd_typelist;
|
||||
Atom xdnd_finished;
|
||||
};
|
||||
|
||||
struct caret_tag;
|
||||
|
||||
class timer_runner;
|
||||
|
||||
class platform_scope_guard
|
||||
{
|
||||
public:
|
||||
platform_scope_guard();
|
||||
~platform_scope_guard();
|
||||
};
|
||||
|
||||
class platform_spec
|
||||
{
|
||||
typedef platform_spec self_type;
|
||||
|
||||
struct window_context_t
|
||||
{
|
||||
native_window_type owner;
|
||||
std::vector<native_window_type> * owned;
|
||||
};
|
||||
public:
|
||||
int error_code;
|
||||
public:
|
||||
typedef drawable_impl_type::font_ptr_t font_ptr_t;
|
||||
typedef void (*timer_proc_type)(unsigned tid);
|
||||
typedef void (*event_proc_type)(Display*, msg_packet_tag&);
|
||||
typedef ::nana::event_code event_code;
|
||||
typedef ::nana::native_window_type native_window_type;
|
||||
|
||||
|
||||
platform_spec();
|
||||
~platform_spec();
|
||||
|
||||
const font_ptr_t& default_native_font() const;
|
||||
void default_native_font(const font_ptr_t&);
|
||||
unsigned font_size_to_height(unsigned) const;
|
||||
unsigned font_height_to_size(unsigned) const;
|
||||
font_ptr_t make_native_font(const nana::char_t* name, unsigned height, unsigned weight, bool italic, bool underline, bool strick_out);
|
||||
|
||||
Display* open_display();
|
||||
void close_display();
|
||||
|
||||
void lock_xlib();
|
||||
void unlock_xlib();
|
||||
|
||||
Window root_window();
|
||||
int screen_depth();
|
||||
Visual* screen_visual();
|
||||
|
||||
Colormap& colormap();
|
||||
|
||||
static self_type& instance();
|
||||
const atombase_tag & atombase() const;
|
||||
|
||||
void make_owner(native_window_type owner, native_window_type wd);
|
||||
native_window_type get_owner(native_window_type) const;
|
||||
void remove(native_window_type);
|
||||
|
||||
void write_keystate(const XKeyEvent&);
|
||||
void read_keystate(XKeyEvent&);
|
||||
|
||||
XIC caret_input_context(native_window_type) const;
|
||||
void caret_open(native_window_type, const ::nana::size&);
|
||||
void caret_close(native_window_type);
|
||||
void caret_pos(native_window_type, const ::nana::point&);
|
||||
void caret_visible(native_window_type, bool);
|
||||
void caret_flash(caret_tag&);
|
||||
bool caret_update(native_window_type, nana::paint::graphics& root_graph, bool is_erase_caret_from_root_graph);
|
||||
static bool caret_reinstate(caret_tag&);
|
||||
void set_error_handler();
|
||||
int rev_error_handler();
|
||||
|
||||
//grab
|
||||
//register a grab window while capturing it if it is unviewable.
|
||||
//when native_interface::show a window that is registered as a grab
|
||||
//window, the native_interface grabs the window.
|
||||
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);
|
||||
|
||||
//Message dispatcher
|
||||
void msg_insert(native_window_type);
|
||||
void msg_set(timer_proc_type, event_proc_type);
|
||||
void msg_dispatch(native_window_type modal);
|
||||
|
||||
//X Selections
|
||||
void* request_selection(native_window_type requester, Atom type, size_t & bufsize);
|
||||
void write_selection(native_window_type owner, Atom type, const void* buf, size_t bufsize);
|
||||
|
||||
//Icon storage
|
||||
//@biref: The image object should be kept for a long time till the window is closed,
|
||||
// the image object is release in remove() method.
|
||||
const nana::paint::graphics& keep_window_icon(native_window_type, const nana::paint::image&);
|
||||
private:
|
||||
static int _m_msg_filter(XEvent&, msg_packet_tag&);
|
||||
void _m_caret_routine();
|
||||
private:
|
||||
Display* display_;
|
||||
Colormap colormap_;
|
||||
atombase_tag atombase_;
|
||||
font_ptr_t def_font_ptr_;
|
||||
XKeyEvent key_state_;
|
||||
int (*def_X11_error_handler_)(Display*, XErrorEvent*);
|
||||
Window grab_;
|
||||
std::recursive_mutex xlib_locker_;
|
||||
struct caret_holder_tag
|
||||
{
|
||||
volatile bool exit_thread;
|
||||
std::unique_ptr<std::thread> thr;
|
||||
std::map<native_window_type, caret_tag*> carets;
|
||||
}caret_holder_;
|
||||
|
||||
std::map<native_window_type, window_context_t> wincontext_;
|
||||
std::map<native_window_type, nana::paint::graphics> iconbase_;
|
||||
|
||||
struct timer_runner_tag
|
||||
{
|
||||
timer_runner * runner;
|
||||
std::recursive_mutex mutex;
|
||||
bool delete_declared;
|
||||
timer_runner_tag();
|
||||
}timer_;
|
||||
|
||||
struct selection_tag
|
||||
{
|
||||
struct item_t
|
||||
{
|
||||
Atom type;
|
||||
Window requestor;
|
||||
void* buffer;
|
||||
size_t bufsize;
|
||||
std::mutex cond_mutex;
|
||||
std::condition_variable cond;
|
||||
};
|
||||
|
||||
std::vector<item_t*> items;
|
||||
|
||||
struct content_tag
|
||||
{
|
||||
std::string * utf8_string;
|
||||
}content;
|
||||
}selection_;
|
||||
|
||||
struct xdnd_tag
|
||||
{
|
||||
Atom good_type;
|
||||
int timestamp;
|
||||
Window wd_src;
|
||||
nana::point pos;
|
||||
}xdnd_;
|
||||
|
||||
msg_dispatcher * msg_dispatcher_;
|
||||
};//end class platform_X11
|
||||
|
||||
}//end namespace detail
|
||||
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
|
||||
@ -16,6 +16,6 @@
|
||||
|
||||
#if defined(NANA_WINDOWS)
|
||||
#include <nana/detail/win32/platform_spec.hpp>
|
||||
#else
|
||||
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#include <nana/detail/linux_X11/platform_spec.hpp>
|
||||
#endif
|
||||
@ -1,341 +0,0 @@
|
||||
/*
|
||||
* Message Dispatcher 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/detail/msg_dispatcher.hpp
|
||||
*
|
||||
* @DO NOT INCLUDE THIS HEADER FILE IN YOUR SOURCE FILE!!
|
||||
*
|
||||
* This class msg_dispatcher provides a simulation of Windows-like message
|
||||
* dispatcher. Every event is dispatched into its own message queue for
|
||||
* corresponding thread.
|
||||
*/
|
||||
|
||||
#ifndef NANA_DETAIL_MSG_DISPATCHER_HPP
|
||||
#define NANA_DETAIL_MSG_DISPATCHER_HPP
|
||||
#include <nana/detail/linux_X11/msg_packet.hpp>
|
||||
#include <nana/system/platform.hpp>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class msg_dispatcher
|
||||
{
|
||||
struct thread_binder
|
||||
{
|
||||
unsigned tid;
|
||||
std::mutex mutex;
|
||||
std::condition_variable cond;
|
||||
std::list<msg_packet_tag> msg_queue;
|
||||
std::set<Window> window;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef msg_packet_tag msg_packet;
|
||||
typedef void (*timer_proc_type)(unsigned tid);
|
||||
typedef void (*event_proc_type)(Display*, msg_packet_tag&);
|
||||
typedef int (*event_filter_type)(XEvent&, msg_packet_tag&);
|
||||
|
||||
typedef std::list<msg_packet_tag> msg_queue_type;
|
||||
|
||||
msg_dispatcher(Display* disp)
|
||||
: display_(disp), is_work_(false)
|
||||
{
|
||||
proc_.event_proc = 0;
|
||||
proc_.timer_proc = 0;
|
||||
proc_.filter_proc = 0;
|
||||
}
|
||||
|
||||
void set(timer_proc_type timer_proc, event_proc_type event_proc, event_filter_type filter)
|
||||
{
|
||||
proc_.timer_proc = timer_proc;
|
||||
proc_.event_proc = event_proc;
|
||||
proc_.filter_proc = filter;
|
||||
}
|
||||
|
||||
void insert(Window wd)
|
||||
{
|
||||
unsigned tid = nana::system::this_thread_id();
|
||||
|
||||
bool start_driver;
|
||||
|
||||
{
|
||||
std::lock_guard<decltype(table_.mutex)> lock(table_.mutex);
|
||||
|
||||
//No thread is running, so msg dispatcher should start the msg driver.
|
||||
start_driver = (0 == table_.thr_table.size());
|
||||
thread_binder * thr;
|
||||
|
||||
std::map<unsigned, thread_binder*>::iterator i = table_.thr_table.find(tid);
|
||||
if(i == table_.thr_table.end())
|
||||
{
|
||||
thr = new thread_binder;
|
||||
thr->tid = tid;
|
||||
table_.thr_table.insert(std::make_pair(tid, thr));
|
||||
}
|
||||
else
|
||||
thr = i->second;
|
||||
|
||||
thr->mutex.lock();
|
||||
thr->window.insert(wd);
|
||||
thr->mutex.unlock();
|
||||
|
||||
table_.wnd_table[wd] = thr;
|
||||
}
|
||||
|
||||
if(start_driver && proc_.event_proc && proc_.timer_proc)
|
||||
{
|
||||
//It should start the msg driver, before starting it, the msg driver must be inactive.
|
||||
if(thrd_)
|
||||
{
|
||||
is_work_ = false;
|
||||
thrd_->join();
|
||||
}
|
||||
is_work_ = true;
|
||||
thrd_ = std::unique_ptr<std::thread>(new std::thread([this](){ this->_m_msg_driver(); }));
|
||||
}
|
||||
}
|
||||
|
||||
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())
|
||||
{
|
||||
thread_binder * const thr = i->second;
|
||||
std::lock_guard<decltype(thr->mutex)> lock(thr->mutex);
|
||||
for(auto li = thr->msg_queue.begin(); li != thr->msg_queue.end();)
|
||||
{
|
||||
if(wd == _m_window(*li))
|
||||
li = thr->msg_queue.erase(li);
|
||||
else
|
||||
++li;
|
||||
}
|
||||
|
||||
table_.wnd_table.erase(i);
|
||||
thr->window.erase(wd);
|
||||
|
||||
//There still is at least one window alive.
|
||||
if(thr->window.size())
|
||||
{
|
||||
//Make a cleanup msg packet to infor the dispatcher the window is closed.
|
||||
msg_packet_tag msg;
|
||||
msg.kind = msg.kind_cleanup;
|
||||
msg.u.packet_window = wd;
|
||||
thr->msg_queue.push_back(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dispatch(Window modal)
|
||||
{
|
||||
unsigned 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)))
|
||||
{
|
||||
//the queue is empty
|
||||
if(-1 == qstate)
|
||||
{
|
||||
if(false == _m_wait_for_queue(tid))
|
||||
proc_.timer_proc(tid);
|
||||
}
|
||||
else
|
||||
{
|
||||
proc_.event_proc(display_, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
void _m_msg_driver()
|
||||
{
|
||||
int fd_X11 = ConnectionNumber(display_);
|
||||
|
||||
msg_packet_tag msg_pack;
|
||||
XEvent event;
|
||||
while(is_work_)
|
||||
{
|
||||
int pending;
|
||||
{
|
||||
nana::detail::platform_scope_guard lock;
|
||||
pending = ::XPending(display_);
|
||||
if(pending)
|
||||
{
|
||||
::XNextEvent(display_, &event);
|
||||
if(::XFilterEvent(&event, None))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(0 == pending)
|
||||
{
|
||||
fd_set fdset;
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(fd_X11, &fdset);
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_usec = 10000;
|
||||
tv.tv_sec = 0;
|
||||
::select(fd_X11 + 1, &fdset, 0, 0, &tv);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(proc_.filter_proc(event, msg_pack))
|
||||
{
|
||||
case 0:
|
||||
msg_pack.kind = msg_pack.kind_xevent;
|
||||
msg_pack.u.xevent = event;
|
||||
case 1:
|
||||
_m_msg_dispatch(msg_pack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
static Window _m_event_window(const XEvent& event)
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case MapNotify:
|
||||
case UnmapNotify:
|
||||
return event.xmap.window;
|
||||
}
|
||||
return event.xkey.window;
|
||||
}
|
||||
|
||||
static Window _m_window(const msg_packet_tag& pack)
|
||||
{
|
||||
switch(pack.kind)
|
||||
{
|
||||
case msg_packet_tag::kind_xevent:
|
||||
return _m_event_window(pack.u.xevent);
|
||||
case msg_packet_tag::kind_mouse_drop:
|
||||
return pack.u.mouse_drop.window;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _m_msg_dispatch(const msg_packet_tag &msg)
|
||||
{
|
||||
std::lock_guard<decltype(table_.mutex)> lock(table_.mutex);
|
||||
auto i = table_.wnd_table.find(_m_window(msg));
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
//_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)
|
||||
{
|
||||
bool stop_driver = false;
|
||||
|
||||
{
|
||||
std::lock_guard<decltype(table_.mutex)> lock(table_.mutex);
|
||||
//Find the thread whether it is registered for the window.
|
||||
auto i = table_.thr_table.find(tid);
|
||||
if(i != table_.thr_table.end())
|
||||
{
|
||||
if(i->second->window.size())
|
||||
{
|
||||
msg_queue_type & queue = i->second->msg_queue;
|
||||
if(queue.size())
|
||||
{
|
||||
msg = queue.front();
|
||||
queue.pop_front();
|
||||
|
||||
//Check whether the event dispatcher is used for the modal window
|
||||
//and when the modal window is closing, the event dispatcher would
|
||||
//stop event pumping.
|
||||
if((modal == msg.u.packet_window) && (msg.kind == msg.kind_cleanup))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
delete i->second;
|
||||
table_.thr_table.erase(i);
|
||||
stop_driver = (table_.thr_table.size() == 0);
|
||||
}
|
||||
}
|
||||
if(stop_driver)
|
||||
{
|
||||
is_work_ = false;
|
||||
thrd_->join();
|
||||
thrd_.reset();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//_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)
|
||||
{
|
||||
thread_binder * thr = nullptr;
|
||||
{
|
||||
std::lock_guard<decltype(table_.mutex)> lock(table_.mutex);
|
||||
auto i = table_.thr_table.find(tid);
|
||||
if(i != table_.thr_table.end())
|
||||
{
|
||||
if(i->second->msg_queue.size())
|
||||
return true;
|
||||
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_;
|
||||
std::unique_ptr<std::thread> thrd_;
|
||||
|
||||
struct table_tag
|
||||
{
|
||||
std::recursive_mutex mutex;
|
||||
std::map<unsigned, thread_binder*> thr_table;
|
||||
std::map<Window, thread_binder*> wnd_table;
|
||||
}table_;
|
||||
|
||||
struct proc_tag
|
||||
{
|
||||
timer_proc_type timer_proc;
|
||||
event_proc_type event_proc;
|
||||
event_filter_type filter_proc;
|
||||
}proc_;
|
||||
};
|
||||
}//end namespace detail
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -17,8 +17,6 @@
|
||||
|
||||
#if defined(NANA_WINDOWS)
|
||||
#include "win32/platform_spec.cpp"
|
||||
#elif defined(NANA_LINUX)
|
||||
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#include "linux_X11/platform_spec.cpp"
|
||||
#elif defined(NANA_MACOS)
|
||||
#include "macos_X11/platform_spec.cpp"
|
||||
#endif
|
||||
@ -12,7 +12,7 @@
|
||||
#include <nana/system/shared_wrapper.hpp>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#if defined(NANA_LINUX) or defined(NANA_MACOS)
|
||||
#if defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
#include <dlfcn.h>
|
||||
#else
|
||||
#include <windows.h>
|
||||
@ -30,7 +30,7 @@ namespace system
|
||||
|
||||
module_t open(const char* filename)
|
||||
{
|
||||
#if defined(NANA_LINUX) or defined(NANA_MACOS)
|
||||
#if defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
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) or defined(NANA_MACOS)
|
||||
#if defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
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) or defined(NANA_MACOS)
|
||||
#if defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
::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) or defined(NANA_MACOS)
|
||||
#if defined(NANA_LINUX) || defined(NANA_MACOS)
|
||||
ofn.replace(length - 13, 13, ".so");
|
||||
#else
|
||||
ofn.replace(length - 13, 13, ".DLL");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user