<commit_before>/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtSystems 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 <qdisplayinfo.h>

#include <QtGui/qapplication.h>
#include <QtGui/qdesktopwidget.h>

#if defined(Q_OS_LINUX)
#  include "qdisplayinfo_linux_p.h"
#elif defined(Q_OS_WIN)
#  include "qdisplayinfo_win_p.h"
#else
QT_BEGIN_NAMESPACE
class QDisplayInfoPrivate
{
public:
    QDisplayInfoPrivate(QDisplayInfo *) {}

    int brightness(int) { return -1; }
    int colorDepth(int) { return -1; }
    int contrast(int) const { return -1; }
    int dpiX(int) { return -1; }
    int dpiY(int) { return -1; }
    int physicalHeight(int) { return -1; }
    int physicalWidth(int) { return -1; }
    QDisplayInfo::BacklightState backlightState(int) { return QDisplayInfo::BacklightUnknown; }
    QDisplayInfo::Orientation orientation(int) { return QDisplayInfo::OrientationUnknown; }
};
QT_END_NAMESPACE
#endif

QT_BEGIN_NAMESPACE

/*!
    \class QDisplayInfo
    \inmodule QtSystems
    \brief The QDisplayInfo class provides various information of the display.
*/

/*!
    \enum QDisplayInfo::BacklightState
    This enum describes the state of the backlight.

    \value BacklightUnknown     The state of the backlight is unkown.
    \value BacklightOff         Backlight is turned off.
    \value BacklightDimmed      Backlight has been dimmed.
    \value BacklightOn          Backlight is on.
*/

/*!
    \enum QDisplayInfo::Orientation
    This enum describes the orientation of the UI. For orientation of the display, please refer to
    QOrientationSensor and QOrientationReading in the QSensors module.

    \value OrientationUnknown   The orientation is unknown.
    \value Landscape            The orientation is landscape, i.e. the width is bigger than the height.
    \value Portrait             The orientation is portrait, i.e. the height is bigger than the width.
    \value InvertedLandscape    Landscape, but inverted.
    \value InvertedPortrait     Portrait, but inverted.
*/

/*!
    \fn void QDisplayInfo::orientationChanged(int screen, QDisplayInfo::DisplayOrientation orientation)

    This signal is emitted when the orientation of the \a screen has changed to \a orientation.
*/

/*!
    Constructs a QDisplayInfo object with the given \a parent.
*/
QDisplayInfo::QDisplayInfo(QObject *parent)
    : QObject(parent)
    , d_ptr(new QDisplayInfoPrivate(this))
{
}

/*!
    Destroys the object
*/
QDisplayInfo::~QDisplayInfo()
{
    delete d_ptr;
}

/*!
    Returns the display brightness of the given \a screen, in 0 - 100 scale. In case of error or
    the information is not available, -1 is returned.
*/
int QDisplayInfo::brightness(int screen) const
{
    if (screen < 0 || screen >= QApplication::desktop()->screenCount())
        return -1;
    return d_ptr->brightness(screen);
}

/*!
    Returns the color depth of the given \a screen, in bits per pixel. -1 is returned if not
    available or on error.
*/
int QDisplayInfo::colorDepth(int screen) const
{
    if (screen < 0 || screen >= QApplication::desktop()->screenCount())
        return -1;
    return d_ptr->colorDepth(screen);
}

/*!
    Returns the contrast of the given \a screen, in 0 - 100 scale. -1 is returned if not available
    or on error.
*/
int QDisplayInfo::contrast(int screen) const
{
    if (screen < 0 || screen >= QApplication::desktop()->screenCount())
        return -1;
    return d_ptr->contrast(screen);
}

/*!
    Returns the horizontal resolution of the given \a screen in terms of the number of dots per inch.
    -1 is returned if not available or on error.
*/
int QDisplayInfo::dpiX(int screen) const
{
    if (screen < 0 || screen >= QApplication::desktop()->screenCount())
        return -1;
    return d_ptr->dpiX(screen);
}

/*!
    Returns the vertical resolution of the given \a screen in terms of the number of dots per inch.
    -1 is returned if not available or on error.
*/
int QDisplayInfo::dpiY(int screen) const
{
    if (screen < 0 || screen >= QApplication::desktop()->screenCount())
        return -1;
    return d_ptr->dpiY(screen);
}

/*!
    Returns the physical height of the \a screen in millimeters. -1 is returned if not available
    or on error.
*/
int QDisplayInfo::physicalHeight(int screen) const
{
    if (screen < 0 || screen >= QApplication::desktop()->screenCount())
        return -1;
    return d_ptr->physicalHeight(screen);
}

/*!
    Returns the physical width of \a screen in millimeters. -1 is returned if not available or
    on error.
*/
int QDisplayInfo::physicalWidth(int screen) const
{
    if (screen < 0 || screen >= QApplication::desktop()->screenCount())
        return -1;
    return d_ptr->physicalWidth(screen);
}

/*!
    Returns the backlight state of the given \a screen.
*/
QDisplayInfo::BacklightState QDisplayInfo::backlightState(int screen) const
{
    if (screen < 0 || screen >= QApplication::desktop()->screenCount())
        return QDisplayInfo::BacklightUnknown;
    return d_ptr->backlightState(screen);
}

/*!
    Returns the orientation of the given \a screen.
*/
QDisplayInfo::Orientation QDisplayInfo::orientation(int screen) const
{
    QDisplayInfo::Orientation orient = d_ptr->orientation(screen);
    if (orient != QDisplayInfo::OrientationUnknown) {
        return orient;
    } else {
        QWidget *widget = qApp->desktop()->screen(screen);
        if (widget->width() > widget->height())
            return QDisplayInfo::Landscape;
        else if (widget->width() < widget->height())
            return QDisplayInfo::Portrait;
        else
            return QDisplayInfo::OrientationUnknown;
    }
}

QT_END_NAMESPACE
<commit_msg>Update docs for orientation.<commit_after>/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtSystems 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 <qdisplayinfo.h>

#include <QtGui/qapplication.h>
#include <QtGui/qdesktopwidget.h>

#if defined(Q_OS_LINUX)
#  include "qdisplayinfo_linux_p.h"
#elif defined(Q_OS_WIN)
#  include "qdisplayinfo_win_p.h"
#else
QT_BEGIN_NAMESPACE
class QDisplayInfoPrivate
{
public:
    QDisplayInfoPrivate(QDisplayInfo *) {}

    int brightness(int) { return -1; }
    int colorDepth(int) { return -1; }
    int contrast(int) const { return -1; }
    int dpiX(int) { return -1; }
    int dpiY(int) { return -1; }
    int physicalHeight(int) { return -1; }
    int physicalWidth(int) { return -1; }
    QDisplayInfo::BacklightState backlightState(int) { return QDisplayInfo::BacklightUnknown; }
    QDisplayInfo::Orientation orientation(int) { return QDisplayInfo::OrientationUnknown; }
};
QT_END_NAMESPACE
#endif

QT_BEGIN_NAMESPACE

/*!
    \class QDisplayInfo
    \inmodule QtSystems
    \brief The QDisplayInfo class provides various information of the display.
*/

/*!
    \enum QDisplayInfo::BacklightState
    This enum describes the state of the backlight.

    \value BacklightUnknown     The state of the backlight is unkown.
    \value BacklightOff         Backlight is turned off.
    \value BacklightDimmed      Backlight has been dimmed.
    \value BacklightOn          Backlight is on.
*/

/*!
    \enum QDisplayInfo::Orientation
    This enum describes the orientation of the window system. Note that if the UI of an application
    is rotated through methods other than talking with the window system, its orientation can't be
    correctly reported by QDisplayInfo.

    For orientation of the display, please refer to QOrientationSensor and QOrientationReading in
    the QtSensors module.

    \value OrientationUnknown   The orientation is unknown.
    \value Landscape            The orientation is landscape, i.e. the width is bigger than the height.
    \value Portrait             The orientation is portrait, i.e. the height is bigger than the width.
    \value InvertedLandscape    Landscape, but inverted.
    \value InvertedPortrait     Portrait, but inverted.
*/

/*!
    \fn void QDisplayInfo::orientationChanged(int screen, QDisplayInfo::DisplayOrientation orientation)

    This signal is emitted when the orientation of the \a screen has changed to \a orientation.
*/

/*!
    Constructs a QDisplayInfo object with the given \a parent.
*/
QDisplayInfo::QDisplayInfo(QObject *parent)
    : QObject(parent)
    , d_ptr(new QDisplayInfoPrivate(this))
{
}

/*!
    Destroys the object
*/
QDisplayInfo::~QDisplayInfo()
{
    delete d_ptr;
}

/*!
    Returns the display brightness of the given \a screen, in 0 - 100 scale. In case of error or
    the information is not available, -1 is returned.
*/
int QDisplayInfo::brightness(int screen) const
{
    if (screen < 0 || screen >= QApplication::desktop()->screenCount())
        return -1;
    return d_ptr->brightness(screen);
}

/*!
    Returns the color depth of the given \a screen, in bits per pixel. -1 is returned if not
    available or on error.
*/
int QDisplayInfo::colorDepth(int screen) const
{
    if (screen < 0 || screen >= QApplication::desktop()->screenCount())
        return -1;
    return d_ptr->colorDepth(screen);
}

/*!
    Returns the contrast of the given \a screen, in 0 - 100 scale. -1 is returned if not available
    or on error.
*/
int QDisplayInfo::contrast(int screen) const
{
    if (screen < 0 || screen >= QApplication::desktop()->screenCount())
        return -1;
    return d_ptr->contrast(screen);
}

/*!
    Returns the horizontal resolution of the given \a screen in terms of the number of dots per inch.
    -1 is returned if not available or on error.
*/
int QDisplayInfo::dpiX(int screen) const
{
    if (screen < 0 || screen >= QApplication::desktop()->screenCount())
        return -1;
    return d_ptr->dpiX(screen);
}

/*!
    Returns the vertical resolution of the given \a screen in terms of the number of dots per inch.
    -1 is returned if not available or on error.
*/
int QDisplayInfo::dpiY(int screen) const
{
    if (screen < 0 || screen >= QApplication::desktop()->screenCount())
        return -1;
    return d_ptr->dpiY(screen);
}

/*!
    Returns the physical height of the \a screen in millimeters. -1 is returned if not available
    or on error.
*/
int QDisplayInfo::physicalHeight(int screen) const
{
    if (screen < 0 || screen >= QApplication::desktop()->screenCount())
        return -1;
    return d_ptr->physicalHeight(screen);
}

/*!
    Returns the physical width of \a screen in millimeters. -1 is returned if not available or
    on error.
*/
int QDisplayInfo::physicalWidth(int screen) const
{
    if (screen < 0 || screen >= QApplication::desktop()->screenCount())
        return -1;
    return d_ptr->physicalWidth(screen);
}

