<commit_before>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtOpenGL module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qtextureglyphcache_gl_p.h"
#include "qpaintengineex_opengl2_p.h"

#ifdef Q_WS_WIN
extern Q_GUI_EXPORT bool qt_cleartype_enabled;
#endif

QGLTextureGlyphCache::QGLTextureGlyphCache(QGLContext *context, QFontEngineGlyphCache::Type type, const QTransform &matrix)
    : QTextureGlyphCache(type, matrix)
    , ctx(context)
    , m_width(0)
    , m_height(0)
{
    glGenFramebuffers(1, &m_fbo);
    connect(QGLSignalProxy::instance(), SIGNAL(aboutToDestroyContext(const QGLContext*)),
            SLOT(contextDestroyed(const QGLContext*)));
}

QGLTextureGlyphCache::~QGLTextureGlyphCache()
{
    if (ctx) {
        QGLShareContextScope scope(ctx);
        glDeleteFramebuffers(1, &m_fbo);

        if (m_width || m_height)
            glDeleteTextures(1, &m_texture);
    }
}

void QGLTextureGlyphCache::createTextureData(int width, int height)
{
    glGenTextures(1, &m_texture);
    glBindTexture(GL_TEXTURE_2D, m_texture);

    m_width = width;
    m_height = height;

    QVarLengthArray<uchar> data(width * height);
    for (int i = 0; i < data.size(); ++i)
        data[i] = 0;

    if (m_type == QFontEngineGlyphCache::Raster_RGBMask)
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &data[0]);
    else
        glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &data[0]);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}

void QGLTextureGlyphCache::resizeTextureData(int width, int height)
{
    // ### the QTextureGlyphCache API needs to be reworked to allow
    // ### resizeTextureData to fail

    int oldWidth = m_width;
    int oldHeight = m_height;

    GLuint oldTexture = m_texture;
    createTextureData(width, height);

    glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_fbo);

    GLuint tmp_texture;
    glGenTextures(1, &tmp_texture);
    glBindTexture(GL_TEXTURE_2D, tmp_texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, oldWidth, oldHeight, 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glBindTexture(GL_TEXTURE_2D, 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                           GL_TEXTURE_2D, tmp_texture, 0);

    glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
    glBindTexture(GL_TEXTURE_2D, oldTexture);

    pex->transferMode(BrushDrawingMode);

    glDisable(GL_STENCIL_TEST);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_SCISSOR_TEST);
    glDisable(GL_BLEND);

    glViewport(0, 0, oldWidth, oldHeight);

    GLfloat* vertexCoordinateArray = pex->staticVertexCoordinateArray;
    vertexCoordinateArray[0] = -1.0f;
    vertexCoordinateArray[1] = -1.0f;
    vertexCoordinateArray[2] =  1.0f;
    vertexCoordinateArray[3] = -1.0f;
    vertexCoordinateArray[4] =  1.0f;
    vertexCoordinateArray[5] =  1.0f;
    vertexCoordinateArray[6] = -1.0f;
    vertexCoordinateArray[7] =  1.0f;

    GLfloat* textureCoordinateArray = pex->staticTextureCoordinateArray;
    textureCoordinateArray[0] = 0.0f;
    textureCoordinateArray[1] = 0.0f;
    textureCoordinateArray[2] = 1.0f;
    textureCoordinateArray[3] = 0.0f;
    textureCoordinateArray[4] = 1.0f;
    textureCoordinateArray[5] = 1.0f;
    textureCoordinateArray[6] = 0.0f;
    textureCoordinateArray[7] = 1.0f;

    pex->setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, vertexCoordinateArray);
    pex->setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, textureCoordinateArray);

    pex->shaderManager->useBlitProgram();
    pex->shaderManager->blitProgram()->setUniformValue("imageTexture", QT_IMAGE_TEXTURE_UNIT);

    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    glBindTexture(GL_TEXTURE_2D, m_texture);

#ifdef QT_OPENGL_ES_2
    QDataBuffer<uchar> buffer(4*oldWidth*oldHeight);
    buffer.resize(4*oldWidth*oldHeight);
    glReadPixels(0, 0, oldWidth, oldHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());

    // do an in-place conversion from GL_RGBA to GL_ALPHA
    for (int i=0; i<oldWidth*oldHeight; ++i)
        buffer.data()[i] = buffer.at(4*i + 3);

    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, oldWidth, oldHeight,
                    GL_ALPHA, GL_UNSIGNED_BYTE, buffer.data());
#else
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight);
#endif

    glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                              GL_RENDERBUFFER_EXT, 0);
    glDeleteTextures(1, &tmp_texture);
    glDeleteTextures(1, &oldTexture);

    glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);

    glViewport(0, 0, pex->width, pex->height);
    pex->updateClipScissorTest();
}

void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph)
{
    QImage mask = textureMapForGlyph(glyph);
    const int maskWidth = mask.width();
    const int maskHeight = mask.height();

    if (mask.format() == QImage::Format_Mono) {
        mask = mask.convertToFormat(QImage::Format_Indexed8);
        for (int y = 0; y < maskHeight; ++y) {
            uchar *src = (uchar *) mask.scanLine(y);
            for (int x = 0; x < maskWidth; ++x)
                src[x] = -src[x]; // convert 0 and 1 into 0 and 255
        }
     }

    glBindTexture(GL_TEXTURE_2D, m_texture);
    if (mask.format() == QImage::Format_RGB32) {
        glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_BGRA, GL_UNSIGNED_BYTE, mask.bits());
    } else {
#ifdef QT_OPENGL_ES2
        glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_ALPHA, GL_UNSIGNED_BYTE, mask.bits());
#else
        // glTexSubImage2D() might cause some garbage to appear in the texture if the mask width is
        // not a multiple of four bytes. The bug appeared on a computer with 32-bit Windows Vista
        // and nVidia GeForce 8500GT. GL_UNPACK_ALIGNMENT is set to four bytes, 'mask' has a
        // multiple of four bytes per line, and most of the glyph shows up correctly in the
        // texture, which makes me think that this is a driver bug.
        // One workaround is to make sure the mask width is a multiple of four bytes, for instance
        // by converting it to a format with four bytes per pixel. Another is to copy one line at a
        // time.

        for (int i = 0; i < maskHeight; ++i)
            glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, maskWidth, 1, GL_ALPHA, GL_UNSIGNED_BYTE, mask.scanLine(i));
#endif
    }
}

int QGLTextureGlyphCache::glyphMargin() const
{
#if defined(Q_WS_MAC)
    return 2;
#elif defined (Q_WS_X11)
    return 0;
#else
    return m_type == QFontEngineGlyphCache::Raster_RGBMask ? 2 : 0;
#endif
}
<commit_msg>Fixed subpixel antialiased text drawing with the GL2 engine.<commit_after>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtOpenGL module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qtextureglyphcache_gl_p.h"
#include "qpaintengineex_opengl2_p.h"

#ifdef Q_WS_WIN
extern Q_GUI_EXPORT bool qt_cleartype_enabled;
#endif

QGLTextureGlyphCache::QGLTextureGlyphCache(QGLContext *context, QFontEngineGlyphCache::Type type, const QTransform &matrix)
    : QTextureGlyphCache(type, matrix)
    , ctx(context)
    , m_width(0)
    , m_height(0)
{
    glGenFramebuffers(1, &m_fbo);
    connect(QGLSignalProxy::instance(), SIGNAL(aboutToDestroyContext(const QGLContext*)),
            SLOT(contextDestroyed(const QGLContext*)));
}

QGLTextureGlyphCache::~QGLTextureGlyphCache()
{
    if (ctx) {
        QGLShareContextScope scope(ctx);
        glDeleteFramebuffers(1, &m_fbo);

        if (m_width || m_height)
            glDeleteTextures(1, &m_texture);
    }
}

void QGLTextureGlyphCache::createTextureData(int width, int height)
{
    glGenTextures(1, &m_texture);
    glBindTexture(GL_TEXTURE_2D, m_texture);

    m_width = width;
    m_height = height;

    QVarLengthArray<uchar> data(width * height);
    for (int i = 0; i < data.size(); ++i)
        data[i] = 0;

    if (m_type == QFontEngineGlyphCache::Raster_RGBMask)
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &data[0]);
    else
        glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &data[0]);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}

