Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/VLC/modules/gui/skins2/x11/   (VLC Media Plyer ©)  Datei vom 23.9.2026 mit Größe 15 kB image not shown  

Quelle  x11_display.cpp   Sprache: C

 

/*****************************************************************************
 * x11_display.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 <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/xpm.h>
#include <X11/extensions/shape.h>

#include "x11_display.hpp"
#include "../src/logger.hpp"

#include "../share/icons/32x32/vlc.xpm"

template<class type> type X11Display::putPixel(type r, type g, type b) const
{
    return ( (r >> m_redRightShift)   << m_redLeftShift   ) |
           ( (g >> m_greenRightShift) << m_greenLeftShift ) |
           ( (b >> m_blueRightShift)  << m_blueLeftShift  );
}

template<class type>
type X11Display::blendPixel(type v,type r, type g, type b, type a) const
{
    uint16_t temp;

    temp = ((uint8_t)((v >> m_redLeftShift) << m_redRightShift));
    uint8_t red = r + ( temp * (255 - a) ) / 255;
    temp = ((uint8_t)((v >> m_greenLeftShift) << m_greenRightShift));
    uint8_t green = g + ( temp * (255 - a) ) / 255;
    temp = ((uint8_t)((v >> m_blueLeftShift) << m_blueRightShift));
    uint8_t blue = b + ( temp * (255 - a) ) / 255;

    return putPixel<type>(red,green,blue);
}

X11Display::X11Display( intf_thread_t *pIntf ): SkinObject( pIntf ),
    m_mainWindow( 0 ), m_gc( NULL ), m_colormap( 0 )
{
    // Open a connection to the X Server
    m_pDisplay = XOpenDisplay( NULL );
    if( m_pDisplay == NULL )
    {
        msg_Dbg( pIntf, "Cannot open X display" );
        return;
    }

    // Load the XShape extension
    int event, error;
    XShapeQueryExtension( m_pDisplay, &event, &error );

    // Get the display parameters
    int screen = DefaultScreen( m_pDisplay );
    int depth = DefaultDepth( m_pDisplay, screen );
    int order = ImageByteOrder( m_pDisplay );
    Window root = DefaultRootWindow( m_pDisplay );

    // Template for looking up the XVisualInfo
    XVisualInfo xVInfoTemplate;
    xVInfoTemplate.screen = screen;
    xVInfoTemplate.depth = depth;

    XVisualInfo *pVInfo = NULL;
    int vCount = 0;

    switch( depth )
    {
    case 8:
        xVInfoTemplate.c_class = DirectColor;
        // Get the DirectColor visual
        pVInfo = XGetVisualInfo( m_pDisplay, VisualScreenMask |
                                 VisualClassMask, &xVInfoTemplate,
                                 &vCount );
        if( pVInfo == NULL )
        {
            msg_Err( getIntf(), "no DirectColor visual available" );
            m_pDisplay = NULL;
            break;
        }
        m_pVisual = pVInfo->visual;

        // Compute the color shifts
        getShifts( pVInfo->red_mask, m_redLeftShift, m_redRightShift );
        getShifts( pVInfo->green_mask, m_greenLeftShift,
                   m_greenRightShift );
        getShifts( pVInfo->blue_mask, m_blueLeftShift, m_blueRightShift );

        // Create a color map
        m_colormap = XCreateColormap( m_pDisplay, root,
                DefaultVisual( m_pDisplay, screen ), AllocAll );

        // Create the palette
        XColor pColors[255];
        for( uint16_t i = 0; i < 255; i++ )
        {
            // kludge: colors are indexed reversely because color 255 seems
            // to bereserved for black even if we try to set it to white
            pColors[i].pixel = 254-i;
            pColors[i].pad   = 0;
            pColors[i].flags = DoRed | DoGreen | DoBlue;
            pColors[i].red   =
                (i >> m_redLeftShift) << (m_redRightShift + 8);
            pColors[i].green =
                (i >> m_greenLeftShift) << (m_greenRightShift + 8);
            pColors[i].blue  =
                (i >> m_blueLeftShift) << (m_blueRightShift + 8);
        }
        XStoreColors( m_pDisplay, m_colormap, pColors, 255 );
        blendPixelImpl = &X11Display::blendPixel8;
        putPixelImpl = &X11Display::putPixel8;
        m_pixelSize = 1;
        break;

    case 15:
    case 16:
    case 24:
    case 32:
        // Get the TrueColor visual
        xVInfoTemplate.c_class = TrueColor;
        pVInfo = XGetVisualInfo( m_pDisplay, VisualScreenMask |
                                 VisualDepthMask | VisualClassMask,
                                 &xVInfoTemplate, &vCount );
        if( pVInfo == NULL )
        {
            msg_Err( getIntf(), "No TrueColor visual for depth %d", depth );
            m_pDisplay = NULL;
            break;
        }
        m_pVisual = pVInfo->visual;

        // Compute the color shifts
        getShifts( pVInfo->red_mask,   m_redLeftShift,   m_redRightShift   );
        getShifts( pVInfo->green_mask, m_greenLeftShift, m_greenRightShift );
        getShifts( pVInfo->blue_mask,  m_blueLeftShift,  m_blueRightShift  );

        if( depth == 15 || depth == 16 )
        {
            if( order == MSBFirst )
            {
                blendPixelImpl = &X11Display::blendPixel16MSB;
                putPixelImpl = &X11Display::putPixel16MSB;
            }
            else
            {
                blendPixelImpl = &X11Display::blendPixel16LSB;
                putPixelImpl = &X11Display::putPixel16LSB;
            }
            m_pixelSize = 2;
        }
        else
        {
            if( order == MSBFirst )
            {
                blendPixelImpl = &X11Display::blendPixel32MSB;
                putPixelImpl = &X11Display::putPixel32MSB;
            }
            else
            {
                blendPixelImpl = &X11Display::blendPixel32LSB;
                putPixelImpl = &X11Display::putPixel32LSB;
            }
            m_pixelSize = 4;
        }
        break;

    default:
        msg_Err( getIntf(), "unsupported depth: %d bpp", depth );
        m_pDisplay = NULL;
        break;
    }

    // Free the visual info
    if( pVInfo )
    {
        XFree( pVInfo );
    }

    // Create a graphics context that doesn't generate GraphicsExpose events
    if( m_pDisplay )
    {
        XGCValues xgcvalues;
        xgcvalues.graphics_exposures = False;
        m_gc = XCreateGC( m_pDisplay, root, GCGraphicsExposures, &xgcvalues );

        // Create a parent window to have a single task in the task bar
        XSetWindowAttributes attr;
        m_mainWindow = XCreateWindow( m_pDisplay, root, 0, 0, 1, 1, 0, 0,
                                      InputOutput, CopyFromParent, 0, &attr );

        // initialize WM_CLASS
        XClassHint classhint;
        classhint.res_name = (char*) "vlc";
        classhint.res_class = (char*) "Vlc";
        XSetClassHint( m_pDisplay, m_mainWindow, &classhint );

        // Receive WM_DELETE_WINDOW
        Atom wm_delete = XInternAtom( m_pDisplay, "WM_DELETE_WINDOW", False);
        XSetWMProtocols( m_pDisplay, m_mainWindow, &wm_delete, 1);

        // Changing decorations
        struct {
            unsigned long flags;
            unsigned long functions;
            unsigned long decorations;
            long input_mode;
            unsigned long status;
        } motifWmHints;
        Atom hints_atom = XInternAtom( m_pDisplay, "_MOTIF_WM_HINTS", False );
        motifWmHints.flags = 2;    // MWM_HINTS_DECORATIONS;
        motifWmHints.decorations = 0;
        XChangeProperty( m_pDisplay, m_mainWindow, hints_atom, hints_atom, 32,
                         PropModeReplace, (unsigned char *)&motifWmHints,
                         sizeof( motifWmHints ) / sizeof( long ) );

        // Change the window title
        XStoreName( m_pDisplay, m_mainWindow, "VLC Media Player" );

        // Add an icon
        Pixmap icon_pixmap, shape_pixmap;
        int ret = XpmCreatePixmapFromData( m_pDisplay, root, (char**)vlc_xpm,
                                           &icon_pixmap, &shape_pixmap, NULL );
        if( ret == XpmSuccess )
        {
            XWMHints *wm = XAllocWMHints();
            if( wm )
            {
                wm->icon_pixmap = icon_pixmap;
                wm->icon_mask = shape_pixmap;
                wm->flags = (IconPixmapHint|IconMaskHint);

                XSetWMHints( m_pDisplay, m_mainWindow, wm );
                XFree( wm );
            }
        }
        else
        {
            msg_Err( getIntf(), "icon failed to be loaded (err=%i)", ret );
        }

        // Receive map notify events
        XSelectInput( m_pDisplay, m_mainWindow, StructureNotifyMask );

        // Set an empty mask for the window
        Region mask = XCreateRegion();
        XShapeCombineRegion( m_pDisplay, m_mainWindow, ShapeBounding, 0, 0,
                             mask, ShapeSet );
        XDestroyRegion( mask );

        // test EWMH capabilities
        testEWMH();

        // Try to avoid tiling window managers treating us like a normal window
        if( m_net_wm_window_type != None )
        {
            XChangeProperty( m_pDisplay, m_mainWindow, m_net_wm_window_type,
                    XA_ATOM, 32, PropModeReplace,
                    (unsigned char *)&m_net_wm_window_type_utility, 1 );
        }

        XMapWindow( m_pDisplay, m_mainWindow);

        // Move it outside the screen to avoid seeing it in workspace selector
        XMoveWindow( m_pDisplay, m_mainWindow, -10, -10 );

        // Force _NET_WM_PID whatever the WM _NET_SUPPORTED says
        m_net_wm_pid = XInternAtom( m_pDisplay, "_NET_WM_PID" , False );
    }
}


X11Display::~X11Display()
{
    if( m_mainWindow ) XDestroyWindow( m_pDisplay, m_mainWindow );
    if( m_gc )         XFreeGC( m_pDisplay, m_gc );
    if( m_colormap )   XFreeColormap( m_pDisplay, m_colormap );
    if( m_pDisplay )   XCloseDisplay( m_pDisplay );
}


void X11Display::testEWMH()
{
    int i_ret, i_format;
    unsigned long i_items, i_bytesafter;
    union { Atom *p_atom; unsigned char *p_char; } p_args;
    p_args.p_atom = NULL;

    m_net_wm_supported = XInternAtom( m_pDisplay, "_NET_SUPPORTED", False );
    msg_Dbg( getIntf(), "EWMH: supported %d", m_net_wm_supported != None ? 1 : 0 );
    if( m_net_wm_supported == None )
        return;

    i_ret = XGetWindowProperty( m_pDisplay, DefaultRootWindow( m_pDisplay ),
                                m_net_wm_supported,
                                0, 16384, False, AnyPropertyType,
                                &m_net_wm_supported,
                                &i_format, &i_items, &i_bytesafter,
                                (unsigned char **)&p_args );

    if( i_ret != Success || i_items == 0 )
        return; /* Not supported */

