<commit_before>// Virvo - Virtual Reality Volume Rendering
// Copyright (C) 1999-2003 University of Stuttgart, 2004-2005 Brown University
// Contact: Jurgen P. Schulze, jschulze@ucsd.edu
//
// This file is part of Virvo.
//
// Virvo is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library (see license.txt); if not, write to the
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

#include "vvcocoaglcontext.h"
#include "vvdebugmsg.h"
#include "vvrendercontext.h"
#include "vvx11.h"

#include <sstream>
#include <vector>

struct ContextArchData
{
#ifdef USE_COCOA
  vvCocoaGLContext* cocoaContext;
#endif

#ifdef USE_X11
  GLXContext glxContext;
  Display* display;
  Drawable drawable;
  std::vector<int> attributes;
  GLXFBConfig* fbConfigs;
#endif
};

vvRenderContext::vvRenderContext(vvContextOptions* co)
  : _options(co)
{
  _archData = new ContextArchData;
  _initialized = false;
  init();
}

vvRenderContext::~vvRenderContext()
{
  vvDebugMsg::msg(1, "vvRenderContext::~vvRenderContext");

  if (_initialized)
  {
#ifdef USE_COCOA
    delete _archData->cocoaContext;
#endif

#ifdef USE_X11
    glXDestroyContext(_archData->display, _archData->glxContext);
    switch (_options->type)
    {
    case vvContextOptions::VV_PBUFFER:
      glXDestroyPbuffer(_archData->display, _archData->drawable);
      break;
    case vvContextOptions::VV_WINDOW:
      // fall through
    default:
      XDestroyWindow(_archData->display, _archData->drawable);
      break;
    }
    XCloseDisplay(_archData->display);
#endif
  }
  delete _archData;
}

bool vvRenderContext::makeCurrent() const
{
  if (_initialized)
  {
#ifdef USE_COCOA
    return _archData->cocoaContext->makeCurrent();
#endif

#if USE_X11
    return glXMakeCurrent(_archData->display, _archData->drawable, _archData->glxContext);
#endif
  }
  return false;
}

void vvRenderContext::swapBuffers() const
{
  if (_initialized)
  {
#ifdef USE_COCOA
    _archData->cocoaContext->swapBuffers();
#endif

#ifdef USE_X11
    glXSwapBuffers(_archData->display, _archData->drawable);
#endif
  }
}

void vvRenderContext::resize(const int w, const int h)
{
  if ((_options->width != w) || (_options->height != h))
  {
    _options->width = w;
    _options->height = h;
    if (_initialized)
    {
#ifdef USE_COCOA
      _archData->cocoaContext->resize(w, h);
#endif

#ifdef USE_X11
      switch (_options->type)
      {
      case vvContextOptions::VV_PBUFFER:
      {
        glXDestroyPbuffer(_archData->display, _archData->drawable);
        initPbuffer();
        makeCurrent();
        break;
      }
      case vvContextOptions::VV_WINDOW:
        // fall through
      default:
        XResizeWindow(_archData->display, _archData->drawable,
                      static_cast<uint>(w),
                      static_cast<uint>(h));
        XSync(_archData->display, False);
        break;
      }
#endif
    }
  }
}

void vvRenderContext::init()
{
#ifdef USE_COCOA
  _archData->cocoaContext = new vvCocoaGLContext(_options);
  _initialized = true;
#endif

#ifdef USE_X11
  _archData->display = XOpenDisplay(_options->displayName.c_str());

  _archData->attributes.push_back(GLX_RGBA);
  _archData->attributes.push_back(GLX_RED_SIZE);
  _archData->attributes.push_back(8);
  _archData->attributes.push_back(GLX_GREEN_SIZE);
  _archData->attributes.push_back(8);
  _archData->attributes.push_back(GLX_BLUE_SIZE);
  _archData->attributes.push_back(8);
  _archData->attributes.push_back(GLX_ALPHA_SIZE);
  _archData->attributes.push_back(8);
  _archData->attributes.push_back(GLX_DEPTH_SIZE);
  _archData->attributes.push_back(24);
  _archData->attributes.push_back(None);

  if(_archData->display != NULL)
  {
    switch(_options->type)
    {
    case vvContextOptions::VV_PBUFFER:
      if (initPbuffer())
      {
         _archData->glxContext = glXCreateNewContext(_archData->display, _archData->fbConfigs[0], GLX_RGBA_TYPE, 0, True);
        _initialized = true;
        return;
      }
      else
      {
        _options->type = vvContextOptions::VV_WINDOW;
      }
      // no pbuffer created - fall through
    case vvContextOptions::VV_WINDOW:
      // fall through
    default:
      {
        const Drawable parent = RootWindow(_archData->display, DefaultScreen(_archData->display));

        XVisualInfo* vi = glXChooseVisual(_archData->display,
                                          DefaultScreen(_archData->display),
                                          &(_archData->attributes)[0]);

        XSetWindowAttributes wa = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        wa.colormap = XCreateColormap(_archData->display, parent, vi->visual, AllocNone);
        wa.background_pixmap = None;
        wa.border_pixel = 0;

        if (vvDebugMsg::getDebugLevel() == 0)
        {
          wa.override_redirect = true;
        }
        else
        {
          wa.override_redirect = false;
        }

        _archData->glxContext = glXCreateContext(_archData->display, vi, NULL, True);

        if (_archData->glxContext != 0)
        {

          int windowWidth = _options->width;
          int windowHeight = _options->height;
          if (vvDebugMsg::getDebugLevel() > 0)
          {
            windowWidth = 512;
            windowHeight = 512;
          }

          _archData->drawable = XCreateWindow(_archData->display, parent, 0, 0, windowWidth, windowHeight, 0,
                                              vi->depth, InputOutput, vi->visual,
                                              CWBackPixmap|CWBorderPixel|CWColormap|CWOverrideRedirect, &wa);
          XMapWindow(_archData->display, _archData->drawable);
          XFlush(_archData->display);
          _initialized = true;
        }
        else
        {
          vvDebugMsg::msg( 0, "Couldn't create OpenGL context");
          _initialized = false;
        }
        _initialized = true;
        delete vi;
        break;
      }
    }
  }
  else
  {
    _initialized = false;
    std::ostringstream errmsg;
    errmsg << "vvRenderContext::init() error: Could not open display " << _options->displayName;
    vvDebugMsg::msg(0, errmsg.str().c_str());
  }
#endif
}

bool vvRenderContext::initPbuffer()
{
#ifdef USE_X11
  int nelements;
  _archData->fbConfigs = glXChooseFBConfig(_archData->display, DefaultScreen(_archData->display),
                                           &(_archData->attributes)[1], &nelements); // first entry (GLX_RGBA) in attributes list confuses pbuffers
  if ((_archData->fbConfigs != NULL) && (nelements > 0))
  {
    // TODO: find the nicest fbconfig.
    int pbAttrList[] = { GLX_PBUFFER_WIDTH, _options->width, GLX_PBUFFER_HEIGHT, _options->height, None };
    _archData->drawable = glXCreatePbuffer(_archData->display, _archData->fbConfigs[0], pbAttrList);
    if (!_archData->drawable)
    {
      std::cerr << "No pbuffer created" << std::endl;
      return false;
    }
    return true;
  }
#endif
  return false;
}
// vim: sw=2:expandtab:softtabstop=2:ts=2:cino=\:0g0t0

<commit_msg>Compile with covise under linux<commit_after>// Virvo - Virtual Reality Volume RenderingVE
// Copyright (C) 1999-2003 University of Stuttgart, 2004-2005 Brown University
// Contact: Jurgen P. Schulze, jschulze@ucsd.edu
//
// This file is part of Virvo.
//
// Virvo is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library (see license.txt); if not, write to the
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

#include "vvcocoaglcontext.h"
#include "vvdebugmsg.h"
#include "vvrendercontext.h"
#include "vvx11.h"

#include <sstream>
#include <vector>

struct ContextArchData
{
#ifdef USE_COCOA
  vvCocoaGLContext* cocoaContext;
#endif

#if defined(HAVE_X11) and defined(USE_X11)
  GLXContext glxContext;
  Display* display;
  Drawable drawable;
  std::vector<int> attributes;
  GLXFBConfig* fbConfigs;
#endif
};

vvRenderContext::vvRenderContext(vvContextOptions* co)
  : _options(co)
{
  _archData = new ContextArchData;
  _initialized = false;
  init();
}

vvRenderContext::~vvRenderContext()
{
  vvDebugMsg::msg(1, "vvRenderContext::~vvRenderContext");

  if (_initialized)
  {
#ifdef USE_COCOA
    delete _archData->cocoaContext;
#endif

#if defined(HAVE_X11) and defined(USE_X11)
    glXDestroyContext(_archData->display, _archData->glxContext);
    switch (_options->type)
    {
    case vvContextOptions::VV_PBUFFER:
      glXDestroyPbuffer(_archData->display, _archData->drawable);
      break;
    case vvContextOptions::VV_WINDOW:
      // fall through
    default:
      XDestroyWindow(_archData->display, _archData->drawable);
      break;
    }
    XCloseDisplay(_archData->display);
#endif
  }
  delete _archData;
}

bool vvRenderContext::makeCurrent() const
{
  if (_initialized)
  {
#ifdef USE_COCOA
    return _archData->cocoaContext->makeCurrent();
#endif

#if defined(HAVE_X11) and defined(USE_X11)
    return glXMakeCurrent(_archData->display, _archData->drawable, _archData->glxContext);
#endif
  }
  return false;
}

void vvRenderContext::swapBuffers() const
{
  if (_initialized)
  {
#ifdef USE_COCOA
    _archData->cocoaContext->swapBuffers();
#endif

#if defined(HAVE_X11) and defined(USE_X11)
    glXSwapBuffers(_archData->display, _archData->drawable);
#endif
  }
}

void vvRenderContext::resize(const int w, const int h)
{
  if ((_options->width != w) || (_options->height != h))
  {
    _options->width = w;
    _options->height = h;
    if (_initialized)
    {
#ifdef USE_COCOA
      _archData->cocoaContext->resize(w, h);
#endif

#if defined(HAVE_X11) and defined(USE_X11)
      switch (_options->type)
      {
      case vvContextOptions::VV_PBUFFER:
      {
        glXDestroyPbuffer(_archData->display, _archData->drawable);
        initPbuffer();
        makeCurrent();
        break;
      }
      case vvContextOptions::VV_WINDOW:
        // fall through
      default:
        XResizeWindow(_archData->display, _archData->drawable,
                      static_cast<uint>(w),
                      static_cast<uint>(h));
        XSync(_archData->display, False);
        break;
      }
#endif
    }
  }
}