void QGLTextureGlyphCache::resizeTextureData(int width, int height)
{
    // ### the QTextureGlyphCache API needs to be reworked to allow
    // ### resizeTextureData to fail

    int oldWidth = m_width;
    int oldHeight = m_height;

    GLuint oldTexture = m_texture;
    createTextureData(width, height);

    glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_fbo);

    GLuint tmp_texture;
    glGenTextures(1, &tmp_texture);
    glBindTexture(GL_TEXTURE_2D, tmp_texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, oldWidth, oldHeight, 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glBindTexture(GL_TEXTURE_2D, 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                           GL_TEXTURE_2D, tmp_texture, 0);

    glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
    glBindTexture(GL_TEXTURE_2D, oldTexture);

    pex->transferMode(BrushDrawingMode);

    glDisable(GL_STENCIL_TEST);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_SCISSOR_TEST);
    glDisable(GL_BLEND);

    glViewport(0, 0, oldWidth, oldHeight);

    GLfloat* vertexCoordinateArray = pex->staticVertexCoordinateArray;
    vertexCoordinateArray[0] = -1.0f;
    vertexCoordinateArray[1] = -1.0f;
    vertexCoordinateArray[2] =  1.0f;
    vertexCoordinateArray[3] = -1.0f;
    vertexCoordinateArray[4] =  1.0f;
    vertexCoordinateArray[5] =  1.0f;
    vertexCoordinateArray[6] = -1.0f;
    vertexCoordinateArray[7] =  1.0f;

    GLfloat* textureCoordinateArray = pex->staticTextureCoordinateArray;
    textureCoordinateArray[0] = 0.0f;
    textureCoordinateArray[1] = 0.0f;
    textureCoordinateArray[2] = 1.0f;
    textureCoordinateArray[3] = 0.0f;
    textureCoordinateArray[4] = 1.0f;
    textureCoordinateArray[5] = 1.0f;
    textureCoordinateArray[6] = 0.0f;
    textureCoordinateArray[7] = 1.0f;

    pex->setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, vertexCoordinateArray);
    pex->setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, textureCoordinateArray);

    pex->shaderManager->useBlitProgram();
    pex->shaderManager->blitProgram()->setUniformValue("imageTexture", QT_IMAGE_TEXTURE_UNIT);

    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    glBindTexture(GL_TEXTURE_2D, m_texture);

#ifdef QT_OPENGL_ES_2
    QDataBuffer<uchar> buffer(4*oldWidth*oldHeight);
    buffer.resize(4*oldWidth*oldHeight);
    glReadPixels(0, 0, oldWidth, oldHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());

    // do an in-place conversion from GL_RGBA to GL_ALPHA
    for (int i=0; i<oldWidth*oldHeight; ++i)
        buffer.data()[i] = buffer.at(4*i + 3);

    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, oldWidth, oldHeight,
                    GL_ALPHA, GL_UNSIGNED_BYTE, buffer.data());
#else
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight);
#endif

    glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                              GL_RENDERBUFFER_EXT, 0);
    glDeleteTextures(1, &tmp_texture);
    glDeleteTextures(1, &oldTexture);

    glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);

    glViewport(0, 0, pex->width, pex->height);
    pex->updateClipScissorTest();
}

void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph)
{
    QImage mask = textureMapForGlyph(glyph);
    const int maskWidth = mask.width();
    const int maskHeight = mask.height();

    if (mask.format() == QImage::Format_Mono) {
        mask = mask.convertToFormat(QImage::Format_Indexed8);
        for (int y = 0; y < maskHeight; ++y) {
            uchar *src = (uchar *) mask.scanLine(y);
            for (int x = 0; x < maskWidth; ++x)
                src[x] = -src[x]; // convert 0 and 1 into 0 and 255
        }
    } else if (mask.format() == QImage::Format_RGB32) {
        // Make the alpha component equal to the average of the RGB values.
        // This is needed when drawing sub-pixel antialiased text on translucent targets.
        for (int y = 0; y < maskHeight; ++y) {
            quint32 *src = (quint32 *) mask.scanLine(y);
            for (int x = 0; x < maskWidth; ++x) {
                uchar r = src[x] >> 16;
                uchar g = src[x] >> 8;
                uchar b = src[x];
                quint32 avg = (quint32(r) + quint32(g) + quint32(b) + 1) / 3; // "+1" for rounding.
                src[x] = (src[x] & 0x00ffffff) | (avg << 24);
            }
        }
    }

    glBindTexture(GL_TEXTURE_2D, m_texture);
    if (mask.format() == QImage::Format_RGB32) {
        glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_BGRA, GL_UNSIGNED_BYTE, mask.bits());
    } else {
#ifdef QT_OPENGL_ES2
        glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_ALPHA, GL_UNSIGNED_BYTE, mask.bits());
#else
        // glTexSubImage2D() might cause some garbage to appear in the texture if the mask width is
        // not a multiple of four bytes. The bug appeared on a computer with 32-bit Windows Vista
        // and nVidia GeForce 8500GT. GL_UNPACK_ALIGNMENT is set to four bytes, 'mask' has a
        // multiple of four bytes per line, and most of the glyph shows up correctly in the
        // texture, which makes me think that this is a driver bug.
        // One workaround is to make sure the mask width is a multiple of four bytes, for instance
        // by converting it to a format with four bytes per pixel. Another is to copy one line at a
        // time.

        for (int i = 0; i < maskHeight; ++i)
            glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, maskWidth, 1, GL_ALPHA, GL_UNSIGNED_BYTE, mask.scanLine(i));
#endif
    }
}

int QGLTextureGlyphCache::glyphMargin() const
{
#if defined(Q_WS_MAC)
    return 2;
#elif defined (Q_WS_X11)
    return 0;
#else
    return m_type == QFontEngineGlyphCache::Raster_RGBMask ? 2 : 0;
#endif
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: pumptest.cxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000-09-18 17:24:19 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#include <stdio.h>

#include <osl/diagnose.h>
#include <com/sun/star/test/XSimpleTest.hpp>

#include <com/sun/star/io/XActiveDataSource.hpp>
#include <com/sun/star/io/XActiveDataSink.hpp>
#include <com/sun/star/io/XActiveDataControl.hpp>
#include <com/sun/star/io/XConnectable.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/registry/XRegistryKey.hpp>

#include <uno/dispatcher.h>
#include <uno/mapping.hxx>
#include <cppuhelper/implbase1.hxx>
#include <cppuhelper/factory.hxx>
#include <osl/mutex.hxx>
#include <osl/thread.h>
#include <stl/list>

using namespace ::rtl;
using namespace ::osl;
using namespace ::cppu;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::test;

#include "testfactreg.hxx"

class OPumpTest : public WeakImplHelper1 < XSimpleTest >
{
public:
    OPumpTest( const Reference< XMultiServiceFactory >  & rFactory );
    ~OPumpTest();

public: // implementation names
    static Sequence< OUString >     getSupportedServiceNames_Static(void) throw();
    static OUString                 getImplementationName_Static() throw();

public:
    virtual void SAL_CALL testInvariant(const OUString& TestName, const Reference < XInterface >& TestObject)
        throw  ( IllegalArgumentException, RuntimeException) ;

    virtual sal_Int32 SAL_CALL test(    const OUString& TestName,
                                        const Reference < XInterface >& TestObject,
                                        sal_Int32 hTestHandle)
        throw  (    IllegalArgumentException,
                    RuntimeException);

    virtual sal_Bool SAL_CALL testPassed(void)                              throw  (    RuntimeException) ;
    virtual Sequence< OUString > SAL_CALL getErrors(void)               throw  (RuntimeException) ;
    virtual Sequence< Any > SAL_CALL getErrorExceptions(void)       throw  (RuntimeException);
    virtual Sequence< OUString > SAL_CALL getWarnings(void)                 throw  (RuntimeException);

private:
    void testSimple( const Reference < XInterface > & );

private:
    Sequence<Any>  m_seqExceptions;
    Sequence<OUString> m_seqErrors;
    Sequence<OUString> m_seqWarnings;

};

OPumpTest::OPumpTest( const Reference< XMultiServiceFactory > &rFactory )
{

}

OPumpTest::~OPumpTest()
{

}

void OPumpTest::testInvariant( const OUString& TestName, const Reference < XInterface >& TestObject )
    throw  (    IllegalArgumentException,
                RuntimeException)
{
    Reference< XServiceInfo > info( TestObject, UNO_QUERY );
//      ERROR_ASSERT( info.is() , "XServiceInfo not supported !" );
    if( info.is() )
    {
//          ERROR_ASSERT( info->supportsService( TestName ), "XServiceInfo test failed" );
        ERROR_ASSERT( ! info->supportsService(
            OUString( RTL_CONSTASCII_USTRINGPARAM("bla bluzb") ) ), "XServiceInfo test failed" );
    }

    Reference < XActiveDataSource > xActiveDataSource( TestObject, UNO_QUERY );
    Reference < XActiveDataSink > xActiveDataSink( TestObject, UNO_QUERY );
    Reference < XActiveDataControl > xActiveDataControl( TestObject , UNO_QUERY );
    Reference < XConnectable > xConnectable( TestObject , UNO_QUERY );

    ERROR_ASSERT( xActiveDataSource.is() && xActiveDataSink.is() && xActiveDataControl.is () &&
                  xConnectable.is(), "specified interface not supported" );
}

sal_Int32 OPumpTest::test(
    const OUString& TestName,
    const Reference < XInterface >& TestObject,
    sal_Int32 hTestHandle)
    throw  (    IllegalArgumentException, RuntimeException)
{
    if( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.io.Pump") ) == TestName )  {
        try
        {
            if( 0 == hTestHandle ) {
                testInvariant( TestName , TestObject );
            }
        }
        catch( Exception & e )
        {
            OString s = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US );
            BUILD_ERROR( 0 , s.getStr() );
        }
        catch( ... )
        {
            BUILD_ERROR( 0 , "unknown exception (Exception is  not base class)" );
        }

        hTestHandle ++;

        if( 1 == hTestHandle )
        {
            // all tests finished.
            hTestHandle = -1;
        }
    }
    else {
        throw IllegalArgumentException();
    }
    return hTestHandle;
}