/*!
    Returns the backlight state of the given \a screen.
*/
QDisplayInfo::BacklightState QDisplayInfo::backlightState(int screen) const
{
    if (screen < 0 || screen >= QApplication::desktop()->screenCount())
        return QDisplayInfo::BacklightUnknown;
    return d_ptr->backlightState(screen);
}

/*!
    Returns the orientation of the given \a screen.
*/
QDisplayInfo::Orientation QDisplayInfo::orientation(int screen) const
{
    QDisplayInfo::Orientation orient = d_ptr->orientation(screen);
    if (orient != QDisplayInfo::OrientationUnknown) {
        return orient;
    } else {
        QWidget *widget = qApp->desktop()->screen(screen);
        if (widget->width() > widget->height())
            return QDisplayInfo::Landscape;
        else if (widget->width() < widget->height())
            return QDisplayInfo::Portrait;
        else
            return QDisplayInfo::OrientationUnknown;
    }
}

QT_END_NAMESPACE
<|endoftext|>


<commit_before>// Copyright (c) 2017-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <consensus/validation.h>
#include <key_io.h>
#include <policy/packages.h>
#include <policy/policy.h>
#include <primitives/transaction.h>
#include <script/script.h>
#include <script/standard.h>
#include <test/util/setup_common.h>
#include <validation.h>

#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_SUITE(txvalidation_tests)

/**
 * Ensure that the mempool won't accept coinbase transactions.
 */
BOOST_FIXTURE_TEST_CASE(tx_mempool_reject_coinbase, TestChain100Setup)
{
    CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
    CMutableTransaction coinbaseTx;

    coinbaseTx.nVersion = 1;
    coinbaseTx.vin.resize(1);
    coinbaseTx.vout.resize(1);
    coinbaseTx.vin[0].scriptSig = CScript() << OP_11 << OP_EQUAL;
    coinbaseTx.vout[0].nValue = 1 * CENT;
    coinbaseTx.vout[0].scriptPubKey = scriptPubKey;

    BOOST_CHECK(CTransaction(coinbaseTx).IsCoinBase());

    LOCK(cs_main);

    unsigned int initialPoolSize = m_node.mempool->size();
    const MempoolAcceptResult result = AcceptToMemoryPool(m_node.chainman->ActiveChainstate(), *m_node.mempool, MakeTransactionRef(coinbaseTx),
                true /* bypass_limits */);

    BOOST_CHECK(result.m_result_type == MempoolAcceptResult::ResultType::INVALID);

    // Check that the transaction hasn't been added to mempool.
    BOOST_CHECK_EQUAL(m_node.mempool->size(), initialPoolSize);

    // Check that the validation state reflects the unsuccessful attempt.
    BOOST_CHECK(result.m_state.IsInvalid());
    BOOST_CHECK_EQUAL(result.m_state.GetRejectReason(), "coinbase");
    BOOST_CHECK(result.m_state.GetResult() == TxValidationResult::TX_CONSENSUS);
}

// Create placeholder transactions that have no meaning.
inline CTransactionRef create_placeholder_tx(size_t num_inputs, size_t num_outputs)
{
    CMutableTransaction mtx = CMutableTransaction();
    mtx.vin.resize(num_inputs);
    mtx.vout.resize(num_outputs);
    auto random_script = CScript() << ToByteVector(InsecureRand256()) << ToByteVector(InsecureRand256());
    for (size_t i{0}; i < num_inputs; ++i) {
        mtx.vin[i].prevout.hash = InsecureRand256();
        mtx.vin[i].prevout.n = 0;
        mtx.vin[i].scriptSig = random_script;
    }
    for (size_t o{0}; o < num_outputs; ++o) {
        mtx.vout[o].nValue = 1 * CENT;
        mtx.vout[o].scriptPubKey = random_script;
    }
    return MakeTransactionRef(mtx);
}

BOOST_FIXTURE_TEST_CASE(package_tests, TestChain100Setup)
{
    LOCK(cs_main);
    unsigned int initialPoolSize = m_node.mempool->size();

    // Parent and Child Package
    CKey parent_key;
    parent_key.MakeNewKey(true);
    CScript parent_locking_script = GetScriptForDestination(PKHash(parent_key.GetPubKey()));
    auto mtx_parent = CreateValidMempoolTransaction(/* input_transaction */ m_coinbase_txns[0], /* vout */ 0,
                                                    /* input_height */ 0, /* input_signing_key */ coinbaseKey,
                                                    /* output_destination */ parent_locking_script,
                                                    /* output_amount */ CAmount(49 * COIN), /* submit */ false);
    CTransactionRef tx_parent = MakeTransactionRef(mtx_parent);

    CKey child_key;
    child_key.MakeNewKey(true);
    CScript child_locking_script = GetScriptForDestination(PKHash(child_key.GetPubKey()));
    auto mtx_child = CreateValidMempoolTransaction(/* input_transaction */ tx_parent, /* vout */ 0,
                                                   /* input_height */ 101, /* input_signing_key */ parent_key,
                                                   /* output_destination */ child_locking_script,
                                                   /* output_amount */ CAmount(48 * COIN), /* submit */ false);
    CTransactionRef tx_child = MakeTransactionRef(mtx_child);
    const auto result_parent_child = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, {tx_parent, tx_child}, /* test_accept */ true);
    BOOST_CHECK_MESSAGE(result_parent_child.m_state.IsValid(),
                        "Package validation unexpectedly failed: " << result_parent_child.m_state.GetRejectReason());
    auto it_parent = result_parent_child.m_tx_results.find(tx_parent->GetWitnessHash());
    auto it_child = result_parent_child.m_tx_results.find(tx_child->GetWitnessHash());
    BOOST_CHECK(it_parent != result_parent_child.m_tx_results.end());
    BOOST_CHECK_MESSAGE(it_parent->second.m_state.IsValid(),
                        "Package validation unexpectedly failed: " << it_parent->second.m_state.GetRejectReason());
    BOOST_CHECK(it_child != result_parent_child.m_tx_results.end());
    BOOST_CHECK_MESSAGE(it_child->second.m_state.IsValid(),
                        "Package validation unexpectedly failed: " << it_child->second.m_state.GetRejectReason());

    // Packages can't have more than 25 transactions.
    Package package_too_many;
    package_too_many.reserve(MAX_PACKAGE_COUNT + 1);
    for (size_t i{0}; i < MAX_PACKAGE_COUNT + 1; ++i) {
        package_too_many.emplace_back(create_placeholder_tx(1, 1));
    }
    auto result_too_many = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package_too_many, /* test_accept */ true);
    BOOST_CHECK(result_too_many.m_state.IsInvalid());
    BOOST_CHECK_EQUAL(result_too_many.m_state.GetResult(), PackageValidationResult::PCKG_POLICY);
    BOOST_CHECK_EQUAL(result_too_many.m_state.GetRejectReason(), "package-too-many-transactions");

    // Packages can't have a total size of more than 101KvB.
    CTransactionRef large_ptx = create_placeholder_tx(150, 150);
    Package package_too_large;
    auto size_large = GetVirtualTransactionSize(*large_ptx);
    size_t total_size{0};
    while (total_size <= MAX_PACKAGE_SIZE * 1000) {
        package_too_large.push_back(large_ptx);
        total_size += size_large;
    }
    BOOST_CHECK(package_too_large.size() <= MAX_PACKAGE_COUNT);
    auto result_too_large = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package_too_large, /* test_accept */ true);
    BOOST_CHECK(result_too_large.m_state.IsInvalid());
    BOOST_CHECK_EQUAL(result_too_large.m_state.GetResult(), PackageValidationResult::PCKG_POLICY);
    BOOST_CHECK_EQUAL(result_too_large.m_state.GetRejectReason(), "package-too-large");

    // A single, giant transaction submitted through ProcessNewPackage fails on single tx policy.
    CTransactionRef giant_ptx = create_placeholder_tx(999, 999);
    BOOST_CHECK(GetVirtualTransactionSize(*giant_ptx) > MAX_PACKAGE_SIZE * 1000);
    auto result_single_large = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, {giant_ptx}, /* test_accept */ true);
    BOOST_CHECK(result_single_large.m_state.IsInvalid());
    BOOST_CHECK_EQUAL(result_single_large.m_state.GetResult(), PackageValidationResult::PCKG_TX);
    BOOST_CHECK_EQUAL(result_single_large.m_state.GetRejectReason(), "transaction failed");
    auto it_giant_tx = result_single_large.m_tx_results.find(giant_ptx->GetWitnessHash());
    BOOST_CHECK(it_giant_tx != result_single_large.m_tx_results.end());
    BOOST_CHECK_EQUAL(it_giant_tx->second.m_state.GetRejectReason(), "tx-size");

    // Check that mempool size hasn't changed.
    BOOST_CHECK_EQUAL(m_node.mempool->size(), initialPoolSize);
}
BOOST_AUTO_TEST_SUITE_END()
<commit_msg>[test] Don't set bypass_limits to true in txvalidation_tests.cpp<commit_after>// Copyright (c) 2017-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <consensus/validation.h>
#include <key_io.h>
#include <policy/packages.h>
#include <policy/policy.h>
#include <primitives/transaction.h>
#include <script/script.h>
#include <script/standard.h>
#include <test/util/setup_common.h>
#include <validation.h>

#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_SUITE(txvalidation_tests)

/**
 * Ensure that the mempool won't accept coinbase transactions.
 */
BOOST_FIXTURE_TEST_CASE(tx_mempool_reject_coinbase, TestChain100Setup)
{
    CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
    CMutableTransaction coinbaseTx;

    coinbaseTx.nVersion = 1;
    coinbaseTx.vin.resize(1);
    coinbaseTx.vout.resize(1);
    coinbaseTx.vin[0].scriptSig = CScript() << OP_11 << OP_EQUAL;
    coinbaseTx.vout[0].nValue = 1 * CENT;
    coinbaseTx.vout[0].scriptPubKey = scriptPubKey;

    BOOST_CHECK(CTransaction(coinbaseTx).IsCoinBase());

    LOCK(cs_main);

    unsigned int initialPoolSize = m_node.mempool->size();
    const MempoolAcceptResult result = AcceptToMemoryPool(m_node.chainman->ActiveChainstate(), *m_node.mempool, MakeTransactionRef(coinbaseTx),
                false /* bypass_limits */);

    BOOST_CHECK(result.m_result_type == MempoolAcceptResult::ResultType::INVALID);

    // Check that the transaction hasn't been added to mempool.
    BOOST_CHECK_EQUAL(m_node.mempool->size(), initialPoolSize);

    // Check that the validation state reflects the unsuccessful attempt.
    BOOST_CHECK(result.m_state.IsInvalid());
    BOOST_CHECK_EQUAL(result.m_state.GetRejectReason(), "coinbase");
    BOOST_CHECK(result.m_state.GetResult() == TxValidationResult::TX_CONSENSUS);
}