void vvRenderContext::init()
{
#ifdef USE_COCOA
  _archData->cocoaContext = new vvCocoaGLContext(_options);
  _initialized = true;
#endif

#if defined(HAVE_X11) and defined(USE_X11)
  _archData->display = XOpenDisplay(_options->displayName.c_str());

  _archData->attributes.push_back(GLX_RGBA);
  _archData->attributes.push_back(GLX_RED_SIZE);
  _archData->attributes.push_back(8);
  _archData->attributes.push_back(GLX_GREEN_SIZE);
  _archData->attributes.push_back(8);
  _archData->attributes.push_back(GLX_BLUE_SIZE);
  _archData->attributes.push_back(8);
  _archData->attributes.push_back(GLX_ALPHA_SIZE);
  _archData->attributes.push_back(8);
  _archData->attributes.push_back(GLX_DEPTH_SIZE);
  _archData->attributes.push_back(24);
  _archData->attributes.push_back(None);

  if(_archData->display != NULL)
  {
    switch(_options->type)
    {
    case vvContextOptions::VV_PBUFFER:
      if (initPbuffer())
      {
         _archData->glxContext = glXCreateNewContext(_archData->display, _archData->fbConfigs[0], GLX_RGBA_TYPE, 0, True);
        _initialized = true;
        return;
      }
      else
      {
        _options->type = vvContextOptions::VV_WINDOW;
      }
      // no pbuffer created - fall through
    case vvContextOptions::VV_WINDOW:
      // fall through
    default:
      {
        const Drawable parent = RootWindow(_archData->display, DefaultScreen(_archData->display));

        XVisualInfo* vi = glXChooseVisual(_archData->display,
                                          DefaultScreen(_archData->display),
                                          &(_archData->attributes)[0]);

        XSetWindowAttributes wa = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        wa.colormap = XCreateColormap(_archData->display, parent, vi->visual, AllocNone);
        wa.background_pixmap = None;
        wa.border_pixel = 0;

        if (vvDebugMsg::getDebugLevel() == 0)
        {
          wa.override_redirect = true;
        }
        else
        {
          wa.override_redirect = false;
        }

        _archData->glxContext = glXCreateContext(_archData->display, vi, NULL, True);

        if (_archData->glxContext != 0)
        {

          int windowWidth = _options->width;
          int windowHeight = _options->height;
          if (vvDebugMsg::getDebugLevel() > 0)
          {
            windowWidth = 512;
            windowHeight = 512;
          }

          _archData->drawable = XCreateWindow(_archData->display, parent, 0, 0, windowWidth, windowHeight, 0,
                                              vi->depth, InputOutput, vi->visual,
                                              CWBackPixmap|CWBorderPixel|CWColormap|CWOverrideRedirect, &wa);
          XMapWindow(_archData->display, _archData->drawable);
          XFlush(_archData->display);
          _initialized = true;
        }
        else
        {
          vvDebugMsg::msg( 0, "Couldn't create OpenGL context");
          _initialized = false;
        }
        _initialized = true;
        delete vi;
        break;
      }
    }
  }
  else
  {
    _initialized = false;
    std::ostringstream errmsg;
    errmsg << "vvRenderContext::init() error: Could not open display " << _options->displayName;
    vvDebugMsg::msg(0, errmsg.str().c_str());
  }
#endif
}

bool vvRenderContext::initPbuffer()
{
#if defined(HAVE_X11) and defined(USE_X11)
  int nelements;
  _archData->fbConfigs = glXChooseFBConfig(_archData->display, DefaultScreen(_archData->display),
                                           &(_archData->attributes)[1], &nelements); // first entry (GLX_RGBA) in attributes list confuses pbuffers
  if ((_archData->fbConfigs != NULL) && (nelements > 0))
  {
    // TODO: find the nicest fbconfig.
    int pbAttrList[] = { GLX_PBUFFER_WIDTH, _options->width, GLX_PBUFFER_HEIGHT, _options->height, None };
    _archData->drawable = glXCreatePbuffer(_archData->display, _archData->fbConfigs[0], pbAttrList);
    if (!_archData->drawable)
    {
      std::cerr << "No pbuffer created" << std::endl;
      return false;
    }
    return true;
  }
#endif
  return false;
}
// vim: sw=2:expandtab:softtabstop=2:ts=2:cino=\:0g0t0

<|endoftext|>


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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_toolkit.hxx"

#ifndef TOOLKIT_HELPER_ACCESSIBILITY_CLIENT_HXX
#include <toolkit/helper/accessibilityclient.hxx>
#endif

#ifndef TOOLKIT_HELPER_ACCESSIBLE_FACTORY_HXX
#include <toolkit/helper/accessiblefactory.hxx>
#endif
#ifndef _OSL_MODULE_H_
#include <osl/module.h>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#ifndef _SOLAR_H
#include <tools/solar.h>
#endif

// #define UNLOAD_ON_LAST_CLIENT_DYING
    // this is not recommended currently. If enabled, the implementation will log
    // the number of active clients, and unload the acc library when the last client
    // goes away.
    // Sounds like a good idea, unfortunately, there's no guarantee that all objects
    // implemented in this library are already dead.
    // Iow, just because an object implementing an XAccessible (implemented in this lib
    // here) died, it's not said that everybody released all references to the
    // XAccessibleContext used by this component, and implemented in the acc lib.
    // So we cannot really unload the lib.
    //
    // Alternatively, if the lib would us own "usage counting", i.e. every component
    // implemented therein would affect a static ref count, the acc lib could care
    // for unloading itself.

//........................................................................
namespace toolkit
{
//........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::accessibility;

    namespace
    {
#ifdef UNLOAD_ON_LAST_CLIENT_DYING
        static oslInterlockedCount                      s_nAccessibilityClients = 0;
#endif // UNLOAD_ON_LAST_CLIENT_DYING
        static oslModule                                s_hAccessibleImplementationModule = NULL;
        static GetStandardAccComponentFactory           s_pAccessibleFactoryFunc = NULL;
        static ::rtl::Reference< IAccessibleFactory >   s_pFactory;
    }

    //====================================================================
    //= AccessibleDummyFactory
    //====================================================================
    class AccessibleDummyFactory : public IAccessibleFactory
    {
    public:
        AccessibleDummyFactory();

    protected:
        virtual ~AccessibleDummyFactory();

    private:
        AccessibleDummyFactory( const AccessibleDummyFactory& );            // never implemented
        AccessibleDummyFactory& operator=( const AccessibleDummyFactory& ); // never implemented

        oslInterlockedCount m_refCount;

    public:
        // IReference
        virtual oslInterlockedCount SAL_CALL acquire();
        virtual oslInterlockedCount SAL_CALL release();

        // IAccessibleFactory
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
                createAccessibleContext( VCLXButton* /*_pXWindow*/ )
        {
            return NULL;
        }
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
                createAccessibleContext( VCLXCheckBox* /*_pXWindow*/ )
        {
            return NULL;
        }
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
                createAccessibleContext( VCLXRadioButton* /*_pXWindow*/ )
        {
            return NULL;
        }
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
                createAccessibleContext( VCLXListBox* /*_pXWindow*/ )
        {
            return NULL;
        }
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
                createAccessibleContext( VCLXFixedText* /*_pXWindow*/ )
        {
            return NULL;
        }
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
                createAccessibleContext( VCLXScrollBar* /*_pXWindow*/ )
        {
            return NULL;
        }
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
                createAccessibleContext( VCLXEdit* /*_pXWindow*/ )
        {
            return NULL;
        }
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
                createAccessibleContext( VCLXComboBox* /*_pXWindow*/ )
        {
            return NULL;
        }
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
                createAccessibleContext( VCLXToolBox* /*_pXWindow*/ )
        {
            return NULL;
        }
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
                createAccessibleContext( VCLXWindow* /*_pXWindow*/ )
        {
            return NULL;
        }
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
                createAccessible( Menu* /*_pMenu*/, sal_Bool /*_bIsMenuBar*/ )
        {
            return NULL;
        }
    };

    //--------------------------------------------------------------------
    AccessibleDummyFactory::AccessibleDummyFactory()
    {
    }

    //--------------------------------------------------------------------
    AccessibleDummyFactory::~AccessibleDummyFactory()
    {
    }

    //--------------------------------------------------------------------
    oslInterlockedCount SAL_CALL AccessibleDummyFactory::acquire()
    {
        return osl_incrementInterlockedCount( &m_refCount );
    }

    //--------------------------------------------------------------------
    oslInterlockedCount SAL_CALL AccessibleDummyFactory::release()
    {
        if ( 0 == osl_decrementInterlockedCount( &m_refCount ) )
        {
            delete this;
            return 0;
        }
        return m_refCount;
    }

    //====================================================================
    //= AccessibilityClient
    //====================================================================
    //--------------------------------------------------------------------
    AccessibilityClient::AccessibilityClient()
        :m_bInitialized( false )
    {
    }

    //--------------------------------------------------------------------
    void AccessibilityClient::ensureInitialized()
    {
        if ( m_bInitialized )
            return;

        ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );

#ifdef UNLOAD_ON_LAST_CLIENT_DYING
        if ( 1 == osl_incrementInterlockedCount( &s_nAccessibilityClients ) )
        {   // the first client
#endif // UNLOAD_ON_LAST_CLIENT_DYING
            // load the library implementing the factory
            if ( !s_pFactory.get() )
            {
                const ::rtl::OUString sModuleName = ::rtl::OUString::createFromAscii(
                    SVLIBRARY( "acc" )
                );
                s_hAccessibleImplementationModule = osl_loadModule( sModuleName.pData, 0 );
                if ( s_hAccessibleImplementationModule != NULL )
                {
                    const ::rtl::OUString sFactoryCreationFunc =
                        ::rtl::OUString::createFromAscii( "getStandardAccessibleFactory" );
                    s_pAccessibleFactoryFunc = (GetStandardAccComponentFactory)
                        osl_getFunctionSymbol( s_hAccessibleImplementationModule, sFactoryCreationFunc.pData );

                }
                OSL_ENSURE( s_pAccessibleFactoryFunc, "AccessibilityClient::ensureInitialized: could not load the library, or not retrieve the needed symbol!" );

                // get a factory instance
                if ( s_pAccessibleFactoryFunc )
                {
                    IAccessibleFactory* pFactory = static_cast< IAccessibleFactory* >( (*s_pAccessibleFactoryFunc)() );
                    OSL_ENSURE( pFactory, "AccessibilityClient::ensureInitialized: no factory provided by the A11Y lib!" );
                    if ( pFactory )
                    {
                        s_pFactory = pFactory;
                        pFactory->release();
                    }
                }
            }

            if ( !s_pFactory.get() )
                // the attempt to load the lib, or to create the factory, failed
                // -> fall back to a dummy factory
                s_pFactory = new AccessibleDummyFactory;
#ifdef UNLOAD_ON_LAST_CLIENT_DYING
        }
#endif

