<commit_before>//=======================================================================
// Copyright (c) 2014-2015 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include <algorithm>

//Include the implementations
#include "etl/impl/std/conv.hpp"
#include "etl/impl/sse/conv.hpp"
#include "etl/impl/avx/conv.hpp"
#include "etl/impl/reduc/conv_mmul.hpp"

namespace etl {

enum class conv_type {
    VALID,
    SAME,
    FULL
};

namespace detail {

enum class conv_impl {
    STD,
    SSE,
    AVX
};

template<bool DMA, typename T>
inline cpp14_constexpr conv_impl select_conv_impl(){
    //Only std implementation is able to handle non-dma expressions
    if(!DMA){
        return conv_impl::STD;
    }

    //Note since these boolean will be known at compile time, the conditions will be a lot simplified
    auto sse = vectorize_impl && vector_mode == vector_mode_t::SSE3;
    auto avx = vectorize_impl && vector_mode == vector_mode_t::AVX;

    if(avx){
        return conv_impl::AVX;
    } else if(sse){
        return conv_impl::SSE;
    } else {
        return conv_impl::STD;
    }
}

template<typename I, typename K, typename C>
struct conv1_full_impl {
    static void apply(const I& input, const K& kernel, C&& conv){
        auto impl = select_conv_impl<all_dma<I,K,C>::value, value_t<I>>();

        if(impl == conv_impl::AVX){
            impl::avx::conv1_full(input, kernel, conv);
        } else if(impl == conv_impl::SSE){
            impl::sse::conv1_full(input, kernel, conv);
        } else if(impl == conv_impl::STD){
            impl::standard::conv1_full(input, kernel, conv);
        }
    }
};

template<typename I, typename K, typename C>
struct conv1_same_impl {
    static void apply(const I& input, const K& kernel, C&& conv){
        auto impl = select_conv_impl<all_dma<I,K,C>::value, value_t<I>>();

        if(impl == conv_impl::AVX){
            impl::avx::conv1_same(input, kernel, conv);
        } else if(impl == conv_impl::SSE){
            impl::sse::conv1_same(input, kernel, conv);
        } else if(impl == conv_impl::STD){
            impl::standard::conv1_same(input, kernel, conv);
        }
    }
};

template<typename I, typename K, typename C>
struct conv1_valid_impl {
    static void apply(const I& input, const K& kernel, C&& conv){
        auto impl = select_conv_impl<all_dma<I,K,C>::value, value_t<I>>();

        if(impl == conv_impl::AVX){
            impl::avx::conv1_valid(input, kernel, conv);
        } else if(impl == conv_impl::SSE){
            impl::sse::conv1_valid(input, kernel, conv);
        } else if(impl == conv_impl::STD){
            impl::standard::conv1_valid(input, kernel, conv);
        }
    }
};

template<typename I, typename K, typename C>
struct conv2_full_impl {
    static void apply(const I& input, const K& kernel, C&& conv){
        auto impl = select_conv_impl<all_dma<I,K,C>::value, value_t<I>>();

        if(impl == conv_impl::AVX){
            impl::avx::conv2_full(input, kernel, conv);
        } else if(impl == conv_impl::SSE){
            impl::sse::conv2_full(input, kernel, conv);
        } else if(impl == conv_impl::STD){
            impl::standard::conv2_full(input, kernel, conv);
        }
    }
};

template<typename I, typename K, typename C>
struct conv2_same_impl {
    static void apply(const I& input, const K& kernel, C&& conv){
        auto impl = select_conv_impl<all_dma<I,K,C>::value, value_t<I>>();

        if(impl == conv_impl::AVX){
            impl::avx::conv2_same(input, kernel, conv);
        } else if(impl == conv_impl::SSE){
            impl::sse::conv2_same(input, kernel, conv);
        } else if(impl == conv_impl::STD){
            impl::standard::conv2_same(input, kernel, conv);
        }
    }
};

template<typename I, typename K, typename C>
struct conv2_valid_impl {
    static void apply(const I& input, const K& kernel, C&& conv){
        auto impl = select_conv_impl<all_dma<I,K,C>::value, value_t<I>>();

        if(impl == conv_impl::AVX){
            impl::avx::conv2_valid(input, kernel, conv);
        } else if(impl == conv_impl::SSE){
            impl::sse::conv2_valid(input, kernel, conv);
        } else if(impl == conv_impl::STD){
            impl::standard::conv2_valid(input, kernel, conv);
        }
    }
};

template<conv_type TT, typename I, typename K, typename C>
struct conv_deep_impl {
    template<conv_type TT2 = TT, typename I2 = I, cpp_enable_if(decay_traits<I2>::dimensions() == 3 && TT2 == conv_type::FULL)>
    static void apply(const I& input, const K& kernel, C&& conv){
        for(std::size_t i = 0; i < dim<0>(input); ++i){
            conv(i) = conv_2d_full(input(i), kernel(i));
        }
    }

    template<conv_type TT2 = TT, typename I2 = I, cpp_enable_if(decay_traits<I2>::dimensions() == 3 && TT2 == conv_type::SAME)>
    static void apply(const I& input, const K& kernel, C&& conv){
        for(std::size_t i = 0; i < dim<0>(input); ++i){
            conv(i) = conv_2d_same(input(i), kernel(i));
        }
    }

    template<conv_type TT2 = TT, typename I2 = I, cpp_enable_if(decay_traits<I2>::dimensions() == 3 && TT2 == conv_type::VALID)>
    static void apply(const I& input, const K& kernel, C&& conv){
        for(std::size_t i = 0; i < dim<0>(input); ++i){
            conv(i) = conv_2d_valid(input(i), kernel(i));
        }
    }

    template<typename I2 = I, cpp_enable_if((decay_traits<I2>::dimensions() > 3))>
    static void apply(const I& input, const K& kernel, C&& conv){
        for(std::size_t i = 0; i < dim<0>(input); ++i){
            conv_deep_impl<TT, decltype(input(i)), decltype(kernel(i)), decltype(conv(i))>::apply(input(i), kernel(i), conv(i));
        }
    }
};

template<typename I, typename K, typename C>
using conv_deep_valid_impl = conv_deep_impl<conv_type::VALID, I, K, C>;

template<typename I, typename K, typename C>
using conv_deep_same_impl = conv_deep_impl<conv_type::SAME, I, K, C>;

template<typename I, typename K, typename C>
using conv_deep_full_impl = conv_deep_impl<conv_type::FULL, I, K, C>;

} //end of namespace detail

} //end of namespace etl
<commit_msg>Review DMA for conv<commit_after>//=======================================================================
// Copyright (c) 2014-2015 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include <algorithm>

//Include the implementations
#include "etl/impl/std/conv.hpp"
#include "etl/impl/sse/conv.hpp"
#include "etl/impl/avx/conv.hpp"
#include "etl/impl/reduc/conv_mmul.hpp"

namespace etl {

enum class conv_type {
    VALID,
    SAME,
    FULL
};

namespace detail {

enum class conv_impl {
    STD,
    SSE,
    AVX
};

template<typename T>
inline cpp14_constexpr conv_impl select_conv_impl(){
    //Note since these boolean will be known at compile time, the conditions will be a lot simplified
    constexpr const bool sse = vectorize_impl && vector_mode == vector_mode_t::SSE3;
    constexpr const bool avx = vectorize_impl && vector_mode == vector_mode_t::AVX;

    if(avx){
        return conv_impl::AVX;
    } else if(sse){
        return conv_impl::SSE;
    } else {
        return conv_impl::STD;
    }
}

template<typename I, typename K, typename C, typename Enable = void>
struct conv1_full_impl {
    static void apply(const I& input, const K& kernel, C&& conv){
        auto impl = select_conv_impl<value_t<I>>();

        if(impl == conv_impl::AVX){
            impl::avx::conv1_full(input, kernel, conv);
        } else if(impl == conv_impl::SSE){
            impl::sse::conv1_full(input, kernel, conv);
        } else if(impl == conv_impl::STD){
            impl::standard::conv1_full(input, kernel, conv);
        }
    }
};

template<typename I, typename K, typename C, typename Enable = void>
struct conv1_same_impl {
    static void apply(const I& input, const K& kernel, C&& conv){
        auto impl = select_conv_impl<value_t<I>>();

        if(impl == conv_impl::AVX){
            impl::avx::conv1_same(input, kernel, conv);
        } else if(impl == conv_impl::SSE){
            impl::sse::conv1_same(input, kernel, conv);
        } else if(impl == conv_impl::STD){
            impl::standard::conv1_same(input, kernel, conv);
        }
    }
};

template<typename I, typename K, typename C, typename Enable = void>
struct conv1_valid_impl {
    static void apply(const I& input, const K& kernel, C&& conv){
        auto impl = select_conv_impl<value_t<I>>();

        if(impl == conv_impl::AVX){
            impl::avx::conv1_valid(input, kernel, conv);
        } else if(impl == conv_impl::SSE){
            impl::sse::conv1_valid(input, kernel, conv);
        } else if(impl == conv_impl::STD){
            impl::standard::conv1_valid(input, kernel, conv);
        }
    }
};

template<typename I, typename K, typename C, typename Enable = void>
struct conv2_full_impl {
    static void apply(const I& input, const K& kernel, C&& conv){
        auto impl = select_conv_impl<value_t<I>>();

        if(impl == conv_impl::AVX){
            impl::avx::conv2_full(input, kernel, conv);
        } else if(impl == conv_impl::SSE){
            impl::sse::conv2_full(input, kernel, conv);
        } else if(impl == conv_impl::STD){
            impl::standard::conv2_full(input, kernel, conv);
        }
    }
};

template<typename I, typename K, typename C, typename Enable = void>
struct conv2_same_impl {
    static void apply(const I& input, const K& kernel, C&& conv){
        auto impl = select_conv_impl<value_t<I>>();

        if(impl == conv_impl::AVX){
            impl::avx::conv2_same(input, kernel, conv);
        } else if(impl == conv_impl::SSE){
            impl::sse::conv2_same(input, kernel, conv);
        } else if(impl == conv_impl::STD){
            impl::standard::conv2_same(input, kernel, conv);
        }
    }
};

template<typename I, typename K, typename C, typename Enable = void>
struct conv2_valid_impl {
    static void apply(const I& input, const K& kernel, C&& conv){
        auto impl = select_conv_impl<value_t<I>>();

        if(impl == conv_impl::AVX){
            impl::avx::conv2_valid(input, kernel, conv);
        } else if(impl == conv_impl::SSE){
            impl::sse::conv2_valid(input, kernel, conv);
        } else if(impl == conv_impl::STD){
            impl::standard::conv2_valid(input, kernel, conv);
        }
    }
};

template<conv_type TT, typename I, typename K, typename C, typename Enable = void>
struct conv_deep_impl {
    template<conv_type TT2 = TT, typename I2 = I, cpp_enable_if(decay_traits<I2>::dimensions() == 3 && TT2 == conv_type::FULL)>
    static void apply(const I& input, const K& kernel, C&& conv){
        for(std::size_t i = 0; i < dim<0>(input); ++i){
            conv(i) = conv_2d_full(input(i), kernel(i));
        }
    }