sal_Bool OPumpTest::testPassed(void)        throw  (RuntimeException)
{
    return m_seqErrors.getLength() == 0;
}

Sequence< OUString > OPumpTest::getErrors(void)     throw  (RuntimeException)
{
    return m_seqErrors;
}

Sequence< Any > OPumpTest::getErrorExceptions(void)                     throw  (RuntimeException)
{
    return m_seqExceptions;
}

Sequence< OUString > OPumpTest::getWarnings(void)                       throw  (RuntimeException)
{
    return m_seqWarnings;
}

/***
* the test methods
*
****/

void OPumpTest::testSimple( const Reference < XInterface > &r )
{
    // jbu todo: add sensible test

}

Reference< XInterface > SAL_CALL OPumpTest_CreateInstance( const Reference< XMultiServiceFactory > & rSMgr ) throw( Exception )
{
    return *new OPumpTest( rSMgr );
}

Sequence<OUString> OPumpTest_getSupportedServiceNames(void) throw()
{
    OUString s = OPumpTest_getServiceName();
    Sequence< OUString > seq( &s , 1 );
    return seq;

}
OUString     OPumpTest_getServiceName() throw()
{
    return OUString( RTL_CONSTASCII_USTRINGPARAM( "test.com.sun.star.io.Pump" ) );
}

OUString    OPumpTest_getImplementationName() throw()
{
    return OUString( RTL_CONSTASCII_USTRINGPARAM( "test.com.sun.star.comp.io.Pump") );
}
<commit_msg>added a simple pumptest<commit_after>/*************************************************************************
 *
 *  $RCSfile: pumptest.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: jbu $ $Date: 2001-01-25 14:06:36 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#include <stdio.h>

#include <osl/diagnose.h>
#include <com/sun/star/test/XSimpleTest.hpp>

#include <com/sun/star/io/XActiveDataSource.hpp>
#include <com/sun/star/io/XActiveDataSink.hpp>
#include <com/sun/star/io/XActiveDataControl.hpp>
#include <com/sun/star/io/XConnectable.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/registry/XRegistryKey.hpp>

#include <uno/dispatcher.h>
#include <uno/mapping.hxx>
#include <cppuhelper/implbase1.hxx>
#include <cppuhelper/factory.hxx>
#include <osl/mutex.hxx>
#include <osl/thread.h>
#include <stl/list>

using namespace ::rtl;
using namespace ::osl;
using namespace ::cppu;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::test;

#include "testfactreg.hxx"

class OPumpTest : public WeakImplHelper1 < XSimpleTest >
{
public:
    OPumpTest( const Reference< XMultiServiceFactory >  & rFactory );
    ~OPumpTest();

public: // implementation names
    static Sequence< OUString >     getSupportedServiceNames_Static(void) throw();
    static OUString                 getImplementationName_Static() throw();

public:
    virtual void SAL_CALL testInvariant(const OUString& TestName, const Reference < XInterface >& TestObject)
        throw  ( IllegalArgumentException, RuntimeException) ;

    virtual sal_Int32 SAL_CALL test(    const OUString& TestName,
                                        const Reference < XInterface >& TestObject,
                                        sal_Int32 hTestHandle)
        throw  (    IllegalArgumentException,
                    RuntimeException);

    virtual sal_Bool SAL_CALL testPassed(void)                              throw  (    RuntimeException) ;
    virtual Sequence< OUString > SAL_CALL getErrors(void)               throw  (RuntimeException) ;
    virtual Sequence< Any > SAL_CALL getErrorExceptions(void)       throw  (RuntimeException);
    virtual Sequence< OUString > SAL_CALL getWarnings(void)                 throw  (RuntimeException);

private:
    void testSimple( const Reference < XInterface > & );
    void testWrongUsage( const Reference < XInterface > & );

private:
    Sequence<Any>  m_seqExceptions;
    Sequence<OUString> m_seqErrors;
    Sequence<OUString> m_seqWarnings;
    Reference< XMultiServiceFactory > m_rSmgr;

};

OPumpTest::OPumpTest( const Reference< XMultiServiceFactory > &rFactory ) :
    m_rSmgr( rFactory )
{

}

OPumpTest::~OPumpTest()
{

}

void OPumpTest::testInvariant( const OUString& TestName, const Reference < XInterface >& TestObject )
    throw  (    IllegalArgumentException,
                RuntimeException)
{
    Reference< XServiceInfo > info( TestObject, UNO_QUERY );
//      ERROR_ASSERT( info.is() , "XServiceInfo not supported !" );
    if( info.is() )
    {
//          ERROR_ASSERT( info->supportsService( TestName ), "XServiceInfo test failed" );
        ERROR_ASSERT( ! info->supportsService(
            OUString( RTL_CONSTASCII_USTRINGPARAM("bla bluzb") ) ), "XServiceInfo test failed" );
    }

    Reference < XActiveDataSource > xActiveDataSource( TestObject, UNO_QUERY );
    Reference < XActiveDataSink > xActiveDataSink( TestObject, UNO_QUERY );
    Reference < XActiveDataControl > xActiveDataControl( TestObject , UNO_QUERY );
    Reference < XConnectable > xConnectable( TestObject , UNO_QUERY );

    ERROR_ASSERT( xActiveDataSource.is() && xActiveDataSink.is() && xActiveDataControl.is () &&
                  xConnectable.is(), "specified interface not supported" );
}

sal_Int32 OPumpTest::test(
    const OUString& TestName,
    const Reference < XInterface >& TestObject,
    sal_Int32 hTestHandle)
    throw  (    IllegalArgumentException, RuntimeException)
{
    if( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.io.Pump") ) == TestName )  {
        try
        {
            if( 0 == hTestHandle ) {
                testInvariant( TestName , TestObject );
            }
            else if ( 1 == hTestHandle )
            {
                testWrongUsage( TestObject);
            }
        }
        catch( Exception & e )
        {
            OString s = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US );
            BUILD_ERROR( 0 , s.getStr() );
        }
        catch( ... )
        {
            BUILD_ERROR( 0 , "unknown exception (Exception is  not base class)" );
        }

        hTestHandle ++;

        if( 2 == hTestHandle )
        {
            // all tests finished.
            hTestHandle = -1;
        }
    }
    else {
        throw IllegalArgumentException();
    }
    return hTestHandle;
}

sal_Bool OPumpTest::testPassed(void)        throw  (RuntimeException)
{
    return m_seqErrors.getLength() == 0;
}

Sequence< OUString > OPumpTest::getErrors(void)     throw  (RuntimeException)
{
    return m_seqErrors;
}

Sequence< Any > OPumpTest::getErrorExceptions(void)                     throw  (RuntimeException)
{
    return m_seqExceptions;
}

Sequence< OUString > OPumpTest::getWarnings(void)                       throw  (RuntimeException)
{
    return m_seqWarnings;
}

/***
* the test methods
*
****/

void OPumpTest::testSimple( const Reference < XInterface > &r )
{
    // jbu todo: add sensible test

}

