Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  x11_factory.cpp   Sprache: C

 

/*****************************************************************************
 * x11_factory.cpp
 *****************************************************************************
 * Copyright (C) 2003 the VideoLAN team
 *
 * Authors: Cyril Deguet     <asmax@via.ecp.fr>
 *          Olivier Teulière <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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/


#ifdef X11_SKINS

#include <errno.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xinerama.h>

#include "x11_factory.hpp"
#include "x11_display.hpp"
#include "x11_graphics.hpp"
#include "x11_loop.hpp"
#include "x11_popup.hpp"
#include "x11_timer.hpp"
#include "x11_window.hpp"
#include "x11_tooltip.hpp"

#include "../src/generic_window.hpp"

#include <vlc_common.h>
#include <vlc_configuration.h>
#include <vlc_xlib.h>

X11Factory::X11Factory( intf_thread_t *pIntf ): OSFactory( pIntf ),
    m_pDisplay( NULL ), m_pTimerLoop( NULL ), m_dirSep( "/" ),
    mPointerWindow( None ), mVoutWindow( None ), mEmptyCursor( None )
{
    // see init()
}


X11Factory::~X11Factory()
{
    if( mEmptyCursor != None )
        XFreeCursor( m_pDisplay->getDisplay(), mEmptyCursor );
    delete m_pTimerLoop;
    delete m_pDisplay;
}


bool X11Factory::init()
{
    // make sure xlib is safe-thread
    if( !vlc_xlib_init( VLC_OBJECT( getIntf() ) ) )
    {
        msg_Err( getIntf(), "initializing xlib for multi-threading failed" );
        return false;
    }

    // Create the X11 display
    m_pDisplay = new X11Display( getIntf() );

    // Get the display
    Display *pDisplay = m_pDisplay->getDisplay();
    if( pDisplay == NULL )
    {
        // Initialization failed
        return false;
    }

    // Create the timer loop
    m_pTimerLoop = new X11TimerLoop( getIntf(),
                                     ConnectionNumber( pDisplay ) );

    // Initialize the resource path
    char *datadir = config_GetUserDir( VLC_USERDATA_DIR );
    if (likely(datadir != nullptr))
    {
        m_resourcePath.push_back( (std::string)datadir + "/skins2" );
        free( datadir );
    }
    m_resourcePath.push_back( (std::string)"share/skins2" );
    datadir = config_GetSysPath(VLC_PKG_DATA_DIR, "skins2");
    if (likely(datadir != nullptr))
    {
        m_resourcePath.push_back( (std::string)datadir );
        free( datadir );
    }

    // Determine the monitor geometry
    getDefaultGeometry( &m_screenWidth, &m_screenHeight );

    // list all available monitors
    int num_screen;
    XineramaScreenInfo* info = XineramaQueryScreens( pDisplay, &num_screen );
    if( info )
    {
        msg_Dbg( getIntf(), "number of monitors detected : %i", num_screen );
        for( int i = 0; i < num_screen; i++ )
            msg_Dbg( getIntf(), "  monitor #%i : %ix%i at +%i+%i",
                                i, info[i].width, info[i].height,
                                info[i].x_org, info[i].y_org );
        XFree( info );
    }

    // init cursors
    initCursors();

    return true;
}


OSGraphics *X11Factory::createOSGraphics( int width, int height )
{
    return new X11Graphics( getIntf(), *m_pDisplay, width, height );
}


OSLoop *X11Factory::getOSLoop()
{
    return X11Loop::instance( getIntf(), *m_pDisplay );
}


void X11Factory::destroyOSLoop()
{
    X11Loop::destroy( getIntf() );
}

void X11Factory::minimize()
{
    XIconifyWindow( m_pDisplay->getDisplay(), m_pDisplay->getMainWindow(),
                    DefaultScreen( m_pDisplay->getDisplay() ) );
}

void X11Factory::restore()
{
    // TODO
}

void X11Factory::addInTray()
{
    // TODO
}

void X11Factory::removeFromTray()
{
    // TODO
}

void X11Factory::addInTaskBar()
{
    // TODO
}

void X11Factory::removeFromTaskBar()
{
    // TODO
}

OSTimer *X11Factory::createOSTimer( CmdGeneric &rCmd )
{
    return new X11Timer( getIntf(), rCmd );
}


OSWindow *X11Factory::createOSWindow( GenericWindow &rWindow, bool dragDrop,
                                      bool playOnDrop, OSWindow *pParent,
                                      GenericWindow::WindowType_t type )
{
    return new X11Window( getIntf(), rWindow, *m_pDisplay, dragDrop,
                          playOnDrop, (X11Window*)pParent, type );
}


OSTooltip *X11Factory::createOSTooltip()
{
    return new X11Tooltip( getIntf(), *m_pDisplay );
}


OSPopup *X11Factory::createOSPopup()
{
    return new X11Popup( getIntf(), *m_pDisplay );
}


int X11Factory::getScreenWidth() const
{
    return m_screenWidth;
}


int X11Factory::getScreenHeight() const
{
    return m_screenHeight;
}


void X11Factory::getMonitorInfo( OSWindow *pWindow,
                                 int* p_x, int* p_y,
                                 int* p_width, int* p_height ) const
{
    X11Window *pWin = (X11Window*)pWindow;
    // initialize to default geometry
    *p_x = 0;
    *p_y = 0;
    *p_width = getScreenWidth();
    *p_height = getScreenHeight();

    // Use Xinerama to determine the monitor where the video
    // mostly resides (biggest surface)
    Display *pDisplay = m_pDisplay->getDisplay();
    Window wnd = pWin->getDrawable();
    Window root = DefaultRootWindow( pDisplay );
    Window child_wnd;

    int x, y;
    unsigned int w, h, border, depth;
    XGetGeometry( pDisplay, wnd, &root, &x, &y, &w, &h, &border, &depth );
    XTranslateCoordinates( pDisplay, wnd, root, 0, 0, &x, &y, &child_wnd );

    int num;
    XineramaScreenInfo* info = XineramaQueryScreens( pDisplay, &num );
    if( info )
    {
        Region reg1 = XCreateRegion();
        XRectangle rect1 = { (short)x, (short)y, (unsigned short)w, (unsigned short)h };
        XUnionRectWithRegion( &rect1, reg1, reg1 );

        unsigned int surface = 0;
        for( int i = 0; i < num; i++ )
        {
            Region reg2 = XCreateRegion();
            XRectangle rect2 = { info[i].x_org, info[i].y_org,
                                 (unsigned short)info[i].width, (unsigned short)info[i].height };
            XUnionRectWithRegion( &rect2, reg2, reg2 );

            Region reg = XCreateRegion();
            XIntersectRegion( reg1, reg2, reg );
            XRectangle rect;
            XClipBox( reg, &rect );
            unsigned int surf = rect.width * rect.height;
            if( surf > surface )
            {
               surface = surf;
               *p_x = info[i].x_org;
               *p_y = info[i].y_org;
               *p_width = info[i].width;
               *p_height = info[i].height;
            }
            XDestroyRegion( reg );
            XDestroyRegion( reg2 );
        }
        XDestroyRegion( reg1 );
        XFree( info );
    }
}


void X11Factory::getMonitorInfo( int numScreen,
                                 int* p_x, int* p_y,
                                 int* p_width, int* p_height ) const
{
    // initialize to default geometry
    *p_x = 0;
    *p_y = 0;
    *p_width = getScreenWidth();
    *p_height = getScreenHeight();

    // try to detect the requested screen via Xinerama
    if( numScreen >= 0 )
    {
        int num;
        Display *pDisplay = m_pDisplay->getDisplay();
        XineramaScreenInfo* info = XineramaQueryScreens( pDisplay, &num );
        if( info )
        {
            if( numScreen < num )
            {
                *p_x = info[numScreen].x_org;
                *p_y = info[numScreen].y_org;
                *p_width = info[numScreen].width;
                *p_height = info[numScreen].height;
            }
            XFree( info );
        }
    }
}


void X11Factory::getDefaultGeometry( int* p_width, int* p_height ) const
{
    Display *pDisplay = m_pDisplay->getDisplay();

    // Initialize to defaults
    int screen = DefaultScreen( pDisplay );
    *p_width = DisplayWidth( pDisplay, screen );
    *p_height = DisplayHeight( pDisplay, screen );

    // Use Xinerama to restrain to the first monitor instead of the full
    // virtual screen
    int num;
    XineramaScreenInfo* info = XineramaQueryScreens( pDisplay, &num );
    if( info )
    {
        for( int i = 0; i < num; i++ )
        {
            if( info[i].x_org == 0 && info[i].y_org == 0 )
            {
                *p_width = info[i].width;
                *p_height = info[i].height;
                break;
            }
        }
        XFree( info );
    }
}


SkinsRect X11Factory::getWorkArea() const
{
    // query Work Area if available from Window Manager
    // otherwise, default to the whole screen
    int x = 0, y = 0;
    int w = getScreenWidth(), h = getScreenHeight();
    if( m_pDisplay->m_net_workarea != None )
    {
        Atom ret;
        int i_format;
        unsigned long i_items, i_bytesafter;
        long *values;
        if( XGetWindowProperty( m_pDisplay->getDisplay(),
                                DefaultRootWindow( m_pDisplay->getDisplay() ),
                                m_pDisplay->m_net_workarea,
                                0, 16384, False, XA_CARDINAL,
                                &ret, &i_format, &i_items, &i_bytesafter,
                                (unsigned char **)&values ) == Success )
        {
            if( values )
            {
                x = values[0];
                y = values[1];
                w = values[2];
                h = values[3];
                XFree( values );
            }
        }
    }
    msg_Dbg( getIntf(),"WorkArea: %ix%i at +%i+%i", w, h, x, y );
    return SkinsRect( x, y, x + w, y + h );
}


void X11Factory::getMousePos( int &rXPos, int &rYPos ) const
{
    Window rootReturn, childReturn;
    int winx, winy;
    unsigned int xmask;

    Display *pDisplay = m_pDisplay->getDisplay();
    Window root = DefaultRootWindow( pDisplay );
    XQueryPointer( pDisplay, root, &rootReturn, &childReturn,
                   &rXPos, &rYPos, &winx, &winy, &xmask );
}


void X11Factory::rmDir( const std::string &rPath )
{
    const char *file;
    vlc_DIR *dir;

    dir = vlc_opendir( rPath.c_str() );
    if( !dir ) return;

    // Parse the directory and remove everything it contains
    while( (file = vlc_readdir( dir )) )
    {
        std::string filename = file;

        // Skip "." and ".."
        if( filename == "." || filename == ".." )
        {
            continue;
        }

        filename = rPath + "/" + filename;

        if( rmdir( filename.c_str() ) && errno == ENOTDIR )
            unlink( filename.c_str() );
    }

    // Close the directory
    vlc_closedir( dir );

    // And delete it
    rmdir( rPath.c_str() );
}


void X11Factory::changeCursor( CursorType_t type ) const
{
    Cursor cursor = mCursors[type];
    Window win = (type == OSFactory::kNoCursor) ? mVoutWindow : mPointerWindow;

    if( win != None )
        XDefineCursor( m_pDisplay->getDisplay(), win, cursor );
}

void X11Factory::initCursors( )
{
    Display *display = m_pDisplay->getDisplay();
    static const struct {
        CursorType_t type;
        const char *name;
    } cursors[] = {
        { kDefaultArrow, "left_ptr" },
        { kResizeNWSE, "bottom_right_corner" },
        { kResizeNS, "bottom_side" },
        { kResizeWE, "right_side" },
        { kResizeNESW, "bottom_left_corner" },
    };
    // retrieve cursors from default theme
    for( unsigned i = 0; i < ARRAY_SIZE(cursors); i++ )
        mCursors[cursors[i].type] =
            XcursorLibraryLoadCursor( display, cursors[i].name );

    // build an additional empty cursor
    XColor color;
    const char data[] = { 0 };
    Window root = DefaultRootWindow( display );
    Pixmap pix = XCreateBitmapFromData( display, root, data, 1, 1 );
    mEmptyCursor = XCreatePixmapCursor( display, pix, pix, &color, &color, 0, 0 );
    XFreePixmap( display, pix );
    mCursors[kNoCursor] = mEmptyCursor;
}


void X11Factory::setPointerWindow( Window win )
{
    GenericWindow *pWin = m_windowMap[win];
    if( pWin->getType() == GenericWindow::VoutWindow )
        mVoutWindow = win;
    mPointerWindow = win;
}
#endif

Messung
CHZG
85979492

¤ Dauer der Verarbeitung: 0.3 Sekunden  (vorverarbeitet am  2026-11-04) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1104857
#Domains=418426