    template<conv_type TT2 = TT, typename I2 = I, cpp_enable_if(decay_traits<I2>::dimensions() == 3 && TT2 == conv_type::SAME)>
    static void apply(const I& input, const K& kernel, C&& conv){
        for(std::size_t i = 0; i < dim<0>(input); ++i){
            conv(i) = conv_2d_same(input(i), kernel(i));
        }
    }

    template<conv_type TT2 = TT, typename I2 = I, cpp_enable_if(decay_traits<I2>::dimensions() == 3 && TT2 == conv_type::VALID)>
    static void apply(const I& input, const K& kernel, C&& conv){
        for(std::size_t i = 0; i < dim<0>(input); ++i){
            conv(i) = conv_2d_valid(input(i), kernel(i));
        }
    }

    template<typename I2 = I, cpp_enable_if((decay_traits<I2>::dimensions() > 3))>
    static void apply(const I& input, const K& kernel, C&& conv){
        for(std::size_t i = 0; i < dim<0>(input); ++i){
            conv_deep_impl<TT, decltype(input(i)), decltype(kernel(i)), decltype(conv(i))>::apply(input(i), kernel(i), conv(i));
        }
    }
};

template<typename I, typename K, typename C>
using conv_deep_valid_impl = conv_deep_impl<conv_type::VALID, I, K, C>;

template<typename I, typename K, typename C>
using conv_deep_same_impl = conv_deep_impl<conv_type::SAME, I, K, C>;

template<typename I, typename K, typename C>
using conv_deep_full_impl = conv_deep_impl<conv_type::FULL, I, K, C>;

//The following partial specializations are here to ensure compilation
//(and avoid using static_if/SFINAE at higher level)

template<typename I, typename K, typename C>
struct conv1_full_impl<I, K, C, std::enable_if_t<!all_dma<I,K,C>::value>> {
    static void apply(const I& /*input*/, const K& /*kernel*/, C&& /*conv*/){
        cpp_unreachable("Should never be reached");
    }
};

template<typename I, typename K, typename C>
struct conv1_valid_impl<I, K, C, std::enable_if_t<!all_dma<I,K,C>::value>> {
    static void apply(const I& /*input*/, const K& /*kernel*/, C&& /*conv*/){
        cpp_unreachable("Should never be reached");
    }
};

template<typename I, typename K, typename C>
struct conv1_same_impl<I, K, C, std::enable_if_t<!all_dma<I,K,C>::value>> {
    static void apply(const I& /*input*/, const K& /*kernel*/, C&& /*conv*/){
        cpp_unreachable("Should never be reached");
    }
};

template<typename I, typename K, typename C>
struct conv2_full_impl<I, K, C, std::enable_if_t<!all_dma<I,K,C>::value>> {
    static void apply(const I& /*input*/, const K& /*kernel*/, C&& /*conv*/){
        cpp_unreachable("Should never be reached");
    }
};

template<typename I, typename K, typename C>
struct conv2_valid_impl<I, K, C, std::enable_if_t<!all_dma<I,K,C>::value>> {
    static void apply(const I& /*input*/, const K& /*kernel*/, C&& /*conv*/){
        cpp_unreachable("Should never be reached");
    }
};

template<typename I, typename K, typename C>
struct conv2_same_impl<I, K, C, std::enable_if_t<!all_dma<I,K,C>::value>> {
    static void apply(const I& /*input*/, const K& /*kernel*/, C&& /*conv*/){
        cpp_unreachable("Should never be reached");
    }
};

template<conv_type TT, typename I, typename K, typename C>
struct conv_deep_impl<TT, I, K, C, std::enable_if_t<!all_dma<I,K,C>::value>> {
    static void apply(const I& /*input*/, const K& /*kernel*/, C&& /*conv*/){
        cpp_unreachable("Should never be reached");
    }
};

} //end of namespace detail

} //end of namespace etl
<|endoftext|>


<commit_before>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2012-2019 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. 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.
 *
 * 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 <modules/basegl/viewmanager.h>
#include <inviwo/core/interaction/events/mouseevent.h>
#include <inviwo/core/interaction/events/gestureevent.h>
#include <inviwo/core/interaction/events/touchevent.h>
#include <inviwo/core/interaction/events/wheelevent.h>
#include <inviwo/core/interaction/events/pickingevent.h>

#include <inviwo/core/util/exception.h>

namespace inviwo {

ViewManager::ViewManager() = default;

bool ViewManager::propagatePickingEvent(PickingEvent* pe, Propagator propagator) {

    auto prop = [&](Event* newEvent, size_t ind) {
        if (newEvent) {
            auto pressPos = pe->getPressedPosition();
            auto previousPos = pe->getPreviousPosition();

            auto offset = dvec2(views_[ind].pos) / dvec2(pe->getCanvasSize() - uvec2(1));
            auto scale = dvec2(pe->getCanvasSize() - uvec2(1)) / dvec2(views_[ind].size - ivec2(1));

            auto pressNDC = dvec3(2.0 * scale * (pressPos - offset) - 1.0, pe->getPressedDepth());
            auto previousNDC =
                dvec3(2.0 * scale * (previousPos - offset) - 1.0, pe->getPreviousDepth());

            PickingEvent newPe(pe->getPickingAction(), static_cast<InteractionEvent*>(newEvent),
                               pe->getState(), pe->getPressState(), pe->getPressItem(),
                               pe->getHoverState(), pe->getPressItems(), pe->getGlobalPickingId(),
                               pe->getCurrentGlobalPickingId(), pe->getPressedGlobalPickingId(),
                               pe->getPreviousGlobalPickingId(), pressNDC, previousNDC);

            propagator(&newPe, ind);
            if (newPe.hasBeenUsed()) newEvent->markAsUsed();
            for (auto p : newPe.getVisitedProcessors()) newEvent->markAsVisited(p);
        }
    };

    auto e = pe->getEvent();
    bool propagated = false;
    switch (e->hash()) {
        case MouseEvent::chash():
            propagated = propagateMouseEvent(static_cast<MouseEvent*>(e), prop);
            break;
        case WheelEvent::chash():
            propagated = propagateWheelEvent(static_cast<WheelEvent*>(e), prop);
            break;
        case GestureEvent::chash():
            propagated = propagateGestureEvent(static_cast<GestureEvent*>(e), prop);
            break;
        case TouchEvent::chash():
            propagated = propagateTouchEvent(static_cast<TouchEvent*>(e), prop);
            break;
        default:
            propagated = false;
            break;
    }
    if (e->hasBeenUsed()) pe->markAsUsed();
    for (auto p : e->getVisitedProcessors()) pe->markAsVisited(p);

    return propagated;
}

bool ViewManager::propagateMouseEvent(MouseEvent* me, Propagator propagator) {
    selectedView_ = eventState_.getView(*this, me);

    if (selectedView_.first && selectedView_.second < views_.size()) {
        MouseEvent newEvent(*me);
        newEvent.setCanvasSize(uvec2(views_[selectedView_.second].size));
        auto offset = dvec2(views_[selectedView_.second].pos) / dvec2(me->canvasSize() - uvec2(1));
        auto scale = dvec2(me->canvasSize() - uvec2(1)) /
                     dvec2(views_[selectedView_.second].size - ivec2(1));
        newEvent.setPosNormalized(scale * (newEvent.posNormalized() - offset));
        propagator(&newEvent, selectedView_.second);
        if (newEvent.hasBeenUsed()) me->markAsUsed();
        for (auto p : newEvent.getVisitedProcessors()) me->markAsVisited(p);

        return true;
    } else {
        return false;
    }
}

bool ViewManager::propagateWheelEvent(WheelEvent* we, Propagator propagator) {
    selectedView_ = findView(we->pos());

    if (selectedView_.first && selectedView_.second < views_.size()) {
        WheelEvent newEvent(*we);
        newEvent.setCanvasSize(uvec2(views_[selectedView_.second].size));
        auto offset = dvec2(views_[selectedView_.second].pos) / dvec2(we->canvasSize() - uvec2(1));
        auto scale = dvec2(we->canvasSize() - uvec2(1)) /
                     dvec2(views_[selectedView_.second].size - ivec2(1));
        newEvent.setPosNormalized(scale * (newEvent.posNormalized() - offset));
        propagator(&newEvent, selectedView_.second);
        if (newEvent.hasBeenUsed()) we->markAsUsed();
        for (auto p : newEvent.getVisitedProcessors()) we->markAsVisited(p);

        return true;
    } else {
        return false;
    }
}

bool ViewManager::propagateGestureEvent(GestureEvent* ge, Propagator propagator) {
    selectedView_ = eventState_.getView(*this, ge);

    if (selectedView_.first && selectedView_.second < views_.size()) {
        GestureEvent newEvent(*ge);
        newEvent.setCanvasSize(uvec2(views_[selectedView_.second].size));
        auto offset = dvec2(views_[selectedView_.second].pos) / dvec2(ge->canvasSize() - uvec2(1));
        auto scale = dvec2(ge->canvasSize() - uvec2(1)) /
                     dvec2(views_[selectedView_.second].size - ivec2(1));
        newEvent.setScreenPosNormalized(scale * (newEvent.screenPosNormalized() - offset));
        propagator(&newEvent, selectedView_.second);
        if (newEvent.hasBeenUsed()) ge->markAsUsed();
        for (auto p : newEvent.getVisitedProcessors()) ge->markAsVisited(p);

        return true;
    } else {
        return false;
    }
}

bool ViewManager::propagateTouchEvent(TouchEvent* te, Propagator propagator) {
    auto& touchPoints = te->touchPoints();

    std::unordered_map<size_t, std::vector<TouchPoint>> viewIdToTouchPoints;
    std::vector<int> propagatedPointIds;

    auto idToView = eventState_.getView(*this, te);
    for (auto& point : touchPoints) {
        auto it = idToView.find(point.id());
        if (it != idToView.end()) {
            viewIdToTouchPoints[it->second].push_back(point);
        }
    }

    for (auto& item : viewIdToTouchPoints) {
        const auto& viewId = item.first;
        auto points = item.second;

        const auto canvasSize = uvec2(views_[viewId].size);
        const auto offset = dvec2(views_[viewId].pos) / dvec2(te->canvasSize() - uvec2(1));
        const auto scale =
            dvec2(te->canvasSize() - uvec2(1)) / dvec2(views_[viewId].size - ivec2(1));

        for (auto& p : points) {
            p.setCanvasSize(canvasSize);
            p.setPosNormalized(scale * (p.posNormalized() - offset));
            p.setPrevPosNormalized(scale * (p.prevPosNormalized() - offset));
            p.setPressedPosNormalized(scale * (p.pressedPosNormalized() - offset));
        }

        TouchEvent newEvent(points, te->getDevice(), te->modifiers());

        propagator(&newEvent, viewId);

        for (auto p : newEvent.getVisitedProcessors()) te->markAsVisited(p);
        for (const auto& p : points) propagatedPointIds.push_back(p.id());
    }

    // remove the "used" points from the event
    util::erase_remove_if(
        touchPoints, [&](const auto& p) { return util::contains(propagatedPointIds, p.id()); });

    if (touchPoints.empty()) te->markAsUsed();

    return touchPoints.empty();
}

bool ViewManager::propagateEvent(Event* event, Propagator propagator) {
    switch (event->hash()) {
        case PickingEvent::chash(): {
            return propagatePickingEvent(static_cast<PickingEvent*>(event), propagator);
        }
        case MouseEvent::chash(): {
            return propagateMouseEvent(static_cast<MouseEvent*>(event), propagator);
        }
        case WheelEvent::chash(): {
            return propagateWheelEvent(static_cast<WheelEvent*>(event), propagator);
        }
        case GestureEvent::chash(): {
            return propagateGestureEvent(static_cast<GestureEvent*>(event), propagator);
        }
        case TouchEvent::chash(): {
            return propagateTouchEvent(static_cast<TouchEvent*>(event), propagator);
        }
        default:
            return false;
    }
}

std::pair<bool, ViewManager::ViewId> ViewManager::getSelectedView() const { return selectedView_; }

const ViewManager::ViewList& ViewManager::getViews() const { return views_; }

void ViewManager::push_back(View view) { views_.push_back(view); }

void ViewManager::erase(View view) {
    util::erase_remove_if(views_,
                          [&](const auto& v) { return view.pos == v.pos && view.size == v.size; });
}

void ViewManager::erase(ViewId ind) {
    if (ind < views_.size()) {
        views_.erase(views_.begin() + ind);
    }
}

void ViewManager::replace(ViewId ind, View view) {
    if (ind < views_.size()) {
        views_[ind] = view;
    } else {
        throw Exception("Out of range", IVW_CONTEXT);
    }
}

ViewManager::View& ViewManager::operator[](ViewId ind) { return views_[ind]; }

size_t ViewManager::size() const { return views_.size(); }

void ViewManager::clear() { views_.clear(); }

std::pair<bool, ViewManager::ViewId> ViewManager::findView(ivec2 pos) const {
    auto it = util::find_if(views_, [&](const auto& view) { return inView(view, pos); });
    if (it != views_.end()) {
        return {true, std::distance(views_.begin(), it)};
    } else {
        return {false, 0};
    }
}

bool ViewManager::inView(const View& view, const ivec2& pos) {
    return glm::all(glm::greaterThanEqual(pos, view.pos)) &&
           glm::all(glm::lessThan(pos, view.pos + view.size));
}

std::pair<bool, ViewManager::ViewId> ViewManager::EventState::getView(ViewManager& m,
                                                                      const MouseEvent* me) {
    if (!pressing_ && me->buttonState() != MouseButton::None) {  // Start Pressing
        pressing_ = true;
        pressedView_ = m.findView(static_cast<ivec2>(me->pos()));
    } else if (pressing_ && me->buttonState() == MouseButton::None) {  // Stop Pressing
        pressing_ = false;
        pressedView_ = {false, 0};
    }
    return pressing_ ? pressedView_ : m.findView(static_cast<ivec2>(me->pos()));
}

std::pair<bool, ViewManager::ViewId> ViewManager::EventState::getView(ViewManager& m,
                                                                      const GestureEvent* ge) {
    if (!pressing_ && ge->state() == GestureState::Started) {  // Start Pressing
        pressing_ = true;
        pressedView_ =
            m.findView(static_cast<ivec2>(dvec2(ge->canvasSize()) * ge->screenPosNormalized()));
    } else if (pressing_ && ge->state() == GestureState::Finished) {  // Stop Pressing
        pressing_ = false;
        auto tmp = pressedView_;
        pressedView_ = {false, 0};
        return tmp;
    }
    return pressedView_;
}

std::unordered_map<int, ViewManager::ViewId> ViewManager::EventState::getView(
    ViewManager& m, const TouchEvent* te) {

    std::unordered_map<int, ViewId> newTouchpointIdToViewID;
    std::vector<std::pair<bool, ViewManager::ViewId>> foundViews;

    for (const auto& tp : te->touchPoints()) {
        switch (tp.state()) {
            case TouchState::Started: {
                auto res = m.findView(static_cast<ivec2>(tp.pos()));
                if (res.first) {
                    touchpointIdToViewId_[tp.id()] = res.second;
                    newTouchpointIdToViewID[tp.id()] = res.second;
                }
                break;
            }
            case TouchState::Finished: {
                auto it = touchpointIdToViewId_.find(tp.id());
                if (it != touchpointIdToViewId_.end()) {
                    newTouchpointIdToViewID[tp.id()] = it->second;
                }
                touchpointIdToViewId_.erase(tp.id());
                break;
            }
            case TouchState::Stationary:
            case TouchState::Updated:
            case TouchState::None:
            default: {
                auto it = touchpointIdToViewId_.find(tp.id());
                if (it != touchpointIdToViewId_.end()) {
                    newTouchpointIdToViewID[tp.id()] = it->second;
                }
                break;
            }
        }
    }
    return newTouchpointIdToViewID;
}

}  // namespace inviwo
<commit_msg>BaseGL: ViewManager: Only check agains points of used events to determine wether the event was used or not.<commit_after>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2012-2019 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. 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.
 *
 * 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 <modules/basegl/viewmanager.h>