// Create placeholder transactions that have no meaning.
inline CTransactionRef create_placeholder_tx(size_t num_inputs, size_t num_outputs)
{
    CMutableTransaction mtx = CMutableTransaction();
    mtx.vin.resize(num_inputs);
    mtx.vout.resize(num_outputs);
    auto random_script = CScript() << ToByteVector(InsecureRand256()) << ToByteVector(InsecureRand256());
    for (size_t i{0}; i < num_inputs; ++i) {
        mtx.vin[i].prevout.hash = InsecureRand256();
        mtx.vin[i].prevout.n = 0;
        mtx.vin[i].scriptSig = random_script;
    }
    for (size_t o{0}; o < num_outputs; ++o) {
        mtx.vout[o].nValue = 1 * CENT;
        mtx.vout[o].scriptPubKey = random_script;
    }
    return MakeTransactionRef(mtx);
}

BOOST_FIXTURE_TEST_CASE(package_tests, TestChain100Setup)
{
    LOCK(cs_main);
    unsigned int initialPoolSize = m_node.mempool->size();

    // Parent and Child Package
    CKey parent_key;
    parent_key.MakeNewKey(true);
    CScript parent_locking_script = GetScriptForDestination(PKHash(parent_key.GetPubKey()));
    auto mtx_parent = CreateValidMempoolTransaction(/* input_transaction */ m_coinbase_txns[0], /* vout */ 0,
                                                    /* input_height */ 0, /* input_signing_key */ coinbaseKey,
                                                    /* output_destination */ parent_locking_script,
                                                    /* output_amount */ CAmount(49 * COIN), /* submit */ false);
    CTransactionRef tx_parent = MakeTransactionRef(mtx_parent);

    CKey child_key;
    child_key.MakeNewKey(true);
    CScript child_locking_script = GetScriptForDestination(PKHash(child_key.GetPubKey()));
    auto mtx_child = CreateValidMempoolTransaction(/* input_transaction */ tx_parent, /* vout */ 0,
                                                   /* input_height */ 101, /* input_signing_key */ parent_key,
                                                   /* output_destination */ child_locking_script,
                                                   /* output_amount */ CAmount(48 * COIN), /* submit */ false);
    CTransactionRef tx_child = MakeTransactionRef(mtx_child);
    const auto result_parent_child = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, {tx_parent, tx_child}, /* test_accept */ true);
    BOOST_CHECK_MESSAGE(result_parent_child.m_state.IsValid(),
                        "Package validation unexpectedly failed: " << result_parent_child.m_state.GetRejectReason());
    auto it_parent = result_parent_child.m_tx_results.find(tx_parent->GetWitnessHash());
    auto it_child = result_parent_child.m_tx_results.find(tx_child->GetWitnessHash());
    BOOST_CHECK(it_parent != result_parent_child.m_tx_results.end());
    BOOST_CHECK_MESSAGE(it_parent->second.m_state.IsValid(),
                        "Package validation unexpectedly failed: " << it_parent->second.m_state.GetRejectReason());
    BOOST_CHECK(it_child != result_parent_child.m_tx_results.end());
    BOOST_CHECK_MESSAGE(it_child->second.m_state.IsValid(),
                        "Package validation unexpectedly failed: " << it_child->second.m_state.GetRejectReason());

    // Packages can't have more than 25 transactions.
    Package package_too_many;
    package_too_many.reserve(MAX_PACKAGE_COUNT + 1);
    for (size_t i{0}; i < MAX_PACKAGE_COUNT + 1; ++i) {
        package_too_many.emplace_back(create_placeholder_tx(1, 1));
    }
    auto result_too_many = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package_too_many, /* test_accept */ true);
    BOOST_CHECK(result_too_many.m_state.IsInvalid());
    BOOST_CHECK_EQUAL(result_too_many.m_state.GetResult(), PackageValidationResult::PCKG_POLICY);
    BOOST_CHECK_EQUAL(result_too_many.m_state.GetRejectReason(), "package-too-many-transactions");

    // Packages can't have a total size of more than 101KvB.
    CTransactionRef large_ptx = create_placeholder_tx(150, 150);
    Package package_too_large;
    auto size_large = GetVirtualTransactionSize(*large_ptx);
    size_t total_size{0};
    while (total_size <= MAX_PACKAGE_SIZE * 1000) {
        package_too_large.push_back(large_ptx);
        total_size += size_large;
    }
    BOOST_CHECK(package_too_large.size() <= MAX_PACKAGE_COUNT);
    auto result_too_large = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package_too_large, /* test_accept */ true);
    BOOST_CHECK(result_too_large.m_state.IsInvalid());
    BOOST_CHECK_EQUAL(result_too_large.m_state.GetResult(), PackageValidationResult::PCKG_POLICY);
    BOOST_CHECK_EQUAL(result_too_large.m_state.GetRejectReason(), "package-too-large");

    // A single, giant transaction submitted through ProcessNewPackage fails on single tx policy.
    CTransactionRef giant_ptx = create_placeholder_tx(999, 999);
    BOOST_CHECK(GetVirtualTransactionSize(*giant_ptx) > MAX_PACKAGE_SIZE * 1000);
    auto result_single_large = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, {giant_ptx}, /* test_accept */ true);
    BOOST_CHECK(result_single_large.m_state.IsInvalid());
    BOOST_CHECK_EQUAL(result_single_large.m_state.GetResult(), PackageValidationResult::PCKG_TX);
    BOOST_CHECK_EQUAL(result_single_large.m_state.GetRejectReason(), "transaction failed");
    auto it_giant_tx = result_single_large.m_tx_results.find(giant_ptx->GetWitnessHash());
    BOOST_CHECK(it_giant_tx != result_single_large.m_tx_results.end());
    BOOST_CHECK_EQUAL(it_giant_tx->second.m_state.GetRejectReason(), "tx-size");

    // Check that mempool size hasn't changed.
    BOOST_CHECK_EQUAL(m_node.mempool->size(), initialPoolSize);
}
BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>#include <catch.hpp>
#include "../coap-encoder.h"
#include "mc/memory.h"
#include "../coap_transmission.h"
#include "../coap-token.h"
#include "../mc/experimental.h"
#include "coap/encoder.hpp"

#include "exp/netbuf.h"

using namespace moducom::coap;
using namespace moducom::pipeline;

TEST_CASE("CoAP encoder tests", "[coap-encoder]")
{
    typedef Option number_t;

    SECTION("1")
    {
        layer3::MemoryChunk<128> chunk;
        layer3::SimpleBufferedPipelineWriter writer(chunk);
        moducom::coap::experimental::BlockingEncoder encoder(writer);

        encoder.header(Header::Get);

        encoder.option(number_t::ETag, "etag");
        encoder.option(number_t::UriPath, "query");

        encoder.payload("A payload");

        const int option_pos = 4;

        REQUIRE(chunk[option_pos + 0] == 0x44);
        REQUIRE(chunk[option_pos + 5] == 0x75);
        REQUIRE(chunk[option_pos + 6] == 'q');
    }
    SECTION("Experimental encoder")
    {
        layer3::MemoryChunk<128> chunk;
        layer3::SimpleBufferedPipelineWriter writer(chunk);
        moducom::coap::experimental::BufferedEncoder encoder(writer);
        Header& header = *encoder.header();
        moducom::coap::layer1::Token& token = *encoder.token();

        header.token_length(2);
        header.type(Header::Confirmable);
        header.code(Header::Get);
        header.message_id(0xAA);

        token[0] = 1;
        token[1] = 2;

        encoder.option(number_t::UriPath,
                       moducom::pipeline::MemoryChunk((uint8_t*)"Test", 4));

        moducom::pipeline::MemoryChunk chunk2 = encoder.payload();

        int l = sprintf((char*)chunk2.data(), "Guess we'll do it directly %s.", "won't we");

        // remove null terminator
        encoder.advance(l - 1);
        //encoder.payload("Now for something completely different");

        encoder.complete();

        const int option_pos = 5;

//#if !defined (__APPLE__)
        // FIX: on MBP QTcreator this fails
        REQUIRE(chunk[4] == 1);
        REQUIRE(chunk[5] == 2);
        REQUIRE(chunk[option_pos + 6] == 0xFF);
//#endif
    }
    // TODO: Move this to more proper test file location
    SECTION("Read Only Memory Buffer")
    {
        // TODO: Make a layer2::string merely to be a wrapper around const char*
        MemoryChunk::readonly_t str = MemoryChunk::readonly_t::str_ptr("Test");

        REQUIRE(str.length() == 4);
    }
    SECTION("NetBuf encoder")
    {
        typedef moducom::io::experimental::layer2::NetBufMemoryWriter<256> netbuf_t;
        netbuf_t netbuf;
        MemoryChunk chunk = netbuf.chunk();
        Header header;
        NetBufEncoder<netbuf_t&> encoder(netbuf);
        Option::Numbers n = Option::UriPath;

        encoder.header(header);
        encoder.option(n, MemoryChunk((uint8_t*)"test", 4));

        netbuf_t& w = encoder.netbuf();

        // Header + option "header" of size 1 + option_value of 4
        size_t expected_msg_size = 4 + 1 + 4;

        // TODO: Make a distinctive netbuf length_written vs length_free, right now
        // length() represents amount available in current 'PBUF'
        REQUIRE(netbuf.length() + expected_msg_size == chunk.length());

        encoder.option(n, std::string("test2"));

        // option "header" of size 1 + option_value of size 5
        expected_msg_size += (1 + 5);

        REQUIRE(netbuf.length() + expected_msg_size == chunk.length());
    }
}
<commit_msg>Finding some glitches in netbuf and/or memchunk<commit_after>#include <catch.hpp>
#include "../coap-encoder.h"
#include "mc/memory.h"
#include "../coap_transmission.h"
#include "../coap-token.h"
#include "../mc/experimental.h"
#include "coap/encoder.hpp"

#include "exp/netbuf.h"

using namespace moducom::coap;
using namespace moducom::pipeline;

