<commit_before>/*************************************************************************
 *
 *  $RCSfile: olmenu.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: tl $ $Date: 2001-05-08 13:19:39 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _OLMENU_HXX
#define _OLMENU_HXX

#ifndef _COM_SUN_STAR_LINGUISTIC2_XDICTIONARY_HPP_
#include <com/sun/star/linguistic2/XDictionary.hpp>
#endif
#ifndef _COM_SUN_STAR_LINGUISTIC2_XSPELLALTERNATIVES_HPP_
#include <com/sun/star/linguistic2/XSpellAlternatives.hpp>
#endif

#ifndef _MENU_HXX //autogen
#include <vcl/menu.hxx>
#endif

class SwWrtShell;
class SvStringsDtor;

class SwSpellPopup : public PopupMenu
{
    SwWrtShell* pSh;
    ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XDictionary >  >     aDics;
    ::com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XSpellAlternatives > xSpellAlt;

    LanguageType                nCorrLang;

public:
    SwSpellPopup( SwWrtShell*,
            const ::com::sun::star::uno::Reference<
                ::com::sun::star::linguistic2::XSpellAlternatives >  &xAlt );

    sal_uInt16  Execute( Window* pWin, const Point& rPopupPos );
};

#endif

<commit_msg>INTEGRATION: CWS os17 (1.3.376); FILE MERGED 2004/04/28 08:45:28 os 1.3.376.1: #i18735# open spelling popup outside of the wrong word's rectangle<commit_after>/*************************************************************************
 *
 *  $RCSfile: olmenu.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: kz $ $Date: 2004-05-17 17:28:52 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _OLMENU_HXX
#define _OLMENU_HXX

#ifndef _COM_SUN_STAR_LINGUISTIC2_XDICTIONARY_HPP_
#include <com/sun/star/linguistic2/XDictionary.hpp>
#endif
#ifndef _COM_SUN_STAR_LINGUISTIC2_XSPELLALTERNATIVES_HPP_
#include <com/sun/star/linguistic2/XSpellAlternatives.hpp>
#endif

#ifndef _MENU_HXX //autogen
#include <vcl/menu.hxx>
#endif

class SwWrtShell;
class SvStringsDtor;

class SwSpellPopup : public PopupMenu
{
    SwWrtShell* pSh;
    ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XDictionary >  >     aDics;
    ::com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XSpellAlternatives > xSpellAlt;

    LanguageType                nCorrLang;

public:
    SwSpellPopup( SwWrtShell*,
            const ::com::sun::star::uno::Reference<
                ::com::sun::star::linguistic2::XSpellAlternatives >  &xAlt );

    sal_uInt16  Execute( Window* pWin, const Rectangle& rPopupPos );
};

#endif

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: swlbox.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: kz $ $Date: 2007-10-02 10:19:36 $
 *
 *  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 _SWLBOX_HXX
#define _SWLBOX_HXX

#ifndef _SVARRAY_HXX //autogen
#include <svtools/svarray.hxx>
#endif

#ifndef _LSTBOX_HXX //autogen
#include <vcl/lstbox.hxx>
#endif

#ifndef _COMBOBOX_HXX //autogen
#include <vcl/combobox.hxx>
#endif

#ifndef INCLUDED_SWDLLAPI_H
#include "swdllapi.h"
#endif

class SwBoxEntry;
class Window;

SV_DECL_PTRARR_DEL(SwEntryLst, SwBoxEntry*, 10, 10)

/*--------------------------------------------------------------------
     Beschreibung: SwBoxEntry
 --------------------------------------------------------------------*/

class SW_DLLPUBLIC SwBoxEntry
{
    friend class SwComboBox;

    BOOL    bModified : 1;
    BOOL    bNew : 1;

    String  aName;
    USHORT  nId;

public:
    SwBoxEntry(const String& aName, USHORT nId=0);
    SwBoxEntry(const SwBoxEntry& rOrg);
    SwBoxEntry();

    const String& GetName() const { return aName;}
};

/*--------------------------------------------------------------------
     Beschreibung: fuer ComboBoxen
 --------------------------------------------------------------------*/

typedef USHORT SwComboBoxStyle;
namespace nsSwComboBoxStyle
{
    const SwComboBoxStyle CBS_UPPER         = 0x01;
    const SwComboBoxStyle CBS_LOWER         = 0x02;
    const SwComboBoxStyle CBS_ALL           = 0x04;
    const SwComboBoxStyle CBS_FILENAME      = 0x08;
#ifdef WIN
    const SwComboBoxStyle CBS_SW_FILENAME   = CBS_FILENAME | CBS_LOWER;
#else
    const SwComboBoxStyle CBS_SW_FILENAME   = CBS_FILENAME;
#endif
}

class SW_DLLPUBLIC SwComboBox : public ComboBox
{
    SwEntryLst              aEntryLst;
    SwEntryLst              aDelEntryLst;
    SwBoxEntry              aDefault;
    USHORT                  nStyle;

    SW_DLLPRIVATE void                  InitComboBox();
    SW_DLLPRIVATE void                  InsertSorted(SwBoxEntry* pEntry);

public:
    SwComboBox(Window* pParent, const ResId& rId,
               USHORT nStyleBits = nsSwComboBoxStyle::CBS_ALL);
    ~SwComboBox();

    virtual void            KeyInput( const KeyEvent& rKEvt );

    using ComboBox::InsertEntry;
    void                    InsertEntry(const SwBoxEntry&);
    USHORT                  InsertEntry( const XubString& rStr, USHORT = 0)
                            {        InsertEntry( SwBoxEntry( rStr ) ); return 0;    }

    using ComboBox::RemoveEntry;
    void                    RemoveEntry(USHORT nPos);

    using ComboBox::GetEntryPos;
    USHORT                  GetEntryPos(const SwBoxEntry& rEntry) const;
    const SwBoxEntry&       GetEntry(USHORT) const;

    USHORT                  GetRemovedCount() const;
    const SwBoxEntry&       GetRemovedEntry(USHORT nPos) const;

    USHORT                  GetStyle() const            { return nStyle;    }
    using Window::SetStyle;
    void                    SetStyle(const USHORT nSt)  { nStyle = nSt;     }

    String                  GetText() const;
};

#endif /* _SWLBOX_HXX */
<commit_msg>INTEGRATION: CWS swusing (1.6.4); FILE MERGED 2007/10/12 09:58:34 tl 1.6.4.2: #i82476# make 'using' declarations private 2007/10/10 14:15:12 tl 1.6.4.1: #i82476# make newly added 'using' declarations private<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: swlbox.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: vg $ $Date: 2007-10-22 15:23:58 $
 *
 *  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 _SWLBOX_HXX
#define _SWLBOX_HXX

#ifndef _SVARRAY_HXX //autogen
#include <svtools/svarray.hxx>
#endif

#ifndef _LSTBOX_HXX //autogen
#include <vcl/lstbox.hxx>
#endif

#ifndef _COMBOBOX_HXX //autogen
#include <vcl/combobox.hxx>
#endif

#ifndef INCLUDED_SWDLLAPI_H
#include "swdllapi.h"
#endif

class SwBoxEntry;
class Window;

SV_DECL_PTRARR_DEL(SwEntryLst, SwBoxEntry*, 10, 10)

/*--------------------------------------------------------------------
     Beschreibung: SwBoxEntry
 --------------------------------------------------------------------*/

class SW_DLLPUBLIC SwBoxEntry
{
    friend class SwComboBox;

    BOOL    bModified : 1;
    BOOL    bNew : 1;

    String  aName;
    USHORT  nId;

public:
    SwBoxEntry(const String& aName, USHORT nId=0);
    SwBoxEntry(const SwBoxEntry& rOrg);
    SwBoxEntry();

    const String& GetName() const { return aName;}
};

/*--------------------------------------------------------------------
     Beschreibung: fuer ComboBoxen
 --------------------------------------------------------------------*/

typedef USHORT SwComboBoxStyle;
namespace nsSwComboBoxStyle
{
    const SwComboBoxStyle CBS_UPPER         = 0x01;
    const SwComboBoxStyle CBS_LOWER         = 0x02;
    const SwComboBoxStyle CBS_ALL           = 0x04;
    const SwComboBoxStyle CBS_FILENAME      = 0x08;
#ifdef WIN
    const SwComboBoxStyle CBS_SW_FILENAME   = CBS_FILENAME | CBS_LOWER;
#else
    const SwComboBoxStyle CBS_SW_FILENAME   = CBS_FILENAME;
#endif
}

class SW_DLLPUBLIC SwComboBox : public ComboBox
{
    SwEntryLst              aEntryLst;
    SwEntryLst              aDelEntryLst;
    SwBoxEntry              aDefault;
    USHORT                  nStyle;

    SW_DLLPRIVATE void                  InitComboBox();
    SW_DLLPRIVATE void                  InsertSorted(SwBoxEntry* pEntry);

    using ComboBox::InsertEntry;
    using ComboBox::RemoveEntry;
    using Window::SetStyle;

public:

    using ComboBox::GetEntryPos;

    SwComboBox(Window* pParent, const ResId& rId,
               USHORT nStyleBits = nsSwComboBoxStyle::CBS_ALL);
    ~SwComboBox();

    virtual void            KeyInput( const KeyEvent& rKEvt );

    void                    InsertEntry(const SwBoxEntry&);
    USHORT                  InsertEntry( const XubString& rStr, USHORT = 0)
                            {        InsertEntry( SwBoxEntry( rStr ) ); return 0;    }

    void                    RemoveEntry(USHORT nPos);

    USHORT                  GetEntryPos(const SwBoxEntry& rEntry) const;
    const SwBoxEntry&       GetEntry(USHORT) const;

    USHORT                  GetRemovedCount() const;
    const SwBoxEntry&       GetRemovedEntry(USHORT nPos) const;

    USHORT                  GetStyle() const            { return nStyle;    }
    void                    SetStyle(const USHORT nSt)  { nStyle = nSt;     }

    String                  GetText() const;
};

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


<commit_before>/* Generated from orogen/lib/orogen/templates/typekit/Plugin.cpp */

// First load all RTT interfaces so that we get all "extern template"
// declarations in the TypekitImpl files
#include "Plugin.hpp"

#include <iostream>
#include <boost/cstdint.hpp>
#include <boost/lexical_cast.hpp>

#include <rtt/types/TypeInfoRepository.hpp>
#include "type_info/Registration.hpp"

using namespace RTT;

orogen_typekits::<%= typekit.name %>TypekitPlugin::<%= typekit.name %>TypekitPlugin()
{}

orogen_typekits::<%= typekit.name %>TypekitPlugin::~<%= typekit.name %>TypekitPlugin()
{}