#define TEST_EWMH( name, value ) \
{\
    name = XInternAtom( m_pDisplay, value, False );\
    unsigned int i;\
    for( i = 0; i < i_items; i++ )\
    {\
        if( p_args.p_atom[i] == name ) break;\
    }\
    if( i == i_items )\
    {\
        msg_Dbg( getIntf(), "%s support: no", value );\
        name = None;\
    }\
    else\
        msg_Dbg( getIntf(), "%s support: yes", value );\
}

    TEST_EWMH( m_net_wm_window_type, "_NET_WM_WINDOW_TYPE" )
    TEST_EWMH( m_net_wm_window_type_normal, "_NET_WM_WINDOW_TYPE_NORMAL" )
    TEST_EWMH( m_net_wm_window_type_utility, "_NET_WM_WINDOW_TYPE_UTILITY" )

    TEST_EWMH( m_net_wm_state, "_NET_WM_STATE" )
    TEST_EWMH( m_net_wm_state_fullscreen, "_NET_WM_STATE_FULLSCREEN" )
    TEST_EWMH( m_net_wm_stays_on_top, "_NET_WM_STATE_STAYS_ON_TOP" )
    TEST_EWMH( m_net_wm_state_above, "_NET_WM_STATE_ABOVE" )

    TEST_EWMH( m_net_wm_window_opacity, "_NET_WM_WINDOW_OPACITY" )

    TEST_EWMH( m_net_wm_pid, "_NET_WM_PID" )
    TEST_EWMH( m_net_workarea, "_NET_WORKAREA" )