TEST_CASE("CoAP encoder tests", "[coap-encoder]")
{
    typedef Option number_t;

    SECTION("1")
    {
        layer3::MemoryChunk<128> chunk;
        layer3::SimpleBufferedPipelineWriter writer(chunk);
        moducom::coap::experimental::BlockingEncoder encoder(writer);

        encoder.header(Header::Get);

        encoder.option(number_t::ETag, "etag");
        encoder.option(number_t::UriPath, "query");

        encoder.payload("A payload");

        const int option_pos = 4;

        REQUIRE(chunk[option_pos + 0] == 0x44);
        REQUIRE(chunk[option_pos + 5] == 0x75);
        REQUIRE(chunk[option_pos + 6] == 'q');
    }
    SECTION("Experimental encoder")
    {
        layer3::MemoryChunk<128> chunk;
        layer3::SimpleBufferedPipelineWriter writer(chunk);
        moducom::coap::experimental::BufferedEncoder encoder(writer);
        Header& header = *encoder.header();
        moducom::coap::layer1::Token& token = *encoder.token();

        header.token_length(2);
        header.type(Header::Confirmable);
        header.code(Header::Get);
        header.message_id(0xAA);

        token[0] = 1;
        token[1] = 2;

        encoder.option(number_t::UriPath,
                       moducom::pipeline::MemoryChunk((uint8_t*)"Test", 4));

        moducom::pipeline::MemoryChunk chunk2 = encoder.payload();

        int l = sprintf((char*)chunk2.data(), "Guess we'll do it directly %s.", "won't we");

        // remove null terminator
        encoder.advance(l - 1);
        //encoder.payload("Now for something completely different");

        encoder.complete();

        const int option_pos = 5;

//#if !defined (__APPLE__)
        // FIX: on MBP QTcreator this fails
        REQUIRE(chunk[4] == 1);
        REQUIRE(chunk[5] == 2);
        REQUIRE(chunk[option_pos + 6] == 0xFF);
//#endif
    }
    // TODO: Move this to more proper test file location
    SECTION("Read Only Memory Buffer")
    {
        // TODO: Make a layer2::string merely to be a wrapper around const char*
        MemoryChunk::readonly_t str = MemoryChunk::readonly_t::str_ptr("Test");

        REQUIRE(str.length() == 4);
    }
    SECTION("NetBuf encoder")
    {
        typedef moducom::io::experimental::layer2::NetBufMemoryWriter<256> netbuf_t;
        netbuf_t netbuf;
        // FIX: netbuf.chunk() broken in this context in that the data
        // it's inspecting appears to not be the netbuf_t buffer.  length is correct
        MemoryChunk chunk = netbuf.chunk();
        //const moducom::pipeline::layer1::MemoryChunk<256>& chunk = netbuf.chunk();
        const uint8_t* data = netbuf.data();

        Header header;
        NetBufEncoder<netbuf_t&> encoder(netbuf);
        Option::Numbers n = Option::UriPath;

        encoder.header(header);
        encoder.option(n, MemoryChunk((uint8_t*)"test", 4));

        netbuf_t& w = encoder.netbuf();

        // Header + option "header" of size 1 + option_value of 4
        size_t expected_msg_size = 4 + 1 + 4;

        // TODO: Make a distinctive netbuf length_written vs length_free, right now
        // length() represents amount available in current 'PBUF'
        REQUIRE(netbuf.length() + expected_msg_size == chunk.length());
        REQUIRE(0xB4 == data[4]); // option 11, length 4
        //REQUIRE(0xB4 == chunk.data()[4]); // option 11, length 4

        encoder.option(n, std::string("test2"));

        // option "header" of size 1 + option_value of size 5
        expected_msg_size += (1 + 5);

        REQUIRE(netbuf.length() + expected_msg_size == chunk.length());
    }
}
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright  2007, Casey Langen
//
// Sources and Binaries of: win32cpp
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//    * Redistributions of source code must retain the above copyright notice,
//      this list of conditions and the following disclaimer.
//
//    * Redistributions in binary form must reproduce the above copyright
//      notice, this list of conditions and the following disclaimer in the
//      documentation and/or other materials provided with the distribution.
//
//    * Neither the name of the author nor the names of other contributors may
//      be used to endorse or promote products derived from this software
//      without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////

#include <pch.hpp>
#include <win32cpp/Win32Config.hpp>
#include <win32cpp/TopLevelWindow.hpp>
#include <win32cpp/Types.hpp>
#include <win32cpp/MemoryDC.hpp>
#include <win32cpp/Application.hpp>
#include <win32cpp/Color.hpp>

//////////////////////////////////////////////////////////////////////////////

using namespace win32cpp;

//////////////////////////////////////////////////////////////////////////////

#define CLASS_NAME _T("win32cpp TopLevelWindow")

///\brief Constructor.
///
///\param windowTitle
///The title that will be displayed in the title bar..
/*ctor*/    TopLevelWindow::TopLevelWindow(const uichar* windowTitle)
: base()
, windowTitle(windowTitle)
, minSize(0, 0)
, closed(false)
, modalChild(NULL)
, parentWindow(NULL)
{
}

/*dtor*/    TopLevelWindow::~TopLevelWindow()
{
}

bool        TopLevelWindow::RegisterWindowClass()
{
    static bool registered  = false;

    if ( ! registered)
    {
        WNDCLASSEX wc = { 0 };

        // register the window class
        wc.cbSize        = sizeof(WNDCLASSEX);
        wc.style         = 0;
        wc.lpfnWndProc   = Window::StaticWindowProc;
        wc.cbClsExtra    = 0;
        wc.cbWndExtra    = 0;
        wc.hInstance     = Application::Instance();
        wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
        wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);
        wc.lpszMenuName  = NULL;
        wc.lpszClassName = CLASS_NAME;
        wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

        registered = (::RegisterClassEx(&wc) != 0);
    }

    return registered;
}

HWND        TopLevelWindow::Create(Window* parent)
{
    HINSTANCE hInstance = Application::Instance();
    HWND parentHWND = (parent ? parent->Handle() : NULL);

    if ( ! TopLevelWindow::RegisterWindowClass())
    {
        return NULL;
    }

    // create the window
    DWORD style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
    DWORD styleEx = NULL;
    //
    HWND hwnd = ::CreateWindowEx(
        styleEx,                    // ExStyle
        CLASS_NAME,                 // Class name
        this->windowTitle.c_str(),  // Window name
        style,                      // Style
        CW_USEDEFAULT,              // X
        CW_USEDEFAULT,              // Y
        240,                        // Width
        120,                        // Height
        parentHWND,                 // Parent
        NULL,                       // Menu
        hInstance,                  // Instance
        NULL);                      // lParam

    return hwnd;
}

///\brief Sets the minimum size of the window.
///\param size The minimium size.
void        TopLevelWindow::SetMinimumSize(const Size& size)
{
    this->minSize = size;

    Size currentSize = this->WindowSize();
    if (currentSize.width < size.width) currentSize.width = size.width;
    if (currentSize.height < size.height) currentSize.height = size.height;

    this->Resize(currentSize);
}

///\brief Returns the minimum size of the window.
Size        TopLevelWindow::MinimumSize() const
{
    return this->minSize;
}

///\brief Closes the TopLevelWindow
void        TopLevelWindow::Close()
{
    this->SendMessage(WM_CLOSE, NULL, NULL);
}

LRESULT     TopLevelWindow::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
    if(this == Application::Instance().MainWindow()) {
        Application::Instance().SysTrayManager()->WindowProc(this->Handle(), message, wParam, lParam);
    }

    switch (message)
    {
    case WM_SIZE:
        {
            Size size(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
            this->OnResizedBase(size);
        }
        return 0;

    case WM_DESTROY:
        {
            // Destroy handler is used together with ShowModal
            // According to http://msdn.microsoft.com/en-us/library/ms646291.aspx
            // we need to do:
            // "A window must be enabled before it can be activated. For example,
            //  if an application is displaying a modeless dialog box and has disabled
            //  its main window, the application must enable the main window before
            //  destroying the dialog box. Otherwise, another window will receive the
            //  keyboard focus and be activated."
            if(this->parentWindow) {
                this->parentWindow->Enable(true);
                SetForegroundWindow(this->parentWindow->Handle());
                BringWindowToTop(this->parentWindow->Handle());

                this->parentWindow = NULL;
            }
        }
        break;

    case WM_CLOSE:
        {
            this->closed = true;
        }
        break;

    case WM_PRINTCLIENT:
        {
            HDC hdc = (HDC) wParam;
            RECT rcClient = this->ClientRect();

            HBRUSH bgBrush = ::CreateSolidBrush(this->BackgroundColor());
            ::FillRect(hdc, &rcClient, bgBrush);
            ::DeleteObject(bgBrush);
        }
        return 0;

    case WM_GETMINMAXINFO:
        {
            MINMAXINFO* minMaxInfo = reinterpret_cast<MINMAXINFO*>(lParam);
            minMaxInfo->ptMinTrackSize.x = this->minSize.width;
            minMaxInfo->ptMinTrackSize.y = this->minSize.height;
        }
        return 0;
    }

    return base::WindowProc(message, wParam, lParam);
}

void        TopLevelWindow::OnRequestFocusNext()
{
    bool focusChildSuccess = false;

    // if we're on the last focused item, loop back around to the first.
    if ((this->focusedWindow != NULL)
    &&  (this->focusedWindow == this->childWindows.back()))
    {
        focusChildSuccess = this->FocusFirstChild();
    }

    // we weren't able to focus the next child, so notify the parent.
    if ( ! focusChildSuccess)
    {
        base::OnRequestFocusNext();
    }
}

void        TopLevelWindow::OnRequestFocusPrev()
{
    bool focusChildSuccess = false;

    // if we're on the first focused item, jump to the last.
    if ((this->focusedWindow != NULL)
    &&  (this->focusedWindow == this->childWindows.front()))
    {
        focusChildSuccess = this->FocusLastChild();
    }

    // we weren't able to focus the next child, so notify the parent.
    if ( ! focusChildSuccess)
    {
        base::OnRequestFocusPrev();
    }
}

void        TopLevelWindow::OnEraseBackground(HDC hdc)
{
    // do nothing.
}

void        TopLevelWindow::OnPaint()
{
    PAINTSTRUCT paintStruct;
    RECT clientRect = this->ClientRect();
    HDC hdc = ::BeginPaint(this->Handle(), &paintStruct);
    //
    {
        MemoryDC memDC(hdc, clientRect);

        HBRUSH backBrush = ::CreateSolidBrush(this->BackgroundColor());
        ::FillRect(memDC, &clientRect, backBrush);
        DeleteObject(backBrush);

        this->DefaultWindowProc(WM_PAINT, (WPARAM) (HDC) memDC, NULL);
    }
    //
    ::EndPaint(this->Handle(), &paintStruct);
}