        m_bInitialized = true;
    }

    //--------------------------------------------------------------------
    AccessibilityClient::~AccessibilityClient()
    {
        if ( m_bInitialized )
        {
            ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );

#ifdef UNLOAD_ON_LAST_CLIENT_DYING
            if( 0 == osl_decrementInterlockedCount( &s_nAccessibilityClients ) )
            {
                s_pFactory = NULL;
                s_pAccessibleFactoryFunc = NULL;
                if ( s_hAccessibleImplementationModule )
                {
                    osl_unloadModule( s_hAccessibleImplementationModule );
                    s_hAccessibleImplementationModule = NULL;
                }
            }
#endif // UNLOAD_ON_LAST_CLIENT_DYING
        }
    }

    //--------------------------------------------------------------------
    IAccessibleFactory& AccessibilityClient::getFactory()
    {
        ensureInitialized();
        OSL_ENSURE( s_pFactory.is(), "AccessibilityClient::getFactory: at least a dummy factory should have been created!" );
        return *s_pFactory;
    }

//........................................................................
}   // namespace toolkit
//........................................................................
<commit_msg>INTEGRATION: CWS sb71 (1.2.14); FILE MERGED 2007/08/23 15:41:14 sb 1.2.14.2: RESYNC: (1.2-1.3); FILE MERGED 2007/07/23 11:33:44 sb 1.2.14.1: #i75466# Use osl_loadModuleRelative when loading with a relative path.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: accessibilityclient.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: vg $ $Date: 2007-10-15 11:51:33 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_toolkit.hxx"

#ifndef TOOLKIT_HELPER_ACCESSIBILITY_CLIENT_HXX
#include <toolkit/helper/accessibilityclient.hxx>
#endif

#ifndef TOOLKIT_HELPER_ACCESSIBLE_FACTORY_HXX
#include <toolkit/helper/accessiblefactory.hxx>
#endif
#ifndef _OSL_MODULE_H_
#include <osl/module.h>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#ifndef _SOLAR_H
#include <tools/solar.h>
#endif

// #define UNLOAD_ON_LAST_CLIENT_DYING
    // this is not recommended currently. If enabled, the implementation will log
    // the number of active clients, and unload the acc library when the last client
    // goes away.
    // Sounds like a good idea, unfortunately, there's no guarantee that all objects
    // implemented in this library are already dead.
    // Iow, just because an object implementing an XAccessible (implemented in this lib
    // here) died, it's not said that everybody released all references to the
    // XAccessibleContext used by this component, and implemented in the acc lib.
    // So we cannot really unload the lib.
    //
    // Alternatively, if the lib would us own "usage counting", i.e. every component
    // implemented therein would affect a static ref count, the acc lib could care
    // for unloading itself.

//........................................................................
namespace toolkit
{
//........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::accessibility;

    namespace
    {
#ifdef UNLOAD_ON_LAST_CLIENT_DYING
        static oslInterlockedCount                      s_nAccessibilityClients = 0;
#endif // UNLOAD_ON_LAST_CLIENT_DYING
        static oslModule                                s_hAccessibleImplementationModule = NULL;
        static GetStandardAccComponentFactory           s_pAccessibleFactoryFunc = NULL;
        static ::rtl::Reference< IAccessibleFactory >   s_pFactory;
    }

    //====================================================================
    //= AccessibleDummyFactory
    //====================================================================
    class AccessibleDummyFactory : public IAccessibleFactory
    {
    public:
        AccessibleDummyFactory();

    protected:
        virtual ~AccessibleDummyFactory();

    private:
        AccessibleDummyFactory( const AccessibleDummyFactory& );            // never implemented
        AccessibleDummyFactory& operator=( const AccessibleDummyFactory& ); // never implemented

        oslInterlockedCount m_refCount;

    public:
        // IReference
        virtual oslInterlockedCount SAL_CALL acquire();
        virtual oslInterlockedCount SAL_CALL release();

        // IAccessibleFactory
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
                createAccessibleContext( VCLXButton* /*_pXWindow*/ )
        {
            return NULL;
        }
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
                createAccessibleContext( VCLXCheckBox* /*_pXWindow*/ )
        {
            return NULL;
        }
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
                createAccessibleContext( VCLXRadioButton* /*_pXWindow*/ )
        {
            return NULL;
        }
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
                createAccessibleContext( VCLXListBox* /*_pXWindow*/ )
        {
            return NULL;
        }
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
                createAccessibleContext( VCLXFixedText* /*_pXWindow*/ )
        {
            return NULL;
        }
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
                createAccessibleContext( VCLXScrollBar* /*_pXWindow*/ )
        {
            return NULL;
        }
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
                createAccessibleContext( VCLXEdit* /*_pXWindow*/ )
        {
            return NULL;
        }
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
                createAccessibleContext( VCLXComboBox* /*_pXWindow*/ )
        {
            return NULL;
        }
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
                createAccessibleContext( VCLXToolBox* /*_pXWindow*/ )
        {
            return NULL;
        }
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
                createAccessibleContext( VCLXWindow* /*_pXWindow*/ )
        {
            return NULL;
        }
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
                createAccessible( Menu* /*_pMenu*/, sal_Bool /*_bIsMenuBar*/ )
        {
            return NULL;
        }
    };

    //--------------------------------------------------------------------
    AccessibleDummyFactory::AccessibleDummyFactory()
    {
    }

    //--------------------------------------------------------------------
    AccessibleDummyFactory::~AccessibleDummyFactory()
    {
    }

    //--------------------------------------------------------------------
    oslInterlockedCount SAL_CALL AccessibleDummyFactory::acquire()
    {
        return osl_incrementInterlockedCount( &m_refCount );
    }

    //--------------------------------------------------------------------
    oslInterlockedCount SAL_CALL AccessibleDummyFactory::release()
    {
        if ( 0 == osl_decrementInterlockedCount( &m_refCount ) )
        {
            delete this;
            return 0;
        }
        return m_refCount;
    }

    //====================================================================
    //= AccessibilityClient
    //====================================================================
    //--------------------------------------------------------------------
    AccessibilityClient::AccessibilityClient()
        :m_bInitialized( false )
    {
    }

    //--------------------------------------------------------------------
    extern "C" { static void SAL_CALL thisModule() {} }

    void AccessibilityClient::ensureInitialized()
    {
        if ( m_bInitialized )
            return;

        ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );

#ifdef UNLOAD_ON_LAST_CLIENT_DYING
        if ( 1 == osl_incrementInterlockedCount( &s_nAccessibilityClients ) )
        {   // the first client
#endif // UNLOAD_ON_LAST_CLIENT_DYING
            // load the library implementing the factory
            if ( !s_pFactory.get() )
            {
                const ::rtl::OUString sModuleName = ::rtl::OUString::createFromAscii(
                    SVLIBRARY( "acc" )
                );
                s_hAccessibleImplementationModule = osl_loadModuleRelative( &thisModule, sModuleName.pData, 0 );
                if ( s_hAccessibleImplementationModule != NULL )
                {
                    const ::rtl::OUString sFactoryCreationFunc =
                        ::rtl::OUString::createFromAscii( "getStandardAccessibleFactory" );
                    s_pAccessibleFactoryFunc = (GetStandardAccComponentFactory)
                        osl_getFunctionSymbol( s_hAccessibleImplementationModule, sFactoryCreationFunc.pData );

                }
                OSL_ENSURE( s_pAccessibleFactoryFunc, "AccessibilityClient::ensureInitialized: could not load the library, or not retrieve the needed symbol!" );

                // get a factory instance
                if ( s_pAccessibleFactoryFunc )
                {
                    IAccessibleFactory* pFactory = static_cast< IAccessibleFactory* >( (*s_pAccessibleFactoryFunc)() );
                    OSL_ENSURE( pFactory, "AccessibilityClient::ensureInitialized: no factory provided by the A11Y lib!" );
                    if ( pFactory )
                    {
                        s_pFactory = pFactory;
                        pFactory->release();
                    }
                }
            }

            if ( !s_pFactory.get() )
                // the attempt to load the lib, or to create the factory, failed
                // -> fall back to a dummy factory
                s_pFactory = new AccessibleDummyFactory;
#ifdef UNLOAD_ON_LAST_CLIENT_DYING
        }
#endif

        m_bInitialized = true;
    }

    //--------------------------------------------------------------------
    AccessibilityClient::~AccessibilityClient()
    {
        if ( m_bInitialized )
        {
            ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );

#ifdef UNLOAD_ON_LAST_CLIENT_DYING
            if( 0 == osl_decrementInterlockedCount( &s_nAccessibilityClients ) )
            {
                s_pFactory = NULL;
                s_pAccessibleFactoryFunc = NULL;
                if ( s_hAccessibleImplementationModule )
                {
                    osl_unloadModule( s_hAccessibleImplementationModule );
                    s_hAccessibleImplementationModule = NULL;
                }
            }
#endif // UNLOAD_ON_LAST_CLIENT_DYING
        }
    }

    //--------------------------------------------------------------------
    IAccessibleFactory& AccessibilityClient::getFactory()
    {
        ensureInitialized();
        OSL_ENSURE( s_pFactory.is(), "AccessibilityClient::getFactory: at least a dummy factory should have been created!" );
        return *s_pFactory;
    }

//........................................................................
}   // namespace toolkit
//........................................................................
<|endoftext|>


<commit_before>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License.  You may
 * obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ***************************************************************/

#include "condor_common.h"
#include "condor_debug.h"

#include "sysapi.h"
#include "sysapi_externs.h"

#include "condor_sockaddr.h"

static bool net_devices_cached = false;
static std::vector<NetworkDeviceInfo> net_devices_cache;

#if WIN32

#include <Ws2ipdef.h>

bool sysapi_get_network_device_info_raw(std::vector<NetworkDeviceInfo> &devices)
{
	int i,num_interfaces=0,max_interfaces=20;
	LPINTERFACE_INFO interfaces=NULL;
	DWORD bytes_out=0;
	SOCKET sock;

	sock = socket(AF_INET, SOCK_DGRAM, 0);
	if( sock == INVALID_SOCKET ) {
		dprintf(D_ALWAYS,"sysapi_get_network_device_info_raw: socket() failed: (errno %d)\n",
				WSAGetLastError());
		return false;
	}

	while( true ) {
		interfaces = new INTERFACE_INFO[max_interfaces];

		int rc = WSAIoctl(
			sock,
			SIO_GET_INTERFACE_LIST,
			NULL,
			0,
			interfaces,
			sizeof(INTERFACE_INFO)*max_interfaces,
			&bytes_out,
			NULL,
			NULL);

		if( rc == 0 ) { // success
			num_interfaces = bytes_out/sizeof(INTERFACE_INFO);
			break;
		}

		delete [] interfaces;

		int error = WSAGetLastError();
		if( error == WSAEFAULT ) { // not enough space in buffer
			max_interfaces *= 2;
			continue;
		}
		dprintf(D_ALWAYS,"SIO_GET_INTERFACE_LIST failed: %d\n",error);
		closesocket(sock);
		return false;
	}

	for(i=0;i<num_interfaces;i++) {
		char const *ip = NULL;
		if( interfaces[i].iiAddress.Address.sa_family == AF_INET ) {
			ip = inet_ntoa(((struct sockaddr_in *)&interfaces[i].iiAddress)->sin_addr);
		}
		if( ip ) {
			bool is_up = interfaces[i].iiFlags & IFF_UP;
			NetworkDeviceInfo inf("",ip, is_up);
			devices.push_back(inf);
		}
	}

	delete [] interfaces;
	closesocket(sock);
	return true;
}