void OPumpTest::testWrongUsage( const Reference< XInterface > &r )
{
    Reference< XActiveDataSource > rSource ( r, UNO_QUERY );
    Reference< XActiveDataSink > rSink( r , UNO_QUERY );
    Reference< XActiveDataControl > rControl( r, UNO_QUERY );

    Reference< XInputStream > rIn( m_rSmgr->createInstance(
        OUString::createFromAscii( "com.sun.star.io.DataInputStream" )),UNO_QUERY);
    Reference< XOutputStream > rOut( m_rSmgr->createInstance(
        OUString::createFromAscii( "com.sun.star.io.DataOutputStream" )),UNO_QUERY);

    rSink->setInputStream( rIn );
    rSource->setOutputStream( rOut );

    rControl->start();

    //wait a second, so that the pumpthread can terminate
    TimeValue w = {1,1};
    osl_waitThread( &w );
}

Reference< XInterface > SAL_CALL OPumpTest_CreateInstance( const Reference< XMultiServiceFactory > & rSMgr ) throw( Exception )
{
    return *new OPumpTest( rSMgr );
}

Sequence<OUString> OPumpTest_getSupportedServiceNames(void) throw()
{
    OUString s = OPumpTest_getServiceName();
    Sequence< OUString > seq( &s , 1 );
    return seq;

}
OUString     OPumpTest_getServiceName() throw()
{
    return OUString( RTL_CONSTASCII_USTRINGPARAM( "test.com.sun.star.io.Pump" ) );
}

OUString    OPumpTest_getImplementationName() throw()
{
    return OUString( RTL_CONSTASCII_USTRINGPARAM( "test.com.sun.star.comp.io.Pump") );
}
<|endoftext|>


<commit_before>/* -*- 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 <tools/tempfile.hxx>
#include "comdep.hxx"

#include <rtl/ustring.hxx>
#include <rtl/ustrbuf.hxx>
#include <osl/file.hxx>
#include <rtl/instance.hxx>
#include <tools/time.hxx>
#include <tools/debug.hxx>

#include <stdio.h>

using namespace osl;

namespace { struct TempNameBase_Impl : public rtl::Static< ::rtl::OUString, TempNameBase_Impl > {}; }

struct TempFile_Impl
{
    String      aName;
};

OUString ConstructTempDir_Impl()
{
    // use system directory
    ::rtl::OUString& rTempNameBase_Impl = TempNameBase_Impl::get();
    if ( rTempNameBase_Impl.isEmpty() )
        osl::FileBase::getTempDirURL( rTempNameBase_Impl );
    OUString aName = rTempNameBase_Impl;

    // Make sure that directory ends with a separator
    if( !aName.endsWith( "/" ) )
        aName += "/";

    return aName;
}

void CreateTempName_Impl( String& rName, sal_Bool bKeep, sal_Bool bDir = sal_True )
{
    // add a suitable tempname
    // Prefix can have 5 chars, leaving 3 for numbers. 26 ** 3 == 17576
    // ER 13.07.00  why not radix 36 [0-9A-Z] ?!?
    const unsigned nRadix = 26;
    String aName( rName );
    aName += rtl::OUString("sv");

    rName.Erase();
    static unsigned long u = Time::GetSystemTicks();
    for ( unsigned long nOld = u; ++u != nOld; )
    {
        u %= (nRadix*nRadix*nRadix);
        rtl::OUString aTmp = rtl::OUStringBuffer(aName).
            append((sal_Int32)(unsigned)u, nRadix).
            append(".tmp").
            makeStringAndClear();

        if ( bDir )
        {
            FileBase::RC err = Directory::create( aTmp );
            if (  err == FileBase::E_None )
            {
                // !bKeep: only for creating a name, not a file or directory
                if ( bKeep || Directory::remove( aTmp ) == FileBase::E_None )
                    rName = aTmp;
                break;
            }
            else if ( err != FileBase::E_EXIST )
            {
                // if f.e. name contains invalid chars stop trying to create dirs
                break;
            }
        }
        else
        {
            DBG_ASSERT( bKeep, "Too expensive, use directory for creating name!" );
            File aFile( aTmp );
            FileBase::RC err = aFile.open(osl_File_OpenFlag_Create);
            if (  err == FileBase::E_None )
            {
                rName = aTmp;
                aFile.close();
                break;
            }
            else if ( err != FileBase::E_EXIST )
            {
                 // if f.e. name contains invalid chars stop trying to create files
                 break;
            }
        }
    }
}

String TempFile::CreateTempName()
{
    // get correct directory
    String aName = ConstructTempDir_Impl();

    // get TempFile name with default naming scheme
    CreateTempName_Impl( aName, sal_False );

    return aName;
}

TempFile::TempFile()
    : pImp( new TempFile_Impl )
    , bKillingFileEnabled( sal_False )
{
    // get correct directory
    pImp->aName = ConstructTempDir_Impl();

    // get TempFile with default naming scheme
    CreateTempName_Impl( pImp->aName, sal_True );
}

TempFile::TempFile( const String& rLeadingChars, const String* pExtension )
    : pImp( new TempFile_Impl )
    , bKillingFileEnabled( sal_False )
{
    // get correct directory
    String aName = ConstructTempDir_Impl();

    // now use special naming scheme ( name takes leading chars and an index counting up from zero
    aName += rLeadingChars;
    for ( sal_Int32 i=0;; i++ )
    {
        rtl::OUStringBuffer aTmpBuffer(aName);
        aTmpBuffer.append(i);
        if ( pExtension )
            aTmpBuffer.append(*pExtension);
        else
            aTmpBuffer.append(".tmp");
        rtl::OUString aTmp = aTmpBuffer.makeStringAndClear();

        File aFile( aTmp );
        FileBase::RC err = aFile.open(osl_File_OpenFlag_Create);
        if ( err == FileBase::E_None )
        {
            pImp->aName = aTmp;
            aFile.close();
            break;
        }
        else if ( err != FileBase::E_EXIST )
            // if f.e. name contains invalid chars stop trying to create dirs
            break;
    }
}

TempFile::~TempFile()
{
    if ( bKillingFileEnabled )
    {
        File::remove( pImp->aName );
    }

    delete pImp;
}

String TempFile::GetName() const
{
    rtl::OUString aTmp;
    aTmp = pImp->aName;
    return aTmp;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>tools: TempFile: create a file in ctor, not a directory<commit_after>/* -*- 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 <tools/tempfile.hxx>
#include "comdep.hxx"

#include <rtl/ustring.hxx>
#include <rtl/ustrbuf.hxx>
#include <osl/file.hxx>
#include <rtl/instance.hxx>
#include <tools/time.hxx>
#include <tools/debug.hxx>

#include <stdio.h>

using namespace osl;

namespace { struct TempNameBase_Impl : public rtl::Static< ::rtl::OUString, TempNameBase_Impl > {}; }

struct TempFile_Impl
{
    String      aName;
};

OUString ConstructTempDir_Impl()
{
    // use system directory
    ::rtl::OUString& rTempNameBase_Impl = TempNameBase_Impl::get();
    if ( rTempNameBase_Impl.isEmpty() )
        osl::FileBase::getTempDirURL( rTempNameBase_Impl );
    OUString aName = rTempNameBase_Impl;

    // Make sure that directory ends with a separator
    if( !aName.endsWith( "/" ) )
        aName += "/";

    return aName;
}

void CreateTempName_Impl( String& rName, sal_Bool bKeep, sal_Bool bDir = sal_True )
{
    // add a suitable tempname
    // Prefix can have 5 chars, leaving 3 for numbers. 26 ** 3 == 17576
    // ER 13.07.00  why not radix 36 [0-9A-Z] ?!?
    const unsigned nRadix = 26;
    String aName( rName );
    aName += rtl::OUString("sv");

    rName.Erase();
    static unsigned long u = Time::GetSystemTicks();
    for ( unsigned long nOld = u; ++u != nOld; )
    {
        u %= (nRadix*nRadix*nRadix);
        rtl::OUString aTmp = rtl::OUStringBuffer(aName).
            append((sal_Int32)(unsigned)u, nRadix).
            append(".tmp").
            makeStringAndClear();

        if ( bDir )
        {
            FileBase::RC err = Directory::create( aTmp );
            if (  err == FileBase::E_None )
            {
                // !bKeep: only for creating a name, not a file or directory
                if ( bKeep || Directory::remove( aTmp ) == FileBase::E_None )
                    rName = aTmp;
                break;
            }
            else if ( err != FileBase::E_EXIST )
            {
                // if f.e. name contains invalid chars stop trying to create dirs
                break;
            }
        }
        else
        {
            DBG_ASSERT( bKeep, "Too expensive, use directory for creating name!" );
            File aFile( aTmp );
            FileBase::RC err = aFile.open(osl_File_OpenFlag_Create);
            if (  err == FileBase::E_None )
            {
                rName = aTmp;
                aFile.close();
                break;
            }
            else if ( err != FileBase::E_EXIST )
            {
                 // if f.e. name contains invalid chars stop trying to create files
                 break;
            }
        }
    }
}

String TempFile::CreateTempName()
{
    // get correct directory
    String aName = ConstructTempDir_Impl();

    // get TempFile name with default naming scheme
    CreateTempName_Impl( aName, sal_False );

    return aName;
}

TempFile::TempFile()
    : pImp( new TempFile_Impl )
    , bKillingFileEnabled( sal_False )
{
    // get correct directory
    pImp->aName = ConstructTempDir_Impl();

    // get TempFile with default naming scheme
    CreateTempName_Impl( pImp->aName, sal_True, false );
}

TempFile::TempFile( const String& rLeadingChars, const String* pExtension )
    : pImp( new TempFile_Impl )
    , bKillingFileEnabled( sal_False )
{
    // get correct directory
    String aName = ConstructTempDir_Impl();

    // now use special naming scheme ( name takes leading chars and an index counting up from zero
    aName += rLeadingChars;
    for ( sal_Int32 i=0;; i++ )
    {
        rtl::OUStringBuffer aTmpBuffer(aName);
        aTmpBuffer.append(i);
        if ( pExtension )
            aTmpBuffer.append(*pExtension);
        else
            aTmpBuffer.append(".tmp");
        rtl::OUString aTmp = aTmpBuffer.makeStringAndClear();

        File aFile( aTmp );
        FileBase::RC err = aFile.open(osl_File_OpenFlag_Create);
        if ( err == FileBase::E_None )
        {
            pImp->aName = aTmp;
            aFile.close();
            break;
        }
        else if ( err != FileBase::E_EXIST )
            // if f.e. name contains invalid chars stop trying to create dirs
            break;
    }
}

TempFile::~TempFile()
{
    if ( bKillingFileEnabled )
    {
        File::remove( pImp->aName );
    }

    delete pImp;
}

String TempFile::GetName() const
{
    rtl::OUString aTmp;
    aTmp = pImp->aName;
    return aTmp;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/*
 * Copyright 2021 The Imaging Source Europe GmbH
 *
 * Licensed 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
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "indexer.h"

Device to_device(GstDevice* device)
{
    GstStructure* struc = gst_device_get_properties(device);
    gchar* display_name = gst_device_get_display_name(device);
    g_free(display_name);
    if (!struc)
    {
        qWarning("No properties to handle.\n");
        gst_object_unref(device);
        return Device();
    }

    GstCaps* caps = gst_device_get_caps(device);

    std::string name;
    const char* name_str = gst_structure_get_string(struc, "model");

    if (name_str)
    {
        name = name_str;
    }

    std::string serial;
    const char* serial_str = gst_structure_get_string(struc, "serial");

    if (serial_str)
    {
        serial = serial_str;
    }

    std::string type;
    const char* type_str = gst_structure_get_string(struc, "type");

    if (type_str)
    {
        type = type_str;
    }
    else
    {
        type = "unknown";
    }

    Device ret(name, serial, type, caps);

    gst_structure_free(struc);
    gst_caps_unref(caps);
    return ret;
}

gboolean Indexer::bus_function(GstBus* /*bus*/, GstMessage* message, gpointer user_data)
{
    GstDevice* device;
    Indexer* self = static_cast<Indexer*>(user_data);

    switch (GST_MESSAGE_TYPE(message))
    {
        case GST_MESSAGE_DEVICE_ADDED:
        {
            gst_message_parse_device_added(message, &device);
            auto dev = to_device(device);
            emit self->new_device(dev);
            self->m_mutex.lock();
            self->m_device_list.push_back(dev);
            self->m_mutex.unlock();
            gst_object_unref(device);
            break;
        }
        case GST_MESSAGE_DEVICE_REMOVED:
        {
            gst_message_parse_device_removed(message, &device);
            Device dev = to_device(device);

            self->m_mutex.lock();

            self->m_device_list.erase(std::remove_if(self->m_device_list.begin(),
                                                    self->m_device_list.end(),
                                                    [&dev](const Device& d) {
                                                        if (dev == d)
                                                        {
                                                            return true;
                                                        }
                                                        return false;
                                                    }),
                                     self->m_device_list.end());

            self->m_mutex.unlock();
            qInfo("Device lost: %s", dev.serial_long().c_str());
            emit self->device_lost(dev);
            gst_object_unref(device);
            break;
        }
        default:
        {
            break;
        }
    }

    return G_SOURCE_CONTINUE;
}