#include <inviwo/core/interaction/events/mouseevent.h>
#include <inviwo/core/interaction/events/gestureevent.h>
#include <inviwo/core/interaction/events/touchevent.h>
#include <inviwo/core/interaction/events/wheelevent.h>
#include <inviwo/core/interaction/events/pickingevent.h>

#include <inviwo/core/util/exception.h>

namespace inviwo {

ViewManager::ViewManager() = default;

bool ViewManager::propagatePickingEvent(PickingEvent* pe, Propagator propagator) {

    auto prop = [&](Event* newEvent, size_t ind) {
        if (newEvent) {
            auto pressPos = pe->getPressedPosition();
            auto previousPos = pe->getPreviousPosition();

            auto offset = dvec2(views_[ind].pos) / dvec2(pe->getCanvasSize() - uvec2(1));
            auto scale = dvec2(pe->getCanvasSize() - uvec2(1)) / dvec2(views_[ind].size - ivec2(1));

            auto pressNDC = dvec3(2.0 * scale * (pressPos - offset) - 1.0, pe->getPressedDepth());
            auto previousNDC =
                dvec3(2.0 * scale * (previousPos - offset) - 1.0, pe->getPreviousDepth());

            PickingEvent newPe(pe->getPickingAction(), static_cast<InteractionEvent*>(newEvent),
                               pe->getState(), pe->getPressState(), pe->getPressItem(),
                               pe->getHoverState(), pe->getPressItems(), pe->getGlobalPickingId(),
                               pe->getCurrentGlobalPickingId(), pe->getPressedGlobalPickingId(),
                               pe->getPreviousGlobalPickingId(), pressNDC, previousNDC);

            propagator(&newPe, ind);
            if (newPe.hasBeenUsed()) newEvent->markAsUsed();
            for (auto p : newPe.getVisitedProcessors()) newEvent->markAsVisited(p);
        }
    };

    auto e = pe->getEvent();
    bool propagated = false;
    switch (e->hash()) {
        case MouseEvent::chash():
            propagated = propagateMouseEvent(static_cast<MouseEvent*>(e), prop);
            break;
        case WheelEvent::chash():
            propagated = propagateWheelEvent(static_cast<WheelEvent*>(e), prop);
            break;
        case GestureEvent::chash():
            propagated = propagateGestureEvent(static_cast<GestureEvent*>(e), prop);
            break;
        case TouchEvent::chash():
            propagated = propagateTouchEvent(static_cast<TouchEvent*>(e), prop);
            break;
        default:
            propagated = false;
            break;
    }
    if (e->hasBeenUsed()) pe->markAsUsed();
    for (auto p : e->getVisitedProcessors()) pe->markAsVisited(p);

    return propagated;
}

bool ViewManager::propagateMouseEvent(MouseEvent* me, Propagator propagator) {
    selectedView_ = eventState_.getView(*this, me);

    if (selectedView_.first && selectedView_.second < views_.size()) {
        MouseEvent newEvent(*me);
        newEvent.setCanvasSize(uvec2(views_[selectedView_.second].size));
        auto offset = dvec2(views_[selectedView_.second].pos) / dvec2(me->canvasSize() - uvec2(1));
        auto scale = dvec2(me->canvasSize() - uvec2(1)) /
                     dvec2(views_[selectedView_.second].size - ivec2(1));
        newEvent.setPosNormalized(scale * (newEvent.posNormalized() - offset));
        propagator(&newEvent, selectedView_.second);
        if (newEvent.hasBeenUsed()) me->markAsUsed();
        for (auto p : newEvent.getVisitedProcessors()) me->markAsVisited(p);

        return true;
    } else {
        return false;
    }
}

bool ViewManager::propagateWheelEvent(WheelEvent* we, Propagator propagator) {
    selectedView_ = findView(we->pos());

    if (selectedView_.first && selectedView_.second < views_.size()) {
        WheelEvent newEvent(*we);
        newEvent.setCanvasSize(uvec2(views_[selectedView_.second].size));
        auto offset = dvec2(views_[selectedView_.second].pos) / dvec2(we->canvasSize() - uvec2(1));
        auto scale = dvec2(we->canvasSize() - uvec2(1)) /
                     dvec2(views_[selectedView_.second].size - ivec2(1));
        newEvent.setPosNormalized(scale * (newEvent.posNormalized() - offset));
        propagator(&newEvent, selectedView_.second);
        if (newEvent.hasBeenUsed()) we->markAsUsed();
        for (auto p : newEvent.getVisitedProcessors()) we->markAsVisited(p);

        return true;
    } else {
        return false;
    }
}

bool ViewManager::propagateGestureEvent(GestureEvent* ge, Propagator propagator) {
    selectedView_ = eventState_.getView(*this, ge);

    if (selectedView_.first && selectedView_.second < views_.size()) {
        GestureEvent newEvent(*ge);
        newEvent.setCanvasSize(uvec2(views_[selectedView_.second].size));
        auto offset = dvec2(views_[selectedView_.second].pos) / dvec2(ge->canvasSize() - uvec2(1));
        auto scale = dvec2(ge->canvasSize() - uvec2(1)) /
                     dvec2(views_[selectedView_.second].size - ivec2(1));
        newEvent.setScreenPosNormalized(scale * (newEvent.screenPosNormalized() - offset));
        propagator(&newEvent, selectedView_.second);
        if (newEvent.hasBeenUsed()) ge->markAsUsed();
        for (auto p : newEvent.getVisitedProcessors()) ge->markAsVisited(p);

        return true;
    } else {
        return false;
    }
}

bool ViewManager::propagateTouchEvent(TouchEvent* te, Propagator propagator) {
    auto& touchPoints = te->touchPoints();

    std::unordered_map<size_t, std::vector<TouchPoint>> viewIdToTouchPoints;
    std::vector<int> usedPointIds;

    auto idToView = eventState_.getView(*this, te);
    for (auto& point : touchPoints) {
        auto it = idToView.find(point.id());
        if (it != idToView.end()) {
            viewIdToTouchPoints[it->second].push_back(point);
        }
    }

    for (auto& item : viewIdToTouchPoints) {
        const auto& viewId = item.first;
        auto points = item.second;

        const auto canvasSize = uvec2(views_[viewId].size);
        const auto offset = dvec2(views_[viewId].pos) / dvec2(te->canvasSize() - uvec2(1));
        const auto scale =
            dvec2(te->canvasSize() - uvec2(1)) / dvec2(views_[viewId].size - ivec2(1));

        for (auto& p : points) {
            p.setCanvasSize(canvasSize);
            p.setPosNormalized(scale * (p.posNormalized() - offset));
            p.setPrevPosNormalized(scale * (p.prevPosNormalized() - offset));
            p.setPressedPosNormalized(scale * (p.pressedPosNormalized() - offset));
        }

        TouchEvent newEvent(points, te->getDevice(), te->modifiers());

        propagator(&newEvent, viewId);

        for (auto p : newEvent.getVisitedProcessors()) te->markAsVisited(p);
        if (newEvent.hasBeenUsed()) {
            for (const auto& p : points) {
                usedPointIds.push_back(p.id());
            }
        }
    }

    // remove the "used" points from the event
    util::erase_remove_if(touchPoints,
                          [&](const auto& p) { return util::contains(usedPointIds, p.id()); });

    if (touchPoints.empty()) {
        te->markAsUsed();
    }

    return touchPoints.empty();
}

bool ViewManager::propagateEvent(Event* event, Propagator propagator) {
    switch (event->hash()) {
        case PickingEvent::chash(): {
            return propagatePickingEvent(static_cast<PickingEvent*>(event), propagator);
        }
        case MouseEvent::chash(): {
            return propagateMouseEvent(static_cast<MouseEvent*>(event), propagator);
        }
        case WheelEvent::chash(): {
            return propagateWheelEvent(static_cast<WheelEvent*>(event), propagator);
        }
        case GestureEvent::chash(): {
            return propagateGestureEvent(static_cast<GestureEvent*>(event), propagator);
        }
        case TouchEvent::chash(): {
            return propagateTouchEvent(static_cast<TouchEvent*>(event), propagator);
        }
        default:
            return false;
    }
}

std::pair<bool, ViewManager::ViewId> ViewManager::getSelectedView() const { return selectedView_; }

const ViewManager::ViewList& ViewManager::getViews() const { return views_; }

void ViewManager::push_back(View view) { views_.push_back(view); }

void ViewManager::erase(View view) {
    util::erase_remove_if(views_,
                          [&](const auto& v) { return view.pos == v.pos && view.size == v.size; });
}

void ViewManager::erase(ViewId ind) {
    if (ind < views_.size()) {
        views_.erase(views_.begin() + ind);
    }
}

void ViewManager::replace(ViewId ind, View view) {
    if (ind < views_.size()) {
        views_[ind] = view;
    } else {
        throw Exception("Out of range", IVW_CONTEXT);
    }
}

ViewManager::View& ViewManager::operator[](ViewId ind) { return views_[ind]; }

size_t ViewManager::size() const { return views_.size(); }

void ViewManager::clear() { views_.clear(); }

std::pair<bool, ViewManager::ViewId> ViewManager::findView(ivec2 pos) const {
    auto it = util::find_if(views_, [&](const auto& view) { return inView(view, pos); });
    if (it != views_.end()) {
        return {true, std::distance(views_.begin(), it)};
    } else {
        return {false, 0};
    }
}

bool ViewManager::inView(const View& view, const ivec2& pos) {
    return glm::all(glm::greaterThanEqual(pos, view.pos)) &&
           glm::all(glm::lessThan(pos, view.pos + view.size));
}

std::pair<bool, ViewManager::ViewId> ViewManager::EventState::getView(ViewManager& m,
                                                                      const MouseEvent* me) {
    if (!pressing_ && me->buttonState() != MouseButton::None) {  // Start Pressing
        pressing_ = true;
        pressedView_ = m.findView(static_cast<ivec2>(me->pos()));
    } else if (pressing_ && me->buttonState() == MouseButton::None) {  // Stop Pressing
        pressing_ = false;
        pressedView_ = {false, 0};
    }
    return pressing_ ? pressedView_ : m.findView(static_cast<ivec2>(me->pos()));
}

std::pair<bool, ViewManager::ViewId> ViewManager::EventState::getView(ViewManager& m,
                                                                      const GestureEvent* ge) {
    if (!pressing_ && ge->state() == GestureState::Started) {  // Start Pressing
        pressing_ = true;
        pressedView_ =
            m.findView(static_cast<ivec2>(dvec2(ge->canvasSize()) * ge->screenPosNormalized()));
    } else if (pressing_ && ge->state() == GestureState::Finished) {  // Stop Pressing
        pressing_ = false;
        auto tmp = pressedView_;
        pressedView_ = {false, 0};
        return tmp;
    }
    return pressedView_;
}

std::unordered_map<int, ViewManager::ViewId> ViewManager::EventState::getView(
    ViewManager& m, const TouchEvent* te) {

    std::unordered_map<int, ViewId> newTouchpointIdToViewID;
    std::vector<std::pair<bool, ViewManager::ViewId>> foundViews;

    for (const auto& tp : te->touchPoints()) {
        switch (tp.state()) {
            case TouchState::Started: {
                auto res = m.findView(static_cast<ivec2>(tp.pos()));
                if (res.first) {
                    touchpointIdToViewId_[tp.id()] = res.second;
                    newTouchpointIdToViewID[tp.id()] = res.second;
                }
                break;
            }
            case TouchState::Finished: {
                auto it = touchpointIdToViewId_.find(tp.id());
                if (it != touchpointIdToViewId_.end()) {
                    newTouchpointIdToViewID[tp.id()] = it->second;
                }
                touchpointIdToViewId_.erase(tp.id());
                break;
            }
            case TouchState::Stationary:
            case TouchState::Updated:
            case TouchState::None:
            default: {
                auto it = touchpointIdToViewId_.find(tp.id());
                if (it != touchpointIdToViewId_.end()) {
                    newTouchpointIdToViewID[tp.id()] = it->second;
                }
                break;
            }
        }
    }
    return newTouchpointIdToViewID;
}

}  // namespace inviwo
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

