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 )