#define TYPEKIT_PACKAGE_NAME_aux0(target) #target
#define TYPEKIT_PACKAGE_NAME_aux(target) "<%= typekit.name %>-typekit-" TYPEKIT_PACKAGE_NAME_aux0(target)
#define TYPEKIT_PACKAGE_NAME TYPEKIT_PACKAGE_NAME_aux(OROCOS_TARGET)
bool orogen_typekits::<%= typekit.name %>TypekitPlugin::loadTypes()
{
    RTT::types::TypeInfoRepository::shared_ptr ti_repository = RTT::types::TypeInfoRepository::Instance();

    RTT::types::TypeInfoGenerator* ti = 0;
    <% registered_types.each do |type| %>
        <% if type < Typelib::ArrayType %>
    ti = <%= type.deference.method_name(true) %>_ArrayTypeInfo();
    if(!ti_repository->type(ti->getTypeName()))
    {
	ti_repository->addType( ti );
    }
        <% else %>
    ti = <%= type.method_name(true) %>_TypeInfo();
    if(!ti_repository->type(ti->getTypeName()))
    {
	ti_repository->addType( ti );
    }
        <% end %>
    <% end %>

    return true;
}

bool orogen_typekits::<%= typekit.name %>TypekitPlugin::loadOperators()
{ return true; }
bool orogen_typekits::<%= typekit.name %>TypekitPlugin::loadConstructors()
{ return true; }
std::string orogen_typekits::<%= typekit.name %>TypekitPlugin::getName()
{ return "/orogen/<%= typekit.name %>"; }

ORO_TYPEKIT_PLUGIN(orogen_typekits::<%= typekit.name %>TypekitPlugin);

<commit_msg>don't check for already registered types anymore<commit_after>/* Generated from orogen/lib/orogen/templates/typekit/Plugin.cpp */

// First load all RTT interfaces so that we get all "extern template"
// declarations in the TypekitImpl files
#include "Plugin.hpp"

#include <iostream>
#include <boost/cstdint.hpp>
#include <boost/lexical_cast.hpp>

#include <rtt/types/TypeInfoRepository.hpp>
#include "type_info/Registration.hpp"

using namespace RTT;

orogen_typekits::<%= typekit.name %>TypekitPlugin::<%= typekit.name %>TypekitPlugin()
{}

orogen_typekits::<%= typekit.name %>TypekitPlugin::~<%= typekit.name %>TypekitPlugin()
{}

#define TYPEKIT_PACKAGE_NAME_aux0(target) #target
#define TYPEKIT_PACKAGE_NAME_aux(target) "<%= typekit.name %>-typekit-" TYPEKIT_PACKAGE_NAME_aux0(target)
#define TYPEKIT_PACKAGE_NAME TYPEKIT_PACKAGE_NAME_aux(OROCOS_TARGET)
bool orogen_typekits::<%= typekit.name %>TypekitPlugin::loadTypes()
{
    RTT::types::TypeInfoRepository::shared_ptr ti_repository = RTT::types::TypeInfoRepository::Instance();

    RTT::types::TypeInfoGenerator* ti = 0;
    <% registered_types.each do |type| %>
        <% if type < Typelib::ArrayType %>
    ti = <%= type.deference.method_name(true) %>_ArrayTypeInfo();
    ti_repository->addType( ti );
        <% else %>
    ti = <%= type.method_name(true) %>_TypeInfo();
    ti_repository->addType( ti );
        <% end %>
    <% end %>

    return true;
}

bool orogen_typekits::<%= typekit.name %>TypekitPlugin::loadOperators()
{ return true; }
bool orogen_typekits::<%= typekit.name %>TypekitPlugin::loadConstructors()
{ return true; }
std::string orogen_typekits::<%= typekit.name %>TypekitPlugin::getName()
{ return "/orogen/<%= typekit.name %>"; }

ORO_TYPEKIT_PLUGIN(orogen_typekits::<%= typekit.name %>TypekitPlugin);

<|endoftext|>


<commit_before>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright 2011-2018 Dominik Charousset                                     *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#include "caf/io/network/interfaces.hpp"

#include "caf/config.hpp"

#include <algorithm>
#include <cerrno>
#include <cstdlib>
#include <cstring>

// clang-format off
#ifdef CAF_WINDOWS
#  ifndef _WIN32_WINNT
#    define _WIN32_WINNT 0x0600
#  endif
#  include <iostream>
#  include <winsock2.h>
#  include <ws2tcpip.h>
#  include <iphlpapi.h>
#else
#  include <arpa/inet.h>
#  include <ifaddrs.h>
#  include <net/if.h>
#  include <netdb.h>
#  include <netinet/in.h>
#  include <sys/ioctl.h>
#  include <sys/socket.h>
#  include <unistd.h>
#endif
// clang-format on

#include <memory>
#include <utility>

#include "caf/detail/get_mac_addresses.hpp"
#include "caf/io/network/ip_endpoint.hpp"
#include "caf/raise_error.hpp"

namespace caf {
namespace io {
namespace network {

// {interface_name => {protocol => address}}
using interfaces_map = std::map<
  std::string, std::map<protocol::network, std::vector<std::string>>>;

template <class T>
void* vptr(T* ptr) {
  return static_cast<void*>(ptr);
}

void* fetch_in_addr(int family, sockaddr* addr) {
  if (family == AF_INET)
    return vptr(&reinterpret_cast<sockaddr_in*>(addr)->sin_addr);
  return vptr(&reinterpret_cast<sockaddr_in6*>(addr)->sin6_addr);
}

int fetch_addr_str(bool get_ipv4, bool get_ipv6, char (&buf)[INET6_ADDRSTRLEN],
                   sockaddr* addr) {
  if (addr == nullptr)
    return AF_UNSPEC;
  auto family = addr->sa_family;
  auto in_addr = fetch_in_addr(family, addr);
  return ((family == AF_INET && get_ipv4) || (family == AF_INET6 && get_ipv6))
             && inet_ntop(family, in_addr, buf, INET6_ADDRSTRLEN) == buf
           ? family
           : AF_UNSPEC;
}

#ifdef CAF_WINDOWS

// F consumes `{interface_name, protocol, is_localhost, address}` entries.
template <class F>
void for_each_address(bool get_ipv4, bool get_ipv6, F fun) {
  ULONG tmp_size = 16 * 1024; // try 16kb buffer first
  IP_ADAPTER_ADDRESSES* tmp = nullptr;
  constexpr size_t max_tries = 3;
  size_t try_nr = 0;
  int retval = 0;
  do {
    if (tmp)
      free(tmp);
    tmp = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(malloc(tmp_size));
    if (!tmp)
      CAF_RAISE_ERROR("malloc() failed");
    retval = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr,
                                  tmp, &tmp_size);
  } while (retval == ERROR_BUFFER_OVERFLOW && ++try_nr < max_tries);
  std::unique_ptr<IP_ADAPTER_ADDRESSES, decltype(free)*> ifs{tmp, free};
  if (retval != NO_ERROR) {
    std::cerr << "Call to GetAdaptersAddresses failed with error: " << retval
              << std::endl;
    if (retval == ERROR_NO_DATA) {
      std::cerr << "No addresses were found for the requested parameters"
                << std::endl;
    } else {
      void* msgbuf = nullptr;
      if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
                          | FORMAT_MESSAGE_FROM_SYSTEM
                          | FORMAT_MESSAGE_IGNORE_INSERTS,
                        nullptr, retval,
                        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                        (LPTSTR) &msgbuf, 0, nullptr)) {
        printf("Error: %s", static_cast<char*>(msgbuf));
        LocalFree(msgbuf);
      }
    }
    return;
  }
  char buffer[INET6_ADDRSTRLEN];
  for (auto i = ifs.get(); i != nullptr; i = i->Next) {
    for (auto j = i->FirstUnicastAddress; j != nullptr; j = j->Next) {
      auto addr = j->Address.lpSockaddr;
      auto family = fetch_addr_str(get_ipv4, get_ipv6, buffer, addr);
      if (family != AF_UNSPEC)
        fun(i->AdapterName, family == AF_INET ? protocol::ipv4 : protocol::ipv6,
            false, buffer);
    }
  }
}

#else // ifdef CAF_WINDOWS

// F consumes `{interface_name, protocol, is_localhost, address}` entries.
template <class F>
void for_each_address(bool get_ipv4, bool get_ipv6, F fun) {
  ifaddrs* tmp = nullptr;
  if (getifaddrs(&tmp) != 0) {
    perror("getifaddrs");
    return;
  }
  char buffer[INET6_ADDRSTRLEN];
  std::unique_ptr<ifaddrs, decltype(freeifaddrs)*> ifs{tmp, freeifaddrs};
  for (auto i = ifs.get(); i != nullptr; i = i->ifa_next) {
    auto family = fetch_addr_str(get_ipv4, get_ipv6, buffer, i->ifa_addr);
    if (family != AF_UNSPEC)
      fun(i->ifa_name, family == AF_INET ? protocol::ipv4 : protocol::ipv6,
          (i->ifa_flags & IFF_LOOPBACK) != 0, buffer);
  }
}

#endif // ifdef CAF_WINDOWS

namespace {

template <class F>
void traverse_impl(std::initializer_list<protocol::network> ps, F f) {
  auto get_ipv4 = std::find(ps.begin(), ps.end(), protocol::ipv4) != ps.end();
  auto get_ipv6 = std::find(ps.begin(), ps.end(), protocol::ipv6) != ps.end();
  for_each_address(get_ipv4, get_ipv6, f);
}

} // namespace

void interfaces::traverse(std::initializer_list<protocol::network> ps,
                          consumer f) {
  traverse_impl(ps, std::move(f));
}

void interfaces::traverse(consumer f) {
  traverse_impl({protocol::ipv4, protocol::ipv6}, std::move(f));
}

interfaces_map interfaces::list_all(bool include_localhost) {
  interfaces_map result;
  traverse_impl({protocol::ipv4, protocol::ipv6},
                [&](const char* name, protocol::network p, bool lo,
                    const char* addr) {
                  if (include_localhost || !lo)
                    result[name][p].emplace_back(addr);
                });
  return result;
}

std::map<protocol::network, std::vector<std::string>>
interfaces::list_addresses(bool include_localhost) {
  std::map<protocol::network, std::vector<std::string>> result;
  traverse_impl({protocol::ipv4, protocol::ipv6},
                [&](const char*, protocol::network p, bool lo,
                    const char* addr) {
                  if (include_localhost || !lo)
                    result[p].emplace_back(addr);
                });
  return result;
}

std::vector<std::string>
interfaces::list_addresses(std::initializer_list<protocol::network> procs,
                           bool include_localhost) {
  std::vector<std::string> result;
  traverse_impl(procs,
                [&](const char*, protocol::network, bool lo, const char* addr) {
                  if (include_localhost || !lo)
                    result.emplace_back(addr);
                });
  return result;
}

std::vector<std::string> interfaces::list_addresses(protocol::network proc,
                                                    bool include_localhost) {
  return list_addresses({proc}, include_localhost);
}