//The implementations
#include "etl/impl/std/mmul.hpp"
#include "etl/impl/std/strassen_mmul.hpp"
#include "etl/impl/blas/gemm.hpp"
#include "etl/impl/vec/gemm.hpp"
#include "etl/impl/cublas/gemm.hpp"

namespace etl {

namespace detail {

/*!
 * \brief Select an implementation of GEMM, not considering local context
 * \param n1 The left dimension of the  multiplication
 * \param n2 The inner dimension of the  multiplication
 * \param n3 The right dimension of the  multiplication
 * \return The implementation to use
 */
template <typename A, typename B, typename C>
inline cpp14_constexpr gemm_impl select_default_gemm_impl(const std::size_t n1, const std::size_t n2, const std::size_t n3) {
    cpp_unused(n2);

    constexpr bool DMA = all_dma<A, B, C>::value;

    //Note since these boolean will be known at compile time, the conditions will be a lot simplified
    constexpr bool blas   = is_cblas_enabled;
    constexpr bool cublas = is_cublas_enabled;

    if (cublas && DMA) {
        if (n1 * n3 < gemm_cublas_min) {
            if (blas) {
                return gemm_impl::BLAS;
            }

            if (n1 * n3 < gemm_std_max) {
                return gemm_impl::STD;
            }
        }

        return gemm_impl::CUBLAS;
    } else if (blas && DMA) {
        return gemm_impl::BLAS;
    }

    if(vec_enabled && all_vectorizable<vector_mode, A, B, C>::value){
        return gemm_impl::VEC;
    }

    return gemm_impl::STD;
}

/*!
 * \brief Select an implementation of GEMM
 * \param n1 The left dimension of the  multiplication
 * \param n2 The inner dimension of the  multiplication
 * \param n3 The right dimension of the  multiplication
 * \return The implementation to use
 */
template <typename A, typename B, typename C>
inline gemm_impl select_gemm_impl(const std::size_t n1, const std::size_t n2, const std::size_t n3) {
    constexpr bool DMA = all_dma<A, B, C>::value;

    auto def = select_default_gemm_impl<A, B, C>(n1, n2, n3);

    if (local_context().gemm_selector.forced) {
        auto forced = local_context().gemm_selector.impl;

        switch (forced) {
            //CUBLAS cannot always be used
            case gemm_impl::CUBLAS:
                if (!is_cublas_enabled || !DMA) {                                                                                //COVERAGE_EXCLUDE_LINE
                    std::cerr << "Forced selection to CUBLAS gemm implementation, but not possible for this expression" << std::endl; //COVERAGE_EXCLUDE_LINE
                    return def;                                                              //COVERAGE_EXCLUDE_LINE
                }                                                                                //COVERAGE_EXCLUDE_LINE

                return forced;

            //BLAS cannot always be used
            case gemm_impl::BLAS:
                if (!is_cblas_enabled || !DMA) {                                                                                //COVERAGE_EXCLUDE_LINE
                    std::cerr << "Forced selection to BLAS gemm implementation, but not possible for this expression" << std::endl; //COVERAGE_EXCLUDE_LINE
                    return def;                                                            //COVERAGE_EXCLUDE_LINE
                }                                                                                //COVERAGE_EXCLUDE_LINE

                return forced;

            //VEC cannot always be used
            case gemm_impl::VEC:
                if (!vec_enabled || !all_vectorizable<vector_mode, A, B, C>::value) {                                               //COVERAGE_EXCLUDE_LINE
                    std::cerr << "Forced selection to VEC gemv implementation, but not possible for this expression" << std::endl; //COVERAGE_EXCLUDE_LINE
                    return def;                                                            //COVERAGE_EXCLUDE_LINE
                }                                                                                //COVERAGE_EXCLUDE_LINE

                return forced;

            //In other cases, simply use the forced impl
            default:
                return forced;
        }
    }

    return def;
}

/*!
 * \brief Select an implementation of GEMV, not considering local context
 * \param n1 The left dimension of the  multiplication
 * \param n2 The right dimension of the  multiplication
 * \return The implementation to use
 */
template <typename A, typename B, typename C>
inline cpp14_constexpr gemm_impl select_default_gemv_impl(const std::size_t n1, const std::size_t n2) {
    constexpr bool DMA = all_dma<A, B, C>::value;
    using T = value_t<A>;

    if(DMA && is_cblas_enabled){
        return gemm_impl::BLAS;
    }

    if(all_vectorizable<vector_mode, A, B, C>::value && vec_enabled){
        return gemm_impl::VEC;
    }

    if (is_cublas_enabled) {
        if (is_complex_single_t<T>::value && n1 * n2 > 1000 * 1000) {
            return gemm_impl::CUBLAS;
        }
    }

    return gemm_impl::STD;
}

/*!
 * \brief Select an implementation of GEMV
 * \param n1 The left dimension of the  multiplication
 * \param n2 The right dimension of the  multiplication
 * \return The implementation to use
 */
template <typename A, typename B, typename C>
inline gemm_impl select_gemv_impl(const std::size_t n1, const std::size_t n2) {
    static constexpr bool DMA = all_dma<A, B, C>::value;

    if (local_context().gemm_selector.forced) {
        auto forced = local_context().gemm_selector.impl;

        switch (forced) {
            //CUBLAS cannot always be used
            case gemm_impl::CUBLAS:
                if (!is_cublas_enabled || !DMA) {                                                                                //COVERAGE_EXCLUDE_LINE
                    std::cerr << "Forced selection to CUBLAS gemv implementation, but not possible for this expression" << std::endl; //COVERAGE_EXCLUDE_LINE
                    return select_default_gemv_impl<A, B, C>(n1, n2);                                                                  //COVERAGE_EXCLUDE_LINE
                }                                                                                //COVERAGE_EXCLUDE_LINE

                return forced;

            //BLAS cannot always be used
            case gemm_impl::BLAS:
                if (!is_cblas_enabled || !DMA) {                                                                                //COVERAGE_EXCLUDE_LINE
                    std::cerr << "Forced selection to BLAS gemv implementation, but not possible for this expression" << std::endl; //COVERAGE_EXCLUDE_LINE
                    return select_default_gemv_impl<A, B, C>(n1, n2);                                                                //COVERAGE_EXCLUDE_LINE
                }                                                                                //COVERAGE_EXCLUDE_LINE

                return forced;

            //VEC cannot always be used
            case gemm_impl::VEC:
                if (!vec_enabled || !all_vectorizable<vector_mode, A, B, C>::value) {                                               //COVERAGE_EXCLUDE_LINE
                    std::cerr << "Forced selection to VEC gemv implementation, but not possible for this expression" << std::endl; //COVERAGE_EXCLUDE_LINE
                    return select_default_gemv_impl<A, B, C>(n1, n2);                                                                //COVERAGE_EXCLUDE_LINE
                }                                                                                //COVERAGE_EXCLUDE_LINE

                return forced;

            //In other cases, simply use the forced impl
            default:
                return forced;
        }
    }

    return select_default_gemv_impl<A, B, C>(n1, n2);
}

/*!
 * \brief Select an implementation of GEVM, not considering local context
 * \param n1 The left dimension of the  multiplication
 * \param n2 The right dimension of the  multiplication
 * \return The implementation to use
 */
template <typename A, typename B, typename C>
inline cpp14_constexpr gemm_impl select_default_gevm_impl(const std::size_t n1, const std::size_t n2) {
    constexpr bool DMA = all_dma<A, B, C>::value;
    using T = value_t<A>;

    if(DMA && is_cblas_enabled){
        return gemm_impl::BLAS;
    }

    if(all_vectorizable<vector_mode, A, B, C>::value && vec_enabled){
        return gemm_impl::VEC;
    }

    if (is_cublas_enabled) {
        if (is_complex_single_t<T>::value && n1 * n2 > 1000 * 1000) {
            return gemm_impl::CUBLAS;
        }
    }

    return gemm_impl::STD;
}

/*!
 * \brief Select an implementation of GEVM
 * \param n1 The left dimension of the  multiplication
 * \param n2 The right dimension of the  multiplication
 * \return The implementation to use
 */
template <typename A, typename B, typename C>
inline gemm_impl select_gevm_impl(const std::size_t n1, const std::size_t n2) {
    static constexpr bool DMA = all_dma<A, B, C>::value;

    if (local_context().gemm_selector.forced) {
        auto forced = local_context().gemm_selector.impl;

        switch (forced) {
            //CUBLAS cannot always be used
            case gemm_impl::CUBLAS:
                if (!is_cublas_enabled || !DMA) {                                                                                //COVERAGE_EXCLUDE_LINE
                    std::cerr << "Forced selection to CUBLAS gevm implementation, but not possible for this expression" << std::endl; //COVERAGE_EXCLUDE_LINE
                    return select_default_gevm_impl<A, B, C>(n1, n2);                                                                  //COVERAGE_EXCLUDE_LINE
                }                                                                                //COVERAGE_EXCLUDE_LINE

                return forced;

            //BLAS cannot always be used
            case gemm_impl::BLAS:
                if (!is_cblas_enabled || !DMA) {                                                                                //COVERAGE_EXCLUDE_LINE
                    std::cerr << "Forced selection to BLAS gevm implementation, but not possible for this expression" << std::endl; //COVERAGE_EXCLUDE_LINE
                    return select_default_gevm_impl<A, B, C>(n1, n2);                                                                //COVERAGE_EXCLUDE_LINE
                }                                                                                //COVERAGE_EXCLUDE_LINE

                return forced;

            //VEC cannot always be used
            case gemm_impl::VEC:
                if (!vec_enabled || !all_vectorizable<vector_mode, A, B, C>::value) {                                               //COVERAGE_EXCLUDE_LINE
                    std::cerr << "Forced selection to VEC gemv implementation, but not possible for this expression" << std::endl; //COVERAGE_EXCLUDE_LINE
                    return select_default_gemv_impl<A, B, C>(n1, n2);                                                                //COVERAGE_EXCLUDE_LINE
                }                                                                                //COVERAGE_EXCLUDE_LINE

                return forced;

            //In other cases, simply use the forced impl
            default:
                return forced;
        }
    }

    return select_default_gevm_impl<A, B, C>(n1, n2);
}

/*!
 * \brief Functor for matrix-matrix multiplication
 */
struct mm_mul_impl {
    /*!
     * \brief Apply the function C = A * B
     * \param a The lhs of the multiplication
     * \param b The rhs of the multiplication
     * \param c The target of the multiplication
     */
    template <typename A, typename B, typename C>
    static void apply(A&& a, B&& b, C&& c) {
        gemm_impl impl = select_gemm_impl<A, B, C>(etl::dim<0>(a), etl::dim<1>(a), etl::dim<1>(c));

        if (impl == gemm_impl::STD) {
            etl::impl::standard::mm_mul(a, b, c);
        } else if (impl == gemm_impl::VEC) {
            etl::impl::vec::gemm(a, b, c);
        } else if (impl == gemm_impl::BLAS) {
            etl::impl::blas::gemm(a, b, c);
        } else if (impl == gemm_impl::CUBLAS) {
            etl::impl::cublas::gemm(a, b, c);
        }
    }
};

/*!
 * \brief Functor for vector-matrix multiplication
 */
struct vm_mul_impl {
    /*!
     * \brief Apply the function C = A * B
     * \param a The lhs of the multiplication
     * \param b The rhs of the multiplication
     * \param c The target of the multiplication
     */
    template <typename A, typename B, typename C>
    static void apply(A&& a, B&& b, C&& c) {
        gemm_impl impl = select_gevm_impl<A, B, C>(etl::dim<0>(b), etl::dim<1>(b));

        if (impl == gemm_impl::STD) {
            etl::impl::standard::vm_mul(a, b, c);
        } else if (impl == gemm_impl::BLAS) {
            etl::impl::blas::gevm(a, b, c);
        } else if (impl == gemm_impl::VEC) {
            etl::impl::vec::gevm(a, b, c);
        } else if (impl == gemm_impl::CUBLAS) {
            etl::impl::cublas::gevm(a, b, c);
        }
    }
};

/*!
 * \brief Functor for matrix-vector multiplication
 */
struct mv_mul_impl {
    /*!
     * \brief Apply the function C = A * B
     * \param a The lhs of the multiplication
     * \param b The rhs of the multiplication
     * \param c The target of the multiplication
     */
    template <typename A, typename B, typename C>
    static void apply(A&& a, B&& b, C&& c) {
        gemm_impl impl = select_gemv_impl<A, B, C>(etl::dim<0>(a), etl::dim<1>(a));

        if (impl == gemm_impl::STD) {
            etl::impl::standard::mv_mul(a, b, c);
        } else if (impl == gemm_impl::BLAS) {
            etl::impl::blas::gemv(a, b, c);
        } else if (impl == gemm_impl::VEC) {
            etl::impl::vec::gemv(a, b, c);
        } else if (impl == gemm_impl::CUBLAS) {
            etl::impl::cublas::gemv(a, b, c);
        }
    }
};

/*!
 * \brief Functor for Strassen matrix-matrix multiplication
 */
struct strassen_mm_mul_impl {
    /*!
     * \brief Apply the function C = A * B
     * \param a The lhs of the multiplication
     * \param b The rhs of the multiplication
     * \param c The target of the multiplication
     */
    template <typename A, typename B, typename C>
    static void apply(A&& a, B&& b, C&& c) {
        etl::impl::standard::strassen_mm_mul(a, b, c);
    }
};

} //end of namespace detail

} //end of namespace etl
<commit_msg>Cleanup<commit_after>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