#elif HAVE_GETIFADDRS
#include <sys/types.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <net/if.h>

bool sysapi_get_network_device_info_raw(std::vector<NetworkDeviceInfo> &devices)
{
	struct ifaddrs *ifap_list=NULL;
	if( getifaddrs(&ifap_list) == -1 ) {
		dprintf(D_ALWAYS,"getifaddrs failed: errno=%d: %s\n",errno,strerror(errno));
		return false;
	}
	struct ifaddrs *ifap=ifap_list;
	char ip_buf[INET6_ADDRSTRLEN];
	for(ifap=ifap_list;
		ifap;
		ifap=ifap->ifa_next)
	{
		const char* ip = NULL;
		char const *name = ifap->ifa_name;
		if( ifap->ifa_addr && ifap->ifa_addr->sa_family == AF_INET ) {
			condor_sockaddr addr(ifap->ifa_addr);
			ip = addr.to_ip_string(ip_buf, INET6_ADDRSTRLEN);
		}
		if( ip ) {
			bool is_up = ifap->ifa_flags & IFF_UP;
			dprintf(D_FULLDEBUG, "Enumerating interfaces: %s %s %s\n", name, ip, is_up?"up":"down");
			NetworkDeviceInfo inf(name,ip,is_up);
			devices.push_back(inf);
		}
	}
	freeifaddrs(ifap_list);

	return true;
}

#elif defined(SIOCGIFCONF)

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>

bool sysapi_get_network_device_info_raw(std::vector<NetworkDeviceInfo> &devices)
{
	int sock = socket(AF_INET, SOCK_DGRAM, 0);
	if( sock == -1 ) {
		dprintf(D_ALWAYS,"sysapi_get_network_device_info_raw: socket() failed: (errno %d) %s\n",
				errno,strerror(errno));
		return false;
	}

	struct ifconf ifc,prev;
	memset(&ifc, 0, sizeof(ifc));

	const int max_interfaces = 10000;
	int num_interfaces;
	for(num_interfaces=100;num_interfaces<max_interfaces;num_interfaces+=100) {
		prev.ifc_len = ifc.ifc_len;
		ifc.ifc_len = num_interfaces*sizeof(struct ifreq);

		ifc.ifc_req = (struct ifreq *)malloc(ifc.ifc_len);

		if( ifc.ifc_req == NULL ) {
			dprintf(D_ALWAYS,"sysapi_get_network_device_info_raw: out of memory\n");
			return false;
		}

			// EINVAL (on some platforms) indicates that the buffer
			// is not large enough
		if( ioctl(sock, SIOCGIFCONF, &ifc) < 0 && errno != EINVAL ) {
			dprintf(D_ALWAYS,"sysapi_get_network_device_info_raw: ioctlsocket() failed after allocating buffer: (errno %d) %s\n",
					errno,strerror(errno));
			free( ifc.ifc_req );
			return false;
		}

		if( ifc.ifc_len == prev.ifc_len ) {
				// Getting the same length in successive calls to
				// SIOCGIFCONF is the only reliable way to know that
				// the buffer was big enough, because some
				// implementations silently return truncated results
				// if the buffer isn't big enough.
			break;
		}
		free( ifc.ifc_req );
		ifc.ifc_req = NULL;
	}
	if( num_interfaces > max_interfaces ) {
			// something must be going wrong
		dprintf(D_ALWAYS,"sysapi_get_network_device_info_raw: unexpectedly large SIOCGIFCONF buffer: %d (errno=%d)\n",num_interfaces,errno);
		return false;
	}

	num_interfaces = ifc.ifc_len/sizeof(struct ifreq);

	char ip_buf[INET6_ADDRSTRLEN];
	int i;
	for(i=0; i<num_interfaces; i++) {
		struct ifreq *ifr = &ifc.ifc_req[i];
		char const *name = ifr->ifr_name;
		const char* ip = NULL;

		if( ifr->ifr_addr.sa_family == AF_INET ||ifr->ifr_addr.sa_family == AF_INET6 ) {
			condor_sockaddr addr(&ifr->ifr_addr);
			ip = addr.to_ip_string(ip_buf, INET6_ADDRSTRLEN);
		}
		if( ip ) {
			bool is_up = true;
			NetworkDeviceInfo inf(name,ip,is_up);
			devices.push_back(inf);
		}
	}
	free( ifc.ifc_req );

	return true;
}

#else

#error sysapi_get_network_device_info() must be implemented for this platform

#endif

bool sysapi_get_network_device_info(std::vector<NetworkDeviceInfo> &devices)
{
	if( net_devices_cached ) {
		devices = net_devices_cache;
		return true;
	}

	bool rc = sysapi_get_network_device_info_raw(devices);

	if( rc ) {
		net_devices_cached = true;
		net_devices_cache = devices;
	}
	return rc;
}

void sysapi_clear_network_device_info_cache() {
	net_devices_cached = false;
}
<commit_msg>sysapi_get_network_device_info should return IPv6 also<commit_after>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License.  You may
 * obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ***************************************************************/

#include "condor_common.h"
#include "condor_debug.h"

#include "sysapi.h"
#include "sysapi_externs.h"

#include "condor_sockaddr.h"

static bool net_devices_cached = false;
static std::vector<NetworkDeviceInfo> net_devices_cache;

#if WIN32

#include <Ws2ipdef.h>

bool sysapi_get_network_device_info_raw(std::vector<NetworkDeviceInfo> &devices)
{
	int i,num_interfaces=0,max_interfaces=20;
	LPINTERFACE_INFO interfaces=NULL;
	DWORD bytes_out=0;
	SOCKET sock;

	sock = socket(AF_INET, SOCK_DGRAM, 0);
	if( sock == INVALID_SOCKET ) {
		dprintf(D_ALWAYS,"sysapi_get_network_device_info_raw: socket() failed: (errno %d)\n",
				WSAGetLastError());
		return false;
	}

	while( true ) {
		interfaces = new INTERFACE_INFO[max_interfaces];

		int rc = WSAIoctl(
			sock,
			SIO_GET_INTERFACE_LIST,
			NULL,
			0,
			interfaces,
			sizeof(INTERFACE_INFO)*max_interfaces,
			&bytes_out,
			NULL,
			NULL);

		if( rc == 0 ) { // success
			num_interfaces = bytes_out/sizeof(INTERFACE_INFO);
			break;
		}

		delete [] interfaces;

		int error = WSAGetLastError();
		if( error == WSAEFAULT ) { // not enough space in buffer
			max_interfaces *= 2;
			continue;
		}
		dprintf(D_ALWAYS,"SIO_GET_INTERFACE_LIST failed: %d\n",error);
		closesocket(sock);
		return false;
	}

	for(i=0;i<num_interfaces;i++) {
		char const *ip = NULL;
		if( interfaces[i].iiAddress.Address.sa_family == AF_INET ) {
			ip = inet_ntoa(((struct sockaddr_in *)&interfaces[i].iiAddress)->sin_addr);
		}
		if( ip ) {
			bool is_up = interfaces[i].iiFlags & IFF_UP;
			NetworkDeviceInfo inf("",ip, is_up);
			devices.push_back(inf);
		}
	}

	delete [] interfaces;
	closesocket(sock);
	return true;
}

#elif HAVE_GETIFADDRS
#include <sys/types.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <net/if.h>

bool sysapi_get_network_device_info_raw(std::vector<NetworkDeviceInfo> &devices)
{
	struct ifaddrs *ifap_list=NULL;
	if( getifaddrs(&ifap_list) == -1 ) {
		dprintf(D_ALWAYS,"getifaddrs failed: errno=%d: %s\n",errno,strerror(errno));
		return false;
	}
	struct ifaddrs *ifap=ifap_list;
	char ip_buf[INET6_ADDRSTRLEN];
	for(ifap=ifap_list;
		ifap;
		ifap=ifap->ifa_next)
	{
		const char* ip = NULL;
		char const *name = ifap->ifa_name;
		if( ifap->ifa_addr &&
			(ifap->ifa_addr->sa_family == AF_INET || ifap->ifa_addr->sa_family == AF_INET6)
			) {
			condor_sockaddr addr(ifap->ifa_addr);
			ip = addr.to_ip_string(ip_buf, INET6_ADDRSTRLEN);
		}
		if( ip ) {
			bool is_up = ifap->ifa_flags & IFF_UP;
			dprintf(D_FULLDEBUG, "Enumerating interfaces: %s %s %s\n", name, ip, is_up?"up":"down");
			NetworkDeviceInfo inf(name,ip,is_up);
			devices.push_back(inf);
		}
	}
	freeifaddrs(ifap_list);

	return true;
}

#elif defined(SIOCGIFCONF)

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>

bool sysapi_get_network_device_info_raw(std::vector<NetworkDeviceInfo> &devices)
{
	int sock = socket(AF_INET, SOCK_DGRAM, 0);
	if( sock == -1 ) {
		dprintf(D_ALWAYS,"sysapi_get_network_device_info_raw: socket() failed: (errno %d) %s\n",
				errno,strerror(errno));
		return false;
	}

	struct ifconf ifc,prev;
	memset(&ifc, 0, sizeof(ifc));

	const int max_interfaces = 10000;
	int num_interfaces;
	for(num_interfaces=100;num_interfaces<max_interfaces;num_interfaces+=100) {
		prev.ifc_len = ifc.ifc_len;
		ifc.ifc_len = num_interfaces*sizeof(struct ifreq);

		ifc.ifc_req = (struct ifreq *)malloc(ifc.ifc_len);

		if( ifc.ifc_req == NULL ) {
			dprintf(D_ALWAYS,"sysapi_get_network_device_info_raw: out of memory\n");
			return false;
		}

			// EINVAL (on some platforms) indicates that the buffer
			// is not large enough
		if( ioctl(sock, SIOCGIFCONF, &ifc) < 0 && errno != EINVAL ) {
			dprintf(D_ALWAYS,"sysapi_get_network_device_info_raw: ioctlsocket() failed after allocating buffer: (errno %d) %s\n",
					errno,strerror(errno));
			free( ifc.ifc_req );
			return false;
		}

		if( ifc.ifc_len == prev.ifc_len ) {
				// Getting the same length in successive calls to
				// SIOCGIFCONF is the only reliable way to know that
				// the buffer was big enough, because some
				// implementations silently return truncated results
				// if the buffer isn't big enough.
			break;
		}
		free( ifc.ifc_req );
		ifc.ifc_req = NULL;
	}
	if( num_interfaces > max_interfaces ) {
			// something must be going wrong
		dprintf(D_ALWAYS,"sysapi_get_network_device_info_raw: unexpectedly large SIOCGIFCONF buffer: %d (errno=%d)\n",num_interfaces,errno);
		return false;
	}

	num_interfaces = ifc.ifc_len/sizeof(struct ifreq);

	char ip_buf[INET6_ADDRSTRLEN];
	int i;
	for(i=0; i<num_interfaces; i++) {
		struct ifreq *ifr = &ifc.ifc_req[i];
		char const *name = ifr->ifr_name;
		const char* ip = NULL;

		if( ifr->ifr_addr.sa_family == AF_INET ||ifr->ifr_addr.sa_family == AF_INET6 ) {
			condor_sockaddr addr(&ifr->ifr_addr);
			ip = addr.to_ip_string(ip_buf, INET6_ADDRSTRLEN);
		}
		if( ip ) {
			bool is_up = true;
			NetworkDeviceInfo inf(name,ip,is_up);
			devices.push_back(inf);
		}
	}
	free( ifc.ifc_req );

	return true;
}