Indexer::Indexer()
{

    p_monitor = gst_device_monitor_new();

    GstBus* bus = gst_device_monitor_get_bus(p_monitor);
    gst_bus_add_watch(bus, &Indexer::bus_function, this);
    gst_object_unref(bus);

    gst_device_monitor_add_filter(p_monitor, "Video/Source/tcam", NULL);
    gst_device_monitor_start(p_monitor);
}

Indexer::~Indexer()
{
    gst_device_monitor_stop(p_monitor);

    gst_object_unref(p_monitor);
}

std::vector<Device> Indexer::get_device_list()
{
    QMutexLocker lock(&m_mutex);
    return m_device_list;
}

void Indexer::update()
{}
<commit_msg>tcam-capture: Retrieve complete device list before listening to events<commit_after>/*
 * Copyright 2021 The Imaging Source Europe GmbH
 *
 * Licensed 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
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "indexer.h"

Device to_device(GstDevice* device)
{
    GstStructure* struc = gst_device_get_properties(device);
    gchar* display_name = gst_device_get_display_name(device);
    g_free(display_name);
    if (!struc)
    {
        qWarning("No properties to handle.\n");
        gst_object_unref(device);
        return Device();
    }

    GstCaps* caps = gst_device_get_caps(device);

    std::string name;
    const char* name_str = gst_structure_get_string(struc, "model");

    if (name_str)
    {
        name = name_str;
    }

    std::string serial;
    const char* serial_str = gst_structure_get_string(struc, "serial");

    if (serial_str)
    {
        serial = serial_str;
    }

    std::string type;
    const char* type_str = gst_structure_get_string(struc, "type");

    if (type_str)
    {
        type = type_str;
    }
    else
    {
        type = "unknown";
    }

    Device ret(name, serial, type, caps);

    gst_structure_free(struc);
    gst_caps_unref(caps);
    return ret;
}

gboolean Indexer::bus_function(GstBus* /*bus*/, GstMessage* message, gpointer user_data)
{
    GstDevice* device;
    Indexer* self = static_cast<Indexer*>(user_data);

    switch (GST_MESSAGE_TYPE(message))
    {
        case GST_MESSAGE_DEVICE_ADDED:
        {
            gst_message_parse_device_added(message, &device);
            auto dev = to_device(device);

            if (std::none_of(self->m_device_list.begin(), self->m_device_list.end(),
                             [&dev](const Device& vec_dev)
                             {
                                 if (vec_dev == dev)
                                 {
                                     return false;
                                 }
                                 return true;
                             }))
            {
                emit self->new_device(dev);
                self->m_mutex.lock();

                self->m_device_list.push_back(dev);

                self->m_mutex.unlock();
            }
            gst_object_unref(device);
            break;
        }
        case GST_MESSAGE_DEVICE_REMOVED:
        {
            gst_message_parse_device_removed(message, &device);
            Device dev = to_device(device);

            self->m_mutex.lock();

            self->m_device_list.erase(std::remove_if(self->m_device_list.begin(),
                                                    self->m_device_list.end(),
                                                    [&dev](const Device& d) {
                                                        if (dev == d)
                                                        {
                                                            return true;
                                                        }
                                                        return false;
                                                    }),
                                     self->m_device_list.end());

            self->m_mutex.unlock();
            qInfo("Device lost: %s", dev.serial_long().c_str());
            emit self->device_lost(dev);
            gst_object_unref(device);
            break;
        }
        default:
        {
            break;
        }
    }

    return G_SOURCE_CONTINUE;
}