//The implementations
#include "etl/impl/std/mmul.hpp"
#include "etl/impl/std/strassen_mmul.hpp"
#include "etl/impl/blas/gemm.hpp"
#include "etl/impl/vec/gemm.hpp"
#include "etl/impl/cublas/gemm.hpp"

namespace etl {

namespace detail {

/*!
 * \brief Select an implementation of GEMM, not considering local context
 * \param n1 The left dimension of the  multiplication
 * \param n2 The inner dimension of the  multiplication
 * \param n3 The right dimension of the  multiplication
 * \return The implementation to use
 */
template <typename A, typename B, typename C>
inline cpp14_constexpr gemm_impl select_default_gemm_impl(const std::size_t n1, const std::size_t n2, const std::size_t n3) {
    cpp_unused(n2);

    constexpr bool DMA = all_dma<A, B, C>::value;

    //Note since these boolean will be known at compile time, the conditions will be a lot simplified
    constexpr bool blas   = is_cblas_enabled;
    constexpr bool cublas = is_cublas_enabled;

    if (cublas && DMA) {
        if (n1 * n3 < gemm_cublas_min) {
            if (blas) {
                return gemm_impl::BLAS;
            }

            if (n1 * n3 < gemm_std_max) {
                return gemm_impl::STD;
            }
        }

        return gemm_impl::CUBLAS;
    } else if (blas && DMA) {
        return gemm_impl::BLAS;
    }

    if(vec_enabled && all_vectorizable<vector_mode, A, B, C>::value){
        return gemm_impl::VEC;
    }

    return gemm_impl::STD;
}

/*!
 * \brief Select an implementation of GEMM
 * \param n1 The left dimension of the  multiplication
 * \param n2 The inner dimension of the  multiplication
 * \param n3 The right dimension of the  multiplication
 * \return The implementation to use
 */
template <typename A, typename B, typename C>
inline gemm_impl select_gemm_impl(const std::size_t n1, const std::size_t n2, const std::size_t n3) {
    constexpr bool DMA = all_dma<A, B, C>::value;

    auto def = select_default_gemm_impl<A, B, C>(n1, n2, n3);

    if (local_context().gemm_selector.forced) {
        auto forced = local_context().gemm_selector.impl;

        switch (forced) {
            //CUBLAS cannot always be used
            case gemm_impl::CUBLAS:
                if (!is_cublas_enabled || !DMA) {                                                                                //COVERAGE_EXCLUDE_LINE
                    std::cerr << "Forced selection to CUBLAS gemm implementation, but not possible for this expression" << std::endl; //COVERAGE_EXCLUDE_LINE
                    return def;                                                              //COVERAGE_EXCLUDE_LINE
                }                                                                                //COVERAGE_EXCLUDE_LINE

                return forced;

            //BLAS cannot always be used
            case gemm_impl::BLAS:
                if (!is_cblas_enabled || !DMA) {                                                                                //COVERAGE_EXCLUDE_LINE
                    std::cerr << "Forced selection to BLAS gemm implementation, but not possible for this expression" << std::endl; //COVERAGE_EXCLUDE_LINE
                    return def;                                                            //COVERAGE_EXCLUDE_LINE
                }                                                                                //COVERAGE_EXCLUDE_LINE

                return forced;

            //VEC cannot always be used
            case gemm_impl::VEC:
                if (!vec_enabled || !all_vectorizable<vector_mode, A, B, C>::value) {                                               //COVERAGE_EXCLUDE_LINE
                    std::cerr << "Forced selection to VEC gemv implementation, but not possible for this expression" << std::endl; //COVERAGE_EXCLUDE_LINE
                    return def;                                                            //COVERAGE_EXCLUDE_LINE
                }                                                                                //COVERAGE_EXCLUDE_LINE

                return forced;

            //In other cases, simply use the forced impl
            default:
                return forced;
        }
    }

    return def;
}

/*!
 * \brief Select an implementation of GEMV, not considering local context
 * \param n1 The left dimension of the  multiplication
 * \param n2 The right dimension of the  multiplication
 * \return The implementation to use
 */
template <typename A, typename B, typename C>
inline cpp14_constexpr gemm_impl select_default_gemv_impl(const std::size_t n1, const std::size_t n2) {
    constexpr bool DMA = all_dma<A, B, C>::value;
    using T = value_t<A>;

    if(DMA && is_cblas_enabled){
        return gemm_impl::BLAS;
    }

    if(all_vectorizable<vector_mode, A, B, C>::value && vec_enabled){
        return gemm_impl::VEC;
    }

    if (is_cublas_enabled && is_complex_single_t<T>::value && n1 * n2 > 1000 * 1000) {
        return gemm_impl::CUBLAS;
    }

    return gemm_impl::STD;
}

/*!
 * \brief Select an implementation of GEMV
 * \param n1 The left dimension of the  multiplication
 * \param n2 The right dimension of the  multiplication
 * \return The implementation to use
 */
template <typename A, typename B, typename C>
inline gemm_impl select_gemv_impl(const std::size_t n1, const std::size_t n2) {
    static constexpr bool DMA = all_dma<A, B, C>::value;

    if (local_context().gemm_selector.forced) {
        auto forced = local_context().gemm_selector.impl;

        switch (forced) {
            //CUBLAS cannot always be used
            case gemm_impl::CUBLAS:
                if (!is_cublas_enabled || !DMA) {                                                                                //COVERAGE_EXCLUDE_LINE
                    std::cerr << "Forced selection to CUBLAS gemv implementation, but not possible for this expression" << std::endl; //COVERAGE_EXCLUDE_LINE
                    return select_default_gemv_impl<A, B, C>(n1, n2);                                                                  //COVERAGE_EXCLUDE_LINE
                }                                                                                //COVERAGE_EXCLUDE_LINE

                return forced;

            //BLAS cannot always be used
            case gemm_impl::BLAS:
                if (!is_cblas_enabled || !DMA) {                                                                                //COVERAGE_EXCLUDE_LINE
                    std::cerr << "Forced selection to BLAS gemv implementation, but not possible for this expression" << std::endl; //COVERAGE_EXCLUDE_LINE
                    return select_default_gemv_impl<A, B, C>(n1, n2);                                                                //COVERAGE_EXCLUDE_LINE
                }                                                                                //COVERAGE_EXCLUDE_LINE

                return forced;

            //VEC cannot always be used
            case gemm_impl::VEC:
                if (!vec_enabled || !all_vectorizable<vector_mode, A, B, C>::value) {                                               //COVERAGE_EXCLUDE_LINE
                    std::cerr << "Forced selection to VEC gemv implementation, but not possible for this expression" << std::endl; //COVERAGE_EXCLUDE_LINE
                    return select_default_gemv_impl<A, B, C>(n1, n2);                                                                //COVERAGE_EXCLUDE_LINE
                }                                                                                //COVERAGE_EXCLUDE_LINE

                return forced;

            //In other cases, simply use the forced impl
            default:
                return forced;
        }
    }

    return select_default_gemv_impl<A, B, C>(n1, n2);
}

/*!
 * \brief Select an implementation of GEVM, not considering local context
 * \param n1 The left dimension of the  multiplication
 * \param n2 The right dimension of the  multiplication
 * \return The implementation to use
 */
template <typename A, typename B, typename C>
inline cpp14_constexpr gemm_impl select_default_gevm_impl(const std::size_t n1, const std::size_t n2) {
    constexpr bool DMA = all_dma<A, B, C>::value;
    using T = value_t<A>;

    if(DMA && is_cblas_enabled){
        return gemm_impl::BLAS;
    }

    if(all_vectorizable<vector_mode, A, B, C>::value && vec_enabled){
        return gemm_impl::VEC;
    }

    if (is_cublas_enabled && is_complex_single_t<T>::value && n1 * n2 > 1000 * 1000) {
        return gemm_impl::CUBLAS;
    }

    return gemm_impl::STD;
}

/*!
 * \brief Select an implementation of GEVM
 * \param n1 The left dimension of the  multiplication
 * \param n2 The right dimension of the  multiplication
 * \return The implementation to use
 */
template <typename A, typename B, typename C>
inline gemm_impl select_gevm_impl(const std::size_t n1, const std::size_t n2) {
    static constexpr bool DMA = all_dma<A, B, C>::value;

    if (local_context().gemm_selector.forced) {
        auto forced = local_context().gemm_selector.impl;

        switch (forced) {
            //CUBLAS cannot always be used
            case gemm_impl::CUBLAS:
                if (!is_cublas_enabled || !DMA) {                                                                                //COVERAGE_EXCLUDE_LINE
                    std::cerr << "Forced selection to CUBLAS gevm implementation, but not possible for this expression" << std::endl; //COVERAGE_EXCLUDE_LINE
                    return select_default_gevm_impl<A, B, C>(n1, n2);                                                                  //COVERAGE_EXCLUDE_LINE
                }                                                                                //COVERAGE_EXCLUDE_LINE

                return forced;

            //BLAS cannot always be used
            case gemm_impl::BLAS:
                if (!is_cblas_enabled || !DMA) {                                                                                //COVERAGE_EXCLUDE_LINE
                    std::cerr << "Forced selection to BLAS gevm implementation, but not possible for this expression" << std::endl; //COVERAGE_EXCLUDE_LINE
                    return select_default_gevm_impl<A, B, C>(n1, n2);                                                                //COVERAGE_EXCLUDE_LINE
                }                                                                                //COVERAGE_EXCLUDE_LINE

                return forced;

            //VEC cannot always be used
            case gemm_impl::VEC:
                if (!vec_enabled || !all_vectorizable<vector_mode, A, B, C>::value) {                                               //COVERAGE_EXCLUDE_LINE
                    std::cerr << "Forced selection to VEC gemv implementation, but not possible for this expression" << std::endl; //COVERAGE_EXCLUDE_LINE
                    return select_default_gemv_impl<A, B, C>(n1, n2);                                                                //COVERAGE_EXCLUDE_LINE
                }                                                                                //COVERAGE_EXCLUDE_LINE

                return forced;

            //In other cases, simply use the forced impl
            default:
                return forced;
        }
    }

    return select_default_gevm_impl<A, B, C>(n1, n2);
}

/*!
 * \brief Functor for matrix-matrix multiplication
 */
struct mm_mul_impl {
    /*!
     * \brief Apply the function C = A * B
     * \param a The lhs of the multiplication
     * \param b The rhs of the multiplication
     * \param c The target of the multiplication
     */
    template <typename A, typename B, typename C>
    static void apply(A&& a, B&& b, C&& c) {
        gemm_impl impl = select_gemm_impl<A, B, C>(etl::dim<0>(a), etl::dim<1>(a), etl::dim<1>(c));

        if (impl == gemm_impl::STD) {
            etl::impl::standard::mm_mul(a, b, c);
        } else if (impl == gemm_impl::VEC) {
            etl::impl::vec::gemm(a, b, c);
        } else if (impl == gemm_impl::BLAS) {
            etl::impl::blas::gemm(a, b, c);
        } else if (impl == gemm_impl::CUBLAS) {
            etl::impl::cublas::gemm(a, b, c);
        }
    }
};

/*!
 * \brief Functor for vector-matrix multiplication
 */
struct vm_mul_impl {
    /*!
     * \brief Apply the function C = A * B
     * \param a The lhs of the multiplication
     * \param b The rhs of the multiplication
     * \param c The target of the multiplication
     */
    template <typename A, typename B, typename C>
    static void apply(A&& a, B&& b, C&& c) {
        gemm_impl impl = select_gevm_impl<A, B, C>(etl::dim<0>(b), etl::dim<1>(b));

        if (impl == gemm_impl::STD) {
            etl::impl::standard::vm_mul(a, b, c);
        } else if (impl == gemm_impl::BLAS) {
            etl::impl::blas::gevm(a, b, c);
        } else if (impl == gemm_impl::VEC) {
            etl::impl::vec::gevm(a, b, c);
        } else if (impl == gemm_impl::CUBLAS) {
            etl::impl::cublas::gevm(a, b, c);
        }
    }
};

/*!
 * \brief Functor for matrix-vector multiplication
 */
struct mv_mul_impl {
    /*!
     * \brief Apply the function C = A * B
     * \param a The lhs of the multiplication
     * \param b The rhs of the multiplication
     * \param c The target of the multiplication
     */
    template <typename A, typename B, typename C>
    static void apply(A&& a, B&& b, C&& c) {
        gemm_impl impl = select_gemv_impl<A, B, C>(etl::dim<0>(a), etl::dim<1>(a));

        if (impl == gemm_impl::STD) {
            etl::impl::standard::mv_mul(a, b, c);
        } else if (impl == gemm_impl::BLAS) {
            etl::impl::blas::gemv(a, b, c);
        } else if (impl == gemm_impl::VEC) {
            etl::impl::vec::gemv(a, b, c);
        } else if (impl == gemm_impl::CUBLAS) {
            etl::impl::cublas::gemv(a, b, c);
        }
    }
};

/*!
 * \brief Functor for Strassen matrix-matrix multiplication
 */
struct strassen_mm_mul_impl {
    /*!
     * \brief Apply the function C = A * B
     * \param a The lhs of the multiplication
     * \param b The rhs of the multiplication
     * \param c The target of the multiplication
     */
    template <typename A, typename B, typename C>
    static void apply(A&& a, B&& b, C&& c) {
        etl::impl::standard::strassen_mm_mul(a, b, c);
    }
};

} //end of namespace detail

} //end of namespace etl
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: register.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: vg $ $Date: 2006-09-25 13:06:05 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _REGISTER_HXX_
#include "register.hxx"
#endif