optional<std::pair<std::string, protocol::network>>
interfaces::native_address(const std::string& host,
                           optional<protocol::network> preferred) {
  addrinfo hint;
  memset(&hint, 0, sizeof(hint));
  hint.ai_socktype = SOCK_STREAM;
  if (preferred)
    hint.ai_family = *preferred == protocol::ipv4 ? AF_INET : AF_INET6;
  addrinfo* tmp = nullptr;
  if (getaddrinfo(host.c_str(), nullptr, &hint, &tmp) != 0)
    return none;
  std::unique_ptr<addrinfo, decltype(freeaddrinfo)*> addrs{tmp, freeaddrinfo};
  char buffer[INET6_ADDRSTRLEN];
  for (auto i = addrs.get(); i != nullptr; i = i->ai_next) {
    auto family = fetch_addr_str(true, true, buffer, i->ai_addr);
    if (family != AF_UNSPEC)
      return std::make_pair(buffer, family == AF_INET ? protocol::ipv4
                                                      : protocol::ipv6);
  }
  return none;
}

std::vector<std::pair<std::string, protocol::network>>
interfaces::server_address(uint16_t port, const char* host,
                           optional<protocol::network> preferred) {
  using addr_pair = std::pair<std::string, protocol::network>;
  addrinfo hint;
  memset(&hint, 0, sizeof(hint));
  hint.ai_socktype = SOCK_STREAM;
  if (preferred)
    hint.ai_family = *preferred == protocol::ipv4 ? AF_INET : AF_INET6;
  else
    hint.ai_family = AF_UNSPEC;
  if (host == nullptr)
    hint.ai_flags = AI_PASSIVE;
  auto port_str = std::to_string(port);
  addrinfo* tmp = nullptr;
  if (getaddrinfo(host, port_str.c_str(), &hint, &tmp) != 0)
    return {};
  std::unique_ptr<addrinfo, decltype(freeaddrinfo)*> addrs{tmp, freeaddrinfo};
  char buffer[INET6_ADDRSTRLEN];
  // Take the first ipv6 address or the first available address otherwise
  std::vector<addr_pair> results;
  for (auto i = addrs.get(); i != nullptr; i = i->ai_next) {
    auto family = fetch_addr_str(true, true, buffer, i->ai_addr);
    if (family != AF_UNSPEC) {
      results.emplace_back(std::string{buffer},
                           family == AF_INET ? protocol::ipv4 : protocol::ipv6);
    }
  }
  std::stable_sort(std::begin(results), std::end(results),
                   [](const addr_pair& lhs, const addr_pair& rhs) {
                     return lhs.second > rhs.second;
                   });
  return results;
}

bool interfaces::get_endpoint(const std::string& host, uint16_t port,
                              ip_endpoint& ep,
                              optional<protocol::network> preferred) {
  static_assert(sizeof(uint16_t) == sizeof(unsigned short int),
                "uint16_t cannot be printed with %hu in snprintf");
  addrinfo hint;
  // max port is 2^16 which needs 5 characters plus null terminator
  char port_hint[6];
  sprintf(port_hint, "%hu", port);
  memset(&hint, 0, sizeof(hint));
  hint.ai_socktype = SOCK_DGRAM;
  if (preferred)
    hint.ai_family = *preferred == protocol::network::ipv4 ? AF_INET : AF_INET6;
#ifndef __OpenBSD__
  if (hint.ai_family == AF_INET6)
    hint.ai_flags = AI_V4MAPPED;
#endif
  addrinfo* tmp = nullptr;
  if (getaddrinfo(host.c_str(), port_hint, &hint, &tmp) != 0)
    return false;
  std::unique_ptr<addrinfo, decltype(freeaddrinfo)*> addrs{tmp, freeaddrinfo};
  for (auto i = addrs.get(); i != nullptr; i = i->ai_next) {
    if (i->ai_family != AF_UNSPEC) {
      memcpy(ep.address(), i->ai_addr, i->ai_addrlen);
      *ep.length() = i->ai_addrlen;
      return true;
    }
  }
  return false;
}

} // namespace network
} // namespace io
} // namespace caf
<commit_msg>Enable IPv4 mapping rather then exluding OpenBSD<commit_after>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright 2011-2018 Dominik Charousset                                     *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#include "caf/io/network/interfaces.hpp"

#include "caf/config.hpp"

#include <algorithm>
#include <cerrno>
#include <cstdlib>
#include <cstring>

// clang-format off
#ifdef CAF_WINDOWS
#  ifndef _WIN32_WINNT
#    define _WIN32_WINNT 0x0600
#  endif
#  include <iostream>
#  include <winsock2.h>
#  include <ws2tcpip.h>
#  include <iphlpapi.h>
#else
#  include <arpa/inet.h>
#  include <ifaddrs.h>
#  include <net/if.h>
#  include <netdb.h>
#  include <netinet/in.h>
#  include <sys/ioctl.h>
#  include <sys/socket.h>
#  include <unistd.h>
#endif
// clang-format on

#include <memory>
#include <utility>

#include "caf/detail/get_mac_addresses.hpp"
#include "caf/io/network/ip_endpoint.hpp"
#include "caf/raise_error.hpp"

namespace caf {
namespace io {
namespace network {

// {interface_name => {protocol => address}}
using interfaces_map = std::map<
  std::string, std::map<protocol::network, std::vector<std::string>>>;

template <class T>
void* vptr(T* ptr) {
  return static_cast<void*>(ptr);
}

void* fetch_in_addr(int family, sockaddr* addr) {
  if (family == AF_INET)
    return vptr(&reinterpret_cast<sockaddr_in*>(addr)->sin_addr);
  return vptr(&reinterpret_cast<sockaddr_in6*>(addr)->sin6_addr);
}

int fetch_addr_str(bool get_ipv4, bool get_ipv6, char (&buf)[INET6_ADDRSTRLEN],
                   sockaddr* addr) {
  if (addr == nullptr)
    return AF_UNSPEC;
  auto family = addr->sa_family;
  auto in_addr = fetch_in_addr(family, addr);
  return ((family == AF_INET && get_ipv4) || (family == AF_INET6 && get_ipv6))
             && inet_ntop(family, in_addr, buf, INET6_ADDRSTRLEN) == buf
           ? family
           : AF_UNSPEC;
}

#ifdef CAF_WINDOWS

// F consumes `{interface_name, protocol, is_localhost, address}` entries.
template <class F>
void for_each_address(bool get_ipv4, bool get_ipv6, F fun) {
  ULONG tmp_size = 16 * 1024; // try 16kb buffer first
  IP_ADAPTER_ADDRESSES* tmp = nullptr;
  constexpr size_t max_tries = 3;
  size_t try_nr = 0;
  int retval = 0;
  do {
    if (tmp)
      free(tmp);
    tmp = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(malloc(tmp_size));
    if (!tmp)
      CAF_RAISE_ERROR("malloc() failed");
    retval = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr,
                                  tmp, &tmp_size);
  } while (retval == ERROR_BUFFER_OVERFLOW && ++try_nr < max_tries);
  std::unique_ptr<IP_ADAPTER_ADDRESSES, decltype(free)*> ifs{tmp, free};
  if (retval != NO_ERROR) {
    std::cerr << "Call to GetAdaptersAddresses failed with error: " << retval
              << std::endl;
    if (retval == ERROR_NO_DATA) {
      std::cerr << "No addresses were found for the requested parameters"
                << std::endl;
    } else {
      void* msgbuf = nullptr;
      if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
                          | FORMAT_MESSAGE_FROM_SYSTEM
                          | FORMAT_MESSAGE_IGNORE_INSERTS,
                        nullptr, retval,
                        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                        (LPTSTR) &msgbuf, 0, nullptr)) {
        printf("Error: %s", static_cast<char*>(msgbuf));
        LocalFree(msgbuf);
      }
    }
    return;
  }
  char buffer[INET6_ADDRSTRLEN];
  for (auto i = ifs.get(); i != nullptr; i = i->Next) {
    for (auto j = i->FirstUnicastAddress; j != nullptr; j = j->Next) {
      auto addr = j->Address.lpSockaddr;
      auto family = fetch_addr_str(get_ipv4, get_ipv6, buffer, addr);
      if (family != AF_UNSPEC)
        fun(i->AdapterName, family == AF_INET ? protocol::ipv4 : protocol::ipv6,
            false, buffer);
    }
  }
}

#else // ifdef CAF_WINDOWS

// F consumes `{interface_name, protocol, is_localhost, address}` entries.
template <class F>
void for_each_address(bool get_ipv4, bool get_ipv6, F fun) {
  ifaddrs* tmp = nullptr;
  if (getifaddrs(&tmp) != 0) {
    perror("getifaddrs");
    return;
  }
  char buffer[INET6_ADDRSTRLEN];
  std::unique_ptr<ifaddrs, decltype(freeifaddrs)*> ifs{tmp, freeifaddrs};
  for (auto i = ifs.get(); i != nullptr; i = i->ifa_next) {
    auto family = fetch_addr_str(get_ipv4, get_ipv6, buffer, i->ifa_addr);
    if (family != AF_UNSPEC)
      fun(i->ifa_name, family == AF_INET ? protocol::ipv4 : protocol::ipv6,
          (i->ifa_flags & IFF_LOOPBACK) != 0, buffer);
  }
}

#endif // ifdef CAF_WINDOWS

namespace {

template <class F>
void traverse_impl(std::initializer_list<protocol::network> ps, F f) {
  auto get_ipv4 = std::find(ps.begin(), ps.end(), protocol::ipv4) != ps.end();
  auto get_ipv6 = std::find(ps.begin(), ps.end(), protocol::ipv6) != ps.end();
  for_each_address(get_ipv4, get_ipv6, f);
}

} // namespace

void interfaces::traverse(std::initializer_list<protocol::network> ps,
                          consumer f) {
  traverse_impl(ps, std::move(f));
}

void interfaces::traverse(consumer f) {
  traverse_impl({protocol::ipv4, protocol::ipv6}, std::move(f));
}

interfaces_map interfaces::list_all(bool include_localhost) {
  interfaces_map result;
  traverse_impl({protocol::ipv4, protocol::ipv6},
                [&](const char* name, protocol::network p, bool lo,
                    const char* addr) {
                  if (include_localhost || !lo)
                    result[name][p].emplace_back(addr);
                });
  return result;
}

std::map<protocol::network, std::vector<std::string>>
interfaces::list_addresses(bool include_localhost) {
  std::map<protocol::network, std::vector<std::string>> result;
  traverse_impl({protocol::ipv4, protocol::ipv6},
                [&](const char*, protocol::network p, bool lo,
                    const char* addr) {
                  if (include_localhost || !lo)
                    result[p].emplace_back(addr);
                });
  return result;
}

std::vector<std::string>
interfaces::list_addresses(std::initializer_list<protocol::network> procs,
                           bool include_localhost) {
  std::vector<std::string> result;
  traverse_impl(procs,
                [&](const char*, protocol::network, bool lo, const char* addr) {
                  if (include_localhost || !lo)
                    result.emplace_back(addr);
                });
  return result;
}

std::vector<std::string> interfaces::list_addresses(protocol::network proc,
                                                    bool include_localhost) {
  return list_addresses({proc}, include_localhost);
}