Indexer::Indexer()
{

    p_monitor = gst_device_monitor_new();

    GstBus* bus = gst_device_monitor_get_bus(p_monitor);
    gst_bus_add_watch(bus, &Indexer::bus_function, this);
    gst_object_unref(bus);

    gst_device_monitor_add_filter(p_monitor, "Video/Source/tcam", NULL);

    GList* devices = gst_device_monitor_get_devices(p_monitor);

    m_device_list.reserve(g_list_length(devices));
    for (GList* entry = devices; entry != nullptr; entry = entry->next)
    {
        GstDevice* dev = (GstDevice*)entry->data;

        auto device = to_device(dev);

        m_device_list.push_back(device);
    }

    g_list_free(devices);

    for (const auto& dev : m_device_list)
    {
        emit new_device(dev);
    }

    gst_device_monitor_start(p_monitor);
}

Indexer::~Indexer()
{
    gst_device_monitor_stop(p_monitor);

    gst_object_unref(p_monitor);
}

std::vector<Device> Indexer::get_device_list()
{
    QMutexLocker lock(&m_mutex);
    return m_device_list;
}

void Indexer::update()
{}
<|endoftext|>


<commit_before>/*
 * Very basic Telepathy-Qt <-> Telepathy-Farsight integration.
 *
 * Copyright (C) 2008-2009 Collabora Ltd. <http://www.collabora.co.uk/>
 * Copyright (C) 2009 Nokia Corporation
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "farsight-channel.h"
#include "_gen/farsight-channel.moc.hpp"

#include <QDebug>

#include <telepathy-farsight/channel.h>
#include <telepathy-glib/channel.h>
#include <telepathy-glib/connection.h>
#include <telepathy-glib/dbus.h>
#include <TelepathyQt4/Client/Connection>
#include <TelepathyQt4/Client/StreamedMediaChannel>

namespace Telepathy {
namespace Client {

struct FarsightChannel::Private
{
    Private(FarsightChannel *parent, StreamedMediaChannel *channel);
    ~Private();

    static gboolean busWatch(GstBus *bus,
            GstMessage *message, FarsightChannel::Private *self);
    static void onClosed(TfChannel *tfChannel,
            FarsightChannel::Private *self);
    static void onSessionCreated(TfChannel *tfChannel,
            FsConference *conference, FsParticipant *participant,
            FarsightChannel::Private *self);
    static void onStreamCreated(TfChannel *tfChannel,
            TfStream *stream, FarsightChannel::Private *self);
    static void onSrcPadAdded(TfStream *stream,
            GstPad *pad, FsCodec *codec, FarsightChannel::Private *self);
    static gboolean onRequestResource(TfStream *stream,
            guint direction, gpointer data);

    FarsightChannel *parent;
    StreamedMediaChannel *channel;
    Status status;
    TfChannel *tfChannel;
    GstBus *bus;
    GstElement *pipeline;
    GstElement *audio_input;
    GstElement *audio_output;
};

FarsightChannel::Private::Private(FarsightChannel *parent,
        StreamedMediaChannel *channel)
    : parent(parent),
      channel(channel),
      status(StatusDisconnected),
      tfChannel(0),
      bus(0),
      pipeline(0),
      audio_input(0),
      audio_output(0)
{
    TpDBusDaemon *dbus = tp_dbus_daemon_dup(0);
    if (!dbus) {
        qWarning() << "Unable to connect to D-Bus";
        return;
    }

    Connection *connection = channel->connection();

    TpConnection *gconnection = tp_connection_new(dbus,
            connection->busName().toAscii(),
            connection->objectPath().toAscii(),
            0);
    g_object_unref(dbus);
    dbus = 0;

    if (!gconnection) {
        qWarning() << "Unable to construct TpConnection";
        return;
    }

    TpChannel *gchannel = tp_channel_new(gconnection,
            channel->objectPath().toAscii(),
            TELEPATHY_INTERFACE_CHANNEL_TYPE_STREAMED_MEDIA,
            (TpHandleType) channel->targetHandleType(),
            channel->targetHandle(),
            0);
    g_object_unref(gconnection);
    gconnection = 0;

    if (!gchannel) {
        qWarning() << "Unable to construct TpChannel";
        return;
    }

    tfChannel = tf_channel_new(gchannel);
    g_object_unref(gchannel);
    gchannel = 0;

    if (!tfChannel) {
        qWarning() << "Unable to construct TfChannel";
        return;
    }

    /* Set up the telepathy farsight channel */
    g_signal_connect(tfChannel, "closed",
        G_CALLBACK(&FarsightChannel::Private::onClosed), this);
    g_signal_connect(tfChannel, "session-created",
        G_CALLBACK(&FarsightChannel::Private::onSessionCreated), this);
    g_signal_connect(tfChannel, "stream-created",
        G_CALLBACK(&FarsightChannel::Private::onStreamCreated), this);

    pipeline = gst_pipeline_new (NULL);
    bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));

    audio_input = gst_element_factory_make("gconfaudiosrc", NULL);
    gst_object_ref(audio_input);
    gst_object_sink(audio_input);

    audio_output = gst_bin_new("bin");
    GstElement *resample = gst_element_factory_make("audioresample", NULL);
    GstElement *audio_sink = gst_element_factory_make("gconfaudiosink", NULL);
    gst_bin_add_many(GST_BIN(audio_output), resample, audio_sink, NULL);
    gst_element_link_many(resample, audio_sink, NULL);
    GstPad *sink = gst_element_get_static_pad(resample, "sink");
    GstPad *ghost = gst_ghost_pad_new("sink", sink);
    gst_element_add_pad(GST_ELEMENT(audio_output), ghost);
    gst_object_unref(G_OBJECT(sink));
    gst_object_ref(audio_output);
    gst_object_sink(audio_output);

    gst_element_set_state(pipeline, GST_STATE_PLAYING);

    status = StatusConnecting;
    emit parent->statusChanged(status);
}

FarsightChannel::Private::~Private()
{
    if (tfChannel) {
        g_object_unref(tfChannel);
        tfChannel = 0;
    }

    if (bus) {
        g_object_unref(bus);
        bus = 0;
    }

    gst_element_set_state(pipeline, GST_STATE_NULL);

    if (pipeline) {
        g_object_unref(pipeline);
        pipeline = 0;
    }

    if (audio_input) {
        g_object_unref(audio_input);
        audio_input = 0;
    }

    if (audio_output) {
        g_object_unref(audio_output);
        audio_output = 0;
    }
}

gboolean FarsightChannel::Private::busWatch(GstBus *bus,
        GstMessage *message, FarsightChannel::Private *self)
{
    tf_channel_bus_message(self->tfChannel, message);
    return TRUE;
}

void FarsightChannel::Private::onClosed(TfChannel *tfChannel,
        FarsightChannel::Private *self)
{
    self->status = StatusDisconnected;
    emit self->parent->statusChanged(self->status);
}

void FarsightChannel::Private::onSessionCreated(TfChannel *tfChannel,
        FsConference *conference, FsParticipant *participant,
        FarsightChannel::Private *self)
{
    gst_bus_add_watch(self->bus,
            (GstBusFunc) &FarsightChannel::Private::busWatch, self);

    gst_bin_add(GST_BIN(self->pipeline), GST_ELEMENT(conference));
    gst_element_set_state(GST_ELEMENT(conference), GST_STATE_PLAYING);
}

void FarsightChannel::Private::onStreamCreated(TfChannel *tfChannel,
        TfStream *stream, FarsightChannel::Private *self)
{
    guint media_type;
    GstPad *sink;

    g_signal_connect(stream, "src-pad-added",
        G_CALLBACK(&FarsightChannel::Private::onSrcPadAdded), self);
    g_signal_connect(stream, "request-resource",
        G_CALLBACK(&FarsightChannel::Private::onRequestResource), NULL);

    g_object_get(stream, "media-type", &media_type,
            "sink-pad", &sink, NULL);

    GstPad *pad;
    switch (media_type) {
    case TP_MEDIA_STREAM_TYPE_AUDIO:
        gst_bin_add(GST_BIN(self->pipeline), self->audio_input);
        gst_element_set_state(self->audio_input, GST_STATE_PLAYING);

        pad = gst_element_get_static_pad(self->audio_input, "src");
        gst_pad_link(pad, sink);
        break;
    case TP_MEDIA_STREAM_TYPE_VIDEO:
        // TODO
        break;
    default:
        Q_ASSERT(false);
    }

    gst_object_unref(sink);
}