void        TopLevelWindow::ShowModal(TopLevelWindow* parent)
{
    if (this->closed)
    {
        throw WindowAlreadyClosedException();
    }

    if ( ! this->Handle())
    {
        this->Initialize(parent);
    }

    if (parent)
    {
        parent->modalChild = this;

        // Disable keyboard/mouse input on the parent window,
        // this also means it gets deactivated (NOT in foreground)
        parent->Enable(false);

        // Remember the parent window
        this->parentWindow = parent;
    }

    try
    {
        // center the child dialog over the parent
        if (parent)
        {
            Point location(0, 0);
            RECT parentRect;
            ::GetWindowRect(parent->windowHandle, &parentRect);

            Size thisSize = this->WindowSize();
            location.x = (parentRect.left + parentRect.right) / 2 - thisSize.width / 2;
            location.y = (parentRect.top + parentRect.bottom) / 2 - thisSize.height / 2;

            this->MoveTo(location);
        }

        // removes the dialog from the titlebar
        ::SetWindowLong(this->Handle(), GWL_STYLE, WS_CAPTION | WS_SYSMENU | WS_THICKFRAME);
        this->Show(SW_SHOW);

        bool shouldQuit = false;
        MSG msg;
        while (( ! shouldQuit) && (::GetMessage(&msg, NULL, 0, 0) > 0))
        {
            if (msg.message == WM_QUIT)
            {
                shouldQuit = true;
                ::PostQuitMessage(0);
                break;
            }

            ::TranslateMessage(&msg);
            ::DispatchMessage(&msg);

            shouldQuit |= this->closed;
        }
    }
    catch (Exception e)
    {
        // TODO: log me
    }

    if (parent)
    {
        parent->modalChild = NULL;
    }

    if (this->parentWindow) {
        this->parentWindow = NULL;
    }
}

void                TopLevelWindow::OnGainedFocus()
{
    if (this->modalChild)
    {
        this->modalChild->SetFocus();
    }
}

TopLevelWindow*     TopLevelWindow::FindFromAncestor(Window* window)
{
    Window* topLevelWindow = window->Parent(), *scratch = NULL;
    while ((topLevelWindow) && (scratch = topLevelWindow->Parent()))
    {
        topLevelWindow = scratch;
    }

    return dynamic_cast<TopLevelWindow*>(topLevelWindow);
}
<commit_msg>BUGFIX: Fixed Window Centering for new TopLevelWindows<commit_after>//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright  2007, Casey Langen
//
// Sources and Binaries of: win32cpp
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//    * Redistributions of source code must retain the above copyright notice,
//      this list of conditions and the following disclaimer.
//
//    * Redistributions in binary form must reproduce the above copyright
//      notice, this list of conditions and the following disclaimer in the
//      documentation and/or other materials provided with the distribution.
//
//    * Neither the name of the author nor the names of other contributors may
//      be used to endorse or promote products derived from this software
//      without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////

#include <pch.hpp>
#include <win32cpp/Win32Config.hpp>
#include <win32cpp/TopLevelWindow.hpp>
#include <win32cpp/Types.hpp>
#include <win32cpp/MemoryDC.hpp>
#include <win32cpp/Application.hpp>
#include <win32cpp/Color.hpp>

//////////////////////////////////////////////////////////////////////////////

using namespace win32cpp;

//////////////////////////////////////////////////////////////////////////////

#define CLASS_NAME _T("win32cpp TopLevelWindow")

///\brief Constructor.
///
///\param windowTitle
///The title that will be displayed in the title bar..
/*ctor*/    TopLevelWindow::TopLevelWindow(const uichar* windowTitle)
: base()
, windowTitle(windowTitle)
, minSize(0, 0)
, closed(false)
, modalChild(NULL)
, parentWindow(NULL)
{
}

/*dtor*/    TopLevelWindow::~TopLevelWindow()
{
}

bool        TopLevelWindow::RegisterWindowClass()
{
    static bool registered  = false;

    if ( ! registered)
    {
        WNDCLASSEX wc = { 0 };

        // register the window class
        wc.cbSize        = sizeof(WNDCLASSEX);
        wc.style         = 0;
        wc.lpfnWndProc   = Window::StaticWindowProc;
        wc.cbClsExtra    = 0;
        wc.cbWndExtra    = 0;
        wc.hInstance     = Application::Instance();
        wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
        wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);
        wc.lpszMenuName  = NULL;
        wc.lpszClassName = CLASS_NAME;
        wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

        registered = (::RegisterClassEx(&wc) != 0);
    }

    return registered;
}

HWND        TopLevelWindow::Create(Window* parent)
{
    HINSTANCE hInstance = Application::Instance();
    HWND parentHWND = (parent ? parent->Handle() : NULL);

    if ( ! TopLevelWindow::RegisterWindowClass())
    {
        return NULL;
    }

    // create the window
    DWORD style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
    DWORD styleEx = NULL;
    //
    HWND hwnd = ::CreateWindowEx(
        styleEx,                    // ExStyle
        CLASS_NAME,                 // Class name
        this->windowTitle.c_str(),  // Window name
        style,                      // Style
        CW_USEDEFAULT,              // X
        CW_USEDEFAULT,              // Y
        (this->minSize.width) ? this->minSize.width : 240,  // Width
        (this->minSize.height) ? this->minSize.height: 120, // Height
        parentHWND,                 // Parent
        NULL,                       // Menu
        hInstance,                  // Instance
        NULL);                      // lParam

    return hwnd;
}

///\brief Sets the minimum size of the window.
///\param size The minimium size.
void        TopLevelWindow::SetMinimumSize(const Size& size)
{
    this->minSize = size;

    Size currentSize = this->WindowSize();
    if (currentSize.width < size.width) currentSize.width = size.width;
    if (currentSize.height < size.height) currentSize.height = size.height;

    this->Resize(currentSize);
}

///\brief Returns the minimum size of the window.
Size        TopLevelWindow::MinimumSize() const
{
    return this->minSize;
}

///\brief Closes the TopLevelWindow
void        TopLevelWindow::Close()
{
    this->SendMessage(WM_CLOSE, NULL, NULL);
}

LRESULT     TopLevelWindow::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
    if(this == Application::Instance().MainWindow()) {
        Application::Instance().SysTrayManager()->WindowProc(this->Handle(), message, wParam, lParam);
    }

    switch (message)
    {
    case WM_SIZE:
        {
            Size size(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
            this->OnResizedBase(size);
        }
        return 0;

    case WM_DESTROY:
        {
            // Destroy handler is used together with ShowModal
            // According to http://msdn.microsoft.com/en-us/library/ms646291.aspx
            // we need to do:
            // "A window must be enabled before it can be activated. For example,
            //  if an application is displaying a modeless dialog box and has disabled
            //  its main window, the application must enable the main window before
            //  destroying the dialog box. Otherwise, another window will receive the
            //  keyboard focus and be activated."
            if(this->parentWindow) {
                this->parentWindow->Enable(true);
                SetForegroundWindow(this->parentWindow->Handle());
                BringWindowToTop(this->parentWindow->Handle());

                this->parentWindow = NULL;
            }
        }
        break;

    case WM_CLOSE:
        {
            this->closed = true;
        }
        break;

    case WM_PRINTCLIENT:
        {
            HDC hdc = (HDC) wParam;
            RECT rcClient = this->ClientRect();

            HBRUSH bgBrush = ::CreateSolidBrush(this->BackgroundColor());
            ::FillRect(hdc, &rcClient, bgBrush);
            ::DeleteObject(bgBrush);
        }
        return 0;

    case WM_GETMINMAXINFO:
        {
            MINMAXINFO* minMaxInfo = reinterpret_cast<MINMAXINFO*>(lParam);
            minMaxInfo->ptMinTrackSize.x = this->minSize.width;
            minMaxInfo->ptMinTrackSize.y = this->minSize.height;
        }
        return 0;
    }

    return base::WindowProc(message, wParam, lParam);
}

void        TopLevelWindow::OnRequestFocusNext()
{
    bool focusChildSuccess = false;

    // if we're on the last focused item, loop back around to the first.
    if ((this->focusedWindow != NULL)
    &&  (this->focusedWindow == this->childWindows.back()))
    {
        focusChildSuccess = this->FocusFirstChild();
    }

    // we weren't able to focus the next child, so notify the parent.
    if ( ! focusChildSuccess)
    {
        base::OnRequestFocusNext();
    }
}

void        TopLevelWindow::OnRequestFocusPrev()
{
    bool focusChildSuccess = false;

    // if we're on the first focused item, jump to the last.
    if ((this->focusedWindow != NULL)
    &&  (this->focusedWindow == this->childWindows.front()))
    {
        focusChildSuccess = this->FocusLastChild();
    }

    // we weren't able to focus the next child, so notify the parent.
    if ( ! focusChildSuccess)
    {
        base::OnRequestFocusPrev();
    }
}

void        TopLevelWindow::OnEraseBackground(HDC hdc)
{
    // do nothing.
}

void        TopLevelWindow::OnPaint()
{
    PAINTSTRUCT paintStruct;
    RECT clientRect = this->ClientRect();
    HDC hdc = ::BeginPaint(this->Handle(), &paintStruct);
    //
    {
        MemoryDC memDC(hdc, clientRect);

        HBRUSH backBrush = ::CreateSolidBrush(this->BackgroundColor());
        ::FillRect(memDC, &clientRect, backBrush);
        DeleteObject(backBrush);

        this->DefaultWindowProc(WM_PAINT, (WPARAM) (HDC) memDC, NULL);
    }
    //
    ::EndPaint(this->Handle(), &paintStruct);
}

void        TopLevelWindow::ShowModal(TopLevelWindow* parent)
{
    if (this->closed)
    {
        throw WindowAlreadyClosedException();
    }

    if ( ! this->Handle())
    {
        this->Initialize(parent);
    }

    if (parent)
    {
        parent->modalChild = this;

        // Disable keyboard/mouse input on the parent window,
        // this also means it gets deactivated (NOT in foreground)
        parent->Enable(false);

        // Remember the parent window
        this->parentWindow = parent;
    }

    try
    {
        // center the child dialog over the parent
        if (parent)
        {
            Point location(0, 0);
            RECT parentRect;
            ::GetWindowRect(parent->windowHandle, &parentRect);

            Size thisSize = this->WindowSize();
            location.x = (parentRect.left + parentRect.right) / 2 - thisSize.width / 2;
            location.y = (parentRect.top + parentRect.bottom) / 2 - thisSize.height / 2;

            this->MoveTo(location);
        }

        // removes the dialog from the titlebar
        ::SetWindowLong(this->Handle(), GWL_STYLE, WS_CAPTION | WS_SYSMENU | WS_THICKFRAME);
        this->Show(SW_SHOW);

        bool shouldQuit = false;
        MSG msg;
        while (( ! shouldQuit) && (::GetMessage(&msg, NULL, 0, 0) > 0))
        {
            if (msg.message == WM_QUIT)
            {
                shouldQuit = true;
                ::PostQuitMessage(0);
                break;
            }

            ::TranslateMessage(&msg);
            ::DispatchMessage(&msg);

            shouldQuit |= this->closed;
        }
    }
    catch (Exception e)
    {
        // TODO: log me
    }

    if (parent)
    {
        parent->modalChild = NULL;
    }

    if (this->parentWindow) {
        this->parentWindow = NULL;
    }
}

void                TopLevelWindow::OnGainedFocus()
{
    if (this->modalChild)
    {
        this->modalChild->SetFocus();
    }
}