optional<std::pair<std::string, protocol::network>>
interfaces::native_address(const std::string& host,
                           optional<protocol::network> preferred) {
  addrinfo hint;
  memset(&hint, 0, sizeof(hint));
  hint.ai_socktype = SOCK_STREAM;
  if (preferred)
    hint.ai_family = *preferred == protocol::ipv4 ? AF_INET : AF_INET6;
  addrinfo* tmp = nullptr;
  if (getaddrinfo(host.c_str(), nullptr, &hint, &tmp) != 0)
    return none;
  std::unique_ptr<addrinfo, decltype(freeaddrinfo)*> addrs{tmp, freeaddrinfo};
  char buffer[INET6_ADDRSTRLEN];
  for (auto i = addrs.get(); i != nullptr; i = i->ai_next) {
    auto family = fetch_addr_str(true, true, buffer, i->ai_addr);
    if (family != AF_UNSPEC)
      return std::make_pair(buffer, family == AF_INET ? protocol::ipv4
                                                      : protocol::ipv6);
  }
  return none;
}

std::vector<std::pair<std::string, protocol::network>>
interfaces::server_address(uint16_t port, const char* host,
                           optional<protocol::network> preferred) {
  using addr_pair = std::pair<std::string, protocol::network>;
  addrinfo hint;
  memset(&hint, 0, sizeof(hint));
  hint.ai_socktype = SOCK_STREAM;
  if (preferred)
    hint.ai_family = *preferred == protocol::ipv4 ? AF_INET : AF_INET6;
  else
    hint.ai_family = AF_UNSPEC;
  if (host == nullptr)
    hint.ai_flags = AI_PASSIVE;
  auto port_str = std::to_string(port);
  addrinfo* tmp = nullptr;
  if (getaddrinfo(host, port_str.c_str(), &hint, &tmp) != 0)
    return {};
  std::unique_ptr<addrinfo, decltype(freeaddrinfo)*> addrs{tmp, freeaddrinfo};
  char buffer[INET6_ADDRSTRLEN];
  // Take the first ipv6 address or the first available address otherwise
  std::vector<addr_pair> results;
  for (auto i = addrs.get(); i != nullptr; i = i->ai_next) {
    auto family = fetch_addr_str(true, true, buffer, i->ai_addr);
    if (family != AF_UNSPEC) {
      results.emplace_back(std::string{buffer},
                           family == AF_INET ? protocol::ipv4 : protocol::ipv6);
    }
  }
  std::stable_sort(std::begin(results), std::end(results),
                   [](const addr_pair& lhs, const addr_pair& rhs) {
                     return lhs.second > rhs.second;
                   });
  return results;
}

bool interfaces::get_endpoint(const std::string& host, uint16_t port,
                              ip_endpoint& ep,
                              optional<protocol::network> preferred) {
  static_assert(sizeof(uint16_t) == sizeof(unsigned short int),
                "uint16_t cannot be printed with %hu in snprintf");
  addrinfo hint;
  // max port is 2^16 which needs 5 characters plus null terminator
  char port_hint[6];
  sprintf(port_hint, "%hu", port);
  memset(&hint, 0, sizeof(hint));
  hint.ai_socktype = SOCK_DGRAM;
  if (preferred)
    hint.ai_family = *preferred == protocol::network::ipv4 ? AF_INET : AF_INET6;
#ifdef AI_V4MAPPED
  if (hint.ai_family == AF_INET6)
    hint.ai_flags = AI_V4MAPPED;
#endif
  addrinfo* tmp = nullptr;
  if (getaddrinfo(host.c_str(), port_hint, &hint, &tmp) != 0)
    return false;
  std::unique_ptr<addrinfo, decltype(freeaddrinfo)*> addrs{tmp, freeaddrinfo};
  for (auto i = addrs.get(); i != nullptr; i = i->ai_next) {
    if (i->ai_family != AF_UNSPEC) {
      memcpy(ep.address(), i->ai_addr, i->ai_addrlen);
      *ep.length() = i->ai_addrlen;
      return true;
    }
  }
  return false;
}

} // namespace network
} // namespace io
} // namespace caf
<|endoftext|>


<commit_before>/*
    kopeteviewmanager.cpp - View Manager

    Copyright (c) 2003      by Jason Keirstead       <jason@keirstead.org>
    Kopete    (c) 2002-2005 by the Kopete developers <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This program is free software; you can redistribute it and/or modify  *
    * it under the terms of the GNU General Public License as published by  *
    * the Free Software Foundation; either version 2 of the License, or     *
    * (at your option) any later version.                                   *
    *                                                                       *
    *************************************************************************
*/

#include <kapplication.h>
#include <kconfig.h>
#include <kdebug.h>
#include <klocale.h>
#include <qptrlist.h>
#include <qstylesheet.h>
#include <kplugininfo.h>
#include <knotification.h>
#include <kglobal.h>
#include <kwin.h>

#include "kopeteprefs.h"
#include "kopeteaccount.h"
#include "kopetepluginmanager.h"
#include "kopeteviewplugin.h"
#include "kopetechatsessionmanager.h"
#include "kopetemetacontact.h"
#include "kopetenotifyevent.h"
#include "kopetemessageevent.h"
#include "kopeteview.h"
//#include "systemtray.h"

#include "kopeteviewmanager.h"

typedef QMap<Kopete::ChatSession*,KopeteView*> ManagerMap;
typedef QPtrList<Kopete::MessageEvent> EventList;

struct KopeteViewManagerPrivate
{
	ManagerMap managerMap;
	EventList eventList;
	KopeteView *activeView;

	bool useQueueOrStack;
	bool raiseWindow;
	bool queueUnreadMessages;
	bool queueOnlyHighlightedMessagesInGroupChats;
	bool queueOnlyMessagesOnAnotherDesktop;
	bool balloonNotifyIgnoreClosesChatView;
	bool foreignMessage;
};

KopeteViewManager *KopeteViewManager::s_viewManager = 0L;

KopeteViewManager *KopeteViewManager::viewManager()
{
	if( !s_viewManager )
		s_viewManager = new KopeteViewManager();
	return s_viewManager;
}

KopeteViewManager::KopeteViewManager()
{
	s_viewManager=this;
	d = new KopeteViewManagerPrivate;
	d->activeView = 0L;
	d->foreignMessage=false;

	connect( KopetePrefs::prefs(), SIGNAL( saved() ), this, SLOT( slotPrefsChanged() ) );

	connect( Kopete::ChatSessionManager::self() , SIGNAL( display( Kopete::Message &, Kopete::ChatSession *) ),
		this, SLOT ( messageAppended( Kopete::Message &, Kopete::ChatSession *) ) );

	connect( Kopete::ChatSessionManager::self() , SIGNAL( readMessage() ),
		this, SLOT ( nextEvent() ) );

	slotPrefsChanged();
}

KopeteViewManager::~KopeteViewManager()
{
// 	kdDebug(14000) << k_funcinfo << endl;

	//delete all open chatwindow.
	ManagerMap::Iterator it;
	for ( it = d->managerMap.begin(); it != d->managerMap.end(); ++it )
		it.data()->closeView( true ); //this does not clean the map, but we don't care

	delete d;
}

void KopeteViewManager::slotPrefsChanged()
{
	d->useQueueOrStack = KopetePrefs::prefs()->useQueue() || KopetePrefs::prefs()->useStack();
	d->raiseWindow = KopetePrefs::prefs()->raiseMsgWindow();
	d->queueUnreadMessages = KopetePrefs::prefs()->queueUnreadMessages();
	d->queueOnlyHighlightedMessagesInGroupChats = KopetePrefs::prefs()->queueOnlyHighlightedMessagesInGroupChats();
	d->queueOnlyMessagesOnAnotherDesktop = KopetePrefs::prefs()->queueOnlyMessagesOnAnotherDesktop();
	d->balloonNotifyIgnoreClosesChatView = KopetePrefs::prefs()->balloonNotifyIgnoreClosesChatView();
}

KopeteView *KopeteViewManager::view( Kopete::ChatSession* session, const QString &requestedPlugin )
{
// 	kdDebug(14000) << k_funcinfo << endl;

	if( d->managerMap.contains( session ) && d->managerMap[ session ] )
	{
		return d->managerMap[ session ];
	}
	else
	{
		Kopete::PluginManager *pluginManager = Kopete::PluginManager::self();
		Kopete::ViewPlugin *viewPlugin = 0L;

		QString pluginName = requestedPlugin.isEmpty() ? KopetePrefs::prefs()->interfacePreference() : requestedPlugin;
		if( !pluginName.isEmpty() )
		{
			viewPlugin = (Kopete::ViewPlugin*)pluginManager->loadPlugin( pluginName );

			if( !viewPlugin )
			{
				kdWarning(14000) << "Requested view plugin, " << pluginName <<
				    ", was not found. Falling back to chat window plugin" << endl;
			}
		}

		if( !viewPlugin )
			viewPlugin = (Kopete::ViewPlugin*)pluginManager->loadPlugin( QString::fromLatin1("kopete_chatwindow") );

		if( viewPlugin )
		{
			KopeteView *newView = viewPlugin->createView(session);

			d->foreignMessage = false;
			d->managerMap.insert( session, newView );

			connect( session, SIGNAL( closing(Kopete::ChatSession *) ),
					this, SLOT(slotChatSessionDestroyed(Kopete::ChatSession*)) );

			return newView;
		}
		else
		{
			kdError(14000) << "Could not create a view, no plugins available!" << endl;
			return 0L;
		}
	}
}

void KopeteViewManager::messageAppended( Kopete::Message &msg, Kopete::ChatSession *manager)
{
// 	kdDebug(14000) << k_funcinfo << endl;

	bool outgoingMessage = ( msg.direction() == Kopete::Message::Outbound );

	if( !outgoingMessage || d->managerMap.contains( manager ) )
	{
		d->foreignMessage=!outgoingMessage; //let know for the view we are about to create
		manager->view(true,msg.requestedPlugin())->appendMessage( msg );
		d->foreignMessage=false; //the view is created, reset the flag

		bool appendMessageEvent = d->useQueueOrStack;

		QWidget *w;
		if( d->queueUnreadMessages && ( w = dynamic_cast<QWidget*>(view( manager )) ) )
		{
			// append msg event to queue if chat window is active but not the chat view in it...
			appendMessageEvent = appendMessageEvent && !(w->isActiveWindow() && manager->view() == d->activeView);
			// ...and chat window is on another desktop
			appendMessageEvent = appendMessageEvent && (!d->queueOnlyMessagesOnAnotherDesktop || !KWin::windowInfo( w->topLevelWidget()->winId(), NET::WMDesktop ).isOnCurrentDesktop());
		}
		else
		{
			// append if no chat window exists already
			appendMessageEvent = appendMessageEvent && !view( manager )->isVisible();
		}

		// in group chats always append highlighted messages to queue
		appendMessageEvent = appendMessageEvent && (!d->queueOnlyHighlightedMessagesInGroupChats || manager->members().count() == 1 || msg.importance() == Kopete::Message::Highlight);

		if( appendMessageEvent )
		{
			if ( !outgoingMessage )
			{
				Kopete::MessageEvent *event=new Kopete::MessageEvent(msg,manager);
				d->eventList.append( event );
				connect(event, SIGNAL(done(Kopete::MessageEvent *)), this, SLOT(slotEventDeleted(Kopete::MessageEvent *)));
				Kopete::ChatSessionManager::self()->postNewEvent(event);
			}
		}
		else if( d->eventList.isEmpty() )
		{
			readMessages( manager, outgoingMessage );
		}

		if ( !outgoingMessage && ( !manager->account()->isAway() || KopetePrefs::prefs()->soundIfAway() ) )
		{
			QWidget *w=dynamic_cast<QWidget*>(manager->view(false));
			KConfig *config = KGlobal::config();
			config->setGroup("General");
			if( (!manager->view(false) || !w || manager->view() != d->activeView ||
						   config->readBoolEntry("EventIfActive", true) || !w->isActiveWindow())
						   && msg.from())
			{
				QString msgFrom = QString::null;
				if( msg.from()->metaContact() )
					msgFrom = msg.from()->metaContact()->displayName();
				else
					msgFrom = msg.from()->contactId();

				QString msgText = msg.plainBody();
				if( msgText.length() > 90 )
					msgText = msgText.left(88) + QString::fromLatin1("...");

				QString event;
				QString body =i18n( "<qt>Incoming message from %1
\"%2\"</qt>" );

				switch( msg.importance() )
				{
					case Kopete::Message::Low:
						event = QString::fromLatin1( "kopete_contact_lowpriority" );
						break;
					case Kopete::Message::Highlight:
						event = QString::fromLatin1( "kopete_contact_highlight" );
						body = i18n( "<qt>A highlighted message arrived from %1
\"%2\"</qt>" );
						break;
					default:
						event = QString::fromLatin1( "kopete_contact_incoming" );
				}
				KNotification *notify=KNotification::event(msg.from()->metaContact() , event, body.arg( QStyleSheet::escape(msgFrom), QStyleSheet::escape(msgText) ), 0, /*msg.from()->metaContact(),*/
							w , i18n("View") );

				connect(notify,SIGNAL(activated(unsigned int )), manager , SLOT(raiseView()) );
			}
		}
	}
}