void FarsightChannel::Private::onSrcPadAdded(TfStream *stream,
        GstPad *src, FsCodec *codec, FarsightChannel::Private *self)
{
    guint media_type;

    g_object_get(stream, "media-type", &media_type, NULL);

    GstPad *pad;
    GstElement *element = 0;

    switch (media_type) {
    case TP_MEDIA_STREAM_TYPE_AUDIO:
        element = self->audio_output;
        g_object_ref(element);
        break;
    case TP_MEDIA_STREAM_TYPE_VIDEO:
        // TODO
        return;
        break;
    default:
        Q_ASSERT(false);
    }

    gst_bin_add(GST_BIN(self->pipeline), element);

    pad = gst_element_get_static_pad(element, "sink");
    gst_element_set_state(element, GST_STATE_PLAYING);

    gst_pad_link(src, pad);

    self->status = StatusConnected;
    emit self->parent->statusChanged(self->status);
}

gboolean FarsightChannel::Private::onRequestResource(TfStream *stream,
        guint direction, gpointer data)
{
    return TRUE;
}

FarsightChannel::FarsightChannel(StreamedMediaChannel *channel, QObject *parent)
    : QObject(parent),
      mPriv(new Private(this, channel))
{
}

FarsightChannel::~FarsightChannel()
{
    delete mPriv;
}

}
}
<commit_msg>call example: Fixed farsight-channel coding style.<commit_after>/*
 * Very basic Telepathy-Qt <-> Telepathy-Farsight integration.
 *
 * Copyright (C) 2008-2009 Collabora Ltd. <http://www.collabora.co.uk/>
 * Copyright (C) 2009 Nokia Corporation
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "farsight-channel.h"
#include "_gen/farsight-channel.moc.hpp"

#include <QDebug>

#include <telepathy-farsight/channel.h>
#include <telepathy-glib/channel.h>
#include <telepathy-glib/connection.h>
#include <telepathy-glib/dbus.h>
#include <TelepathyQt4/Client/Connection>
#include <TelepathyQt4/Client/StreamedMediaChannel>

namespace Telepathy {
namespace Client {

struct FarsightChannel::Private
{
    Private(FarsightChannel *parent, StreamedMediaChannel *channel);
    ~Private();

    static gboolean busWatch(GstBus *bus,
            GstMessage *message, FarsightChannel::Private *self);
    static void onClosed(TfChannel *tfChannel,
            FarsightChannel::Private *self);
    static void onSessionCreated(TfChannel *tfChannel,
            FsConference *conference, FsParticipant *participant,
            FarsightChannel::Private *self);
    static void onStreamCreated(TfChannel *tfChannel,
            TfStream *stream, FarsightChannel::Private *self);
    static void onSrcPadAdded(TfStream *stream,
            GstPad *pad, FsCodec *codec, FarsightChannel::Private *self);
    static gboolean onRequestResource(TfStream *stream,
            guint direction, gpointer data);

    FarsightChannel *parent;
    StreamedMediaChannel *channel;
    Status status;
    TfChannel *tfChannel;
    GstBus *bus;
    GstElement *pipeline;
    GstElement *audioInput;
    GstElement *audioOutput;
};

FarsightChannel::Private::Private(FarsightChannel *parent,
        StreamedMediaChannel *channel)
    : parent(parent),
      channel(channel),
      status(StatusDisconnected),
      tfChannel(0),
      bus(0),
      pipeline(0),
      audioInput(0),
      audioOutput(0)
{
    TpDBusDaemon *dbus = tp_dbus_daemon_dup(0);
    if (!dbus) {
        qWarning() << "Unable to connect to D-Bus";
        return;
    }

    Connection *connection = channel->connection();

    TpConnection *gconnection = tp_connection_new(dbus,
            connection->busName().toAscii(),
            connection->objectPath().toAscii(),
            0);
    g_object_unref(dbus);
    dbus = 0;

    if (!gconnection) {
        qWarning() << "Unable to construct TpConnection";
        return;
    }

    TpChannel *gchannel = tp_channel_new(gconnection,
            channel->objectPath().toAscii(),
            TELEPATHY_INTERFACE_CHANNEL_TYPE_STREAMED_MEDIA,
            (TpHandleType) channel->targetHandleType(),
            channel->targetHandle(),
            0);
    g_object_unref(gconnection);
    gconnection = 0;

    if (!gchannel) {
        qWarning() << "Unable to construct TpChannel";
        return;
    }

    tfChannel = tf_channel_new(gchannel);
    g_object_unref(gchannel);
    gchannel = 0;

    if (!tfChannel) {
        qWarning() << "Unable to construct TfChannel";
        return;
    }

    /* Set up the telepathy farsight channel */
    g_signal_connect(tfChannel, "closed",
        G_CALLBACK(&FarsightChannel::Private::onClosed), this);
    g_signal_connect(tfChannel, "session-created",
        G_CALLBACK(&FarsightChannel::Private::onSessionCreated), this);
    g_signal_connect(tfChannel, "stream-created",
        G_CALLBACK(&FarsightChannel::Private::onStreamCreated), this);

    pipeline = gst_pipeline_new(NULL);
    bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));

    audioInput = gst_element_factory_make("gconfaudiosrc", NULL);
    gst_object_ref(audioInput);
    gst_object_sink(audioInput);

    audioOutput = gst_bin_new("bin");
    GstElement *resample = gst_element_factory_make("audioresample", NULL);
    GstElement *audioSink = gst_element_factory_make("gconfaudiosink", NULL);
    gst_bin_add_many(GST_BIN(audioOutput), resample, audioSink, NULL);
    gst_element_link_many(resample, audioSink, NULL);
    GstPad *sink = gst_element_get_static_pad(resample, "sink");
    GstPad *ghost = gst_ghost_pad_new("sink", sink);
    gst_element_add_pad(GST_ELEMENT(audioOutput), ghost);
    gst_object_unref(G_OBJECT(sink));
    gst_object_ref(audioOutput);
    gst_object_sink(audioOutput);

    gst_element_set_state(pipeline, GST_STATE_PLAYING);

    status = StatusConnecting;
    emit parent->statusChanged(status);
}

FarsightChannel::Private::~Private()
{
    if (tfChannel) {
        g_object_unref(tfChannel);
        tfChannel = 0;
    }

    if (bus) {
        g_object_unref(bus);
        bus = 0;
    }

    gst_element_set_state(pipeline, GST_STATE_NULL);

    if (pipeline) {
        g_object_unref(pipeline);
        pipeline = 0;
    }

    if (audioInput) {
        g_object_unref(audioInput);
        audioInput = 0;
    }

    if (audioOutput) {
        g_object_unref(audioOutput);
        audioOutput = 0;
    }
}

gboolean FarsightChannel::Private::busWatch(GstBus *bus,
        GstMessage *message, FarsightChannel::Private *self)
{
    tf_channel_bus_message(self->tfChannel, message);
    return TRUE;
}

void FarsightChannel::Private::onClosed(TfChannel *tfChannel,
        FarsightChannel::Private *self)
{
    self->status = StatusDisconnected;
    emit self->parent->statusChanged(self->status);
}

void FarsightChannel::Private::onSessionCreated(TfChannel *tfChannel,
        FsConference *conference, FsParticipant *participant,
        FarsightChannel::Private *self)
{
    gst_bus_add_watch(self->bus,
            (GstBusFunc) &FarsightChannel::Private::busWatch, self);

    gst_bin_add(GST_BIN(self->pipeline), GST_ELEMENT(conference));
    gst_element_set_state(GST_ELEMENT(conference), GST_STATE_PLAYING);
}

void FarsightChannel::Private::onStreamCreated(TfChannel *tfChannel,
        TfStream *stream, FarsightChannel::Private *self)
{
    guint media_type;
    GstPad *sink;

    g_signal_connect(stream, "src-pad-added",
        G_CALLBACK(&FarsightChannel::Private::onSrcPadAdded), self);
    g_signal_connect(stream, "request-resource",
        G_CALLBACK(&FarsightChannel::Private::onRequestResource), NULL);

    g_object_get(stream, "media-type", &media_type,
            "sink-pad", &sink, NULL);

    GstPad *pad;
    switch (media_type) {
    case TP_MEDIA_STREAM_TYPE_AUDIO:
        gst_bin_add(GST_BIN(self->pipeline), self->audioInput);
        gst_element_set_state(self->audioInput, GST_STATE_PLAYING);

        pad = gst_element_get_static_pad(self->audioInput, "src");
        gst_pad_link(pad, sink);
        break;
    case TP_MEDIA_STREAM_TYPE_VIDEO:
        // TODO
        break;
    default:
        Q_ASSERT(false);
    }

    gst_object_unref(sink);
}