#else

#error sysapi_get_network_device_info() must be implemented for this platform

#endif

bool sysapi_get_network_device_info(std::vector<NetworkDeviceInfo> &devices)
{
	if( net_devices_cached ) {
		devices = net_devices_cache;
		return true;
	}

	bool rc = sysapi_get_network_device_info_raw(devices);

	if( rc ) {
		net_devices_cached = true;
		net_devices_cache = devices;
	}
	return rc;
}

void sysapi_clear_network_device_info_cache() {
	net_devices_cached = false;
}
<|endoftext|>


<commit_before>/*
*/
//#include <Windows.h>
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _UNICODE
#define _UNICODE
#endif
//#include <winhttp.h>
//Base64 Encoding
#include "WinHttpClient.h"
#include <wincrypt.h>
#include <stdint.h>
#include <sstream>
#include <vector>
#include "getopt.h"

#pragma comment(lib,"crypt32.lib")

struct URLStruct{
    std::wstring host;
    std::wstring rawpath;
    bool isSSL;
    int port;
};

#define USER_AGENT L"git/2.5.0.Simulator.0"

int DefaultPort(const wchar_t * scheme);
bool URLParse(const wchar_t* uri,
    std::wstring& scheme,
    std::wstring& hostname,
    int &port,
    std::wstring& path);

/*
BOOL WINAPI CryptBinaryToString(
  _In_      const BYTE   *pbBinary,
  _In_            DWORD  cbBinary,
  _In_            DWORD  dwFlags,
  _Out_opt_       LPTSTR pszString,
  _Inout_         DWORD  *pcchString
);

BOOL WINAPI CryptStringToBinary(
  _In_    LPCTSTR pszString,
  _In_    DWORD   cchString,
  _In_    DWORD   dwFlags,
  _In_    BYTE    *pbBinary,
  _Inout_ DWORD   *pcbBinary,
  _Out_   DWORD   *pdwSkip,
  _Out_   DWORD   *pdwFlags
);

Base64 dwFlags CRYPT_STRING_BASE64

*/

/// Name and pwd to UTF8
BOOL WINAPI PasswordEncodingBase64(const char* name,const char* pwd,std::wstring &outtext)
{
    char buffer[512]={0};
    wchar_t receivebuf[1024]={0};
    sprintf_s(buffer,512,"%s:%s",name,pwd);
    auto size=strlen(buffer);
    DWORD  pcchString;
    auto bRet=CryptBinaryToStringW(
        (const BYTE*)(buffer),
        size,
        CRYPT_STRING_BASE64,
        receivebuf,
        &pcchString);
    if(bRet){
        outtext=receivebuf;
    }
    return bRet;
}

class BBuffer{
private:
    BYTE *Ptr;
public:
    BBuffer(unsigned size)
    {
        Ptr=(BYTE*)malloc(sizeof(BYTE)*size);
    }
    ~BBuffer(){
        if(Ptr)
            free(Ptr);
    }
    BYTE* get(){
        return this->Ptr;
    }
};

 /*************
<NULL> is \x00
001e# service=git-upload-pack
000000d16b608d3d4c01a5933342823a0cdfde90f8753301 HEADmulti_ack thin-pack side-band side-band-64k ofs-delta shallow no-progress include-tag multi_ack_detailed no-done symref=HEAD:refs/heads/master agent=git/1.9.1
00410d2661d52ca24946d3a6945424f71fd1c0f8dcb8 refs/heads/gh-pages
003f6b608d3d4c01a5933342823a0cdfde90f8753301 refs/heads/master
003be8ad4c2d0953b1cb3d7a01e27db7a20d51e85168 refs/tags/1.0
003d9e0f6cc8b1ff90c12bd301bfe05b58671fb474e4 refs/tags/1.0.2
003d6373e88d0680a7e22df40637346c55e33c467aff refs/tags/1.0.3
003ea98d1eb56a704f29cf7f8b7a74b4a5c53371d1f8 refs/tags/v1.0.4
0000

008awant adb4536c655707a637aa74aef0d899ef57b28a1d multi_ack_detailed no-done side-band-64k thin-pack ofs-delta agent=git/2.5.0.Simulator.0
0032want adb4536c655707a637aa74aef0d899ef57b28a1d
0032want adb4536c655707a637aa74aef0d899ef57b28a1d
00000009done

************************** */

BOOL WINAPI ResolveContent(const BYTE* raw,unsigned len,BYTE *buffer,unsigned *bufferSize)
{
    auto end=raw+len;
    auto begin=raw;
    BYTE line[2048]={0};
    unsigned ll=0;
    BYTE fline[41]={0};
    static std::stringstream sstr;
    while(begin++<end&&ll<2047)
    {
        if(*begin==0x0A)
        {
            if(ll>70&&memcmp(line,"0000",4)==0)
            {
                auto oid=const_cast<BYTE*>(line+8);
                memcpy(fline,oid,40);
                sstr<<"008awant "<<fline<<L" multi_ack_detailed no-done side-band-64k thin-pack ofs-delta agent=git/2.5.0.Simulator.0\n";
            }else if(ll>56){
                auto oid=const_cast<BYTE*>(line+4);
                memcpy(fline,oid,40);
                sstr<<"0032want "<<fline<<"\n";
            }else{
                /////Not do more
            }
            ll=0;
        }else{
            line[ll]=*begin;
            ll++;
        }
    }
    sstr<<"00000009done\n";
    memcmp(buffer,sstr.str().c_str(),sstr.str().size());
    *bufferSize=sstr.str().size();
    return TRUE;
}

class CloneStep{
private:
    /// Basic xXxxxxxxxxxxxxxxxx
    std::wstring base64Info;
    std::wstring murl;
    bool RequestGET();
    bool RequestPOST(URLStruct &us,BYTE* content,unsigned len);
public:
    CloneStep(std::wstring url):murl(url){}
    CloneStep(){}
    bool SetURL(const wchar_t *url){
        murl.assign(url);
        return true;
    }
    bool SetAuthInfo(std::wstring &binfo)
    {
        this->base64Info=binfo;
        return this->base64Info.size()>10?true:false;
    }
    int Start();
};

bool CloneStep::RequestGET()
{
    ///
    ///std::wstring get_url=this->murl+L"info/refs?service=git-upload-pack";
    URLStruct urlAtom;
    std::wstring scheme;
    urlAtom.isSSL=false;
    if(!URLParse(this->murl.c_str(),scheme,urlAtom.host,urlAtom.port,urlAtom.rawpath))
    {
        wprintf(L"Failed to Parse URL: %s\n",this->murl.c_str());
        return false;
    }
    if(scheme.compare(L"https"))
        urlAtom.isSSL=true;
    std::wstring header=L"Accept-Encoding: gzip\r\nConnection: keep-alive\r\n";
    std::wstring requestURL=murl+L"info/refs?service=git-upload-pack";
    WinHttpClient client(requestURL);
    std::wstring headers=L"Accept: */*\r\nAccept-Encoding: gzip\r\nPragma: no-cache\r\n";
    client.SetRequireValidSslCertificates(urlAtom.isSSL);
    client.SetAdditionalRequestHeaders(headers);
    client.SendHttpRequest();
    std::wstring httpResponseHeader=client.GetResponseHeader();
    auto raw=client.GetRawResponseContent();
    auto size=client.GetRawResponseContentLength();
    wprintf(L"Response Header:\n%s\n",httpResponseHeader.c_str());
    BBuffer buffer(size);
    unsigned bufferSize=0;
    if(ResolveContent(raw,size,buffer.get(),&bufferSize)){
        return this->RequestPOST(urlAtom,buffer.get(),bufferSize);
    }
    wprintf(L"Faied Parser Response Content");
    return false;
}

/*
POST /user/proj.git/git-upload-pack HTTP/1.1
User-Agent: git/2.5.0.Simulator.0
Host: git.oschina.net
Accept-Encoding: gzip
Content-Type: application/x-git-upload-pack-request
Accept: application/x-git-upload-pack-result
Content-Length: 399
*/

bool ProgressProc(double progress)
{
    wprintf(L"Current Receive Data:%-.1f%%\r\n",progress);
    return true;
}

bool CloneStep::RequestPOST(URLStruct &us,BYTE* content,unsigned len)
{
    /*
    Content-Type: application/x-git-upload-pack-request
    Accept: application/x-git-upload-pack-result
    */
    std::wstring requestURL=this->murl+L"/git-upload-pack";
    WinHttpClient client(requestURL,ProgressProc);
    ////When POST not set gzip
    std::wstring headers=L"Content-Type: application/x-git-upload-pack-request\r\nAccept: application/x-git-upload-pack-result\r\n";
    headers+=L"Content-Length: ";
    wchar_t szSize[50] = L"";
    swprintf_s(szSize, L"%d", len);
    headers += szSize;
    client.SetRequireValidSslCertificates(us.isSSL);
    client.SetAdditionalRequestHeaders(headers);
    client.SendHttpRequest(L"POST");
    client.SetAdditionalDataToSend(content,len);
    wstring httpResponseHeader = client.GetResponseHeader();
    wstring httpResponseContent = client.GetResponseContent();
    return true;
}

int CloneStep::Start()
{
    //
    return 0;
}

bool Initialize()
{
    auto lcid=GetSystemDefaultLCID();
    wchar_t localeBuffer[80]={0};
    LCIDToLocaleName(lcid,localeBuffer,LOCALE_NAME_MAX_LENGTH,LOCALE_ALLOW_NEUTRAL_NAMES);
    _wsetlocale(LC_ALL,localeBuffer);
    return true;
}

//git-clone-stress --input(-i) repo.list -e some@site.com -p password
int wmain(int argc,wchar_t **argv)
{
    ///
    int ch;
    while((ch=wgetopt(argc,argv,L"e:i:p:"))!=-1)
    {
        ///
        switch(ch){
            case 'e':
            wprintf(L"Email: %s\n",woptarg);
            break;
            case 'i':
            wprintf(L"Input: %s\n",woptarg);
            break;
            case 'p':
            wprintf(L"Password: %s\n",woptarg);
            break;
            default:
            break;
        }
    }
    Initialize();
    bool isAuthEnable=false;
    CloneStep cloneStep;

    return 0;
}
<commit_msg>fix commandline parser<commit_after>/*
*/
//#include <Windows.h>
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _UNICODE
#define _UNICODE
#endif
//#include <winhttp.h>
//Base64 Encoding
#include "WinHttpClient.h"
#include <wincrypt.h>
#include <stdint.h>
#include <sstream>
#include <vector>
#include <stdio.h>
#include <wchar.h>
#include <stdarg.h>
#include "getopt.h"