void KopeteViewManager::readMessages( Kopete::ChatSession *manager, bool outgoingMessage, bool activate )
{
// 	kdDebug( 14000 ) << k_funcinfo << endl;
	d->foreignMessage=!outgoingMessage; //let know for the view we are about to create
	KopeteView *thisView = manager->view( true );
	d->foreignMessage=false; //the view is created, reset the flag
	if( ( outgoingMessage && !thisView->isVisible() ) || d->raiseWindow || activate )
		thisView->raise( activate );
	else if( !thisView->isVisible() )
		thisView->makeVisible();

	QPtrListIterator<Kopete::MessageEvent> it( d->eventList );
	Kopete::MessageEvent* event;
	while ( ( event = it.current() ) != 0 )
	{
		++it;
		if ( event->message().manager() == manager )
		{
			event->apply();
			d->eventList.remove( event );
		}
	}
}

void KopeteViewManager::slotEventDeleted( Kopete::MessageEvent *event )
{
// 	kdDebug(14000) << k_funcinfo << endl;
	Kopete::ChatSession *kmm=event->message().manager();
	if(!kmm)
		return;

	d->eventList.remove( event );

	if ( event->state() == Kopete::MessageEvent::Applied )
	{
		readMessages( kmm, false, true );
	}
	else if ( event->state() == Kopete::MessageEvent::Ignored && d->balloonNotifyIgnoreClosesChatView )
	{
		bool bAnotherWithThisManager = false;
		for( QPtrListIterator<Kopete::MessageEvent> it( d->eventList ); it; ++it )
		{
			Kopete::MessageEvent *event = it.current();
			if ( event->message().manager() == kmm )
				bAnotherWithThisManager = true;
		}
		if ( !bAnotherWithThisManager && kmm->view( false ) )
			kmm->view()->closeView( true );
	}
}

void KopeteViewManager::nextEvent()
{
// 	kdDebug( 14000 ) << k_funcinfo << endl;

	if( d->eventList.isEmpty() )
		return;

	Kopete::MessageEvent* event = d->eventList.first();

	if ( event )
		event->apply();
}

void KopeteViewManager::slotViewActivated( KopeteView *view )
{
// 	kdDebug( 14000 ) << k_funcinfo << endl;
	d->activeView = view;

	QPtrListIterator<Kopete::MessageEvent> it ( d->eventList );
	Kopete::MessageEvent* event;
	while ( ( event = it.current() ) != 0 )
	{
		++it;
		if ( event->message().manager() == view->msgManager() )
			event->deleteLater();
	}

}

void KopeteViewManager::slotViewDestroyed( KopeteView *closingView )
{
// 	kdDebug( 14000 ) << k_funcinfo << endl;

	if( d->managerMap.contains( closingView->msgManager() ) )
	{
		d->managerMap.remove( closingView->msgManager() );
//		closingView->msgManager()->setCanBeDeleted( true );
	}

	if( closingView == d->activeView )
		d->activeView = 0L;
}

void KopeteViewManager::slotChatSessionDestroyed( Kopete::ChatSession *manager )
{
// 	kdDebug( 14000 ) << k_funcinfo << endl;

	if( d->managerMap.contains( manager ) )
	{
		d->managerMap[ manager ]->closeView( true );
	}
}

KopeteView* KopeteViewManager::activeView() const
{
	return d->activeView;
}

#include "kopeteviewmanager.moc"

// vim: set noet ts=4 sts=4 sw=4:

<commit_msg>don't notify internal messages<commit_after>/*
    kopeteviewmanager.cpp - View Manager

    Copyright (c) 2003      by Jason Keirstead       <jason@keirstead.org>
    Kopete    (c) 2002-2005 by the Kopete developers <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This program is free software; you can redistribute it and/or modify  *
    * it under the terms of the GNU General Public License as published by  *
    * the Free Software Foundation; either version 2 of the License, or     *
    * (at your option) any later version.                                   *
    *                                                                       *
    *************************************************************************
*/

#include <kapplication.h>
#include <kconfig.h>
#include <kdebug.h>
#include <klocale.h>
#include <qptrlist.h>
#include <qstylesheet.h>
#include <kplugininfo.h>
#include <knotification.h>
#include <kglobal.h>
#include <kwin.h>

#include "kopeteprefs.h"
#include "kopeteaccount.h"
#include "kopetepluginmanager.h"
#include "kopeteviewplugin.h"
#include "kopetechatsessionmanager.h"
#include "kopetemetacontact.h"
#include "kopetenotifyevent.h"
#include "kopetemessageevent.h"
#include "kopeteview.h"
//#include "systemtray.h"

#include "kopeteviewmanager.h"

typedef QMap<Kopete::ChatSession*,KopeteView*> ManagerMap;
typedef QPtrList<Kopete::MessageEvent> EventList;

struct KopeteViewManagerPrivate
{
	ManagerMap managerMap;
	EventList eventList;
	KopeteView *activeView;

	bool useQueueOrStack;
	bool raiseWindow;
	bool queueUnreadMessages;
	bool queueOnlyHighlightedMessagesInGroupChats;
	bool queueOnlyMessagesOnAnotherDesktop;
	bool balloonNotifyIgnoreClosesChatView;
	bool foreignMessage;
};

KopeteViewManager *KopeteViewManager::s_viewManager = 0L;

KopeteViewManager *KopeteViewManager::viewManager()
{
	if( !s_viewManager )
		s_viewManager = new KopeteViewManager();
	return s_viewManager;
}

KopeteViewManager::KopeteViewManager()
{
	s_viewManager=this;
	d = new KopeteViewManagerPrivate;
	d->activeView = 0L;
	d->foreignMessage=false;

	connect( KopetePrefs::prefs(), SIGNAL( saved() ), this, SLOT( slotPrefsChanged() ) );

	connect( Kopete::ChatSessionManager::self() , SIGNAL( display( Kopete::Message &, Kopete::ChatSession *) ),
		this, SLOT ( messageAppended( Kopete::Message &, Kopete::ChatSession *) ) );

	connect( Kopete::ChatSessionManager::self() , SIGNAL( readMessage() ),
		this, SLOT ( nextEvent() ) );

	slotPrefsChanged();
}

KopeteViewManager::~KopeteViewManager()
{
// 	kdDebug(14000) << k_funcinfo << endl;

	//delete all open chatwindow.
	ManagerMap::Iterator it;
	for ( it = d->managerMap.begin(); it != d->managerMap.end(); ++it )
		it.data()->closeView( true ); //this does not clean the map, but we don't care

	delete d;
}

void KopeteViewManager::slotPrefsChanged()
{
	d->useQueueOrStack = KopetePrefs::prefs()->useQueue() || KopetePrefs::prefs()->useStack();
	d->raiseWindow = KopetePrefs::prefs()->raiseMsgWindow();
	d->queueUnreadMessages = KopetePrefs::prefs()->queueUnreadMessages();
	d->queueOnlyHighlightedMessagesInGroupChats = KopetePrefs::prefs()->queueOnlyHighlightedMessagesInGroupChats();
	d->queueOnlyMessagesOnAnotherDesktop = KopetePrefs::prefs()->queueOnlyMessagesOnAnotherDesktop();
	d->balloonNotifyIgnoreClosesChatView = KopetePrefs::prefs()->balloonNotifyIgnoreClosesChatView();
}

KopeteView *KopeteViewManager::view( Kopete::ChatSession* session, const QString &requestedPlugin )
{
// 	kdDebug(14000) << k_funcinfo << endl;

	if( d->managerMap.contains( session ) && d->managerMap[ session ] )
	{
		return d->managerMap[ session ];
	}
	else
	{
		Kopete::PluginManager *pluginManager = Kopete::PluginManager::self();
		Kopete::ViewPlugin *viewPlugin = 0L;

		QString pluginName = requestedPlugin.isEmpty() ? KopetePrefs::prefs()->interfacePreference() : requestedPlugin;
		if( !pluginName.isEmpty() )
		{
			viewPlugin = (Kopete::ViewPlugin*)pluginManager->loadPlugin( pluginName );

			if( !viewPlugin )
			{
				kdWarning(14000) << "Requested view plugin, " << pluginName <<
				    ", was not found. Falling back to chat window plugin" << endl;
			}
		}

		if( !viewPlugin )
			viewPlugin = (Kopete::ViewPlugin*)pluginManager->loadPlugin( QString::fromLatin1("kopete_chatwindow") );

		if( viewPlugin )
		{
			KopeteView *newView = viewPlugin->createView(session);

			d->foreignMessage = false;
			d->managerMap.insert( session, newView );

			connect( session, SIGNAL( closing(Kopete::ChatSession *) ),
					this, SLOT(slotChatSessionDestroyed(Kopete::ChatSession*)) );

			return newView;
		}
		else
		{
			kdError(14000) << "Could not create a view, no plugins available!" << endl;
			return 0L;
		}
	}
}