#ifndef _REGISTRYEXCEPTION_HXX_
#include "registryexception.hxx"
#endif

#ifndef _REGISTRATIONCONTEXTINFORMATION_HXX_
#include "registrationcontextinformation.hxx"
#endif

#ifndef _USERREGISTRAR_HXX_
#include "userregistrar.hxx"
#endif

#ifndef _WINDOWSREGISTRY_HXX_
#include "windowsregistry.hxx"
#endif

#ifndef _STRINGCONVERTER_HXX_
#include "stringconverter.hxx"
#endif

#ifndef INCLUDED_MSIHELPER_HXX
#include "msihelper.hxx"
#endif

#pragma warning(push, 1) /* disable warnings within system headers */
#pragma warning(disable: 4917)
#include <shlobj.h>
#pragma warning(pop)

#include <assert.h>
#pragma warning(disable: 4350)

typedef std::auto_ptr<Registrar> RegistrarPtr;

namespace /* private */
{
    RegistrarPtr CreateRegistrar(bool InstallForAllUser, const RegistrationContextInformation& RegCtx)
    {
        RegistrarPtr RegPtr;

        if (InstallForAllUser)
            RegPtr = RegistrarPtr(new Registrar(RegCtx));
        else
            RegPtr = RegistrarPtr(new UserRegistrar(RegCtx));

        return RegPtr;
    }
} // namespace private