void FarsightChannel::Private::onSrcPadAdded(TfStream *stream,
        GstPad *src, FsCodec *codec, FarsightChannel::Private *self)
{
    guint media_type;

    g_object_get(stream, "media-type", &media_type, NULL);

    GstPad *pad;
    GstElement *element = 0;

    switch (media_type) {
    case TP_MEDIA_STREAM_TYPE_AUDIO:
        element = self->audioOutput;
        g_object_ref(element);
        break;
    case TP_MEDIA_STREAM_TYPE_VIDEO:
        // TODO
        return;
        break;
    default:
        Q_ASSERT(false);
    }

    gst_bin_add(GST_BIN(self->pipeline), element);

    pad = gst_element_get_static_pad(element, "sink");
    gst_element_set_state(element, GST_STATE_PLAYING);

    gst_pad_link(src, pad);

    self->status = StatusConnected;
    emit self->parent->statusChanged(self->status);
}

gboolean FarsightChannel::Private::onRequestResource(TfStream *stream,
        guint direction, gpointer data)
{
    return TRUE;
}

FarsightChannel::FarsightChannel(StreamedMediaChannel *channel, QObject *parent)
    : QObject(parent),
      mPriv(new Private(this, channel))
{
}

FarsightChannel::~FarsightChannel()
{
    delete mPriv;
}

}
}
<|endoftext|>


<commit_before>/*
 * Copyright 2013 Real Logic Ltd.
 *
 * Licensed 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
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef _SBE_HPP_
#define _SBE_HPP_

#include <string.h>
#include <stdint.h>
#include <limits.h>
#include <stdexcept>

/*
 * Types used by C++ codec. Might have to be platform specific at some stage.
 */
typedef char sbe_char_t;
typedef ::int8_t sbe_int8_t;
typedef ::int16_t sbe_int16_t;
typedef ::int32_t sbe_int32_t;
typedef ::int64_t sbe_int64_t;
typedef ::uint8_t sbe_uint8_t;
typedef ::uint16_t sbe_uint16_t;
typedef ::uint32_t sbe_uint32_t;
typedef ::uint64_t sbe_uint64_t;
typedef float sbe_float_t;
typedef double sbe_double_t;

namespace sbe {

/*
 * Define some byte ordering macros
 */
#if defined(WIN32) || defined(_WIN32)
    #define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
    #define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
    #define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
    #define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
    #define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
    #define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
    #define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
    #define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
    #define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
    #define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
    #define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
    #define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
    #define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
    #define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
    #define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
    #define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
    #define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
    #define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
#else
    #error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
#endif

#if defined(SBE_NO_BOUNDS_CHECK)
    #define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
#elif defined(_MSC_VER)
    #define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
#else
    #define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
#endif

#if defined(__GNUC__)
    #define SBE_NULLVALUE_INT8 (INT8_MIN)
    #define SBE_NULLVALUE_INT16 (INT16_MIN)
    #define SBE_NULLVALUE_INT32 (INT32_MIN)
    #define SBE_NULLVALUE_INT64 (INT64_MIN)
    #define SBE_NULLVALUE_UINT8 (UINT8_MAX)
    #define SBE_NULLVALUE_UINT16 (UINT16_MAX)
    #define SBE_NULLVALUE_UINT32 (UINT32_MAX)
    #define SBE_NULLVALUE_UINT64 (UINT64_MAX)
#elif defined(_MSC_VER)
    // Visual C++ does not handle minimum integer values properly
    // See: http://msdn.microsoft.com/en-us/library/4kh09110.aspx
    #define SBE_NULLVALUE_INT8 (SCHAR_MIN)
    #define SBE_NULLVALUE_INT16 (SHRT_MIN)
    #define SBE_NULLVALUE_INT32 (LONG_MIN)
    #define SBE_NULLVALUE_INT64 (LLONG_MIN)
    #define SBE_NULLVALUE_UINT8 (UCHAR_MAX)
    #define SBE_NULLVALUE_UINT16 (USHRT_MAX)
    #define SBE_NULLVALUE_UINT32 (ULONG_MAX)
    #define SBE_NULLVALUE_UINT64 (ULLONG_MAX)
#else
    #define SBE_NULLVALUE_INT8 (INT8_MIN)
    #define SBE_NULLVALUE_INT16 (INT16_MIN)
    #define SBE_NULLVALUE_INT32 (INT32_MIN)
    #define SBE_NULLVALUE_INT64 (INT64_MIN)
    #define SBE_NULLVALUE_UINT8 (UINT8_MAX)
    #define SBE_NULLVALUE_UINT16 (UINT16_MAX)
    #define SBE_NULLVALUE_UINT32 (UINT32_MAX)
    #define SBE_NULLVALUE_UINT64 (UINT64_MAX)
#endif

namespace MetaAttribute {

enum Attribute
{
    EPOCH,
    TIME_UNIT,
    SEMANTIC_TYPE
};

}

}

#endif /* _SBE_HPP_ */
<commit_msg>[C++]: fix #275. Add __STDC_LIMIT_MACROS before inclusion of stdint.h to comply with C99 requirements.<commit_after>/*
 * Copyright 2013 Real Logic Ltd.
 *
 * Licensed 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
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef _SBE_HPP_
#define _SBE_HPP_

#include <string.h>
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#include <limits.h>
#include <stdexcept>

/*
 * Types used by C++ codec. Might have to be platform specific at some stage.
 */
typedef char sbe_char_t;
typedef ::int8_t sbe_int8_t;
typedef ::int16_t sbe_int16_t;
typedef ::int32_t sbe_int32_t;
typedef ::int64_t sbe_int64_t;
typedef ::uint8_t sbe_uint8_t;
typedef ::uint16_t sbe_uint16_t;
typedef ::uint32_t sbe_uint32_t;
typedef ::uint64_t sbe_uint64_t;
typedef float sbe_float_t;
typedef double sbe_double_t;

namespace sbe {

/*
 * Define some byte ordering macros
 */
#if defined(WIN32) || defined(_WIN32)
    #define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
    #define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
    #define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
    #define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
    #define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
    #define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
    #define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
    #define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
    #define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
    #define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
    #define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
    #define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
    #define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
    #define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
    #define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
    #define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
    #define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
    #define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
#else
    #error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
#endif

#if defined(SBE_NO_BOUNDS_CHECK)
    #define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
#elif defined(_MSC_VER)
    #define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
#else
    #define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
#endif

#if defined(__GNUC__)
    #define SBE_NULLVALUE_INT8 (INT8_MIN)
    #define SBE_NULLVALUE_INT16 (INT16_MIN)
    #define SBE_NULLVALUE_INT32 (INT32_MIN)
    #define SBE_NULLVALUE_INT64 (INT64_MIN)
    #define SBE_NULLVALUE_UINT8 (UINT8_MAX)
    #define SBE_NULLVALUE_UINT16 (UINT16_MAX)
    #define SBE_NULLVALUE_UINT32 (UINT32_MAX)
    #define SBE_NULLVALUE_UINT64 (UINT64_MAX)
#elif defined(_MSC_VER)
    // Visual C++ does not handle minimum integer values properly
    // See: http://msdn.microsoft.com/en-us/library/4kh09110.aspx
    #define SBE_NULLVALUE_INT8 (SCHAR_MIN)
    #define SBE_NULLVALUE_INT16 (SHRT_MIN)
    #define SBE_NULLVALUE_INT32 (LONG_MIN)
    #define SBE_NULLVALUE_INT64 (LLONG_MIN)
    #define SBE_NULLVALUE_UINT8 (UCHAR_MAX)
    #define SBE_NULLVALUE_UINT16 (USHRT_MAX)
    #define SBE_NULLVALUE_UINT32 (ULONG_MAX)
    #define SBE_NULLVALUE_UINT64 (ULLONG_MAX)
#else
    #define SBE_NULLVALUE_INT8 (INT8_MIN)
    #define SBE_NULLVALUE_INT16 (INT16_MIN)
    #define SBE_NULLVALUE_INT32 (INT32_MIN)
    #define SBE_NULLVALUE_INT64 (INT64_MIN)
    #define SBE_NULLVALUE_UINT8 (UINT8_MAX)
    #define SBE_NULLVALUE_UINT16 (UINT16_MAX)
    #define SBE_NULLVALUE_UINT32 (UINT32_MAX)
    #define SBE_NULLVALUE_UINT64 (UINT64_MAX)
#endif

namespace MetaAttribute {

enum Attribute
{
    EPOCH,
    TIME_UNIT,
    SEMANTIC_TYPE
};

}

}

#endif /* _SBE_HPP_ */
<|endoftext|>