void KopeteViewManager::messageAppended( Kopete::Message &msg, Kopete::ChatSession *manager)
{
// 	kdDebug(14000) << k_funcinfo << endl;

	bool outgoingMessage = ( msg.direction() == Kopete::Message::Outbound );

	if( !outgoingMessage || d->managerMap.contains( manager ) )
	{
		d->foreignMessage=!outgoingMessage; //let know for the view we are about to create
		manager->view(true,msg.requestedPlugin())->appendMessage( msg );
		d->foreignMessage=false; //the view is created, reset the flag

		bool appendMessageEvent = d->useQueueOrStack;

		QWidget *w;
		if( d->queueUnreadMessages && ( w = dynamic_cast<QWidget*>(view( manager )) ) )
		{
			// append msg event to queue if chat window is active but not the chat view in it...
			appendMessageEvent = appendMessageEvent && !(w->isActiveWindow() && manager->view() == d->activeView);
			// ...and chat window is on another desktop
			appendMessageEvent = appendMessageEvent && (!d->queueOnlyMessagesOnAnotherDesktop || !KWin::windowInfo( w->topLevelWidget()->winId(), NET::WMDesktop ).isOnCurrentDesktop());
		}
		else
		{
			// append if no chat window exists already
			appendMessageEvent = appendMessageEvent && !view( manager )->isVisible();
		}

		// in group chats always append highlighted messages to queue
		appendMessageEvent = appendMessageEvent && (!d->queueOnlyHighlightedMessagesInGroupChats || manager->members().count() == 1 || msg.importance() == Kopete::Message::Highlight);

		if( appendMessageEvent )
		{
			if ( !outgoingMessage )
			{
				Kopete::MessageEvent *event=new Kopete::MessageEvent(msg,manager);
				d->eventList.append( event );
				connect(event, SIGNAL(done(Kopete::MessageEvent *)), this, SLOT(slotEventDeleted(Kopete::MessageEvent *)));
				Kopete::ChatSessionManager::self()->postNewEvent(event);
			}
		}
		else if( d->eventList.isEmpty() )
		{
			readMessages( manager, outgoingMessage );
		}

		if ( !outgoingMessage && ( !manager->account()->isAway() || KopetePrefs::prefs()->soundIfAway() )
				&& msg.direction() != Kopete::Message::Internal )
		{
			QWidget *w=dynamic_cast<QWidget*>(manager->view(false));
			KConfig *config = KGlobal::config();
			config->setGroup("General");
			if( (!manager->view(false) || !w || manager->view() != d->activeView ||
						   config->readBoolEntry("EventIfActive", true) || !w->isActiveWindow())
						   && msg.from())
			{
				QString msgFrom = QString::null;
				if( msg.from()->metaContact() )
					msgFrom = msg.from()->metaContact()->displayName();
				else
					msgFrom = msg.from()->contactId();

				QString msgText = msg.plainBody();
				if( msgText.length() > 90 )
					msgText = msgText.left(88) + QString::fromLatin1("...");

				QString event;
				QString body =i18n( "<qt>Incoming message from %1
\"%2\"</qt>" );

				switch( msg.importance() )
				{
					case Kopete::Message::Low:
						event = QString::fromLatin1( "kopete_contact_lowpriority" );
						break;
					case Kopete::Message::Highlight:
						event = QString::fromLatin1( "kopete_contact_highlight" );
						body = i18n( "<qt>A highlighted message arrived from %1
\"%2\"</qt>" );
						break;
					default:
						event = QString::fromLatin1( "kopete_contact_incoming" );
				}
				KNotification *notify=KNotification::event(msg.from()->metaContact() , event, body.arg( QStyleSheet::escape(msgFrom), QStyleSheet::escape(msgText) ), 0, /*msg.from()->metaContact(),*/
							w , i18n("View") );

				connect(notify,SIGNAL(activated(unsigned int )), manager , SLOT(raiseView()) );
			}
		}
	}
}

void KopeteViewManager::readMessages( Kopete::ChatSession *manager, bool outgoingMessage, bool activate )
{
// 	kdDebug( 14000 ) << k_funcinfo << endl;
	d->foreignMessage=!outgoingMessage; //let know for the view we are about to create
	KopeteView *thisView = manager->view( true );
	d->foreignMessage=false; //the view is created, reset the flag
	if( ( outgoingMessage && !thisView->isVisible() ) || d->raiseWindow || activate )
		thisView->raise( activate );
	else if( !thisView->isVisible() )
		thisView->makeVisible();

	QPtrListIterator<Kopete::MessageEvent> it( d->eventList );
	Kopete::MessageEvent* event;
	while ( ( event = it.current() ) != 0 )
	{
		++it;
		if ( event->message().manager() == manager )
		{
			event->apply();
			d->eventList.remove( event );
		}
	}
}

void KopeteViewManager::slotEventDeleted( Kopete::MessageEvent *event )
{
// 	kdDebug(14000) << k_funcinfo << endl;
	Kopete::ChatSession *kmm=event->message().manager();
	if(!kmm)
		return;

	d->eventList.remove( event );

	if ( event->state() == Kopete::MessageEvent::Applied )
	{
		readMessages( kmm, false, true );
	}
	else if ( event->state() == Kopete::MessageEvent::Ignored && d->balloonNotifyIgnoreClosesChatView )
	{
		bool bAnotherWithThisManager = false;
		for( QPtrListIterator<Kopete::MessageEvent> it( d->eventList ); it; ++it )
		{
			Kopete::MessageEvent *event = it.current();
			if ( event->message().manager() == kmm )
				bAnotherWithThisManager = true;
		}
		if ( !bAnotherWithThisManager && kmm->view( false ) )
			kmm->view()->closeView( true );
	}
}

void KopeteViewManager::nextEvent()
{
// 	kdDebug( 14000 ) << k_funcinfo << endl;

	if( d->eventList.isEmpty() )
		return;

	Kopete::MessageEvent* event = d->eventList.first();

	if ( event )
		event->apply();
}

void KopeteViewManager::slotViewActivated( KopeteView *view )
{
// 	kdDebug( 14000 ) << k_funcinfo << endl;
	d->activeView = view;

	QPtrListIterator<Kopete::MessageEvent> it ( d->eventList );
	Kopete::MessageEvent* event;
	while ( ( event = it.current() ) != 0 )
	{
		++it;
		if ( event->message().manager() == view->msgManager() )
			event->deleteLater();
	}

}

void KopeteViewManager::slotViewDestroyed( KopeteView *closingView )
{
// 	kdDebug( 14000 ) << k_funcinfo << endl;

	if( d->managerMap.contains( closingView->msgManager() ) )
	{
		d->managerMap.remove( closingView->msgManager() );
//		closingView->msgManager()->setCanBeDeleted( true );
	}

	if( closingView == d->activeView )
		d->activeView = 0L;
}

void KopeteViewManager::slotChatSessionDestroyed( Kopete::ChatSession *manager )
{
// 	kdDebug( 14000 ) << k_funcinfo << endl;

	if( d->managerMap.contains( manager ) )
	{
		d->managerMap[ manager ]->closeView( true );
	}
}

KopeteView* KopeteViewManager::activeView() const
{
	return d->activeView;
}

#include "kopeteviewmanager.moc"

// vim: set noet ts=4 sts=4 sw=4:

<|endoftext|>


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

#include <oh/Platform.hpp>
#include "MonoDefs.hpp"
#include "MonoDomain.hpp"
#include "MonoSystem.hpp"
///these includes are for fiddling around
#include "MonoAssembly.hpp"
#include "MonoClass.hpp"
#include "MonoObject.hpp"
#include "MonoVWObjectScriptManager.hpp"
#include "MonoArray.hpp"
#include "oh/ObjectScriptManagerFactory.hpp"
#include "MonoException.hpp"
#include "MonoHostedObjectExports.hpp"
#include "MonoContext.hpp"
static int core_plugin_refcount = 0;
Mono::MonoSystem * mono_system;

bool loadDependencyAssembly(Mono::MonoSystem*mono_system, const Sirikata::String&assembly) {
    return   mono_system->loadAssembly(assembly,"../../../dependencies/IronPython")
        || mono_system->loadAssembly(assembly,"../../../dependencies/Cecil")
        ||mono_system->loadAssembly(assembly,"../../dependencies/IronPython")
        ||mono_system->loadAssembly(assembly,"../../dependencies/Cecil")
        ||mono_system->loadAssembly(assembly,".")
        ||mono_system->loadAssembly(assembly,"bin")
        ||mono_system->loadAssembly(assembly,"dependencies/IronPython")
        ||mono_system->loadAssembly(assembly,"dependencies/Cecil");
}
bool loadCustomAssembly(Mono::MonoSystem*mono_system, const Sirikata::String&assembly) {
    return
            mono_system->loadAssembly(assembly,".")
            ||mono_system->loadAssembly(assembly,"bin")
            ||mono_system->loadAssembly(assembly,"Release")
            ||mono_system->loadAssembly(assembly,"Debug");
}

SIRIKATA_PLUGIN_EXPORT_C void init() {
    using namespace Sirikata;
    if (core_plugin_refcount==0) {
        mono_system = new Mono::MonoSystem();
        ObjectScriptManagerFactory::getSingleton().registerConstructor("monoscript",
                                                                       std::tr1::bind(&Sirikata::MonoVWObjectScriptManager::createObjectScriptManager,mono_system,_1),
                                                                       true);
        MonoContext::getSingleton().initializeThread();
        Sirikata::InitHostedObjectExports();
        Mono::Domain d=mono_system->createDomain();
        bool retval=loadDependencyAssembly(mono_system,"Microsoft.Scripting");
        retval=loadDependencyAssembly(mono_system,"IronPython")&&retval;
        retval=loadDependencyAssembly(mono_system,"IronPython.Modules")&&retval;

        bool testretval=loadCustomAssembly(mono_system,"Sirikata.Runtime");
        /*
        Mono::Assembly ass=d.getAssembly("Sirikata.Runtime");
        Mono::Class cls =ass.getClass("PythonObject");
        Mono::Object monoobj=cls.instance(d.Array(d.String(String()).type(),0));
        try {
            monoobj.send("processRPC",d.ByteArray("",0),d.String("rpctest"),d.ByteArray("",0));
            monoobj.send("tick",d.Time(Time::now()));
        }catch (Mono::Exception&e) {
            SILOG(mono,error,"Error processing rpc"<<e);
        }
        */
        printf ("Mono Initialized %d %d \n",(int) retval, (int) testretval);

    }
    core_plugin_refcount++;
}

SIRIKATA_PLUGIN_EXPORT_C int increfcount() {
    return ++core_plugin_refcount;
}
SIRIKATA_PLUGIN_EXPORT_C int decrefcount() {
    assert(core_plugin_refcount>0);
    return --core_plugin_refcount;
}

SIRIKATA_PLUGIN_EXPORT_C void destroy() {
    using namespace Sirikata;
    if (core_plugin_refcount>0) {
        core_plugin_refcount--;
        assert(core_plugin_refcount==0);
        if (core_plugin_refcount==0) {
            ObjectScriptManagerFactory::getSingleton().unregisterConstructor("monoscript",true);
            delete mono_system;
        }
    }
}