TopLevelWindow*     TopLevelWindow::FindFromAncestor(Window* window)
{
    Window* topLevelWindow = window->Parent(), *scratch = NULL;
    while ((topLevelWindow) && (scratch = topLevelWindow->Parent()))
    {
        topLevelWindow = scratch;
    }

    return dynamic_cast<TopLevelWindow*>(topLevelWindow);
}
<|endoftext|>


<commit_before>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2014 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include <xenia/gpu/gl4/gl4_shader.h>

#include <xenia/gpu/gpu-private.h>

namespace xe {
namespace gpu {
namespace gl4 {

extern "C" GLEWContext* glewGetContext();

GL4Shader::GL4Shader(ShaderType shader_type, uint64_t data_hash,
                     const uint32_t* dword_ptr, uint32_t dword_count)
    : Shader(shader_type, data_hash, dword_ptr, dword_count), program_(0) {}

GL4Shader::~GL4Shader() { glDeleteProgram(program_); }

const std::string header =
    "#version 450\n"
    "#extension all : warn\n"
    "#extension GL_ARB_bindless_texture : require\n"
    "#extension GL_ARB_explicit_uniform_location : require\n"
    "#extension GL_ARB_shading_language_420pack : require\n"
    "#extension GL_ARB_shader_storage_buffer_object : require\n"
    "#extension GL_NV_shader_buffer_load : require\n"
    "precision highp float;\n"
    "precision highp int;\n"
    "layout(std140, column_major) uniform;\n"
    "layout(std430, column_major) buffer;\n"
    "struct StateData {\n"
    "  vec4 window_offset;\n"
    "  vec4 window_scissor;\n"
    "  vec4 viewport_offset;\n"
    "  vec4 viewport_scale;\n"
    "  vec4 alpha_test;\n"
    "  vec4 float_consts[512];\n"
    "  uint fetch_consts[32 * 6];\n"
    "  int bool_consts[8];\n"
    "  int loop_consts[32];\n"
    "};\n"
    "struct VertexData {\n"
    "  vec4 o[16];\n"
    "};\n"
    "\n"
    "uniform StateData* state;\n";

bool GL4Shader::PrepareVertexShader(
    const xenos::xe_gpu_program_cntl_t& program_cntl) {
  if (has_prepared_) {
    return is_valid_;
  }
  has_prepared_ = true;

  std::string apply_viewport =
      "vec4 applyViewport(vec4 pos) {\n"
      // TODO(benvanik): piecewise viewport_enable -> offset/scale logic.
      "  if (false) {\n"
      "  } else {\n"
      /*"    pos.xy = pos.xy / vec2(state->window_offset.z / 2.0, "
      "-state->window_offset.w / 2.0) + vec2(-1.0, 1.0);\n"
      "    pos.zw = vec2(0.0, 1.0);\n"*/
      "    pos.xy = pos.xy / vec2(1280.0 / 2.0, "
      "-720.0 / 2.0) + vec2(-1.0, 1.0);\n"
      "    //pos.zw = vec2(0.0, 1.0);\n"
      "  }\n"
      "  pos.x = pos.x * state->viewport_scale.x + \n"
      "      state->viewport_offset.x;\n"
      "  pos.y = pos.y * state->viewport_scale.y + \n"
      "      state->viewport_offset.y;\n"
      "  pos.z = pos.z * state->viewport_scale.z + \n"
      "      state->viewport_offset.z;\n"
      "  pos.xy += state->window_offset.xy;\n"
      "  return pos;\n"
      "}\n";
  std::string source =
      header + apply_viewport +
      "out gl_PerVertex {\n"
      "  vec4 gl_Position;\n"
      "  float gl_PointSize;\n"
      "  float gl_ClipDistance[];\n"
      "};\n"
      "layout(location = 0) in vec3 iF0;\n"
      "layout(location = 1) in vec4 iF1;\n"
      "layout(location = 0) out VertexData vtx;\n"
      "void main() {\n"
      //"  vec4 oPos = vec4(iF0.xy, 0.0, 1.0);\n"
      "  vec4 oPos = iF0.xxxx * state->float_consts[0];\n"
      "  oPos = (iF0.yyyy * state->float_consts[1]) + oPos;\n"
      "  oPos = (iF0.zzzz * state->float_consts[2]) + oPos;\n"
      "  oPos = (vec4(1.0, 1.0, 1.0, 1.0) * state->float_consts[3]) + oPos;\n"
      //"  gl_PointSize = 1.0;\n"
      "  for (int i = 0; i < vtx.o.length(); ++i) {\n"
      "    vtx.o[0] = vec4(0.0, 0.0, 0.0, 0.0);\n"
      "  }\n"
      "  vtx.o[0] = iF1;\n"
      "  gl_Position = applyViewport(oPos);\n"
      //"  gl_Position = oPos;\n"
      "}\n";

  if (!CompileProgram(source)) {
    return false;
  }

  is_valid_ = true;
  return true;
}

bool GL4Shader::PreparePixelShader(
    const xenos::xe_gpu_program_cntl_t& program_cntl,
    GL4Shader* vertex_shader) {
  if (has_prepared_) {
    return is_valid_;
  }
  has_prepared_ = true;

  std::string source = header +
                       "layout(location = 0) in VertexData vtx;\n"
                       "layout(location = 0) out vec4 oC[4];\n"
                       "void main() {\n"
                       "  for (int i = 0; i < oC.length(); ++i) {\n"
                       "    oC[i] = vec4(1.0, 0.0, 0.0, 1.0);\n"
                       "  }\n"
                       "  oC[0] = vtx.o[0];\n"
                       //"  gl_FragDepth = 0.0;\n"
                       "}\n";

  if (!CompileProgram(source)) {
    return false;
  }

  is_valid_ = true;
  return true;
}

bool GL4Shader::CompileProgram(std::string source) {
  assert_zero(program_);

  translated_disassembly_ = std::move(source);
  const char* source_str = translated_disassembly_.c_str();

  program_ = glCreateShaderProgramv(shader_type_ == ShaderType::kVertex
                                        ? GL_VERTEX_SHADER
                                        : GL_FRAGMENT_SHADER,
                                    1, &source_str);
  if (!program_) {
    PLOGE("Unable to create shader program");
    return false;
  }

  GLint link_status = 0;
  glGetProgramiv(program_, GL_LINK_STATUS, &link_status);
  if (!link_status) {
    // log_length includes the null character.
    GLint log_length = 0;
    glGetProgramiv(program_, GL_INFO_LOG_LENGTH, &log_length);
    std::string info_log;
    info_log.resize(log_length - 1);
    glGetProgramInfoLog(program_, log_length, &log_length,
                        const_cast<char*>(info_log.data()));
    PLOGE("Unable to link program: %s", info_log.c_str());
    error_log_ = std::move(info_log);
    return false;
  }

  return true;
}

}  // namespace gl4
}  // namespace gpu
}  // namespace xe
<commit_msg>--dump_shaders<commit_after>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2014 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include <xenia/gpu/gl4/gl4_shader.h>

#include <poly/math.h>
#include <xenia/gpu/gpu-private.h>

namespace xe {
namespace gpu {
namespace gl4 {

extern "C" GLEWContext* glewGetContext();

GL4Shader::GL4Shader(ShaderType shader_type, uint64_t data_hash,
                     const uint32_t* dword_ptr, uint32_t dword_count)
    : Shader(shader_type, data_hash, dword_ptr, dword_count), program_(0) {}

GL4Shader::~GL4Shader() { glDeleteProgram(program_); }

const std::string header =
    "#version 450\n"
    "#extension all : warn\n"
    "#extension GL_ARB_bindless_texture : require\n"
    "#extension GL_ARB_explicit_uniform_location : require\n"
    "#extension GL_ARB_shading_language_420pack : require\n"
    "#extension GL_ARB_shader_storage_buffer_object : require\n"
    "#extension GL_NV_shader_buffer_load : require\n"
    "precision highp float;\n"
    "precision highp int;\n"
    "layout(std140, column_major) uniform;\n"
    "layout(std430, column_major) buffer;\n"
    "struct StateData {\n"
    "  vec4 window_offset;\n"
    "  vec4 window_scissor;\n"
    "  vec4 viewport_offset;\n"
    "  vec4 viewport_scale;\n"
    "  vec4 alpha_test;\n"
    "  vec4 float_consts[512];\n"
    "  uint fetch_consts[32 * 6];\n"
    "  int bool_consts[8];\n"
    "  int loop_consts[32];\n"
    "};\n"
    "struct VertexData {\n"
    "  vec4 o[16];\n"
    "};\n"
    "\n"
    "uniform StateData* state;\n";

bool GL4Shader::PrepareVertexShader(
    const xenos::xe_gpu_program_cntl_t& program_cntl) {
  if (has_prepared_) {
    return is_valid_;
  }
  has_prepared_ = true;

  std::string apply_viewport =
      "vec4 applyViewport(vec4 pos) {\n"
      // TODO(benvanik): piecewise viewport_enable -> offset/scale logic.
      "  if (false) {\n"
      "  } else {\n"
      /*"    pos.xy = pos.xy / vec2(state->window_offset.z / 2.0, "
      "-state->window_offset.w / 2.0) + vec2(-1.0, 1.0);\n"
      "    pos.zw = vec2(0.0, 1.0);\n"*/
      "    pos.xy = pos.xy / vec2(1280.0 / 2.0, "
      "-720.0 / 2.0) + vec2(-1.0, 1.0);\n"
      "    //pos.zw = vec2(0.0, 1.0);\n"
      "  }\n"
      "  pos.x = pos.x * state->viewport_scale.x + \n"
      "      state->viewport_offset.x;\n"
      "  pos.y = pos.y * state->viewport_scale.y + \n"
      "      state->viewport_offset.y;\n"
      "  pos.z = pos.z * state->viewport_scale.z + \n"
      "      state->viewport_offset.z;\n"
      "  pos.xy += state->window_offset.xy;\n"
      "  return pos;\n"
      "}\n";
  std::string source =
      header + apply_viewport +
      "out gl_PerVertex {\n"
      "  vec4 gl_Position;\n"
      "  float gl_PointSize;\n"
      "  float gl_ClipDistance[];\n"
      "};\n"
      "layout(location = 0) in vec3 iF0;\n"
      "layout(location = 1) in vec4 iF1;\n"
      "layout(location = 0) out VertexData vtx;\n"
      "void main() {\n"
      //"  vec4 oPos = vec4(iF0.xy, 0.0, 1.0);\n"
      "  vec4 oPos = iF0.xxxx * state->float_consts[0];\n"
      "  oPos = (iF0.yyyy * state->float_consts[1]) + oPos;\n"
      "  oPos = (iF0.zzzz * state->float_consts[2]) + oPos;\n"
      "  oPos = (vec4(1.0, 1.0, 1.0, 1.0) * state->float_consts[3]) + oPos;\n"
      //"  gl_PointSize = 1.0;\n"
      "  for (int i = 0; i < vtx.o.length(); ++i) {\n"
      "    vtx.o[0] = vec4(0.0, 0.0, 0.0, 0.0);\n"
      "  }\n"
      "  vtx.o[0] = iF1;\n"
      "  gl_Position = applyViewport(oPos);\n"
      //"  gl_Position = oPos;\n"
      "}\n";

  if (!CompileProgram(source)) {
    return false;
  }

  is_valid_ = true;
  return true;
}

bool GL4Shader::PreparePixelShader(
    const xenos::xe_gpu_program_cntl_t& program_cntl,
    GL4Shader* vertex_shader) {
  if (has_prepared_) {
    return is_valid_;
  }
  has_prepared_ = true;

  std::string source = header +
                       "layout(location = 0) in VertexData vtx;\n"
                       "layout(location = 0) out vec4 oC[4];\n"
                       "void main() {\n"
                       "  for (int i = 0; i < oC.length(); ++i) {\n"
                       "    oC[i] = vec4(1.0, 0.0, 0.0, 1.0);\n"
                       "  }\n"
                       "  oC[0] = vtx.o[0];\n"
                       //"  gl_FragDepth = 0.0;\n"
                       "}\n";

  if (!CompileProgram(source)) {
    return false;
  }

  is_valid_ = true;
  return true;
}

bool GL4Shader::CompileProgram(std::string source) {
  assert_zero(program_);

  translated_disassembly_ = std::move(source);
  const char* source_str = translated_disassembly_.c_str();

  // Save to disk, if we asked for it.
  if (FLAGS_dump_shaders.size()) {
    auto base_path = FLAGS_dump_shaders.c_str();
    char file_name[poly::max_path];
    snprintf(file_name, poly::countof(file_name), "%s/gl4_gen_%.16llX.%s",
             base_path, data_hash_,
             shader_type_ == ShaderType::kVertex ? "vert" : "frag");
    FILE* f = fopen(file_name, "w");
    fprintf(f, translated_disassembly_.c_str());
    fprintf(f, "\n\n");
    fprintf(f, "/*\n");
    fprintf(f, ucode_disassembly_.c_str());
    fprintf(f, " */\n");
    fclose(f);
  }

  program_ = glCreateShaderProgramv(shader_type_ == ShaderType::kVertex
                                        ? GL_VERTEX_SHADER
                                        : GL_FRAGMENT_SHADER,
                                    1, &source_str);
  if (!program_) {
    PLOGE("Unable to create shader program");
    return false;
  }

  GLint link_status = 0;
  glGetProgramiv(program_, GL_LINK_STATUS, &link_status);
  if (!link_status) {
    // log_length includes the null character.
    GLint log_length = 0;
    glGetProgramiv(program_, GL_INFO_LOG_LENGTH, &log_length);
    std::string info_log;
    info_log.resize(log_length - 1);
    glGetProgramInfoLog(program_, log_length, &log_length,
                        const_cast<char*>(info_log.data()));
    PLOGE("Unable to link program: %s", info_log.c_str());
    error_log_ = std::move(info_log);
    return false;
  }

  return true;
}

}  // namespace gl4
}  // namespace gpu
}  // namespace xe
<|endoftext|>