bool query_preselect_registration_for_ms_application(MSIHANDLE handle, int Register)
{
    bool preselect = false;

    try
    {
        RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
        RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);

        if (Register & MSWORD)
            preselect = CurrentRegistrar->QueryPreselectMsWordRegistration();
        else if (Register & MSEXCEL)
            preselect = CurrentRegistrar->QueryPreselectMsExcelRegistration();
        else if (Register & MSPOWERPOINT)
            preselect = CurrentRegistrar->QueryPreselectMsPowerPointRegistration();
    }
    catch(RegistryException&)
    {
        assert(false);
    }
    return preselect;
}

//-----------------------------------------
// registers StarOffice for MS document
// types and as default HTML editor if
// specified
//-----------------------------------------

void Register4MsDoc(MSIHANDLE handle, int Register)
{
    try
    {
        RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
        RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);

        if ((Register & MSWORD))
            CurrentRegistrar->RegisterForMsWord();

        if ((Register & MSEXCEL))
            CurrentRegistrar->RegisterForMsExcel();

        if ((Register & MSPOWERPOINT))
            CurrentRegistrar->RegisterForMsPowerPoint();

        if ((Register & HTML_EDITOR))
            CurrentRegistrar->RegisterAsHtmlEditorForInternetExplorer();

        if ((Register & DEFAULT_SHELL_HTML_EDITOR))
        {
            CurrentRegistrar->RegisterAsDefaultHtmlEditorForInternetExplorer();
            CurrentRegistrar->RegisterAsDefaultShellHtmlEditor();
        }
    }
    catch(RegistryException&)
    {
        assert(false);
    }

    if (Register)
        SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0);
}

void Unregister4MsDoc(MSIHANDLE handle, int Unregister)
{
    try
    {
        RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
        RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);

        if ((Unregister & MSWORD) && CurrentRegistrar->IsRegisteredFor(MSWORD))
            CurrentRegistrar->UnregisterForMsWord();

        if ((Unregister & HTML_EDITOR) && CurrentRegistrar->IsRegisteredFor(HTML_EDITOR))
            CurrentRegistrar->UnregisterAsHtmlEditorForInternetExplorer();

        if ((Unregister & MSEXCEL) && CurrentRegistrar->IsRegisteredFor(MSEXCEL))
            CurrentRegistrar->UnregisterForMsExcel();

        if ((Unregister & MSPOWERPOINT) && CurrentRegistrar->IsRegisteredFor(MSPOWERPOINT))
            CurrentRegistrar->UnregisterForMsPowerPoint();

        if ((Unregister & DEFAULT_HTML_EDITOR_FOR_IE) && CurrentRegistrar->IsRegisteredFor(DEFAULT_HTML_EDITOR_FOR_IE))
            CurrentRegistrar->UnregisterAsDefaultHtmlEditorForInternetExplorer();

        if ((Unregister & DEFAULT_SHELL_HTML_EDITOR) && CurrentRegistrar->IsRegisteredFor(DEFAULT_SHELL_HTML_EDITOR))
            CurrentRegistrar->UnregisterAsDefaultShellHtmlEditor();
    }
    catch(RegistryException&)
    {
        assert(false);
    }

    if (Unregister)
        SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0);
}

//-----------------------------------------
// restores the entries for the selected
// registry entries
// Algorithm:
//
// 1.
// Target key exist (e.g. '.doc')
// Default value == soffice.?
// Backup key != empty
// Action: Replace Default value with backup
// key
//
// 2.
// Target key exist
// Default value == soffice.?
// Backup key == empty
// Action: delete default value
//
// 3.
// Target key exist
// Default value != soffice.?
// Action: nop
//
// 4.
// Target key does not exist
// Action: nop
//-----------------------------------------

void Unregister4MsDocAll(MSIHANDLE handle)
{
    try
    {
        RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
        RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);

        CurrentRegistrar->UnregisterAllAndCleanUpRegistry();
    }
    catch(RegistryException&)
    {
        assert(false);
    }
}

//-----------------------------------------
// restores lost settings formerly made
// with Register4MsDoc
//-----------------------------------------

void RepairRegister4MsDocSettings(MSIHANDLE handle)
{
    try
    {
        RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
        RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);

        CurrentRegistrar->RepairRegistrationState();
    }
    catch(RegistryException&)
    {
        assert(false);
    }
}

bool IsRegisteredFor(MSIHANDLE handle, int State)
{
    bool Registered = false;

    try
    {
        RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
        RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);

        Registered = CurrentRegistrar->IsRegisteredFor(State);
    }
    catch(RegistryException&)
    {
        assert(false);
    }
    return Registered;
}

#define SO60_UNINSTALL_KEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\StarOffice 6.0"
#define SO_BACKUP_KEY      L"soffice6.bak"
#define REGMSDOCSTATE      L"Reg4MsDocState"
#define SOFTWARE_CLASSES   L"Software\\Classes"

int FixReturnRegistrationState(MSIHANDLE handle)
{
    int registration_state = 0;

    try
    {
        WindowsRegistry registry;

        RegistryValue rv_regmsdocstate = RegistryValue(
            new RegistryValueImpl(REGMSDOCSTATE, 0));

        RegistryKey so_bak_key;

        if (IsAllUserInstallation(handle))
        {
            RegistryKey hkcr_key = registry.GetClassesRootKey();

            if (hkcr_key->HasSubKey(SO_BACKUP_KEY))
                so_bak_key = hkcr_key->OpenSubKey(SO_BACKUP_KEY);
            else
                so_bak_key = hkcr_key->CreateSubKey(SO_BACKUP_KEY);

            if (!so_bak_key->HasValue(REGMSDOCSTATE))
            {
                // set a defined value
                so_bak_key->SetValue(rv_regmsdocstate);

                RegistryKey hklm_key = registry.GetLocalMachineKey();

                if (hklm_key->HasSubKey(SO60_UNINSTALL_KEY))
                {
                    RegistryKey so_uninst_key =
                        hklm_key->OpenSubKey(SO60_UNINSTALL_KEY);

                    if (so_uninst_key->HasValue(REGMSDOCSTATE))
                        so_bak_key->CopyValue(so_uninst_key, REGMSDOCSTATE);
                }
            }
        }
        else
        {
            RegistryKey hkcu_classes_key =
                registry.GetCurrentUserKey()->OpenSubKey(SOFTWARE_CLASSES);

            so_bak_key = hkcu_classes_key->CreateSubKey(SO_BACKUP_KEY);

            if (!so_bak_key->HasValue(REGMSDOCSTATE))
            {
                // set a defined value
                so_bak_key->SetValue(rv_regmsdocstate);

                RegistryKey hklm_sftw_classes =
                    registry.GetLocalMachineKey()->OpenSubKey(SOFTWARE_CLASSES, false);

                RegistryKey so_bak_key_old;

                if (hklm_sftw_classes->HasSubKey(SO_BACKUP_KEY))
                {
                    so_bak_key_old = hklm_sftw_classes->OpenSubKey(SO_BACKUP_KEY, false);

                    if (so_bak_key_old->HasValue(REGMSDOCSTATE))
                        so_bak_key->CopyValue(so_bak_key_old, REGMSDOCSTATE);
                }
                else // try the uninstall key
                {
                    RegistryKey hklm_key = registry.GetLocalMachineKey();

                    if (hklm_key->HasSubKey(SO60_UNINSTALL_KEY))
                    {
                        RegistryKey so_uninst_key =
                            hklm_key->OpenSubKey(SO60_UNINSTALL_KEY);

                        if (so_uninst_key->HasValue(REGMSDOCSTATE))
                            so_bak_key->CopyValue(so_uninst_key, REGMSDOCSTATE);
                    }
                }
            }
        }

        rv_regmsdocstate = so_bak_key->GetValue(REGMSDOCSTATE);
        registration_state = rv_regmsdocstate->GetDataAsInt();
    }
    catch(RegistryException&)
    {
        registration_state = 0;
    }

    return registration_state;
}