#pragma comment(lib,"crypt32.lib")

struct URLStruct{
    std::wstring host;
    std::wstring rawpath;
    bool isSSL;
    int port;
};

#define USER_AGENT L"git/2.5.0.Simulator.0"

int DefaultPort(const wchar_t * scheme);
bool URLParse(const wchar_t* uri,
    std::wstring& scheme,
    std::wstring& hostname,
    int &port,
    std::wstring& path);

class BBuffer{
private:
    BYTE *Ptr;
public:
    BBuffer(unsigned size)
    {
        if(size<UINT32_MAX/4)///1GB small
            Ptr=(BYTE*)malloc(sizeof(BYTE)*size);
        else
            Ptr=nullptr;
    }
    ~BBuffer(){
        if(Ptr)
            free(Ptr);
    }
    BYTE* get(){
        return this->Ptr;
    }
};

class Console{
private:
   HANDLE hConsole;
public:
   Console(){
       hConsole=GetStdHandle(STD_OUTPUT_HANDLE);
   }
   ~Console(){
       if(hConsole)
       {
           CloseHandle(hConsole);
       }
   }
   HANDLE get(){
       return this->hConsole;
   }
}
////When Failed Print Red word
int PrintError(const wchar_t *format,...)
{
    int ret;
    static Console hCon;
    CONSOLE_SCREEN_BUFFER_INFO bInfo;
    GetConsoleScreenBufferInfo(hCon.get(), &bInfo);
    SetConsoleTextAttribute(hCon.get(),FOREGROUND_RED|FOREGROUND_INTENSITY);
    va_list ap;
    va_start(ap, format);
    ret=vwprintf_s(format,ap);
    va_end(ap);
    SetConsoleTextAttribute(hCon.get(),bInfo.wAttributes);
    return ret;
}

static wchar_t recordfile[4096]={0};

int RecordError(const wchar_t *format,...)
{
    int ret;
    FILE *fp;
    if(_wfopen_s(&fp,recordfile,L"a+")!=0)
       return 0;
    va_list ap;
    va_start(ap, format);
    ret=vfwprintf_s(format,ap);
    va_end(ap);
    fclose(fp);
    return ret;
}

/*
BOOL WINAPI CryptBinaryToString(
  _In_      const BYTE   *pbBinary,
  _In_            DWORD  cbBinary,
  _In_            DWORD  dwFlags,
  _Out_opt_       LPTSTR pszString,
  _Inout_         DWORD  *pcchString
);

BOOL WINAPI CryptStringToBinary(
  _In_    LPCTSTR pszString,
  _In_    DWORD   cchString,
  _In_    DWORD   dwFlags,
  _In_    BYTE    *pbBinary,
  _Inout_ DWORD   *pcbBinary,
  _Out_   DWORD   *pdwSkip,
  _Out_   DWORD   *pdwFlags
);

Base64 dwFlags CRYPT_STRING_BASE64

*/

/// Name and pwd to UTF8
BOOL WINAPI PasswordEncodingBase64(const char* name,const char* pwd,std::wstring &outtext)
{
    char buffer[512]={0};
    wchar_t receivebuf[1024]={0};
    sprintf_s(buffer,512,"%s:%s",name,pwd);
    auto size=strlen(buffer);
    DWORD  pcchString;
    auto bRet=CryptBinaryToStringW(
        (const BYTE*)(buffer),
        size,
        CRYPT_STRING_BASE64,
        receivebuf,
        &pcchString);
    if(bRet){
        outtext=receivebuf;
    }
    return bRet;
}

 /*************
<NULL> is \x00
001e# service=git-upload-pack
000000d16b608d3d4c01a5933342823a0cdfde90f8753301 HEADmulti_ack thin-pack side-band side-band-64k ofs-delta shallow no-progress include-tag multi_ack_detailed no-done symref=HEAD:refs/heads/master agent=git/1.9.1
00410d2661d52ca24946d3a6945424f71fd1c0f8dcb8 refs/heads/gh-pages
003f6b608d3d4c01a5933342823a0cdfde90f8753301 refs/heads/master
003be8ad4c2d0953b1cb3d7a01e27db7a20d51e85168 refs/tags/1.0
003d9e0f6cc8b1ff90c12bd301bfe05b58671fb474e4 refs/tags/1.0.2
003d6373e88d0680a7e22df40637346c55e33c467aff refs/tags/1.0.3
003ea98d1eb56a704f29cf7f8b7a74b4a5c53371d1f8 refs/tags/v1.0.4
0000

008awant adb4536c655707a637aa74aef0d899ef57b28a1d multi_ack_detailed no-done side-band-64k thin-pack ofs-delta agent=git/2.5.0.Simulator.0
0032want adb4536c655707a637aa74aef0d899ef57b28a1d
0032want adb4536c655707a637aa74aef0d899ef57b28a1d
00000009done

************************** */

BOOL WINAPI ResolveContent(const BYTE* raw,unsigned len,BYTE *buffer,unsigned *bufferSize)
{
    auto end=raw+len;
    auto begin=raw;
    BYTE line[2048]={0};
    unsigned ll=0;
    BYTE fline[41]={0};
    static std::stringstream sstr;
    while(begin++<end&&ll<2047)
    {
        if(*begin==0x0A)
        {
            if(ll>70&&memcmp(line,"0000",4)==0)
            {
                auto oid=const_cast<BYTE*>(line+8);
                memcpy(fline,oid,40);
                sstr<<"008awant "<<fline<<L" multi_ack_detailed no-done side-band-64k thin-pack ofs-delta agent=git/2.5.0.Simulator.0\n";
            }else if(ll>56){
                auto oid=const_cast<BYTE*>(line+4);
                memcpy(fline,oid,40);
                sstr<<"0032want "<<fline<<"\n";
            }else{
                /////Not do more
            }
            ll=0;
        }else{
            line[ll]=*begin;
            ll++;
        }
    }
    sstr<<"00000009done\n";
    memcmp(buffer,sstr.str().c_str(),sstr.str().size());
    *bufferSize=sstr.str().size();
    return TRUE;
}

class CloneStep{
private:
    /// Basic xXxxxxxxxxxxxxxxxx
    std::wstring base64Info;
    std::wstring murl;
    bool RequestGET();
    bool RequestPOST(URLStruct &us,BYTE* content,unsigned len);
public:
    CloneStep(std::wstring url):murl(url){}
    CloneStep(){}
    bool SetURL(const wchar_t *url){
        murl.assign(url);
        return true;
    }
    bool SetAuthInfo(std::wstring &binfo)
    {
        this->base64Info=binfo;
        return this->base64Info.size()>10?true:false;
    }
    int Start();
};

bool CloneStep::RequestGET()
{
    ///
    ///std::wstring get_url=this->murl+L"info/refs?service=git-upload-pack";
    URLStruct urlAtom;
    std::wstring scheme;
    urlAtom.isSSL=false;
    if(!URLParse(this->murl.c_str(),scheme,urlAtom.host,urlAtom.port,urlAtom.rawpath))
    {
        wprintf(L"Failed to Parse URL: %s\n",this->murl.c_str());
        return false;
    }
    if(scheme.compare(L"https"))
        urlAtom.isSSL=true;
    std::wstring header=L"Accept-Encoding: gzip\r\nConnection: keep-alive\r\n";
    std::wstring requestURL=murl+L"info/refs?service=git-upload-pack";
    WinHttpClient client(requestURL);
    std::wstring headers=L"Accept: */*\r\nAccept-Encoding: gzip\r\nPragma: no-cache\r\n";
    client.SetRequireValidSslCertificates(urlAtom.isSSL);
    client.SetAdditionalRequestHeaders(headers);
    client.SendHttpRequest();
    std::wstring httpResponseHeader=client.GetResponseHeader();
    auto raw=client.GetRawResponseContent();
    auto size=client.GetRawResponseContentLength();
    wprintf(L"Response Header:\n%s\n",httpResponseHeader.c_str());
    BBuffer buffer(size);
    unsigned bufferSize=0;
    if(ResolveContent(raw,size,buffer.get(),&bufferSize)){
        return this->RequestPOST(urlAtom,buffer.get(),bufferSize);
    }
    wprintf(L"Faied Parser Response Content");
    return false;
}

/*
POST /user/proj.git/git-upload-pack HTTP/1.1
User-Agent: git/2.5.0.Simulator.0
Host: git.oschina.net
Accept-Encoding: gzip
Content-Type: application/x-git-upload-pack-request
Accept: application/x-git-upload-pack-result
Content-Length: 399
*/

bool ProgressProc(double progress)
{
    wprintf(L"Current Receive Data:%-.1f%%\r\n",progress);
    return true;
}

bool CloneStep::RequestPOST(URLStruct &us,BYTE* content,unsigned len)
{
    /*
    Content-Type: application/x-git-upload-pack-request
    Accept: application/x-git-upload-pack-result
    */
    std::wstring requestURL=this->murl+L"/git-upload-pack";
    WinHttpClient client(requestURL,ProgressProc);
    ////When POST not set gzip
    std::wstring headers=L"Content-Type: application/x-git-upload-pack-request\r\nAccept: application/x-git-upload-pack-result\r\n";
    headers+=L"Content-Length: ";
    wchar_t szSize[50] = L"";
    swprintf_s(szSize, L"%d", len);
    headers += szSize;
    client.SetRequireValidSslCertificates(us.isSSL);
    client.SetAdditionalRequestHeaders(headers);
    client.SendHttpRequest(L"POST");
    client.SetAdditionalDataToSend(content,len);
    wstring httpResponseHeader = client.GetResponseHeader();
    wstring httpResponseContent = client.GetResponseContent();
    return true;
}

int CloneStep::Start()
{
    //
    return 0;
}

bool Initialize()
{
    auto lcid=GetSystemDefaultLCID();
    wchar_t localeBuffer[80]={0};
    LCIDToLocaleName(lcid,localeBuffer,LOCALE_NAME_MAX_LENGTH,LOCALE_ALLOW_NEUTRAL_NAMES);
    _wsetlocale(LC_ALL,localeBuffer);
    GetTempPathW(MAX_PATH,recordfile);
    wcscat_s(recordfile,MAX_PATH,L"git-clone-stress.error.log");
    return true;
}