SIRIKATA_PLUGIN_EXPORT_C const char* name() {
    return "mono";
}
SIRIKATA_PLUGIN_EXPORT_C int refcount() {
    return core_plugin_refcount;
}
<commit_msg>made C# load the protobuf C# plugin as well<commit_after>/*  Sirikata Graphical Object Host
 *  MonoPlugin.cpp
 *
 *  Copyright (c) 2009, Daniel Reiter Horn
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of Sirikata nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <oh/Platform.hpp>
#include "MonoDefs.hpp"
#include "MonoDomain.hpp"
#include "MonoSystem.hpp"
///these includes are for fiddling around
#include "MonoAssembly.hpp"
#include "MonoClass.hpp"
#include "MonoObject.hpp"
#include "MonoVWObjectScriptManager.hpp"
#include "MonoArray.hpp"
#include "oh/ObjectScriptManagerFactory.hpp"
#include "MonoException.hpp"
#include "MonoHostedObjectExports.hpp"
#include "MonoContext.hpp"
static int core_plugin_refcount = 0;
Mono::MonoSystem * mono_system;

bool loadDependencyAssembly(Mono::MonoSystem*mono_system, const Sirikata::String&assembly) {
    return   mono_system->loadAssembly(assembly,"../../../dependencies/IronPython")
        || mono_system->loadAssembly(assembly,"../../../dependencies/Cecil")
        ||mono_system->loadAssembly(assembly,"../../dependencies/IronPython")
        ||mono_system->loadAssembly(assembly,"../../dependencies/Cecil")
        ||mono_system->loadAssembly(assembly,".")
        ||mono_system->loadAssembly(assembly,"bin")
        ||mono_system->loadAssembly(assembly,"dependencies/IronPython")
        ||mono_system->loadAssembly(assembly,"dependencies/Cecil");
}
bool loadCustomAssembly(Mono::MonoSystem*mono_system, const Sirikata::String&assembly) {
    return
            mono_system->loadAssembly(assembly,".")
            ||mono_system->loadAssembly(assembly,"bin")
            ||mono_system->loadAssembly(assembly,"Release")
            ||mono_system->loadAssembly(assembly,"Debug");
}

SIRIKATA_PLUGIN_EXPORT_C void init() {
    using namespace Sirikata;
    if (core_plugin_refcount==0) {
        mono_system = new Mono::MonoSystem();
        ObjectScriptManagerFactory::getSingleton().registerConstructor("monoscript",
                                                                       std::tr1::bind(&Sirikata::MonoVWObjectScriptManager::createObjectScriptManager,mono_system,_1),
                                                                       true);
        MonoContext::getSingleton().initializeThread();
        Sirikata::InitHostedObjectExports();
        Mono::Domain d=mono_system->createDomain();
        bool retval=loadDependencyAssembly(mono_system,"Microsoft.Scripting");
        retval=loadDependencyAssembly(mono_system,"IronPython")&&retval;
        retval=loadDependencyAssembly(mono_system,"IronPython.Modules")&&retval;

        bool testretval=loadCustomAssembly(mono_system,"Sirikata.Runtime")&&
            loadCustomAssembly(mono_system,"Sirikata.Protocol");
        /*
        Mono::Assembly ass=d.getAssembly("Sirikata.Runtime");
        Mono::Class cls =ass.getClass("PythonObject");
        Mono::Object monoobj=cls.instance(d.Array(d.String(String()).type(),0));
        try {
            monoobj.send("processRPC",d.ByteArray("",0),d.String("rpctest"),d.ByteArray("",0));
            monoobj.send("tick",d.Time(Time::now()));
        }catch (Mono::Exception&e) {
            SILOG(mono,error,"Error processing rpc"<<e);
        }
        */
        printf ("Mono Initialized %d %d \n",(int) retval, (int) testretval);

    }
    core_plugin_refcount++;
}

SIRIKATA_PLUGIN_EXPORT_C int increfcount() {
    return ++core_plugin_refcount;
}
SIRIKATA_PLUGIN_EXPORT_C int decrefcount() {
    assert(core_plugin_refcount>0);
    return --core_plugin_refcount;
}

SIRIKATA_PLUGIN_EXPORT_C void destroy() {
    using namespace Sirikata;
    if (core_plugin_refcount>0) {
        core_plugin_refcount--;
        assert(core_plugin_refcount==0);
        if (core_plugin_refcount==0) {
            ObjectScriptManagerFactory::getSingleton().unregisterConstructor("monoscript",true);
            delete mono_system;
        }
    }
}

SIRIKATA_PLUGIN_EXPORT_C const char* name() {
    return "mono";
}
SIRIKATA_PLUGIN_EXPORT_C int refcount() {
    return core_plugin_refcount;
}
<|endoftext|>


<commit_before>
// STL includes
#include <cassert>

// Hyperion includes
#include "MultiColorTransform.h"

MultiColorTransform::MultiColorTransform(const unsigned ledCnt) :
	_ledTransforms(ledCnt, nullptr)
{
}

MultiColorTransform::~MultiColorTransform()
{
	// Clean up all the transforms
	for (ColorTransform * transform : _transform)
	{
		delete transform;
	}
}

void MultiColorTransform::addTransform(ColorTransform * transform)
{
	_transformIds.push_back(transform->_id);
	_transform.push_back(transform);
}

void MultiColorTransform::setTransformForLed(const std::string& id, const unsigned startLed, const unsigned endLed)
{
	assert(startLed <= endLed);
	assert(endLed < _ledTransforms.size());

	// Get the identified transform (don't care if is nullptr)
	ColorTransform * transform = getTransform(id);
	for (unsigned iLed=startLed; iLed<=endLed; ++iLed)
	{
		_ledTransforms[iLed] = transform;
	}
}

bool MultiColorTransform::verifyTransforms() const
{
	bool allLedsSet = true;
	for (unsigned iLed=0; iLed<_ledTransforms.size(); ++iLed)
	{
		if (_ledTransforms[iLed] == nullptr)
		{
			std::cerr << "No transform set for " << iLed << std::endl;
			allLedsSet = false;
		}
	}
	return allLedsSet;
}

const std::vector<std::string> & MultiColorTransform::getTransformIds()
{
	return _transformIds;
}

ColorTransform* MultiColorTransform::getTransform(const std::string& id)
{
	// Iterate through the unique transforms until we find the one with the given id
	for (ColorTransform* transform : _transform)
	{
		if (transform->_id == id)
		{
			return transform;
		}
	}

	// The ColorTransform was not found
	return nullptr;
}

std::vector<ColorRgb> MultiColorTransform::applyTransform(const std::vector<ColorRgb>& rawColors)
{
	// Create a copy, as we will do the rest of the transformation in place
	std::vector<ColorRgb> ledColors(rawColors);

	const size_t itCnt = std::min(_ledTransforms.size(), rawColors.size());
	for (size_t i=0; i<itCnt; ++i)
	{
		ColorTransform* transform = _ledTransforms[i];
		if (transform == nullptr)
		{
			// No transform set for this led (do nothing)
			continue;
		}
		ColorRgb& color = ledColors[i];

		transform->_hsvTransform.transform(color.red, color.green, color.blue);
		color.red   = transform->_rgbRedTransform.transform(color.red);
		color.green = transform->_rgbGreenTransform.transform(color.green);
		color.blue  = transform->_rgbBlueTransform.transform(color.blue);
	}
	return ledColors;
}
<commit_msg>Update MultiColorTransform.cpp<commit_after>
// STL includes
#include <cassert>

// Hyperion includes
#include "MultiColorTransform.h"

MultiColorTransform::MultiColorTransform(const unsigned ledCnt) :
	_ledTransforms(ledCnt, nullptr)
{
}

MultiColorTransform::~MultiColorTransform()
{
	// Clean up all the transforms
	for (ColorTransform * transform : _transform)
	{
		delete transform;
	}
}

void MultiColorTransform::addTransform(ColorTransform * transform)
{
	_transformIds.push_back(transform->_id);
	_transform.push_back(transform);
}

void MultiColorTransform::setTransformForLed(const std::string& id, const unsigned startLed, const unsigned endLed)
{
	assert(startLed <= endLed);
	assert(endLed < _ledTransforms.size());

	// Get the identified transform (don't care if is nullptr)
	ColorTransform * transform = getTransform(id);
	for (unsigned iLed=startLed; iLed<=endLed; ++iLed)
	{
		_ledTransforms[iLed] = transform;
	}
}

bool MultiColorTransform::verifyTransforms() const
{
	bool allLedsSet = true;
	for (unsigned iLed=0; iLed<_ledTransforms.size(); ++iLed)
	{
		if (_ledTransforms[iLed] == nullptr)
		{
			std::cerr << "No transform set for " << iLed << std::endl;
			allLedsSet = false;
		}
	}
	return allLedsSet;
}

const std::vector<std::string> & MultiColorTransform::getTransformIds()
{
	return _transformIds;
}

ColorTransform* MultiColorTransform::getTransform(const std::string& id)
{
	// Iterate through the unique transforms until we find the one with the given id
	for (ColorTransform* transform : _transform)
	{
		if (transform->_id == id)
		{
			return transform;
		}
	}

	// The ColorTransform was not found
	return nullptr;
}

std::vector<ColorRgb> MultiColorTransform::applyTransform(const std::vector<ColorRgb>& rawColors)
{
	// Create a copy, as we will do the rest of the transformation in place
	std::vector<ColorRgb> ledColors(rawColors);

	const size_t itCnt = std::min(_ledTransforms.size(), rawColors.size());
	for (size_t i=0; i<itCnt; ++i)
	{
		ColorTransform* transform = _ledTransforms[i];
		if (transform == nullptr)
		{
			// No transform set for this led (do nothing)
			continue;
		}
		ColorRgb& color = ledColors[i];

		transform->_hsvTransform.transform(color.red, color.green, color.blue);
		transform->_hslTransform.transform(color.red, color.green, color.blue);
		color.red   = transform->_rgbRedTransform.transform(color.red);
		color.green = transform->_rgbGreenTransform.transform(color.green);
		color.blue  = transform->_rgbBlueTransform.transform(color.blue);
	}
	return ledColors;
}
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/ref_counted.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/debugger/devtools_manager.h"
#include "chrome/browser/debugger/devtools_client_host.h"
#include "chrome/browser/extensions/extension_devtools_browsertest.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/site_instance.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/views/extensions/extension_shelf.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/devtools_messages.h"
#include "chrome/common/extensions/extension_error_reporter.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/ui_test_utils.h"
#include "net/base/net_util.h"

// Looks for an ExtensionHost whose URL has the given path component (including
// leading slash).  Also verifies that the expected number of hosts are loaded.
static ExtensionHost* FindHostWithPath(ExtensionProcessManager* manager,
                                       const std::string& path,
                                       int expected_hosts) {
  ExtensionHost* host = NULL;
  int num_hosts = 0;
  for (ExtensionProcessManager::const_iterator iter = manager->begin();
       iter != manager->end(); ++iter) {
    if ((*iter)->GetURL().path() == path) {
      EXPECT_FALSE(host);
      host = *iter;
    }
    num_hosts++;
  }
  EXPECT_EQ(expected_hosts, num_hosts);
  EXPECT_TRUE(host);
  return host;
}