<commit_msg>INTEGRATION: CWS mingwport06 (1.5.90); FILE MERGED 2007/08/24 13:12:57 vg 1.5.90.1: #i75499# pragma is for MSVC<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: register.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: kz $ $Date: 2007-09-06 13:29:29 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _REGISTER_HXX_
#include "register.hxx"
#endif

#ifndef _REGISTRYEXCEPTION_HXX_
#include "registryexception.hxx"
#endif

#ifndef _REGISTRATIONCONTEXTINFORMATION_HXX_
#include "registrationcontextinformation.hxx"
#endif

#ifndef _USERREGISTRAR_HXX_
#include "userregistrar.hxx"
#endif

#ifndef _WINDOWSREGISTRY_HXX_
#include "windowsregistry.hxx"
#endif

#ifndef _STRINGCONVERTER_HXX_
#include "stringconverter.hxx"
#endif

#ifndef INCLUDED_MSIHELPER_HXX
#include "msihelper.hxx"
#endif

#ifdef _MSC_VER
#pragma warning(push, 1) /* disable warnings within system headers */
#pragma warning(disable: 4917)
#endif
#include <shlobj.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include <assert.h>
#ifdef _MSC_VER
#pragma warning(disable: 4350)
#endif

typedef std::auto_ptr<Registrar> RegistrarPtr;

namespace /* private */
{
    RegistrarPtr CreateRegistrar(bool InstallForAllUser, const RegistrationContextInformation& RegCtx)
    {
        RegistrarPtr RegPtr;

        if (InstallForAllUser)
            RegPtr = RegistrarPtr(new Registrar(RegCtx));
        else
            RegPtr = RegistrarPtr(new UserRegistrar(RegCtx));

        return RegPtr;
    }
} // namespace private

bool query_preselect_registration_for_ms_application(MSIHANDLE handle, int Register)
{
    bool preselect = false;

    try
    {
        RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
        RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);

        if (Register & MSWORD)
            preselect = CurrentRegistrar->QueryPreselectMsWordRegistration();
        else if (Register & MSEXCEL)
            preselect = CurrentRegistrar->QueryPreselectMsExcelRegistration();
        else if (Register & MSPOWERPOINT)
            preselect = CurrentRegistrar->QueryPreselectMsPowerPointRegistration();
    }
    catch(RegistryException&)
    {
        assert(false);
    }
    return preselect;
}

//-----------------------------------------
// registers StarOffice for MS document
// types and as default HTML editor if
// specified
//-----------------------------------------

void Register4MsDoc(MSIHANDLE handle, int Register)
{
    try
    {
        RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
        RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);

        if ((Register & MSWORD))
            CurrentRegistrar->RegisterForMsWord();

        if ((Register & MSEXCEL))
            CurrentRegistrar->RegisterForMsExcel();

        if ((Register & MSPOWERPOINT))
            CurrentRegistrar->RegisterForMsPowerPoint();

        if ((Register & HTML_EDITOR))
            CurrentRegistrar->RegisterAsHtmlEditorForInternetExplorer();

        if ((Register & DEFAULT_SHELL_HTML_EDITOR))
        {
            CurrentRegistrar->RegisterAsDefaultHtmlEditorForInternetExplorer();
            CurrentRegistrar->RegisterAsDefaultShellHtmlEditor();
        }
    }
    catch(RegistryException&)
    {
        assert(false);
    }

    if (Register)
        SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0);
}

void Unregister4MsDoc(MSIHANDLE handle, int Unregister)
{
    try
    {
        RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
        RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);

        if ((Unregister & MSWORD) && CurrentRegistrar->IsRegisteredFor(MSWORD))
            CurrentRegistrar->UnregisterForMsWord();

        if ((Unregister & HTML_EDITOR) && CurrentRegistrar->IsRegisteredFor(HTML_EDITOR))
            CurrentRegistrar->UnregisterAsHtmlEditorForInternetExplorer();

        if ((Unregister & MSEXCEL) && CurrentRegistrar->IsRegisteredFor(MSEXCEL))
            CurrentRegistrar->UnregisterForMsExcel();

        if ((Unregister & MSPOWERPOINT) && CurrentRegistrar->IsRegisteredFor(MSPOWERPOINT))
            CurrentRegistrar->UnregisterForMsPowerPoint();

        if ((Unregister & DEFAULT_HTML_EDITOR_FOR_IE) && CurrentRegistrar->IsRegisteredFor(DEFAULT_HTML_EDITOR_FOR_IE))
            CurrentRegistrar->UnregisterAsDefaultHtmlEditorForInternetExplorer();

        if ((Unregister & DEFAULT_SHELL_HTML_EDITOR) && CurrentRegistrar->IsRegisteredFor(DEFAULT_SHELL_HTML_EDITOR))
            CurrentRegistrar->UnregisterAsDefaultShellHtmlEditor();
    }
    catch(RegistryException&)
    {
        assert(false);
    }

    if (Unregister)
        SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0);
}

//-----------------------------------------
// restores the entries for the selected
// registry entries
// Algorithm:
//
// 1.
// Target key exist (e.g. '.doc')
// Default value == soffice.?
// Backup key != empty
// Action: Replace Default value with backup
// key
//
// 2.
// Target key exist
// Default value == soffice.?
// Backup key == empty
// Action: delete default value
//
// 3.
// Target key exist
// Default value != soffice.?
// Action: nop
//
// 4.
// Target key does not exist
// Action: nop
//-----------------------------------------

void Unregister4MsDocAll(MSIHANDLE handle)
{
    try
    {
        RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
        RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);

        CurrentRegistrar->UnregisterAllAndCleanUpRegistry();
    }
    catch(RegistryException&)
    {
        assert(false);
    }
}

//-----------------------------------------
// restores lost settings formerly made
// with Register4MsDoc
//-----------------------------------------

void RepairRegister4MsDocSettings(MSIHANDLE handle)
{
    try
    {
        RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
        RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);

        CurrentRegistrar->RepairRegistrationState();
    }
    catch(RegistryException&)
    {
        assert(false);
    }
}

bool IsRegisteredFor(MSIHANDLE handle, int State)
{
    bool Registered = false;

    try
    {
        RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
        RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);

        Registered = CurrentRegistrar->IsRegisteredFor(State);
    }
    catch(RegistryException&)
    {
        assert(false);
    }
    return Registered;
}

#define SO60_UNINSTALL_KEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\StarOffice 6.0"
#define SO_BACKUP_KEY      L"soffice6.bak"
#define REGMSDOCSTATE      L"Reg4MsDocState"
#define SOFTWARE_CLASSES   L"Software\\Classes"

int FixReturnRegistrationState(MSIHANDLE handle)
{
    int registration_state = 0;

    try
    {
        WindowsRegistry registry;

        RegistryValue rv_regmsdocstate = RegistryValue(
            new RegistryValueImpl(REGMSDOCSTATE, 0));

        RegistryKey so_bak_key;

        if (IsAllUserInstallation(handle))
        {
            RegistryKey hkcr_key = registry.GetClassesRootKey();

            if (hkcr_key->HasSubKey(SO_BACKUP_KEY))
                so_bak_key = hkcr_key->OpenSubKey(SO_BACKUP_KEY);
            else
                so_bak_key = hkcr_key->CreateSubKey(SO_BACKUP_KEY);

            if (!so_bak_key->HasValue(REGMSDOCSTATE))
            {
                // set a defined value
                so_bak_key->SetValue(rv_regmsdocstate);

                RegistryKey hklm_key = registry.GetLocalMachineKey();

                if (hklm_key->HasSubKey(SO60_UNINSTALL_KEY))
                {
                    RegistryKey so_uninst_key =
                        hklm_key->OpenSubKey(SO60_UNINSTALL_KEY);

                    if (so_uninst_key->HasValue(REGMSDOCSTATE))
                        so_bak_key->CopyValue(so_uninst_key, REGMSDOCSTATE);
                }
            }
        }
        else
        {
            RegistryKey hkcu_classes_key =
                registry.GetCurrentUserKey()->OpenSubKey(SOFTWARE_CLASSES);

            so_bak_key = hkcu_classes_key->CreateSubKey(SO_BACKUP_KEY);

            if (!so_bak_key->HasValue(REGMSDOCSTATE))
            {
                // set a defined value
                so_bak_key->SetValue(rv_regmsdocstate);

                RegistryKey hklm_sftw_classes =
                    registry.GetLocalMachineKey()->OpenSubKey(SOFTWARE_CLASSES, false);

                RegistryKey so_bak_key_old;

                if (hklm_sftw_classes->HasSubKey(SO_BACKUP_KEY))
                {
                    so_bak_key_old = hklm_sftw_classes->OpenSubKey(SO_BACKUP_KEY, false);

                    if (so_bak_key_old->HasValue(REGMSDOCSTATE))
                        so_bak_key->CopyValue(so_bak_key_old, REGMSDOCSTATE);
                }
                else // try the uninstall key
                {
                    RegistryKey hklm_key = registry.GetLocalMachineKey();

                    if (hklm_key->HasSubKey(SO60_UNINSTALL_KEY))
                    {
                        RegistryKey so_uninst_key =
                            hklm_key->OpenSubKey(SO60_UNINSTALL_KEY);

                        if (so_uninst_key->HasValue(REGMSDOCSTATE))
                            so_bak_key->CopyValue(so_uninst_key, REGMSDOCSTATE);
                    }
                }
            }
        }

        rv_regmsdocstate = so_bak_key->GetValue(REGMSDOCSTATE);
        registration_state = rv_regmsdocstate->GetDataAsInt();
    }
    catch(RegistryException&)
    {
        registration_state = 0;
    }

    return registration_state;
}

<|endoftext|>