//git-clone-stress --input(-i) repo.list -e some@site.com -p password
int wmain(int argc,wchar_t **argv)
{
    ///Initialize Environment ,support wchar_t output
    Initialize();
    int ch;
    opterr=0;
    const wchar_t *short_opts=L"hvi:e:l:p";
    const woption option_long_opt[]={
     {L"help",no_argument,NULL,'h'},
     {L"version",no_argument,NULL,'v'},
     {L"input",required_argument ,NULL,'i'},
     {L"email",required_argument ,NULL,'e'},
     {L"log",required_argument,NULL,'l'},
     {L"password",required_argument ,NULL,'p'},
     {0,0,0,0}
    };
    while((ch=wgetopt_long(argc,argv,short_opts,option_long_opt,NULL))!=-1)
    {
        ///
        switch(ch){
            case 'h':
            //print usage and exit
            break;
            case 'v'
            //print version
            break;
            case 'e':
            wprintf(L"Email: %s\n",woptarg);
            break;
            case 'i':
            wprintf(L"Input: %s\n",woptarg);
            break;
            case 'l':
            {
                ///get Parent Path with log
            }
            break;
            case 'p':
            wprintf(L"Password: %s\n",woptarg);
            break;
            default:
            break;
        }
    }
    bool isAuthEnable=false;
    CloneStep cloneStep;

    return 0;
}
<|endoftext|>


<commit_before>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** 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
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

//============================================================================
// Description : Tool to handle notifications and notification groups
//============================================================================

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <getopt.h>
#include <QCoreApplication>
#include <MNotification>
#include <MRemoteAction>
#include <MNotificationGroup>
#include <QString>
#include <QStringList>
#include <QRegExp>
#include <QApplication>

// Subclasses to gain access to the IDs
class MNotificationToolNotification : public MNotification
{
public:
    explicit MNotificationToolNotification(const QString &eventType, const QString &summary, const QString &body);
    explicit MNotificationToolNotification(uint id);
    uint id() const;
    void setEventType(const QString &eventType);
};

class MNotificationToolNotificationGroup : public MNotificationGroup
{
public:
    explicit MNotificationToolNotificationGroup(const QString &eventType, const QString &summary, const QString &body);
    explicit MNotificationToolNotificationGroup(uint id);
    uint id() const;
    void setEventType(const QString &eventType);
};

MNotificationToolNotification::MNotificationToolNotification(const QString &eventType, const QString &summary, const QString &body) : MNotification(eventType, summary, body)
{
}

MNotificationToolNotification::MNotificationToolNotification(uint id) : MNotification(id)
{
}

uint MNotificationToolNotification::id() const
{
    return MNotification::id();
}

void MNotificationToolNotification::setEventType(const QString &eventType)
{
    MNotification::setEventType(eventType);
}

MNotificationToolNotificationGroup::MNotificationToolNotificationGroup(const QString &eventType, const QString &summary, const QString &body) : MNotificationGroup(eventType, summary, body)
{
}

MNotificationToolNotificationGroup::MNotificationToolNotificationGroup(uint id) : MNotificationGroup(id)
{
}

uint MNotificationToolNotificationGroup::id() const
{
    return MNotificationGroup::id();
}

void MNotificationToolNotificationGroup::setEventType(const QString &eventType)
{
    MNotificationGroup::setEventType(eventType);
}

// The actions for this tool
enum ToolAction {
    Undefined,
    Add,
    Update,
    Remove
};

// The action to perform
ToolAction toolAction = Undefined;

// Whether to operate on notification groups instead of notifications
bool groupMode = false;

// Notifications list mode in use
bool listMode = false;

// The notification/notification group ID to use
uint id = 0;

// The notification/notification group ID to use
uint count = 1;

// Prints usage information
int usage(const char *program)
{
    std::cerr << std::setw(7) << "Usage: " << program << " [OPTION]... EVENTTYPE [SUMMARY BODY IMAGE SERVICENAME OBJECTPATH INTERFACE METHODNAME ARG...]" << std::endl;
    std::cerr << std::setw(7) << "Manage notifications." << std::endl;
    std::cerr << std::setw(7) << std::endl;
    std::cerr << std::setw(7) << "Mandatory arguments to long options are mandatory for short options too." << std::endl;
    std::cerr << std::setw(7) << "  -a, --action=ACTION        The action (add/update/remove) to perform." << std::endl;
    std::cerr << std::setw(7) << "                             add - Adds a new notification or notification group." << std::endl;
    std::cerr << std::setw(7) << "                             update - Updates an existing notification or notification group." << std::endl;
    std::cerr << std::setw(7) << "                             remove - Removes an existing notification or notification group." << std::endl;
    std::cerr << std::setw(7) << "                                      A specific notification or group can be specified with the -i argument." << std::endl;
    std::cerr << std::setw(7) << "                                      If no id is given, all the notifications will be removed." << std::endl;
    std::cerr << std::setw(7) << "  -g, --group                Whether to operate on notification groups instead of notifications." << std::endl;
    std::cerr << std::setw(7) << "  -i, --id=ID                The notification/notification group ID to use." << std::endl;
    std::cerr << std::setw(7) << "  -c, --count=NUMBER         The number of notifications. This parameter has no effect when the action is 'remove'" << std::endl;
    std::cerr << std::setw(7) << "  -l, --list                 List all notifications that belong to this application. Returns a count of notifications as an exit value." << std::endl;
    std::cerr << std::setw(7) << "      --help     display this help and exit" << std::endl;
    return -1;
}

// Parses command line arguments (the flags)
int parseArguments(int argc, char *argv[])
{
    while (1) {
        int option_index = 0;
        static struct option long_options[] = {
            { "action", required_argument, NULL, 'a' },
            { "group", no_argument, NULL, 'g' },
            { "id", required_argument, NULL, 'i' },
            { "count", required_argument, NULL, 'c' },
            { "help", no_argument, NULL, 'h' },
            { "list", no_argument, NULL, 'l'},
            { 0, 0, 0, 0 }
        };

        int c = getopt_long(argc, argv, "a:gi:c:pl", long_options, &option_index);
        if (c == -1)
            break;

        switch (c) {
        case 'a':
            if (strcmp(optarg, "add") == 0) {
                toolAction = Add;
            } else if (strcmp(optarg, "update") == 0) {
                toolAction = Update;
            } else if (strcmp(optarg, "remove") == 0) {
                toolAction = Remove;
            }
            break;
        case 'i':
            id = atoi(optarg);
            break;
        case 'c':
            count = atoi(optarg);
            break;
        case 'g':
            groupMode = true;
            break;
        case 'l':
            listMode = true;
            break;
        case 'h':
            return usage(argv[0]);
        default:
            break;
        }
    }

    if (!listMode) {
        if (toolAction == Undefined ||
                (toolAction == Add && argc < optind + 1) ||
                (toolAction == Update && argc < optind + 4) ||
                (toolAction == Update && id == 0)) {
            return usage(argv[0]);
        }
    }
    return 0;
}

int main(int argc, char *argv[])
{
    // Parse arguments
    int result = parseArguments(argc, argv);
    if (result != 0) {
        return result;
    }

    // MApplication creates MNotificationManager for specified application
    QScopedPointer<QCoreApplication> application(new QCoreApplication(argc, argv));
    if (application.isNull()) {
        std::cerr << "Couldn't initialize QCoreApplication" << std::endl;
        return -1;
    }

    // Calls notificationIdList from NotificationManager. Returns size of the list from main.
    if (listMode) {
        QList<MNotification *> list = MNotification::notifications();
        result = list.size();
        std::cout << "\n" << list.size() << " notifications." << std::endl;
        if (list.size() > 0) {
            std::cout << "Notifications:" << std::endl;
            std::cout << "Id\tType\tSummary\tBody\tImage\tCount" << std::endl;
            foreach(MNotification *notification, list) {
                MNotificationToolNotification *toolNotification = static_cast<MNotificationToolNotification *>(notification);
                std::cout << toolNotification->id() << "\t" <<
                             toolNotification->eventType().toUtf8().constData() << "\t" <<
                             toolNotification->summary().toUtf8().constData() << "\t" <<
                             toolNotification->body().toUtf8().constData() << "\t" <<
                             toolNotification->image().toUtf8().constData() << "\t" <<
                             toolNotification->count() << std::endl;
                delete notification;
            }
        }
    }

    // Execute the desired action
    switch (toolAction) {
    case Add:
    case Update: {
        // Get the parameters for adding and updating notifications/notification groups
        QString eventType = QString(argv[optind]);
        QString summary, body, image;
        if (argc >= optind + 1) {
            summary = QString(argv[optind + 1]);
        }
        if (argc >= optind + 2) {
            body = QString(argv[optind + 2]);
        }
        if (argc >= optind + 3) {
            image = QString(argv[optind + 3]);
        }

        // Create an action if one is defined
        MRemoteAction *remoteAction;
        if (argc >= optind + 4 + 4) {
            QString serviceName(argv[optind + 4]);
            QString objectPath(argv[optind + 5]);
            QString interface(argv[optind + 6]);
            QString methodName(argv[optind + 7]);
            QList<QVariant> arguments;

            for (int i = optind + 8; i < argc; ++i) {
                arguments.append(QVariant(argv[i]));
            }
            remoteAction = new MRemoteAction(serviceName, objectPath, interface, methodName, arguments);
        } else {
            remoteAction = new MRemoteAction;
        }

        if (toolAction == Add) {
            // Add a notification/notification group
            if (groupMode) {
                MNotificationToolNotificationGroup group(eventType, summary, body);
                group.setImage(image);
                group.setAction(*remoteAction);
                group.setCount(count);
                group.publish();
                result = group.id();
            } else {
                if (id != 0) {
                    MNotificationToolNotification notification(eventType, summary, body);
                    notification.setGroup(MNotificationToolNotificationGroup(id));
                    notification.setImage(image);
                    notification.setAction(*remoteAction);
                    notification.setCount(count);
                    notification.publish();
                    result = notification.id();
                } else {
                    MNotificationToolNotification notification(eventType, summary, body);
                    notification.setImage(image);
                    notification.setAction(*remoteAction);
                    notification.setCount(count);
                    notification.publish();
                    result = notification.id();
                }
            }
        } else {
            // Update a notification/notification group
            if (groupMode) {
                MNotificationToolNotificationGroup group(id);
                group.setEventType(eventType);
                group.setSummary(summary);
                group.setBody(body);
                group.setImage(image);
                group.setAction(*remoteAction);
                group.setCount(count);
                group.publish();
            } else {
                MNotificationToolNotification notification(id);
                notification.setEventType(eventType);
                notification.setSummary(summary);
                notification.setBody(body);
                notification.setImage(image);
                notification.setAction(*remoteAction);
                notification.setCount(count);
                notification.publish();
            }
        }

        delete remoteAction;
        break;
    }
    case Remove:
        if (id > 0) {
            if (groupMode) {
                MNotificationToolNotificationGroup group(id);
                group.remove();
            } else {
                MNotificationToolNotification notification(id);
                notification.remove();
            }
        } else {
            if (groupMode) {
                // Remove all the notifications for this user
                QList<MNotificationGroup*> list = MNotificationGroup::notificationGroups();
                foreach (MNotificationGroup *notificationGroup, list) {
                    notificationGroup->remove();
                    delete notificationGroup;
                }
            } else {
                // Remove all the notifications for this user
                QList<MNotification *> list = MNotification::notifications();
                foreach (MNotification *notification, list) {
                    notification->remove();
                    delete notification;
                }
            }
        }
        break;
    default:
        break;
    }

    return result;
}
<commit_msg>Changes: Identifier string support in mnotificationtool<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** 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
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