// Tests for the experimental timeline extensions API.
IN_PROC_BROWSER_TEST_F(ExtensionDevToolsBrowserTest, DISABLED_TimelineApi) {
  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("devtools").AppendASCII("timeline_api")));

  // Get the ExtensionHost that is hosting our background page.
  ExtensionProcessManager* manager =
      browser()->profile()->GetExtensionProcessManager();
  ExtensionHost* host = FindHostWithPath(manager, "/background.html", 1);

  // Grab a handle to the DevToolsManager so we can forward messages to it.
  DevToolsManager* devtools_manager = DevToolsManager::GetInstance();

  // Grab the tab_id of whatever tab happens to be first.
  TabContents* tab_contents = browser()->tabstrip_model()->GetTabContentsAt(0);
  ASSERT_TRUE(tab_contents);
  int tab_id = ExtensionTabUtil::GetTabId(tab_contents);

  // Test setup.
  bool result = false;
  std::wstring register_listeners_js = StringPrintf(L"setListenersOnTab(%d)",
                                                    tab_id);
  ui_test_utils::ExecuteJavaScriptAndExtractBool(
      host->render_view_host(), L"", register_listeners_js, &result);
  EXPECT_TRUE(result);

  // Setting the events should have caused an ExtensionDevToolsBridge to be
  // registered for the tab's RenderViewHost.
  DevToolsClientHost* devtools_client_host =
      devtools_manager->GetDevToolsClientHostFor(
          tab_contents->render_view_host());
  ASSERT_TRUE(devtools_client_host);

  // Test onPageEvent event.
  result = false;

  DevToolsMessageData message_data;
  message_data.class_name = "ApuAgentDelegate";
  message_data.method_name = "DispatchToApu";
  message_data.arguments.push_back("");
  DevToolsClientMsg_RpcMessage pageEventMessage(message_data);
  devtools_client_host->SendMessageToClient(pageEventMessage);
  ui_test_utils::ExecuteJavaScriptAndExtractBool(
      host->render_view_host(), L"", L"testReceivePageEvent()", &result);
  EXPECT_TRUE(result);

  // Test onTabClose event.
  result = false;
  devtools_manager->UnregisterDevToolsClientHostFor(
      tab_contents->render_view_host());
  ui_test_utils::ExecuteJavaScriptAndExtractBool(
      host->render_view_host(), L"", L"testReceiveTabCloseEvent()", &result);
  EXPECT_TRUE(result);
}

// Tests that ref counting of listeners from multiple processes works.
IN_PROC_BROWSER_TEST_F(ExtensionDevToolsBrowserTest, ProcessRefCounting) {
  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("devtools").AppendASCII("timeline_api")));

  // Get the ExtensionHost that is hosting our background page.
  ExtensionProcessManager* manager =
      browser()->profile()->GetExtensionProcessManager();
  ExtensionHost* host_one = FindHostWithPath(manager, "/background.html", 1);

  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("devtools").AppendASCII("timeline_api_two")));
  ExtensionHost* host_two = FindHostWithPath(manager,
                                             "/background_two.html", 2);

  DevToolsManager* devtools_manager = DevToolsManager::GetInstance();

  // Grab the tab_id of whatever tab happens to be first.
  TabContents* tab_contents = browser()->tabstrip_model()->GetTabContentsAt(0);
  ASSERT_TRUE(tab_contents);
  int tab_id = ExtensionTabUtil::GetTabId(tab_contents);

  // Test setup.
  bool result = false;
  std::wstring register_listeners_js = StringPrintf(L"setListenersOnTab(%d)",
                                                    tab_id);
  ui_test_utils::ExecuteJavaScriptAndExtractBool(
      host_one->render_view_host(), L"", register_listeners_js, &result);
  EXPECT_TRUE(result);

  // Setting the event listeners should have caused an ExtensionDevToolsBridge
  // to be registered for the tab's RenderViewHost.
  ASSERT_TRUE(devtools_manager->GetDevToolsClientHostFor(
      tab_contents->render_view_host()));

  // Register listeners from the second extension as well.
  std::wstring script = StringPrintf(L"registerListenersForTab(%d)", tab_id);
  ui_test_utils::ExecuteJavaScriptAndExtractBool(
      host_two->render_view_host(), L"", script, &result);
  EXPECT_TRUE(result);

  // Removing the listeners from the first extension should leave the bridge
  // alive.
  result = false;
  ui_test_utils::ExecuteJavaScriptAndExtractBool(
      host_one->render_view_host(), L"", L"unregisterListeners()", &result);
  EXPECT_TRUE(result);
  ASSERT_TRUE(devtools_manager->GetDevToolsClientHostFor(
      tab_contents->render_view_host()));

  // Removing the listeners from the second extension should tear the bridge
  // down.
  result = false;
  ui_test_utils::ExecuteJavaScriptAndExtractBool(
      host_two->render_view_host(), L"", L"unregisterListeners()", &result);
  EXPECT_TRUE(result);
  ASSERT_FALSE(devtools_manager->GetDevToolsClientHostFor(
      tab_contents->render_view_host()));
}
<commit_msg>Reenable ExtensionDevToolsBrowserTest.TimelineApi<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/ref_counted.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/debugger/devtools_manager.h"
#include "chrome/browser/debugger/devtools_client_host.h"
#include "chrome/browser/extensions/extension_devtools_browsertest.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/site_instance.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/views/extensions/extension_shelf.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/devtools_messages.h"
#include "chrome/common/extensions/extension_error_reporter.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/ui_test_utils.h"
#include "net/base/net_util.h"

// Looks for an ExtensionHost whose URL has the given path component (including
// leading slash).  Also verifies that the expected number of hosts are loaded.
static ExtensionHost* FindHostWithPath(ExtensionProcessManager* manager,
                                       const std::string& path,
                                       int expected_hosts) {
  ExtensionHost* host = NULL;
  int num_hosts = 0;
  for (ExtensionProcessManager::const_iterator iter = manager->begin();
       iter != manager->end(); ++iter) {
    if ((*iter)->GetURL().path() == path) {
      EXPECT_FALSE(host);
      host = *iter;
    }
    num_hosts++;
  }
  EXPECT_EQ(expected_hosts, num_hosts);
  EXPECT_TRUE(host);
  return host;
}

// Tests for the experimental timeline extensions API.
IN_PROC_BROWSER_TEST_F(ExtensionDevToolsBrowserTest, TimelineApi) {
  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("devtools").AppendASCII("timeline_api")));

  // Get the ExtensionHost that is hosting our background page.
  ExtensionProcessManager* manager =
      browser()->profile()->GetExtensionProcessManager();
  ExtensionHost* host = FindHostWithPath(manager, "/background.html", 1);

  // Grab a handle to the DevToolsManager so we can forward messages to it.
  DevToolsManager* devtools_manager = DevToolsManager::GetInstance();

  // Grab the tab_id of whatever tab happens to be first.
  TabContents* tab_contents = browser()->tabstrip_model()->GetTabContentsAt(0);
  ASSERT_TRUE(tab_contents);
  int tab_id = ExtensionTabUtil::GetTabId(tab_contents);

  // Test setup.
  bool result = false;
  std::wstring register_listeners_js = StringPrintf(L"setListenersOnTab(%d)",
                                                    tab_id);
  ui_test_utils::ExecuteJavaScriptAndExtractBool(
      host->render_view_host(), L"", register_listeners_js, &result);
  EXPECT_TRUE(result);

  // Setting the events should have caused an ExtensionDevToolsBridge to be
  // registered for the tab's RenderViewHost.
  DevToolsClientHost* devtools_client_host =
      devtools_manager->GetDevToolsClientHostFor(
          tab_contents->render_view_host());
  ASSERT_TRUE(devtools_client_host);

  // Test onPageEvent event.
  result = false;

  DevToolsMessageData message_data;
  message_data.class_name = "ApuAgentDelegate";
  message_data.method_name = "DispatchToApu";
  message_data.arguments.push_back("");
  DevToolsClientMsg_RpcMessage pageEventMessage(message_data);
  devtools_client_host->SendMessageToClient(pageEventMessage);
  ui_test_utils::ExecuteJavaScriptAndExtractBool(
      host->render_view_host(), L"", L"testReceivePageEvent()", &result);
  EXPECT_TRUE(result);

  // Test onTabClose event.
  result = false;
  devtools_manager->UnregisterDevToolsClientHostFor(
      tab_contents->render_view_host());
  ui_test_utils::ExecuteJavaScriptAndExtractBool(
      host->render_view_host(), L"", L"testReceiveTabCloseEvent()", &result);
  EXPECT_TRUE(result);
}

// Tests that ref counting of listeners from multiple processes works.
IN_PROC_BROWSER_TEST_F(ExtensionDevToolsBrowserTest, ProcessRefCounting) {
  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("devtools").AppendASCII("timeline_api")));

  // Get the ExtensionHost that is hosting our background page.
  ExtensionProcessManager* manager =
      browser()->profile()->GetExtensionProcessManager();
  ExtensionHost* host_one = FindHostWithPath(manager, "/background.html", 1);

  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("devtools").AppendASCII("timeline_api_two")));
  ExtensionHost* host_two = FindHostWithPath(manager,
                                             "/background_two.html", 2);

  DevToolsManager* devtools_manager = DevToolsManager::GetInstance();

  // Grab the tab_id of whatever tab happens to be first.
  TabContents* tab_contents = browser()->tabstrip_model()->GetTabContentsAt(0);
  ASSERT_TRUE(tab_contents);
  int tab_id = ExtensionTabUtil::GetTabId(tab_contents);

  // Test setup.
  bool result = false;
  std::wstring register_listeners_js = StringPrintf(L"setListenersOnTab(%d)",
                                                    tab_id);
  ui_test_utils::ExecuteJavaScriptAndExtractBool(
      host_one->render_view_host(), L"", register_listeners_js, &result);
  EXPECT_TRUE(result);

  // Setting the event listeners should have caused an ExtensionDevToolsBridge
  // to be registered for the tab's RenderViewHost.
  ASSERT_TRUE(devtools_manager->GetDevToolsClientHostFor(
      tab_contents->render_view_host()));

  // Register listeners from the second extension as well.
  std::wstring script = StringPrintf(L"registerListenersForTab(%d)", tab_id);
  ui_test_utils::ExecuteJavaScriptAndExtractBool(
      host_two->render_view_host(), L"", script, &result);
  EXPECT_TRUE(result);

  // Removing the listeners from the first extension should leave the bridge
  // alive.
  result = false;
  ui_test_utils::ExecuteJavaScriptAndExtractBool(
      host_one->render_view_host(), L"", L"unregisterListeners()", &result);
  EXPECT_TRUE(result);
  ASSERT_TRUE(devtools_manager->GetDevToolsClientHostFor(
      tab_contents->render_view_host()));

  // Removing the listeners from the second extension should tear the bridge
  // down.
  result = false;
  ui_test_utils::ExecuteJavaScriptAndExtractBool(
      host_two->render_view_host(), L"", L"unregisterListeners()", &result);
  EXPECT_TRUE(result);
  ASSERT_FALSE(devtools_manager->GetDevToolsClientHostFor(
      tab_contents->render_view_host()));
}
<|endoftext|>