#undef TEST_EWMH

    XFree( p_args.p_atom );

}


void X11Display::getShifts( uint32_t mask, int &rLeftShift, int &rRightShift )
{
    for( rLeftShift = 0; (rLeftShift < 32) && !(mask & 1); rLeftShift++ )
    {
        mask >>= 1;
    }
    for( rRightShift = 8; (mask & 1) ; rRightShift--)
    {
        mask >>= 1;
    }
    if( rRightShift < 0 )
    {
        rLeftShift -= rRightShift;
        rRightShift = 0;
    }
}


void X11Display::blendPixel8( uint8_t *pPixel, uint8_t r, uint8_t g,
                              uint8_t b, uint8_t a ) const
{
    *pPixel = 255 - blendPixel<uint8_t>(255 - *pPixel,r,g,b,a);
}


void X11Display::blendPixel16MSB( uint8_t *pPixel, uint8_t r, uint8_t g,
                                  uint8_t b, uint8_t a ) const
{
    uint16_t value = pPixel[1] | pPixel[0] << 8;

    value = blendPixel<uint16_t>(value,r,g,b,a);

    pPixel[1] = value; value >>= 8;
    pPixel[0] = value;
}


void X11Display::blendPixel16LSB( uint8_t *pPixel, uint8_t r, uint8_t g,
                                  uint8_t b, uint8_t a ) const
{
    uint16_t value = pPixel[0] | pPixel[1] << 8;

    value = blendPixel<uint16_t>(value,r,g,b,a);

    pPixel[0] = value; value >>= 8;
    pPixel[1] = value;
}


void X11Display::blendPixel32MSB( uint8_t *pPixel, uint8_t r, uint8_t g,
                                  uint8_t b, uint8_t a ) const
{
    uint32_t value = pPixel[3] | pPixel[2] << 8 |
                     pPixel[1] << 16 | pPixel[0] << 24;

    value = blendPixel<uint32_t>(value,r,g,b,a);

    pPixel[3] = value; value >>= 8;
    pPixel[2] = value; value >>= 8;
    pPixel[1] = value; value >>= 8;
    pPixel[0] = value;
}


void X11Display::blendPixel32LSB( uint8_t *pPixel, uint8_t r, uint8_t g,
                                  uint8_t b, uint8_t a ) const
{
    uint32_t value = pPixel[0] | pPixel[1] << 8 |
                     pPixel[2] << 16 | pPixel[3] << 24;

    value = blendPixel<uint32_t>(value,r,g,b,a);

    pPixel[0] = value; value >>= 8;
    pPixel[1] = value; value >>= 8;
    pPixel[2] = value; value >>= 8;
    pPixel[3] = value;
}


void X11Display::putPixel8( uint8_t *pPixel, uint8_t r, uint8_t g,
                            uint8_t b, uint8_t a ) const
{
    (void)a;
    *pPixel = 255 - putPixel<uint8_t>(r,g,b);
}


void X11Display::putPixel16MSB( uint8_t *pPixel, uint8_t r, uint8_t g,
                                uint8_t b, uint8_t a ) const
{
    (void)a;
    uint16_t value = putPixel<uint16_t>(r, g, b);

    pPixel[1] = value; value >>= 8;
    pPixel[0] = value;
}


void X11Display::putPixel16LSB( uint8_t *pPixel, uint8_t r, uint8_t g,
                                uint8_t b, uint8_t a ) const
{
    (void)a;
    uint16_t value = putPixel<uint16_t>(r,g,b);
    pPixel[0] = value; value >>= 8;
    pPixel[1] = value;
}


void X11Display::putPixel32MSB( uint8_t *pPixel, uint8_t r, uint8_t g,
                                uint8_t b, uint8_t a ) const
{
    (void)a;
    uint32_t value = putPixel<uint32_t>(r,g,b);

    pPixel[3] = value; value >>= 8;
    pPixel[2] = value; value >>= 8;
    pPixel[1] = value; value >>= 8;
    pPixel[0] = value;
}


void X11Display::putPixel32LSB( uint8_t *pPixel, uint8_t r, uint8_t g,
                                uint8_t b, uint8_t a ) const
{
    (void)a;
    uint32_t value = putPixel<uint32_t>(r,g,b);

    pPixel[0] = value; value >>= 8;
    pPixel[1] = value; value >>= 8;
    pPixel[2] = value; value >>= 8;
    pPixel[3] = value;
}


unsigned long X11Display::getPixelValue( uint8_t r, uint8_t g, uint8_t b )
    const
{
    unsigned long value = putPixel<unsigned long>(r,g,b);

    return m_pixelSize==1 ? 255 - value : value;
}

#endif

Messung
CHZG
881009995

¤ Dauer der Verarbeitung: 0.7 Sekunden  ¤

*© 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.