//============================================================================
// Description : Tool to handle notifications and notification groups
//============================================================================

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <getopt.h>
#include <QCoreApplication>
#include <MNotification>
#include <MRemoteAction>
#include <MNotificationGroup>
#include <QString>
#include <QStringList>
#include <QRegExp>
#include <QApplication>

// Subclasses to gain access to the IDs
class MNotificationToolNotification : public MNotification
{
public:
    explicit MNotificationToolNotification(const QString &eventType, const QString &summary, const QString &body);
    explicit MNotificationToolNotification(uint id);
    uint id() const;
    void setEventType(const QString &eventType);
};

class MNotificationToolNotificationGroup : public MNotificationGroup
{
public:
    explicit MNotificationToolNotificationGroup(const QString &eventType, const QString &summary, const QString &body);
    explicit MNotificationToolNotificationGroup(uint id);
    uint id() const;
    void setEventType(const QString &eventType);
};

MNotificationToolNotification::MNotificationToolNotification(const QString &eventType, const QString &summary, const QString &body) : MNotification(eventType, summary, body)
{
}

MNotificationToolNotification::MNotificationToolNotification(uint id) : MNotification(id)
{
}

uint MNotificationToolNotification::id() const
{
    return MNotification::id();
}

void MNotificationToolNotification::setEventType(const QString &eventType)
{
    MNotification::setEventType(eventType);
}

MNotificationToolNotificationGroup::MNotificationToolNotificationGroup(const QString &eventType, const QString &summary, const QString &body) : MNotificationGroup(eventType, summary, body)
{
}

MNotificationToolNotificationGroup::MNotificationToolNotificationGroup(uint id) : MNotificationGroup(id)
{
}

uint MNotificationToolNotificationGroup::id() const
{
    return MNotificationGroup::id();
}

void MNotificationToolNotificationGroup::setEventType(const QString &eventType)
{
    MNotificationGroup::setEventType(eventType);
}

// The actions for this tool
enum ToolAction {
    Undefined,
    Add,
    Update,
    Remove
};

// The action to perform
ToolAction toolAction = Undefined;

// Whether to operate on notification groups instead of notifications
bool groupMode = false;

// Notifications list mode in use
bool listMode = false;

// The notification/notification group ID to use
uint id = 0;

// The notification/notification group ID to use
uint count = 1;

// The notification identifier to use
QString identifier = QString();

// Prints usage information
int usage(const char *program)
{
    std::cerr << std::setw(7) << "Usage: " << program << " [OPTION]... EVENTTYPE [SUMMARY BODY IMAGE SERVICENAME OBJECTPATH INTERFACE METHODNAME ARG...]" << std::endl;
    std::cerr << std::setw(7) << "Manage notifications." << std::endl;
    std::cerr << std::setw(7) << std::endl;
    std::cerr << std::setw(7) << "Mandatory arguments to long options are mandatory for short options too." << std::endl;
    std::cerr << std::setw(7) << "  -a, --action=ACTION        The action (add/update/remove) to perform." << std::endl;
    std::cerr << std::setw(7) << "                             add - Adds a new notification or notification group." << std::endl;
    std::cerr << std::setw(7) << "                             update - Updates an existing notification or notification group." << std::endl;
    std::cerr << std::setw(7) << "                             remove - Removes an existing notification or notification group." << std::endl;
    std::cerr << std::setw(7) << "                                      A specific notification or group can be specified with the -i argument." << std::endl;
    std::cerr << std::setw(7) << "                                      If no id is given, all the notifications will be removed." << std::endl;
    std::cerr << std::setw(7) << "  -g, --group                Whether to operate on notification groups instead of notifications." << std::endl;
    std::cerr << std::setw(7) << "  -i, --id=ID                The notification/notification group ID to use." << std::endl;
    std::cerr << std::setw(7) << "  -c, --count=NUMBER         The number of notifications. This parameter has no effect when the action is 'remove'" << std::endl;
    std::cerr << std::setw(7) << "  -l, --list                 List all notifications that belong to this application. Returns a count of notifications as an exit value." << std::endl;
    std::cerr << std::setw(7) << "  -I, --identifier           Notification identifier to use" << std::endl;
    std::cerr << std::setw(7) << "      --help     display this help and exit" << std::endl;
    return -1;
}

// Parses command line arguments (the flags)
int parseArguments(int argc, char *argv[])
{
    while (1) {
        int option_index = 0;
        static struct option long_options[] = {
            { "action", required_argument, NULL, 'a' },
            { "group", no_argument, NULL, 'g' },
            { "id", required_argument, NULL, 'i' },
            { "count", required_argument, NULL, 'c' },
            { "help", no_argument, NULL, 'h' },
            { "list", no_argument, NULL, 'l'},
            { "identifier", required_argument, NULL, 'I'},
            { 0, 0, 0, 0 }
        };

        int c = getopt_long(argc, argv, "a:gi:I:c:pl", long_options, &option_index);
        if (c == -1)
            break;

        switch (c) {
        case 'a':
            if (strcmp(optarg, "add") == 0) {
                toolAction = Add;
            } else if (strcmp(optarg, "update") == 0) {
                toolAction = Update;
            } else if (strcmp(optarg, "remove") == 0) {
                toolAction = Remove;
            }
            break;
        case 'i':
            id = atoi(optarg);
            break;
        case 'c':
            count = atoi(optarg);
            break;
        case 'g':
            groupMode = true;
            break;
        case 'l':
            listMode = true;
            break;
        case 'h':
            return usage(argv[0]);
            break;
        case 'I':
            identifier = optarg;
            break;
        default:
            break;
        }
    }

    if (!listMode) {
        if (toolAction == Undefined ||
                (toolAction == Add && argc < optind + 1) ||
                (toolAction == Update && argc < optind + 4) ||
                (toolAction == Update && id == 0)) {
            return usage(argv[0]);
        }
    }
    return 0;
}

int main(int argc, char *argv[])
{
    // Parse arguments
    int result = parseArguments(argc, argv);
    if (result != 0) {
        return result;
    }

    // MApplication creates MNotificationManager for specified application
    QScopedPointer<QCoreApplication> application(new QCoreApplication(argc, argv));
    if (application.isNull()) {
        std::cerr << "Couldn't initialize QCoreApplication" << std::endl;
        return -1;
    }

    // Calls notificationIdList from NotificationManager. Returns size of the list from main.
    if (listMode) {
        QList<MNotification *> list = MNotification::notifications();
        result = list.size();
        std::cout << "\n" << list.size() << " notifications." << std::endl;
        if (list.size() > 0) {
            std::cout << "Notifications:" << std::endl;
            std::cout << "Id\tType\tSummary\tBody\tImage\tCount" << std::endl;
            foreach(MNotification *notification, list) {
                MNotificationToolNotification *toolNotification = static_cast<MNotificationToolNotification *>(notification);
                std::cout << toolNotification->id() << "\t" <<
                             toolNotification->eventType().toUtf8().constData() << "\t" <<
                             toolNotification->summary().toUtf8().constData() << "\t" <<
                             toolNotification->body().toUtf8().constData() << "\t" <<
                             toolNotification->image().toUtf8().constData() << "\t" <<
                             toolNotification->count() << "\t" <<
                             toolNotification->identifier().toUtf8().constData() << std::endl;
                delete notification;
            }
        }
    }

    // Execute the desired action
    switch (toolAction) {
    case Add:
    case Update: {
        // Get the parameters for adding and updating notifications/notification groups
        QString eventType = QString(argv[optind]);
        QString summary, body, image;
        if (argc >= optind + 1) {
            summary = QString(argv[optind + 1]);
        }
        if (argc >= optind + 2) {
            body = QString(argv[optind + 2]);
        }
        if (argc >= optind + 3) {
            image = QString(argv[optind + 3]);
        }

        // Create an action if one is defined
        MRemoteAction *remoteAction;
        if (argc >= optind + 4 + 4) {
            QString serviceName(argv[optind + 4]);
            QString objectPath(argv[optind + 5]);
            QString interface(argv[optind + 6]);
            QString methodName(argv[optind + 7]);
            QList<QVariant> arguments;

            for (int i = optind + 8; i < argc; ++i) {
                arguments.append(QVariant(argv[i]));
            }
            remoteAction = new MRemoteAction(serviceName, objectPath, interface, methodName, arguments);
        } else {
            remoteAction = new MRemoteAction;
        }

        if (toolAction == Add) {
            // Add a notification/notification group
            if (groupMode) {
                MNotificationToolNotificationGroup group(eventType, summary, body);
                group.setImage(image);
                group.setAction(*remoteAction);
                group.setCount(count);
                group.setIdentifier(identifier);
                group.publish();
                result = group.id();
            } else {
                if (id != 0) {
                    MNotificationToolNotification notification(eventType, summary, body);
                    notification.setGroup(MNotificationToolNotificationGroup(id));
                    notification.setImage(image);
                    notification.setAction(*remoteAction);
                    notification.setCount(count);
                    notification.setIdentifier(identifier);
                    notification.publish();
                    result = notification.id();
                } else {
                    MNotificationToolNotification notification(eventType, summary, body);
                    notification.setImage(image);
                    notification.setAction(*remoteAction);
                    notification.setCount(count);
                    notification.setIdentifier(identifier);
                    notification.publish();
                    result = notification.id();
                }
            }
        } else {
            // Update a notification/notification group
            if (groupMode) {
                MNotificationToolNotificationGroup group(id);
                group.setEventType(eventType);
                group.setSummary(summary);
                group.setBody(body);
                group.setImage(image);
                group.setAction(*remoteAction);
                group.setCount(count);
                group.setIdentifier(identifier);
                group.publish();
            } else {
                MNotificationToolNotification notification(id);
                notification.setEventType(eventType);
                notification.setSummary(summary);
                notification.setBody(body);
                notification.setImage(image);
                notification.setAction(*remoteAction);
                notification.setCount(count);
                notification.setIdentifier(identifier);
                notification.publish();
            }
        }

        delete remoteAction;
        break;
    }
    case Remove:
        if (id > 0) {
            if (groupMode) {
                MNotificationToolNotificationGroup group(id);
                group.remove();
            } else {
                MNotificationToolNotification notification(id);
                notification.remove();
            }
        } else {
            if (groupMode) {
                // Remove all the notifications for this user
                QList<MNotificationGroup*> list = MNotificationGroup::notificationGroups();
                foreach (MNotificationGroup *notificationGroup, list) {
                    notificationGroup->remove();
                    delete notificationGroup;
                }
            } else {
                // Remove all the notifications for this user
                QList<MNotification *> list = MNotification::notifications();
                foreach (MNotification *notification, list) {
                    notification->remove();
                    delete notification;
                }
            }
        }
        break;
    default:
        break;
    }

    return result;
}
<|endoftext|>