Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/LibreOffice/avmedia/source/win/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 13 kB image not shown  

Quelle  window.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <objbase.h>
#include <strmif.h>
#include <control.h>
#include <dshow.h>

#include <com/sun/star/awt/SystemPointer.hpp>
#include <cppuhelper/supportsservice.hxx>

#include "window.hxx"
#include "player.hxx"

constexpr OUStringLiteral AVMEDIA_WIN_WINDOW_IMPLEMENTATIONNAME = u"com.sun.star.comp.avmedia.Window_DirectX";
constexpr OUString AVMEDIA_WIN_WINDOW_SERVICENAME = u"com.sun.star.media.Window_DirectX"_ustr;

using namespace ::com::sun::star;

namespace avmedia::win {

static LRESULT CALLBACK MediaPlayerWndProc( HWND hWnd,UINT nMsg, WPARAM nPar1, LPARAM nPar2 )
{
    Window* pWindow = reinterpret_cast<Window*>(GetWindowLongPtrW( hWnd, 0 ));
    bool    bProcessed = true;

    if( pWindow )
    {
        switch( nMsg )
        {
            case WM_SETCURSOR:
                pWindow->updatePointer();
            break;

            case WM_GRAPHNOTIFY:
                pWindow->processGraphEvent();
            break;

            case WM_MOUSEMOVE:
            case WM_LBUTTONDOWN:
            case WM_MBUTTONDOWN:
            case WM_RBUTTONDOWN:
            case WM_LBUTTONUP:
            case WM_MBUTTONUP:
            case WM_RBUTTONUP:
                PostMessage(pWindow->getParentWnd(), nMsg, nPar1, nPar2);
            break;

            case WM_SETFOCUS:
            {
                const awt::FocusEvent aUNOEvt;
                pWindow->fireSetFocusEvent( aUNOEvt );
            }
            break;

            default:
                bProcessed = false;
            break;
        }
    }
    else
        bProcessed = false;

    return( bProcessed ? 0 : DefWindowProcW( hWnd, nMsg, nPar1, nPar2 ) );
}

static WNDCLASSW* lcl_getWndClass()
{
    WNDCLASSW* s_pWndClass = new WNDCLASSW;

    memset( s_pWndClass, 0, sizeof( *s_pWndClass ) );
    s_pWndClass->hInstance = GetModuleHandleW( nullptr );
    s_pWndClass->cbWndExtra = sizeof( DWORD_PTR );
    s_pWndClass->lpfnWndProc = MediaPlayerWndProc;
    s_pWndClass->lpszClassName = L"com_sun_star_media_PlayerWnd";
    s_pWndClass->hbrBackground = static_cast<HBRUSH>(::GetStockObject( BLACK_BRUSH ));
    s_pWndClass->hCursor = ::LoadCursor( nullptr, IDC_ARROW );

    RegisterClassW( s_pWndClass );

    return s_pWndClass;
}

Window::Window( Player& rPlayer ) :
    meZoomLevel( media::ZoomLevel_NOT_AVAILABLE ),
    mrPlayer( rPlayer ),
    mnFrameWnd( nullptr ),
    mnParentWnd( nullptr ),
    mnPointerType( awt::SystemPointer::ARROW )
{
}

Window::~Window()
{
    if( mnFrameWnd )
        ::DestroyWindow( mnFrameWnd );
}

void Window::ImplLayoutVideoWindow()
{
    if( media::ZoomLevel_NOT_AVAILABLE != meZoomLevel )
    {
        awt::Size           aPrefSize( mrPlayer.getPreferredPlayerWindowSize() );
        awt::Rectangle      aRect = getPosSize();
        int                 nW = aRect.Width, nH = aRect.Height;
        int                 nVideoW = nW, nVideoH = nH;
        int                 nX = 0, nY = 0, nWidth = 0, nHeight = 0;
        bool                bDone = false, bZoom = false;

        if( media::ZoomLevel_ORIGINAL == meZoomLevel )
        {
            bZoom = true;
        }
        else if( media::ZoomLevel_ZOOM_1_TO_4 == meZoomLevel )
        {
            aPrefSize.Width >>= 2;
            aPrefSize.Height >>= 2;
            bZoom = true;
        }
        else if( media::ZoomLevel_ZOOM_1_TO_2 == meZoomLevel )
        {
            aPrefSize.Width >>= 1;
            aPrefSize.Height >>= 1;
            bZoom = true;
        }
        else if( media::ZoomLevel_ZOOM_2_TO_1 == meZoomLevel )
        {
            aPrefSize.Width <<= 1;
            aPrefSize.Height <<= 1;
            bZoom = true;
        }
        else if( media::ZoomLevel_ZOOM_4_TO_1 == meZoomLevel )
        {
            aPrefSize.Width <<= 2;
            aPrefSize.Height <<= 2;
            bZoom = true;
        }
        else if( media::ZoomLevel_FIT_TO_WINDOW == meZoomLevel )
        {
            nWidth = nVideoW;
            nHeight = nVideoH;
            bDone = true;
        }

        if( bZoom )
        {
            if( ( aPrefSize.Width <= nVideoW ) && ( aPrefSize.Height <= nVideoH ) )
            {
                nX = ( nVideoW - aPrefSize.Width ) >> 1;
                nY = ( nVideoH - aPrefSize.Height ) >> 1;
                nWidth = aPrefSize.Width;
                nHeight = aPrefSize.Height;
                bDone = true;
            }
        }

        if( !bDone )
        {
            if( aPrefSize.Width > 0 && aPrefSize.Height > 0 && nVideoW > 0 && nVideoH > 0 )
            {
                double fPrefWH = static_cast<double>(aPrefSize.Width) / aPrefSize.Height;

                if( fPrefWH < ( static_cast<double>(nVideoW) / nVideoH ) )
                    nVideoW = static_cast<int>( nVideoH * fPrefWH );
                else
                    nVideoH = static_cast<int>( nVideoW / fPrefWH );

                nX = ( nW - nVideoW ) >> 1;
                nY = ( nH - nVideoH ) >> 1;
                nWidth = nVideoW;
                nHeight = nVideoH;
            }
            else
                nX = nY = nWidth = nHeight = 0;
        }

        IVideoWindow* pVideoWindow = const_cast< IVideoWindow* >( mrPlayer.getVideoWindow() );

        if( pVideoWindow )
            pVideoWindow->SetWindowPosition( nX, nY, nWidth, nHeight );
    }
}

bool Window::create( const uno::Sequence< uno::Any >& rArguments )
{
    IVideoWindow* pVideoWindow = const_cast< IVideoWindow* >( mrPlayer.getVideoWindow() );
    static WNDCLASSW* mpWndClass = lcl_getWndClass();

    if( !mnFrameWnd && pVideoWindow && mpWndClass )
    {
        awt::Rectangle  aRect;
        sal_IntPtr       nWnd;

        rArguments[ 0 ] >>= nWnd;
        rArguments[ 1 ] >>= aRect;

        mnParentWnd = reinterpret_cast<HWND>(nWnd);

        mnFrameWnd = CreateWindowW( mpWndClass->lpszClassName, nullptr,
                                    WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
                                    aRect.X, aRect.Y, aRect.Width, aRect.Height,
                                    mnParentWnd, nullptr, mpWndClass->hInstance, nullptr );

        if( mnFrameWnd )
        {
            SetWindowLongPtrW( mnFrameWnd, 0, reinterpret_cast<LONG_PTR>(this) );

            pVideoWindow->put_Owner( reinterpret_cast<OAHWND>(mnFrameWnd) );
            pVideoWindow->put_MessageDrain( reinterpret_cast<OAHWND>(mnFrameWnd) );
            pVideoWindow->put_WindowStyle( WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN );

            mrPlayer.setNotifyWnd( mnFrameWnd );

            meZoomLevel = media::ZoomLevel_FIT_TO_WINDOW;
            ImplLayoutVideoWindow();
        }
    }

    return( mnFrameWnd != nullptr );
}

void Window::processGraphEvent()
{
    mrPlayer.processEvent();
}

void Window::updatePointer()
{
    LPCTSTR pCursorName;

    switch( mnPointerType )
    {
        case awt::SystemPointer::CROSS: pCursorName = IDC_CROSS; break;
        case awt::SystemPointer::MOVE: pCursorName = IDC_SIZEALL; break;
        case awt::SystemPointer::WAIT: pCursorName = IDC_WAIT; break;

        default:
            pCursorName = IDC_ARROW;
        break;
    }

    SetCursor( LoadCursor( nullptr, pCursorName ) );
}

void SAL_CALL Window::update(  )
{
    ::RedrawWindow( mnFrameWnd, nullptr, nullptr, RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE  );
}

sal_Bool SAL_CALL Window::setZoomLevel( media::ZoomLevel eZoomLevel )
{
        bool bRet = false;

        if( media::ZoomLevel_NOT_AVAILABLE != meZoomLevel &&
            media::ZoomLevel_NOT_AVAILABLE != eZoomLevel )
        {
            if( eZoomLevel != meZoomLevel )
            {
                meZoomLevel = eZoomLevel;
                ImplLayoutVideoWindow();
            }

            bRet = true;
        }

        return bRet;
}

media::ZoomLevel SAL_CALL Window::getZoomLevel(  )
{
    return meZoomLevel;
}

void SAL_CALL Window::setPointerType( sal_Int32 nPointerType )
{
    mnPointerType = nPointerType;
}

void SAL_CALL Window::setPosSize( sal_Int32 X, sal_Int32 Y, sal_Int32 Width, sal_Int32 Height, sal_Int16 )
{
    if( mnFrameWnd )
    {
        ::SetWindowPos( mnFrameWnd, HWND_TOP, X, Y, Width, Height, 0 );
        ImplLayoutVideoWindow();
    }
}

awt::Rectangle SAL_CALL Window::getPosSize()
{
    awt::Rectangle aRet;

    if( mnFrameWnd )
    {
        ::RECT  aWndRect;

        if( ::GetClientRect( mnFrameWnd, &aWndRect ) )
        {
            aRet.X = aWndRect.left;
            aRet.Y = aWndRect.top;
            aRet.Width = aWndRect.right - aWndRect.left + 1;
            aRet.Height = aWndRect.bottom - aWndRect.top + 1;
        }
    }

    return aRet;
}

void SAL_CALL Window::setVisible( sal_Bool bVisible )
{
    if( mnFrameWnd )
    {
        IVideoWindow* pVideoWindow = const_cast< IVideoWindow* >( mrPlayer.getVideoWindow() );

        if( pVideoWindow )
            pVideoWindow->put_Visible( bVisible ? OATRUE : OAFALSE );

        ::ShowWindow( mnFrameWnd, bVisible ? SW_SHOW : SW_HIDE );
    }
}

void SAL_CALL Window::setEnable( sal_Bool bEnable )
{
    if( mnFrameWnd )
        ::EnableWindow( mnFrameWnd, bEnable );
}

void SAL_CALL Window::setFocus(  )
{
    if( mnFrameWnd )
        ::SetFocus( mnFrameWnd );
}

void SAL_CALL Window::addWindowListener( const uno::Reference< awt::XWindowListener >&&nbsp;xListener )
{
    std::unique_lock g(maMutex);
    maWindowListeners.addInterface( g, xListener );
}

void SAL_CALL Window::removeWindowListener( const uno::Reference< awt::XWindowListener >&&nbsp;xListener )
{
    std::unique_lock g(maMutex);
    maWindowListeners.removeInterface( g, xListener );
}

void SAL_CALL Window::addFocusListener( const uno::Reference< awt::XFocusListener >& xListener )
{
    std::unique_lock g(maMutex);
    maFocusListeners.addInterface( g, xListener );
}

void SAL_CALL Window::removeFocusListener( const uno::Reference< awt::XFocusListener >&&nbsp;xListener )
{
    std::unique_lock g(maMutex);
    maFocusListeners.removeInterface( g, xListener );
}

void SAL_CALL Window::addKeyListener( const uno::Reference< awt::XKeyListener >& xListener )
{
    std::unique_lock g(maMutex);
    maKeyListeners.addInterface( g, xListener );
}

void SAL_CALL Window::removeKeyListener( const uno::Reference< awt::XKeyListener >& xListener )
{
    std::unique_lock g(maMutex);
    maKeyListeners.removeInterface( g, xListener );
}

void SAL_CALL Window::addMouseListener( const uno::Reference< awt::XMouseListener >& xListener )
{
    std::unique_lock g(maMutex);
    maMouseListeners.addInterface( g, xListener );
}

void SAL_CALL Window::removeMouseListener( const uno::Reference< awt::XMouseListener >&&nbsp;xListener )
{
    std::unique_lock g(maMutex);
    maMouseListeners.removeInterface( g, xListener );
}

void SAL_CALL Window::addMouseMotionListener( const uno::Reference< awt::XMouseMotionListener >& xListener )
{
    std::unique_lock g(maMutex);
    maMouseMotionListeners.addInterface( g, xListener );
}

void SAL_CALL Window::removeMouseMotionListener( const uno::Reference< awt::XMouseMotionListener >& xListener )
{
    std::unique_lock g(maMutex);
    maMouseMotionListeners.removeInterface( g, xListener );
}

void SAL_CALL Window::addPaintListener( const uno::Reference< awt::XPaintListener >& xListener )
{
    std::unique_lock g(maMutex);
    maPaintListeners.addInterface( g, xListener );
}

void SAL_CALL Window::removePaintListener( const uno::Reference< awt::XPaintListener >&&nbsp;xListener )
{
    std::unique_lock g(maMutex);
    maPaintListeners.removeInterface( g, xListener );
}

void SAL_CALL Window::dispose(  )
{
}

void SAL_CALL Window::addEventListener( const uno::Reference< lang::XEventListener >& ;xListener )
{
    std::unique_lock g(maMutex);
    maEventListeners.addInterface( g, xListener );
}

void SAL_CALL Window::removeEventListener( const uno::Reference< lang::XEventListener >&&nbsp;xListener )
{
    std::unique_lock g(maMutex);
    maEventListeners.removeInterface( g, xListener );
}

void Window::fireMousePressedEvent( const css::awt::MouseEvent& rEvt )
{
    std::unique_lock g(maMutex);
    maMouseListeners.notifyEach(g, &awt::XMouseListener::mousePressed, rEvt);
}

void Window::fireMouseReleasedEvent( const css::awt::MouseEvent& rEvt )
{
    std::unique_lock g(maMutex);
    maMouseListeners.notifyEach(g, &awt::XMouseListener::mouseReleased, rEvt);
}

void Window::fireMouseMovedEvent( const css::awt::MouseEvent& rEvt )
{
    std::unique_lock g(maMutex);
    maMouseMotionListeners.notifyEach(g, &awt::XMouseMotionListener::mouseMoved, rEvt);
}

void Window::fireSetFocusEvent( const css::awt::FocusEvent& rEvt )
{
    std::unique_lock g(maMutex);
    maFocusListeners.notifyEach(g, &awt::XFocusListener::focusGained, rEvt);
}

OUString SAL_CALL Window::getImplementationName(  )
{
    return AVMEDIA_WIN_WINDOW_IMPLEMENTATIONNAME;
}

sal_Bool SAL_CALL Window::supportsService( const OUString& ServiceName )
{
    return cppu::supportsService(this, ServiceName);
}

uno::Sequence< OUString > SAL_CALL Window::getSupportedServiceNames(  )
{
    return { AVMEDIA_WIN_WINDOW_SERVICENAME };
}

// namespace avmedia::win


/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=95 H=93 G=93

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

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.