<commit_before>/*
 * Copyright 1999-2000,2004 The Apache Software Foundation.
 *
 * 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.
 */

/*
 * $Log$
 * Revision 1.10  2004/09/08 13:56:22  peiyongz
 * Apache License Version 2.0
 *
 * Revision 1.9  2004/01/29 11:48:46  cargilld
 * Code cleanup changes to get rid of various compiler diagnostic messages.
 *
 * Revision 1.8  2003/12/17 00:18:35  cargilld
 * Update to memory management so that the static memory manager (one used to call Initialize) is only for static data.
 *
 * Revision 1.7  2003/10/29 16:17:48  peiyongz
 * size() added
 *
 * Revision 1.6  2003/05/16 06:01:52  knoaman
 * Partial implementation of the configurable memory manager.
 *
 * Revision 1.5  2003/05/15 19:04:35  knoaman
 * Partial implementation of the configurable memory manager.
 *
 * Revision 1.4  2003/03/07 18:11:54  tng
 * Return a reference instead of void for operator=
 *
 * Revision 1.3  2002/12/04 02:32:43  knoaman
 * #include cleanup.
 *
 * Revision 1.2  2002/11/04 15:22:04  tng
 * C++ Namespace Support.
 *
 * Revision 1.1.1.1  2002/02/01 22:22:11  peiyongz
 * sane_include
 *
 * Revision 1.6  2000/09/09 00:11:48  andyh
 * Virtual Destructor Patch, submitted by Kirk Wylie
 *
 * Revision 1.5  2000/07/19 18:47:26  andyh
 * More Macintosh port tweaks, submitted by James Berry.
 *
 * Revision 1.4  2000/03/02 19:54:42  roddey
 * This checkin includes many changes done while waiting for the
 * 1.1.0 code to be finished. I can't list them all here, but a list is
 * available elsewhere.
 *
 * Revision 1.3  2000/02/24 20:05:24  abagchi
 * Swat for removing Log from API docs
 *
 * Revision 1.2  2000/02/06 07:48:02  rahulj
 * Year 2K copyright swat.
 *
 * Revision 1.1.1.1  1999/11/09 01:04:48  twl
 * Initial checkin
 *
 * Revision 1.3  1999/11/08 20:45:10  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

#if !defined(NAMEIDPOOL_HPP)
#define NAMEIDPOOL_HPP

#include <xercesc/util/XMemory.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/PlatformUtils.hpp>

XERCES_CPP_NAMESPACE_BEGIN

//
//  Forward declare the enumerator so he can be our friend. Can you say
//  friend? Sure...
//
template <class TElem> class NameIdPoolEnumerator;

//
//  This class is provided to serve as the basis of many of the pools that
//  are used by the scanner and validators. They often need to be able to
//  store objects in such a way that they can be quickly accessed by the
//  name field of the object, and such that each element added is assigned
//  a unique id via which it can be accessed almost instantly.
//
//  Object names are enforced as being unique, since that's what all these
//  pools require. So its effectively a hash table in conjunction with an
//  array of references into the hash table by id. Ids are assigned such that
//  id N can be used to get the Nth element from the array of references.
//  This provides very fast access by id.
//
//  The way these pools are used, elements are never removed except when the
//  whole thing is flushed. This makes it very easy to maintain the two
//  access methods in sync.
//
//  For efficiency reasons, the id refererence array is never flushed until
//  the dtor. This way, it does not have to be regrown every time its reused.
//
//  All elements are assumed to be owned by the pool!
//
//  We have to have a bucket element structure to use to maintain the linked
//  lists for each bucket. Because some of the compilers we have to support
//  are totally brain dead, it cannot be a nested class as it should be.
//
template <class TElem> struct NameIdPoolBucketElem : public XMemory
{
public :
    NameIdPoolBucketElem
    (
        TElem* const                            value
        , NameIdPoolBucketElem<TElem>* const    next
    );
    ~NameIdPoolBucketElem();

    TElem*                          fData;
    NameIdPoolBucketElem<TElem>*    fNext;
private:
    // -----------------------------------------------------------------------
    //  Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    NameIdPoolBucketElem(const NameIdPoolBucketElem<TElem>&);
    NameIdPoolBucketElem<TElem>& operator=(const NameIdPoolBucketElem<TElem>&);
};

template <class TElem> class NameIdPool : public XMemory
{
public :
    // -----------------------------------------------------------------------
    //  Contructors and Destructor
    // -----------------------------------------------------------------------
    NameIdPool
    (
        const   unsigned int    hashModulus
        , const unsigned int    initSize = 128
        , MemoryManager* const  manager = XMLPlatformUtils::fgMemoryManager
    );

    ~NameIdPool();

    // -----------------------------------------------------------------------
    //  Element management
    // -----------------------------------------------------------------------
    bool containsKey(const XMLCh* const key) const;
    void removeAll();

    // -----------------------------------------------------------------------
    //  Getters
    // -----------------------------------------------------------------------
    TElem* getByKey(const XMLCh* const key);
    const TElem* getByKey(const XMLCh* const key) const;
    TElem* getById(const unsigned elemId);
    const TElem* getById(const unsigned elemId) const;

    MemoryManager* getMemoryManager() const;
    // -----------------------------------------------------------------------
    //  Putters
    //
    //  Dups are not allowed and cause an IllegalArgumentException. The id
    //  of the new element is returned.
    // -----------------------------------------------------------------------
    unsigned int put(TElem* const valueToAdopt);

protected :
    // -----------------------------------------------------------------------
    //  Declare the enumerator our friend so he can see our members
    // -----------------------------------------------------------------------
    friend class NameIdPoolEnumerator<TElem>;

private :
    // -----------------------------------------------------------------------
    //  Unused constructors and operators
    // -----------------------------------------------------------------------
    NameIdPool(const NameIdPool<TElem>&);
    NameIdPool<TElem>& operator=(const NameIdPool<TElem>&);

    // -----------------------------------------------------------------------
    //  Private helper methods
    // -----------------------------------------------------------------------
    NameIdPoolBucketElem<TElem>* findBucketElem
    (
        const XMLCh* const      key
        ,     unsigned int&     hashVal
    );
    const NameIdPoolBucketElem<TElem>* findBucketElem
    (
        const   XMLCh* const    key
        ,       unsigned int&   hashVal
    )   const;

    // -----------------------------------------------------------------------
    //  Data members
    //
    //  fBucketList
    //      This is the array that contains the heads of all of the list
    //      buckets, one for each possible hash value.
    //
    //  fIdPtrs
    //  fIdPtrsCount
    //      This is the array of pointers to the bucket elements in order of
    //      their assigned ids. So taking id N and referencing this array
    //      gives you the element with that id. The count field indicates
    //      the current size of this list. When fIdCounter+1 reaches this
    //      value the list must be expanded.
    //
    //  fIdCounter
    //      This is used to give out unique ids to added elements. It starts
    //      at zero (which means empty), and is bumped up for each newly added
    //      element. So the first element is 1, the next is 2, etc... This
    //      means that this value is set to the top index of the fIdPtrs array.
    //
    //  fHashModulus
    //      This is the modulus to use in this pool. The fBucketList array
    //      is of this size. It should be a prime number.
    // -----------------------------------------------------------------------
    MemoryManager*                  fMemoryManager;
    NameIdPoolBucketElem<TElem>**   fBucketList;
    TElem**                         fIdPtrs;
    unsigned int                    fIdPtrsCount;
    unsigned int                    fIdCounter;
    unsigned int                    fHashModulus;
};

//
//  An enumerator for a name id pool. It derives from the basic enumerator
//  class, so that pools can be generically enumerated.
//
template <class TElem> class NameIdPoolEnumerator : public XMLEnumerator<TElem>, public XMemory
{
public :
    // -----------------------------------------------------------------------
    //  Constructors and Destructor
    // -----------------------------------------------------------------------
    NameIdPoolEnumerator
    (
                NameIdPool<TElem>* const    toEnum
                , MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
    );

    NameIdPoolEnumerator
    (
        const   NameIdPoolEnumerator<TElem>& toCopy
    );

    virtual ~NameIdPoolEnumerator();

    // -----------------------------------------------------------------------
    //  Public operators
    // -----------------------------------------------------------------------
    NameIdPoolEnumerator<TElem>& operator=
    (
        const   NameIdPoolEnumerator<TElem>& toAssign
    );

    // -----------------------------------------------------------------------
    //  Enum interface
    // -----------------------------------------------------------------------
    bool hasMoreElements() const;
    TElem& nextElement();
    void Reset();
    int  size()  const;

private :
    // -----------------------------------------------------------------------
    //  Data Members
    //
    //  fCurIndex
    //      This is the current index into the pool's id mapping array. This
    //      is now we enumerate it.
    //
    //  fToEnum
    //      The name id pool that is being enumerated.
    // -----------------------------------------------------------------------
    unsigned int            fCurIndex;
    NameIdPool<TElem>*      fToEnum;
    MemoryManager* const    fMemoryManager;
};

XERCES_CPP_NAMESPACE_END

#if !defined(XERCES_TMPLSINC)
#include <xercesc/util/NameIdPool.c>
#endif

#endif
<commit_msg>Removed const from variable declaration (jira#1259)<commit_after>/*
 * Copyright 1999-2000,2004 The Apache Software Foundation.
 *
 * 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.
 */

