⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 x11_loop.cpp

📁 video linux conference
💻 CPP
字号:
/***************************************************************************** * x11_loop.cpp ***************************************************************************** * Copyright (C) 2003 VideoLAN * $Id: x11_loop.cpp 10101 2005-03-02 16:47:31Z robux4 $ * * Authors: Cyril Deguet     <asmax@via.ecp.fr> *          Olivier Teuli鑢e <ipkiss@via.ecp.fr> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. *****************************************************************************/#ifdef X11_SKINS#include <X11/keysym.h>#include "x11_loop.hpp"#include "x11_display.hpp"#include "x11_dragdrop.hpp"#include "x11_factory.hpp"#include "x11_timer.hpp"#include "../src/generic_window.hpp"#include "../src/theme.hpp"#include "../src/window_manager.hpp"#include "../events/evt_focus.hpp"#include "../events/evt_key.hpp"#include "../events/evt_mouse.hpp"#include "../events/evt_motion.hpp"#include "../events/evt_leave.hpp"#include "../events/evt_refresh.hpp"#include "../events/evt_scroll.hpp"#include "../commands/async_queue.hpp"#include "../utils/var_bool.hpp"#include "vlc_keys.h"// Maximum interval between clicks for a double-click (in microsec)int X11Loop::m_dblClickDelay = 400000;X11Loop::X11Loop( intf_thread_t *pIntf, X11Display &rDisplay ):    OSLoop( pIntf ), m_rDisplay( rDisplay ), m_exit( false ),    m_lastClickTime( 0 ), m_lastClickPosX( 0 ), m_lastClickPosY( 0 ){    // Initialize the key map    keysymToVlcKey[XK_F1] = KEY_F1;    keysymToVlcKey[XK_F2] = KEY_F2;    keysymToVlcKey[XK_F3] = KEY_F3;    keysymToVlcKey[XK_F4] = KEY_F4;    keysymToVlcKey[XK_F5] = KEY_F5;    keysymToVlcKey[XK_F6] = KEY_F6;    keysymToVlcKey[XK_F7] = KEY_F7;    keysymToVlcKey[XK_F8] = KEY_F8;    keysymToVlcKey[XK_F9] = KEY_F9;    keysymToVlcKey[XK_F10] = KEY_F10;    keysymToVlcKey[XK_F11] = KEY_F11;    keysymToVlcKey[XK_F12] = KEY_F12;    keysymToVlcKey[XK_Return] = KEY_ENTER;    keysymToVlcKey[XK_space] = KEY_SPACE;    keysymToVlcKey[XK_Escape] = KEY_ESC;    keysymToVlcKey[XK_Left] = KEY_LEFT;    keysymToVlcKey[XK_Right] = KEY_RIGHT;    keysymToVlcKey[XK_Up] = KEY_UP;    keysymToVlcKey[XK_Down] = KEY_DOWN;    keysymToVlcKey[XK_Home] = KEY_HOME;    keysymToVlcKey[XK_End] = KEY_END;    keysymToVlcKey[XK_Prior] = KEY_PAGEUP;    keysymToVlcKey[XK_Next] = KEY_PAGEDOWN;}X11Loop::~X11Loop(){}OSLoop *X11Loop::instance( intf_thread_t *pIntf, X11Display &rDisplay ){    if( pIntf->p_sys->p_osLoop == NULL )    {        OSLoop *pOsLoop = new X11Loop( pIntf, rDisplay );        pIntf->p_sys->p_osLoop = pOsLoop;    }    return pIntf->p_sys->p_osLoop;}void X11Loop::destroy( intf_thread_t *pIntf ){    if( pIntf->p_sys->p_osLoop )    {        delete pIntf->p_sys->p_osLoop;        pIntf->p_sys->p_osLoop = NULL;    }}void X11Loop::run(){    OSFactory *pOsFactory = OSFactory::instance( getIntf() );    X11TimerLoop *pTimerLoop = ((X11Factory*)pOsFactory)->getTimerLoop();    // Main event loop    while( ! m_exit )    {        int nPending;        // Number of pending events in the queue        nPending = XPending( XDISPLAY );        while( ! m_exit && nPending > 0 )        {            // Handle the next X11 event            handleX11Event();            // Number of pending events in the queue            nPending = XPending( XDISPLAY );        }        // Wait for the next timer and execute it        // The sleep is interrupted if an X11 event is received        if( !m_exit )        {            pTimerLoop->waitNextTimer();        }    }}void X11Loop::exit(){    m_exit = true;}void X11Loop::handleX11Event(){    XEvent event;    OSFactory *pOsFactory = OSFactory::instance( getIntf() );    // Look for the next event in the queue    XNextEvent( XDISPLAY, &event );    if( event.xany.window == m_rDisplay.getMainWindow() )    {        if( event.type == MapNotify )        {            // When the "parent" window is mapped, show all the visible            // windows, as it is not automatic, unfortunately            Theme *pTheme = getIntf()->p_sys->p_theme;            if( pTheme )            {                pTheme->getWindowManager().synchVisibility();            }        }        return;    }    // Find the window to which the event is sent    GenericWindow *pWin =        ((X11Factory*)pOsFactory)->m_windowMap[event.xany.window];    if( !pWin )    {        msg_Dbg( getIntf(), "No associated generic window !!" );        return;    }    // Send the right event object to the window    switch( event.type )    {        case Expose:        {            EvtRefresh evt( getIntf(), event.xexpose.x,                            event.xexpose.y, event.xexpose.width,                            event.xexpose.height );            pWin->processEvent( evt );            break;        }        case FocusIn:        {            EvtFocus evt( getIntf(), true );            pWin->processEvent( evt );            break;        }        case FocusOut:        {            EvtFocus evt( getIntf(), false );            pWin->processEvent( evt );            break;        }        case MotionNotify:        {            // Don't trust the position in the event, it is            // out of date. Get the actual current position instead            int x, y;            pOsFactory->getMousePos( x, y );            EvtMotion evt( getIntf(), x, y );            pWin->processEvent( evt );            break;        }        case LeaveNotify:        {            EvtLeave evt( getIntf() );            pWin->processEvent( evt );            break;        }        case ButtonPress:        case ButtonRelease:        {            EvtMouse::ActionType_t action = EvtMouse::kDown;            switch( event.type )            {                case ButtonPress:                    action = EvtMouse::kDown;                    break;                case ButtonRelease:                    action = EvtMouse::kUp;                    break;            }            // Get the modifiers            int mod = EvtInput::kModNone;            if( event.xbutton.state & Mod1Mask )            {                mod |= EvtInput::kModAlt;            }            if( event.xbutton.state & ControlMask )            {                mod |= EvtInput::kModCtrl;            }            if( event.xbutton.state & ShiftMask )            {                mod |= EvtInput::kModShift;            }            // Check for double clicks            if( event.type == ButtonPress &&                event.xbutton.button == 1 )            {                mtime_t time = mdate();                int x, y;                pOsFactory->getMousePos( x, y );                if( time - m_lastClickTime < m_dblClickDelay &&                    x == m_lastClickPosX && y == m_lastClickPosY )                {                    m_lastClickTime = 0;                    action = EvtMouse::kDblClick;                }                else                {                    m_lastClickTime = time;                    m_lastClickPosX = x;                    m_lastClickPosY = y;                }            }            switch( event.xbutton.button )            {                case 1:                {                    EvtMouse evt( getIntf(), event.xbutton.x,                                  event.xbutton.y, EvtMouse::kLeft,                                  action, mod );                    pWin->processEvent( evt );                    break;                }                case 2:                {                    EvtMouse evt( getIntf(), event.xbutton.x,                                  event.xbutton.y, EvtMouse::kMiddle,                                  action, mod );                    pWin->processEvent( evt );                    break;                }                case 3:                {                    EvtMouse evt( getIntf(), event.xbutton.x,                                  event.xbutton.y, EvtMouse::kRight,                                  action, mod );                    pWin->processEvent( evt );                    break;                }                case 4:                {                    // Scroll up                    EvtScroll evt( getIntf(), event.xbutton.x,                                   event.xbutton.y, EvtScroll::kUp,                                   mod );                    pWin->processEvent( evt );                    break;                }                case 5:                {                    // Scroll down                    EvtScroll evt( getIntf(), event.xbutton.x,                                   event.xbutton.y, EvtScroll::kDown,                                   mod );                    pWin->processEvent( evt );                    break;                }            }            break;        }        case KeyPress:        case KeyRelease:        {            EvtKey::ActionType_t action = EvtKey::kDown;            int mod = EvtInput::kModNone;            // Get the modifiers            if( event.xkey.state & Mod1Mask )            {                mod |= EvtInput::kModAlt;            }            if( event.xkey.state & ControlMask )            {                mod |= EvtInput::kModCtrl;            }            if( event.xkey.state & ShiftMask )            {                mod |= EvtInput::kModShift;            }            // Take the first keysym = lower case character            KeySym keysym = XLookupKeysym( &event.xkey, 0 );            // Get VLC key code from the keysym            int key = keysymToVlcKey[keysym];            if( !key )            {                // Normal key                key = keysym;            }            switch( event.type )            {                case KeyPress:                    action = EvtKey::kDown;                    break;                case KeyRelease:                    action = EvtKey::kUp;                    break;            }            EvtKey evt( getIntf(), key, action, mod );            pWin->processEvent( evt );            break;        }        case ClientMessage:        {            // Get the message type            string type = XGetAtomName( XDISPLAY, event.xclient.message_type );            // Find the DnD object for this window            X11DragDrop *pDnd =                ((X11Factory*)pOsFactory)->m_dndMap[event.xany.window];            if( !pDnd )            {                msg_Err( getIntf(), "No associated D&D object !!" );                return;            }            if( type == "XdndEnter" )            {                pDnd->dndEnter( event.xclient.data.l );            }            else if( type == "XdndPosition" )            {                pDnd->dndPosition( event.xclient.data.l );            }            else if( type == "XdndLeave" )            {                pDnd->dndLeave( event.xclient.data.l );            }            else if( type == "XdndDrop" )            {                pDnd->dndDrop( event.xclient.data.l );            }            break;        }    }}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -