cppAdaptive2
view release on metacpan or search on metacpan
src/dlib/gui_core/gui_core_kernel_2.cpp view on Meta::CPAN
#include <cstring>
#include <cmath>
#include <X11/Xatom.h>
#include "../sync_extension.h"
#include "../logger.h"
#include <vector>
#include <set>
#include "../smart_pointers_thread_safe.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
namespace gui_core_kernel_2_globals
{
void init_keyboard_mod_masks();
struct user_event_type
{
Window w;
void* p;
int i;
};
typedef sync_extension<queue<user_event_type,memory_manager<char>::kernel_1b>::kernel_2a_c>::kernel_1a queue_of_user_events;
typedef sync_extension<binary_search_tree<Window,base_window*>::kernel_1a>::kernel_1a
window_table_type;
// ----------------------------------------------------------------------------------------
const shared_ptr_thread_safe<dlib::mutex>& global_mutex()
{
static shared_ptr_thread_safe<dlib::mutex> m(new dlib::mutex);
return m;
}
class event_handler_thread : public threaded_object
{
public:
enum et_state
{
uninitialized,
initialized,
failure_to_init
};
et_state status;
logger dlog;
int depth;
Display* disp;
XIM xim;
XIMStyle xim_style;
Screen* screen;
Atom delete_window;
Window exit_window;
std::wstring clipboard;
int alt_mask;
int meta_mask;
int num_lock_mask;
int scroll_lock_mask;
// the mutex in this object is the global mutex used to protect everything
// in the gui_core and gui_widgets components.
window_table_type window_table;
rsignaler window_close_signaler;
rsignaler et_signaler;
queue_of_user_events user_events;
queue_of_user_events user_events_temp;
shared_ptr_thread_safe<dlib::mutex> reference_to_global_mutex;
event_handler_thread(
) :
dlog("dlib.gui_core"),
depth(0),
disp(0),
xim(0),
screen(0),
alt_mask(0),
meta_mask(0),
num_lock_mask(0),
scroll_lock_mask(0),
window_close_signaler(window_table.get_mutex()),
et_signaler(window_table.get_mutex()),
reference_to_global_mutex(global_mutex())
{
auto_mutex M(window_table.get_mutex());
status = uninitialized;
// start up the event handler thread
start();
// wait for the event thread to get up and running
while (status == uninitialized)
et_signaler.wait();
if (status == failure_to_init)
throw gui_error("Failed to initialize X11 resources");
init_keyboard_mod_masks();
}
~event_handler_thread ()
{
if (is_alive())
{
if (status != failure_to_init)
{
XConfigureEvent event;
event.type = ConfigureNotify;
src/dlib/gui_core/gui_core_kernel_2.cpp view on Meta::CPAN
bool quit_event_loop = false;
while (quit_event_loop == false)
{
// get a lock on the window_table's mutex
auto_mutex window_table_locker(window_table.get_mutex());
XEvent ev;
memset(&ev, 0, sizeof(ev));
while (XPending(disp) == 0){
window_table.get_mutex().unlock();
// wait until receiving X11 next event
struct pollfd pfd;
pfd.fd = ConnectionNumber(disp);
pfd.events = POLLIN | POLLPRI;
poll(&pfd, 1, -1);
window_table.get_mutex().lock();
}
XNextEvent(disp,&ev);
// pass events to input method.
// if this event is needed by input method, XFilterEvent returns True
if (XFilterEvent(&ev, None) == True){
continue;
}
// if this event is for one of the windows in the window_table
// then get that window out of the table and put it into win.
XAnyEvent* _ae = reinterpret_cast<XAnyEvent*>(&ev);
base_window** win_ = window_table[_ae->window];
base_window* win = 0;
if (win_)
win = *win_;
// ignore messages for unmapped windows
if (ev.type != MapNotify && win != 0)
{
if (win->is_mapped == false)
continue;
}
switch (ev.type)
{
case SelectionRequest:
{
Atom a_ct = XInternAtom(disp, "COMPOUND_TEXT", False);
XSelectionRequestEvent* req = reinterpret_cast<XSelectionRequestEvent*>(&ev.xselectionrequest);
XEvent respond;
if (req->target == XA_STRING)
{
XChangeProperty (disp,
req->requestor,
req->property,
XA_STRING,
8,
PropModeReplace,
reinterpret_cast<const unsigned char*>(convert_wstring_to_mbstring(clipboard).c_str()),
clipboard.size()+1);
respond.xselection.property=req->property;
}
else if (req->target == a_ct)
{
XChangeProperty (disp,
req->requestor,
req->property,
a_ct,
sizeof(wchar_t)*8,
PropModeReplace,
reinterpret_cast<const unsigned char*>(clipboard.c_str()),
clipboard.size()+1);
respond.xselection.property=req->property;
}
else
{
respond.xselection.property= None;
}
respond.xselection.type= SelectionNotify;
respond.xselection.display= req->display;
respond.xselection.requestor= req->requestor;
respond.xselection.selection=req->selection;
respond.xselection.target= req->target;
respond.xselection.time = req->time;
XSendEvent (disp, req->requestor,0,0,&respond);
XFlush (disp);
} break;
case MapNotify:
{
if (win == 0)
break;
win->is_mapped = true;
if (win->resizable == false)
{
XSizeHints* hints = XAllocSizeHints();
hints->flags = PMinSize|PMaxSize;
hints->min_width = win->width;
hints->max_width = win->width;
hints->max_height = win->height;
hints->min_height = win->height;
XSetNormalHints(disp,win->x11_stuff.hwnd,hints);
XFree(hints);
}
if (win->has_been_resized)
{
XResizeWindow(disp,win->x11_stuff.hwnd,win->width,win->height);
win->has_been_resized = false;
win->on_window_resized();
}
if (win->has_been_moved)
{
XMoveWindow(disp,win->x11_stuff.hwnd,win->x,win->y);
win->has_been_moved = false;
win->on_window_moved();
}
XFlush(disp);
} break;
case KeyPress:
{
XKeyPressedEvent* e = reinterpret_cast<XKeyPressedEvent*>(&ev);
src/dlib/gui_core/gui_core_kernel_2.cpp view on Meta::CPAN
continue;
case XK_Meta_L:
case XK_Meta_R:
meta_mask = index_to_modmask(n / map->max_keypermod);
continue;
case XK_Scroll_Lock:
scroll_lock_mask = index_to_modmask(n / map->max_keypermod);
continue;
case XK_Num_Lock:
num_lock_mask = index_to_modmask(n / map->max_keypermod);
default:
continue;
}
}
XFreeModifiermap( map );
if ( alt_mask == 0 )
{
dlog << LWARN << "Search for Alt-key faild.";
if ( meta_mask != 0 )
alt_mask = meta_mask;
else
alt_mask = Mod1Mask; // resort to guessing
}
}
// ----------------------------------------------------------------------------------------
} // namespace gui_core_kernel_2_globals
// ----------------------------------------------------------------------------------------
void canvas::
fill (
unsigned char red_,
unsigned char green_,
unsigned char blue_
) const
{
pixel pixel_value;
pixel_value.red = red_;
pixel_value.green = green_;
pixel_value.blue = blue_;
pixel_value._padding = 0;
pixel* start = reinterpret_cast<pixel*>(bits);
pixel* end = start + width_*height_;
while (start != end)
{
*start = pixel_value;
++start;
}
}
// ----------------------------------------------------------------------------------------
void put_on_clipboard (
const std::string& str
)
{
put_on_clipboard(convert_mbstring_to_wstring(str));
}
void put_on_clipboard (
const dlib::ustring& str
)
{
put_on_clipboard(convert_utf32_to_wstring(str));
}
void put_on_clipboard (
const std::wstring& str
)
{
using namespace gui_core_kernel_2_globals;
shared_ptr_thread_safe<event_handler_thread> globals(global_data());
auto_mutex M(globals->window_table.get_mutex());
globals->clipboard = str.c_str();
XSetSelectionOwner(globals->disp,XA_PRIMARY,globals->exit_window,CurrentTime);
}
// ----------------------------------------------------------------------------------------
Bool clip_peek_helper (
Display*,
XEvent* event,
XPointer
)
{
if ( event->type == SelectionNotify)
{
return True;
}
else
{
return False;
}
}
void get_from_clipboard (
std::string& str
)
{
std::wstring wstr;
get_from_clipboard(wstr);
str = convert_wstring_to_mbstring(wstr);
}
void get_from_clipboard (
dlib::ustring& str
)
{
std::wstring wstr;
get_from_clipboard(wstr);
str = convert_wstring_to_utf32(wstr);
}
void get_from_clipboard (
std::wstring& str
)
{
using namespace gui_core_kernel_2_globals;
shared_ptr_thread_safe<event_handler_thread> globals(global_data());
auto_mutex M(globals->window_table.get_mutex());
str.clear();
unsigned char *data = 0;
wchar_t **plist = 0;
Window sown;
Atom type;
int format, result;
unsigned long len, bytes_left, dummy;
XEvent e;
try
{
Atom atom_ct = XInternAtom(globals->disp, "COMPOUND_TEXT", False);
sown = XGetSelectionOwner (globals->disp, XA_PRIMARY);
if (sown == globals->exit_window)
{
// if we are copying from ourselfs then don't fool with the Xwindows junk.
str = globals->clipboard.c_str();
}
else if (sown != None)
{
// request that the selection be copied into the XA_PRIMARY property
// of the exit_window. It doesn't matter what window we put it in
// so long as it is one under the control of this process and exit_window
// is easy to use here so that is what I'm using.
XConvertSelection (globals->disp, XA_PRIMARY, atom_ct, XA_PRIMARY,
globals->exit_window, CurrentTime);
// This will wait until we get a SelectionNotify event which should happen
// really soon.
XPeekIfEvent(globals->disp,&e,clip_peek_helper,0);
// See how much data we got
XGetWindowProperty (globals->disp, globals->exit_window,
XA_PRIMARY, // Tricky..
0, 0, // offset - len
0, // Delete 0==FALSE
AnyPropertyType, //flag
&type, // return type
&format, // return format
&len, &bytes_left, //that
&data);
if (data)
{
XFree(data);
data = 0;
}
if (bytes_left > 0 && type == atom_ct)
{
XTextProperty p;
result = XGetWindowProperty (globals->disp, globals->exit_window,
XA_PRIMARY, 0,bytes_left,0,
AnyPropertyType, &p.encoding,&p.format,
&p.nitems, &dummy, &p.value);
if (result == Success && p.encoding == atom_ct)
{
int n;
XwcTextPropertyToTextList(globals->disp, &p, &plist, &n);
str = plist[0];
}
if (plist)
{
XwcFreeStringList(plist);
plist = 0;
}
}
}
}
catch (...)
{
if (data)
XFree(data);
if (plist)
{
XwcFreeStringList(plist);
plist = 0;
}
}
( run in 0.894 second using v1.01-cache-2.11-cpan-81fc1098f69 )