/*
 * $Log$
 * Revision 1.11  2004/09/23 07:10:13  amassari
 * Removed const from variable declaration (jira#1259)
 *
 * Revision 1.10  2004/09/08 13:56:22  peiyongz
 * Apache License Version 2.0
 *
 * Revision 1.9  2004/01/29 11:48:46  cargilld
 * Code cleanup changes to get rid of various compiler diagnostic messages.
 *
 * Revision 1.8  2003/12/17 00:18:35  cargilld
 * Update to memory management so that the static memory manager (one used to call Initialize) is only for static data.
 *
 * Revision 1.7  2003/10/29 16:17:48  peiyongz
 * size() added
 *
 * Revision 1.6  2003/05/16 06:01:52  knoaman
 * Partial implementation of the configurable memory manager.
 *
 * Revision 1.5  2003/05/15 19:04:35  knoaman
 * Partial implementation of the configurable memory manager.
 *
 * Revision 1.4  2003/03/07 18:11:54  tng
 * Return a reference instead of void for operator=
 *
 * Revision 1.3  2002/12/04 02:32:43  knoaman
 * #include cleanup.
 *
 * Revision 1.2  2002/11/04 15:22:04  tng
 * C++ Namespace Support.
 *
 * Revision 1.1.1.1  2002/02/01 22:22:11  peiyongz
 * sane_include
 *
 * Revision 1.6  2000/09/09 00:11:48  andyh
 * Virtual Destructor Patch, submitted by Kirk Wylie
 *
 * Revision 1.5  2000/07/19 18:47:26  andyh
 * More Macintosh port tweaks, submitted by James Berry.
 *
 * Revision 1.4  2000/03/02 19:54:42  roddey
 * This checkin includes many changes done while waiting for the
 * 1.1.0 code to be finished. I can't list them all here, but a list is
 * available elsewhere.
 *
 * Revision 1.3  2000/02/24 20:05:24  abagchi
 * Swat for removing Log from API docs
 *
 * Revision 1.2  2000/02/06 07:48:02  rahulj
 * Year 2K copyright swat.
 *
 * Revision 1.1.1.1  1999/11/09 01:04:48  twl
 * Initial checkin
 *
 * Revision 1.3  1999/11/08 20:45:10  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

#if !defined(NAMEIDPOOL_HPP)
#define NAMEIDPOOL_HPP

#include <xercesc/util/XMemory.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/PlatformUtils.hpp>

XERCES_CPP_NAMESPACE_BEGIN

//
//  Forward declare the enumerator so he can be our friend. Can you say
//  friend? Sure...
//
template <class TElem> class NameIdPoolEnumerator;

//
//  This class is provided to serve as the basis of many of the pools that
//  are used by the scanner and validators. They often need to be able to
//  store objects in such a way that they can be quickly accessed by the
//  name field of the object, and such that each element added is assigned
//  a unique id via which it can be accessed almost instantly.
//
//  Object names are enforced as being unique, since that's what all these
//  pools require. So its effectively a hash table in conjunction with an
//  array of references into the hash table by id. Ids are assigned such that
//  id N can be used to get the Nth element from the array of references.
//  This provides very fast access by id.
//
//  The way these pools are used, elements are never removed except when the
//  whole thing is flushed. This makes it very easy to maintain the two
//  access methods in sync.
//
//  For efficiency reasons, the id refererence array is never flushed until
//  the dtor. This way, it does not have to be regrown every time its reused.
//
//  All elements are assumed to be owned by the pool!
//
//  We have to have a bucket element structure to use to maintain the linked
//  lists for each bucket. Because some of the compilers we have to support
//  are totally brain dead, it cannot be a nested class as it should be.
//
template <class TElem> struct NameIdPoolBucketElem : public XMemory
{
public :
    NameIdPoolBucketElem
    (
        TElem* const                            value
        , NameIdPoolBucketElem<TElem>* const    next
    );
    ~NameIdPoolBucketElem();

    TElem*                          fData;
    NameIdPoolBucketElem<TElem>*    fNext;
private:
    // -----------------------------------------------------------------------
    //  Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    NameIdPoolBucketElem(const NameIdPoolBucketElem<TElem>&);
    NameIdPoolBucketElem<TElem>& operator=(const NameIdPoolBucketElem<TElem>&);
};

template <class TElem> class NameIdPool : public XMemory
{
public :
    // -----------------------------------------------------------------------
    //  Contructors and Destructor
    // -----------------------------------------------------------------------
    NameIdPool
    (
        const   unsigned int    hashModulus
        , const unsigned int    initSize = 128
        , MemoryManager* const  manager = XMLPlatformUtils::fgMemoryManager
    );

    ~NameIdPool();

    // -----------------------------------------------------------------------
    //  Element management
    // -----------------------------------------------------------------------
    bool containsKey(const XMLCh* const key) const;
    void removeAll();

    // -----------------------------------------------------------------------
    //  Getters
    // -----------------------------------------------------------------------
    TElem* getByKey(const XMLCh* const key);
    const TElem* getByKey(const XMLCh* const key) const;
    TElem* getById(const unsigned elemId);
    const TElem* getById(const unsigned elemId) const;

    MemoryManager* getMemoryManager() const;
    // -----------------------------------------------------------------------
    //  Putters
    //
    //  Dups are not allowed and cause an IllegalArgumentException. The id
    //  of the new element is returned.
    // -----------------------------------------------------------------------
    unsigned int put(TElem* const valueToAdopt);

protected :
    // -----------------------------------------------------------------------
    //  Declare the enumerator our friend so he can see our members
    // -----------------------------------------------------------------------
    friend class NameIdPoolEnumerator<TElem>;

private :
    // -----------------------------------------------------------------------
    //  Unused constructors and operators
    // -----------------------------------------------------------------------
    NameIdPool(const NameIdPool<TElem>&);
    NameIdPool<TElem>& operator=(const NameIdPool<TElem>&);

    // -----------------------------------------------------------------------
    //  Private helper methods
    // -----------------------------------------------------------------------
    NameIdPoolBucketElem<TElem>* findBucketElem
    (
        const XMLCh* const      key
        ,     unsigned int&     hashVal
    );
    const NameIdPoolBucketElem<TElem>* findBucketElem
    (
        const   XMLCh* const    key
        ,       unsigned int&   hashVal
    )   const;

    // -----------------------------------------------------------------------
    //  Data members
    //
    //  fBucketList
    //      This is the array that contains the heads of all of the list
    //      buckets, one for each possible hash value.
    //
    //  fIdPtrs
    //  fIdPtrsCount
    //      This is the array of pointers to the bucket elements in order of
    //      their assigned ids. So taking id N and referencing this array
    //      gives you the element with that id. The count field indicates
    //      the current size of this list. When fIdCounter+1 reaches this
    //      value the list must be expanded.
    //
    //  fIdCounter
    //      This is used to give out unique ids to added elements. It starts
    //      at zero (which means empty), and is bumped up for each newly added
    //      element. So the first element is 1, the next is 2, etc... This
    //      means that this value is set to the top index of the fIdPtrs array.
    //
    //  fHashModulus
    //      This is the modulus to use in this pool. The fBucketList array
    //      is of this size. It should be a prime number.
    // -----------------------------------------------------------------------
    MemoryManager*                  fMemoryManager;
    NameIdPoolBucketElem<TElem>**   fBucketList;
    TElem**                         fIdPtrs;
    unsigned int                    fIdPtrsCount;
    unsigned int                    fIdCounter;
    unsigned int                    fHashModulus;
};

//
//  An enumerator for a name id pool. It derives from the basic enumerator
//  class, so that pools can be generically enumerated.
//
template <class TElem> class NameIdPoolEnumerator : public XMLEnumerator<TElem>, public XMemory
{
public :
    // -----------------------------------------------------------------------
    //  Constructors and Destructor
    // -----------------------------------------------------------------------
    NameIdPoolEnumerator
    (
                NameIdPool<TElem>* const    toEnum
                , MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
    );

    NameIdPoolEnumerator
    (
        const   NameIdPoolEnumerator<TElem>& toCopy
    );

    virtual ~NameIdPoolEnumerator();

    // -----------------------------------------------------------------------
    //  Public operators
    // -----------------------------------------------------------------------
    NameIdPoolEnumerator<TElem>& operator=
    (
        const   NameIdPoolEnumerator<TElem>& toAssign
    );

    // -----------------------------------------------------------------------
    //  Enum interface
    // -----------------------------------------------------------------------
    bool hasMoreElements() const;
    TElem& nextElement();
    void Reset();
    int  size()  const;

private :
    // -----------------------------------------------------------------------
    //  Data Members
    //
    //  fCurIndex
    //      This is the current index into the pool's id mapping array. This
    //      is now we enumerate it.
    //
    //  fToEnum
    //      The name id pool that is being enumerated.
    // -----------------------------------------------------------------------
    unsigned int            fCurIndex;
    NameIdPool<TElem>*      fToEnum;
    MemoryManager*          fMemoryManager;
};

XERCES_CPP_NAMESPACE_END

#if !defined(XERCES_TMPLSINC)
#include <xercesc/util/NameIdPool.c>
#endif

#endif
<|endoftext|>