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

#include "chrome/browser/chromeos/main_menu.h"

#include <string>
#include <vector>

#include "app/gfx/insets.h"
#include "app/resource_bundle.h"
#include "base/command_line.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_view_host_factory.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
#include "chrome/browser/renderer_host/site_instance.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
#include "grit/app_resources.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "views/background.h"
#include "views/painter.h"
#include "views/screen.h"
#include "views/widget/root_view.h"
#include "views/widget/widget_gtk.h"

namespace chromeos {

// Initial size of the renderer. This is contained within a window whose size
// is set to the size of the image IDR_MAIN_MENU_BUTTON_DROP_DOWN.
static const int kRendererX = 0;
static const int kRendererY = 25;
static const int kRendererWidth = 250;
static const int kRendererHeight = 400;

// Insets defining the regions that are stretched and titled to create the
// background of the popup. These constants are fed into
// Painter::CreateImagePainter as the insets, see it for details.
static const int kBackgroundImageTop = 27;
static const int kBackgroundImageLeft = 85;
static const int kBackgroundImageBottom = 10;
static const int kBackgroundImageRight = 8;

// Command line switch for specifying url of the page.
static const wchar_t kURLSwitch[] = L"main-menu-url";

// Command line switch for specifying the size of the main menu. The default is
// full screen.
static const wchar_t kMenuSizeSwitch[] = L"main-menu-size";

// URL of the page to load. This is ignored if kURLSwitch is specified.
static const char kMenuURL[] = "http://goto.ext.google.com/crux-home";

// Returns the size of the popup. By default the popup is sized slightly
// larger than full screen, but can be overriden by the command line switch
// kMenuSizeSwitch.
static gfx::Size GetPopupSize() {
  std::wstring cl_size =
      CommandLine::ForCurrentProcess()->GetSwitchValue(kMenuSizeSwitch);
  if (!cl_size.empty()) {
    std::vector<std::string> chunks;
    SplitString(WideToUTF8(cl_size), 'x', &chunks);
    if (chunks.size() == 2)
      return gfx::Size(StringToInt(chunks[0]), StringToInt(chunks[1]));
  }

  gfx::Size size =
      views::Screen::GetMonitorAreaNearestPoint(gfx::Point(0, 0)).size();
  // When full screen we don't want to see the drop shadow. Adjust the width
  // so the drop shadow ends up off screen.
  size.Enlarge(kBackgroundImageRight, kBackgroundImageBottom);
  return size;
}

// Returns the size for the renderer widget host view given the specified
// size of the popup.
static gfx::Size CalculateRWHVSize(const gfx::Size& popup_size) {
  return gfx::Size(popup_size.width() - kRendererX - kBackgroundImageRight,
                   popup_size.height() - kRendererY - kBackgroundImageBottom);
}

// Returns the URL of the menu.
static GURL GetMenuURL() {
  std::wstring url_string =
      CommandLine::ForCurrentProcess()->GetSwitchValue(kURLSwitch);
  if (!url_string.empty())
    return GURL(WideToUTF8(url_string));
  return GURL(kMenuURL);
}

// static
void MainMenu::Show(Browser* browser) {
  MainMenu::Get()->ShowImpl(browser);
}

// static
void MainMenu::ScheduleCreation() {
  MessageLoop::current()->PostDelayedTask(FROM_HERE, new LoadTask(), 5000);
}

MainMenu::~MainMenu() {
  // NOTE: we leak the menu_rvh_ and popup_ as by the time we get here the
  // message loop and notification services have been shutdown.
  // TODO(sky): fix this.
  // menu_rvh_->Shutdown();
  // popup_->CloseNow();
}

MainMenu::MainMenu()
    : browser_(NULL),
      popup_(NULL),
      site_instance_(NULL),
      menu_rvh_(NULL),
      rwhv_(NULL),
      ALLOW_THIS_IN_INITIALIZER_LIST(tab_contents_delegate_(this)),
      ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
      has_shown_(false) {
  SkBitmap* drop_down_image = ResourceBundle::GetSharedInstance().
      GetBitmapNamed(IDR_MAIN_MENU_BUTTON_DROP_DOWN);

  views::WidgetGtk* menu_popup =
      new views::WidgetGtk(views::WidgetGtk::TYPE_POPUP);
  popup_ = menu_popup;
  // The background image has transparency, so we make the window transparent.
  menu_popup->MakeTransparent();
  gfx::Size popup_size = GetPopupSize();
  menu_popup->Init(NULL, gfx::Rect(0, 0, popup_size.width(),
                                   popup_size.height()));

  views::Painter* painter = views::Painter::CreateImagePainter(
      *drop_down_image,
      gfx::Insets(kBackgroundImageTop, kBackgroundImageLeft,
                  kBackgroundImageBottom, kBackgroundImageRight),
      false);
  menu_popup->GetRootView()->set_background(
      views::Background::CreateBackgroundPainter(true, painter));

  GURL menu_url(GetMenuURL());
  DCHECK(BrowserList::begin() != BrowserList::end());
  // TODO(sky): this shouldn't pick a random profile to use.
  site_instance_ = SiteInstance::CreateSiteInstanceForURL(
      (*BrowserList::begin())->profile(), menu_url);
  menu_rvh_ = new RenderViewHost(site_instance_, this, MSG_ROUTING_NONE);

  rwhv_ = new RenderWidgetHostViewGtk(menu_rvh_);
  rwhv_->InitAsChild();
  menu_rvh_->CreateRenderView(browser_->profile()->GetRequestContext());
  menu_popup->AddChild(rwhv_->GetNativeView());
  gfx::Size rwhv_size = CalculateRWHVSize(popup_size);
  menu_popup->PositionChild(rwhv_->GetNativeView(), kRendererX, kRendererY,
                            rwhv_size.width(), rwhv_size.height());
  rwhv_->SetSize(rwhv_size);
  menu_rvh_->NavigateToURL(menu_url);
}

// static
MainMenu* MainMenu::Get() {
  return Singleton<MainMenu>::get();
}

void MainMenu::ShowImpl(Browser* browser) {
  Cleanup();

  browser_ = browser;

  popup_->Show();

  GtkWidget* rwhv_widget = rwhv_->GetNativeView();

  if (!has_shown_) {
    has_shown_ = true;
    gtk_widget_realize(rwhv_widget);
    g_signal_connect(rwhv_widget, "button-press-event",
                     G_CALLBACK(CallButtonPressEvent), this);
  }

  // Do a mouse grab on the renderer widget host view's widget so that we can
  // close the popup if the user clicks anywhere else. And do a keyboard
  // grab so that we get all key events.
  gdk_pointer_grab(rwhv_widget->window, FALSE,
                   static_cast<GdkEventMask>(
                         GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
                         GDK_POINTER_MOTION_MASK),
                   NULL, NULL, GDK_CURRENT_TIME);
  gdk_keyboard_grab(rwhv_widget->window, FALSE, GDK_CURRENT_TIME);
}

void MainMenu::Hide() {
  gdk_keyboard_ungrab(GDK_CURRENT_TIME);
  gdk_pointer_ungrab(GDK_CURRENT_TIME);

  popup_->Hide();

  // The stack may have pending_contents_ on it. Delay deleting the
  // pending_contents_ as TabContents doesn't deal well with being deleted
  // while on the stack.
  MessageLoop::current()->PostTask(FROM_HERE,
      method_factory_.NewRunnableMethod(&MainMenu::Cleanup));
}

void MainMenu::Cleanup() {
  pending_contents_.reset(NULL);
  method_factory_.RevokeAll();
}

// static
gboolean MainMenu::CallButtonPressEvent(GtkWidget* widget,
                                        GdkEventButton* event,
                                        MainMenu* menu) {
  return menu->OnButtonPressEvent(widget, event);
}

gboolean MainMenu::OnButtonPressEvent(GtkWidget* widget,
                                      GdkEventButton* event) {
  if (event->x < 0 || event->y < 0 ||
      event->x >= widget->allocation.width ||
      event->y >= widget->allocation.height) {
    // The user clicked outside the bounds of the menu, delete the main which
    // results in closing it.
    Hide();
  }
  return FALSE;
}

void MainMenu::RequestMove(const gfx::Rect& new_bounds) {
  // Invoking PositionChild results in a gtk signal that triggers attempting to
  // to resize the window. We need to set the size request so that it resizes
  // correctly when this happens.
  gtk_widget_set_size_request(popup_->GetNativeView(),
                              new_bounds.width(), new_bounds.height());
  gfx::Size rwhv_size = CalculateRWHVSize(new_bounds.size());
  popup_->PositionChild(rwhv_->GetNativeView(), kRendererX, kRendererY,
                        rwhv_size.width(), rwhv_size.height());
  popup_->SetBounds(new_bounds);
  rwhv_->SetSize(rwhv_size);
}

void MainMenu::CreateNewWindow(int route_id) {
  if (pending_contents_.get()) {
    NOTREACHED();
    return;
  }

  helper_.CreateNewWindow(route_id, browser_->profile(), site_instance_,
                          DOMUIFactory::GetDOMUIType(GURL(GetMenuURL())),
                          NULL);
  pending_contents_.reset(helper_.GetCreatedWindow(route_id));
  pending_contents_->set_delegate(&tab_contents_delegate_);
}

void MainMenu::ShowCreatedWindow(int route_id,
                                 WindowOpenDisposition disposition,
                                 const gfx::Rect& initial_pos,
                                 bool user_gesture,
                                 const GURL& creator_url) {
  if (disposition == NEW_POPUP) {
    pending_contents_->set_delegate(NULL);
    browser_->GetSelectedTabContents()->AddNewContents(
        pending_contents_.release(), disposition, initial_pos, user_gesture,
        creator_url);
    Hide();
  }
}

void MainMenu::TabContentsDelegateImpl::OpenURLFromTab(
    TabContents* source,
    const GURL& url,
    const GURL& referrer,
    WindowOpenDisposition disposition,
    PageTransition::Type transition) {
  menu_->browser_->OpenURL(url, referrer, NEW_FOREGROUND_TAB,
                           PageTransition::LINK);
  menu_->Hide();
}

// LoadTask -------------------------------------------------------------------

void MainMenu::LoadTask::Run() {
  MainMenu::Get();
}

}  // namespace chromeos
<commit_msg>Fix crashing bug due to browser being NULL. BUG=None TEST=None Review URL: http://codereview.chromium.org/400015<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/main_menu.h"

#include <string>
#include <vector>

#include "app/gfx/insets.h"
#include "app/resource_bundle.h"
#include "base/command_line.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_view_host_factory.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
#include "chrome/browser/renderer_host/site_instance.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
#include "grit/app_resources.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "views/background.h"
#include "views/painter.h"
#include "views/screen.h"
#include "views/widget/root_view.h"
#include "views/widget/widget_gtk.h"

namespace chromeos {

// Initial size of the renderer. This is contained within a window whose size
// is set to the size of the image IDR_MAIN_MENU_BUTTON_DROP_DOWN.
static const int kRendererX = 0;
static const int kRendererY = 25;
static const int kRendererWidth = 250;
static const int kRendererHeight = 400;

// Insets defining the regions that are stretched and titled to create the
// background of the popup. These constants are fed into
// Painter::CreateImagePainter as the insets, see it for details.
static const int kBackgroundImageTop = 27;
static const int kBackgroundImageLeft = 85;
static const int kBackgroundImageBottom = 10;
static const int kBackgroundImageRight = 8;

// Command line switch for specifying url of the page.
static const wchar_t kURLSwitch[] = L"main-menu-url";

// Command line switch for specifying the size of the main menu. The default is
// full screen.
static const wchar_t kMenuSizeSwitch[] = L"main-menu-size";

// URL of the page to load. This is ignored if kURLSwitch is specified.
static const char kMenuURL[] = "http://goto.ext.google.com/crux-home";

// Returns the size of the popup. By default the popup is sized slightly
// larger than full screen, but can be overriden by the command line switch
// kMenuSizeSwitch.
static gfx::Size GetPopupSize() {
  std::wstring cl_size =
      CommandLine::ForCurrentProcess()->GetSwitchValue(kMenuSizeSwitch);
  if (!cl_size.empty()) {
    std::vector<std::string> chunks;
    SplitString(WideToUTF8(cl_size), 'x', &chunks);
    if (chunks.size() == 2)
      return gfx::Size(StringToInt(chunks[0]), StringToInt(chunks[1]));
  }

  gfx::Size size =
      views::Screen::GetMonitorAreaNearestPoint(gfx::Point(0, 0)).size();
  // When full screen we don't want to see the drop shadow. Adjust the width
  // so the drop shadow ends up off screen.
  size.Enlarge(kBackgroundImageRight, kBackgroundImageBottom);
  return size;
}

// Returns the size for the renderer widget host view given the specified
// size of the popup.
static gfx::Size CalculateRWHVSize(const gfx::Size& popup_size) {
  return gfx::Size(popup_size.width() - kRendererX - kBackgroundImageRight,
                   popup_size.height() - kRendererY - kBackgroundImageBottom);
}

// Returns the URL of the menu.
static GURL GetMenuURL() {
  std::wstring url_string =
      CommandLine::ForCurrentProcess()->GetSwitchValue(kURLSwitch);
  if (!url_string.empty())
    return GURL(WideToUTF8(url_string));
  return GURL(kMenuURL);
}

// static
void MainMenu::Show(Browser* browser) {
  MainMenu::Get()->ShowImpl(browser);
}

// static
void MainMenu::ScheduleCreation() {
  MessageLoop::current()->PostDelayedTask(FROM_HERE, new LoadTask(), 5000);
}

MainMenu::~MainMenu() {
  // NOTE: we leak the menu_rvh_ and popup_ as by the time we get here the
  // message loop and notification services have been shutdown.
  // TODO(sky): fix this.
  // menu_rvh_->Shutdown();
  // popup_->CloseNow();
}

MainMenu::MainMenu()
    : browser_(NULL),
      popup_(NULL),
      site_instance_(NULL),
      menu_rvh_(NULL),
      rwhv_(NULL),
      ALLOW_THIS_IN_INITIALIZER_LIST(tab_contents_delegate_(this)),
      ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
      has_shown_(false) {
  SkBitmap* drop_down_image = ResourceBundle::GetSharedInstance().
      GetBitmapNamed(IDR_MAIN_MENU_BUTTON_DROP_DOWN);

  views::WidgetGtk* menu_popup =
      new views::WidgetGtk(views::WidgetGtk::TYPE_POPUP);
  popup_ = menu_popup;
  // The background image has transparency, so we make the window transparent.
  menu_popup->MakeTransparent();
  gfx::Size popup_size = GetPopupSize();
  menu_popup->Init(NULL, gfx::Rect(0, 0, popup_size.width(),
                                   popup_size.height()));

  views::Painter* painter = views::Painter::CreateImagePainter(
      *drop_down_image,
      gfx::Insets(kBackgroundImageTop, kBackgroundImageLeft,
                  kBackgroundImageBottom, kBackgroundImageRight),
      false);
  menu_popup->GetRootView()->set_background(
      views::Background::CreateBackgroundPainter(true, painter));

  GURL menu_url(GetMenuURL());
  DCHECK(BrowserList::begin() != BrowserList::end());
  // TODO(sky): this shouldn't pick a random profile to use.
  Profile* profile = (*BrowserList::begin())->profile();
  site_instance_ = SiteInstance::CreateSiteInstanceForURL(profile, menu_url);
  menu_rvh_ = new RenderViewHost(site_instance_, this, MSG_ROUTING_NONE);

  rwhv_ = new RenderWidgetHostViewGtk(menu_rvh_);
  rwhv_->InitAsChild();
  menu_rvh_->CreateRenderView(profile->GetRequestContext());
  menu_popup->AddChild(rwhv_->GetNativeView());
  gfx::Size rwhv_size = CalculateRWHVSize(popup_size);
  menu_popup->PositionChild(rwhv_->GetNativeView(), kRendererX, kRendererY,
                            rwhv_size.width(), rwhv_size.height());
  rwhv_->SetSize(rwhv_size);
  menu_rvh_->NavigateToURL(menu_url);
}

// static
MainMenu* MainMenu::Get() {
  return Singleton<MainMenu>::get();
}

void MainMenu::ShowImpl(Browser* browser) {
  Cleanup();

  browser_ = browser;

  popup_->Show();

  GtkWidget* rwhv_widget = rwhv_->GetNativeView();

  if (!has_shown_) {
    has_shown_ = true;
    gtk_widget_realize(rwhv_widget);
    g_signal_connect(rwhv_widget, "button-press-event",
                     G_CALLBACK(CallButtonPressEvent), this);
  }

  // Do a mouse grab on the renderer widget host view's widget so that we can
  // close the popup if the user clicks anywhere else. And do a keyboard
  // grab so that we get all key events.
  gdk_pointer_grab(rwhv_widget->window, FALSE,
                   static_cast<GdkEventMask>(
                         GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
                         GDK_POINTER_MOTION_MASK),
                   NULL, NULL, GDK_CURRENT_TIME);
  gdk_keyboard_grab(rwhv_widget->window, FALSE, GDK_CURRENT_TIME);
}

void MainMenu::Hide() {
  gdk_keyboard_ungrab(GDK_CURRENT_TIME);
  gdk_pointer_ungrab(GDK_CURRENT_TIME);

  popup_->Hide();

  // The stack may have pending_contents_ on it. Delay deleting the
  // pending_contents_ as TabContents doesn't deal well with being deleted
  // while on the stack.
  MessageLoop::current()->PostTask(FROM_HERE,
      method_factory_.NewRunnableMethod(&MainMenu::Cleanup));
}

void MainMenu::Cleanup() {
  pending_contents_.reset(NULL);
  method_factory_.RevokeAll();
}

// static
gboolean MainMenu::CallButtonPressEvent(GtkWidget* widget,
                                        GdkEventButton* event,
                                        MainMenu* menu) {
  return menu->OnButtonPressEvent(widget, event);
}

gboolean MainMenu::OnButtonPressEvent(GtkWidget* widget,
                                      GdkEventButton* event) {
  if (event->x < 0 || event->y < 0 ||
      event->x >= widget->allocation.width ||
      event->y >= widget->allocation.height) {
    // The user clicked outside the bounds of the menu, delete the main which
    // results in closing it.
    Hide();
  }
  return FALSE;
}

void MainMenu::RequestMove(const gfx::Rect& new_bounds) {
  // Invoking PositionChild results in a gtk signal that triggers attempting to
  // to resize the window. We need to set the size request so that it resizes
  // correctly when this happens.
  gtk_widget_set_size_request(popup_->GetNativeView(),
                              new_bounds.width(), new_bounds.height());
  gfx::Size rwhv_size = CalculateRWHVSize(new_bounds.size());
  popup_->PositionChild(rwhv_->GetNativeView(), kRendererX, kRendererY,
                        rwhv_size.width(), rwhv_size.height());
  popup_->SetBounds(new_bounds);
  rwhv_->SetSize(rwhv_size);
}

void MainMenu::CreateNewWindow(int route_id) {
  if (pending_contents_.get()) {
    NOTREACHED();
    return;
  }

  helper_.CreateNewWindow(route_id, browser_->profile(), site_instance_,
                          DOMUIFactory::GetDOMUIType(GURL(GetMenuURL())),
                          NULL);
  pending_contents_.reset(helper_.GetCreatedWindow(route_id));
  pending_contents_->set_delegate(&tab_contents_delegate_);
}

void MainMenu::ShowCreatedWindow(int route_id,
                                 WindowOpenDisposition disposition,
                                 const gfx::Rect& initial_pos,
                                 bool user_gesture,
                                 const GURL& creator_url) {
  if (disposition == NEW_POPUP) {
    pending_contents_->set_delegate(NULL);
    browser_->GetSelectedTabContents()->AddNewContents(
        pending_contents_.release(), disposition, initial_pos, user_gesture,
        creator_url);
    Hide();
  }
}

void MainMenu::TabContentsDelegateImpl::OpenURLFromTab(
    TabContents* source,
    const GURL& url,
    const GURL& referrer,
    WindowOpenDisposition disposition,
    PageTransition::Type transition) {
  menu_->browser_->OpenURL(url, referrer, NEW_FOREGROUND_TAB,
                           PageTransition::LINK);
  menu_->Hide();
}

// LoadTask -------------------------------------------------------------------

void MainMenu::LoadTask::Run() {
  MainMenu::Get();
}

}  // namespace chromeos
<|endoftext|>


<commit_before>#include "nw_screen_api.h"

#if defined(OS_WIN)
#include "windows.h"
#endif

#include "base/lazy_instance.h"
#include "base/values.h"
#include "content/nw/src/api/nw_screen.h"
#include "extensions/browser/extensions_browser_client.h"
#include "ui/display/display_observer.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"

// For desktop capture APIs
#include "base/base64.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/media/webrtc/desktop_media_list_observer.h"
#include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
#include "chrome/browser/media/webrtc/native_desktop_media_list.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/desktop_streams_registry.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"

using namespace extensions::nwapi::nw__screen;
using namespace content;

namespace extensions {

  class NwDesktopCaptureMonitor : public DesktopMediaListObserver {
  public:
    static NwDesktopCaptureMonitor* GetInstance();

    NwDesktopCaptureMonitor();
    void Start(bool screens, bool windows);
    void Stop();
    bool IsStarted();

  private:
    int GetPrimaryMonitorIndex();
    // DesktopMediaListObserver implementation.
    void OnSourceAdded(DesktopMediaList* list, int index) override;
    void OnSourceRemoved(DesktopMediaList* list, int index) override;
    void OnSourceMoved(DesktopMediaList* list, int old_index, int new_index) override;
    void OnSourceNameChanged(DesktopMediaList* list, int index) override;
    void OnSourceThumbnailChanged(DesktopMediaList* list, int index) override;
    void OnSourcePreviewChanged(DesktopMediaList* list, size_t index) override;

    bool started_;
    std::vector<std::unique_ptr<DesktopMediaList>> media_list_;

    DISALLOW_COPY_AND_ASSIGN(NwDesktopCaptureMonitor);
  };

  class NwScreenDisplayObserver: public display::DisplayObserver {
  public:
    static NwScreenDisplayObserver* GetInstance();
    NwScreenDisplayObserver();

  private:
    ~NwScreenDisplayObserver() override;
    // gfx::DisplayObserver implementation.
    void OnDisplayMetricsChanged(const display::Display& display, uint32_t changed_metrics) override;
    void OnDisplayAdded(const display::Display& new_display) override;
    void OnDisplayRemoved(const display::Display& old_display) override;

    DISALLOW_COPY_AND_ASSIGN(NwScreenDisplayObserver);
  };

  namespace {

    // Helper function to convert display::Display to nwapi::nw__screen::Display
    std::unique_ptr<nwapi::nw__screen::Display> ConvertGfxDisplay(const display::Display& gfx_display) {
      std::unique_ptr<nwapi::nw__screen::Display> displayResult(new nwapi::nw__screen::Display);

      displayResult->id = gfx_display.id();
      displayResult->scale_factor = gfx_display.device_scale_factor();
      displayResult->is_built_in = gfx_display.IsInternal();
      displayResult->rotation = gfx_display.RotationAsDegree();
      displayResult->touch_support = (int)gfx_display.touch_support();

      gfx::Rect rect = gfx_display.bounds();
      DisplayGeometry& bounds = displayResult->bounds;
      bounds.x = rect.x();
      bounds.y = rect.y();
      bounds.width = rect.width();
      bounds.height = rect.height();

      rect = gfx_display.work_area();
      DisplayGeometry& work_area = displayResult->work_area;
      work_area.x = rect.x();
      work_area.y = rect.y();
      work_area.width = rect.width();
      work_area.height = rect.height();

      return displayResult;
    }

    void DispatchEvent(
        events::HistogramValue histogram_value,
        const std::string& event_name,
        std::vector<base::Value> args) {
      DCHECK_CURRENTLY_ON(BrowserThread::UI);
      //std::unique_ptr<base::ListValue> arg_list(std::move(args));
      ExtensionsBrowserClient::Get()->
        BroadcastEventToRenderers(
                                  histogram_value, event_name,
                                  std::make_unique<base::ListValue>(std::move(args)),
                                  false);
    }

    // Lazy initialize screen event listeners until first call
    base::LazyInstance<NwScreenDisplayObserver>::Leaky
      g_display_observer = LAZY_INSTANCE_INITIALIZER;

    base::LazyInstance<NwDesktopCaptureMonitor>::Leaky
      g_desktop_capture_monitor = LAZY_INSTANCE_INITIALIZER;

  }

  // static
  NwScreenDisplayObserver* NwScreenDisplayObserver::GetInstance() {
    return g_display_observer.Pointer();
  }

  NwScreenDisplayObserver::NwScreenDisplayObserver() {
    display::Screen* screen = display::Screen::GetScreen();
    if (screen) {
      screen->AddObserver(this);
    }
  }

  NwScreenDisplayObserver::~NwScreenDisplayObserver() {
    display::Screen* screen = display::Screen::GetScreen();
    if (screen) {
      screen->RemoveObserver(this);
    }
  }

  // Called when the |display|'s bound has changed.
  void NwScreenDisplayObserver::OnDisplayMetricsChanged(const display::Display& display,
    uint32_t changed_metrics) {
    std::vector<base::Value> args =
      nwapi::nw__screen::OnDisplayBoundsChanged::Create(*ConvertGfxDisplay(display),
                                                        changed_metrics);
    DispatchEvent(
      events::HistogramValue::UNKNOWN,
      nwapi::nw__screen::OnDisplayBoundsChanged::kEventName,
      std::move(args));
  }

  // Called when |new_display| has been added.
  void NwScreenDisplayObserver::OnDisplayAdded(const display::Display& new_display) {
    std::vector<base::Value> args =
      nwapi::nw__screen::OnDisplayAdded::Create(*ConvertGfxDisplay(new_display));
    DispatchEvent(
      events::HistogramValue::UNKNOWN,
      nwapi::nw__screen::OnDisplayAdded::kEventName,
      std::move(args));
  }

  // Called when |old_display| has been removed.
  void NwScreenDisplayObserver::OnDisplayRemoved(const display::Display& old_display) {
    std::vector<base::Value> args =
      nwapi::nw__screen::OnDisplayRemoved::Create(*ConvertGfxDisplay(old_display));
    DispatchEvent(
      events::HistogramValue::UNKNOWN,
      nwapi::nw__screen::OnDisplayRemoved::kEventName,
      std::move(args));
  }

  NwScreenGetScreensFunction::NwScreenGetScreensFunction() {}

  bool NwScreenGetScreensFunction::RunNWSync(base::ListValue* response, std::string* error) {
    const std::vector<display::Display>& displays = display::Screen::GetScreen()->GetAllDisplays();

    for (size_t i=0; i<displays.size(); i++) {
      response->Append(ConvertGfxDisplay(displays[i])->ToValue());
    }

    return true;
  }

  NwScreenInitEventListenersFunction::NwScreenInitEventListenersFunction() {}

  bool NwScreenInitEventListenersFunction::RunNWSync(base::ListValue* response, std::string* error) {
    NwScreenDisplayObserver::GetInstance();
    return true;
  }

  NwDesktopCaptureMonitor* NwDesktopCaptureMonitor::GetInstance() {
    return g_desktop_capture_monitor.Pointer();
  }

  NwDesktopCaptureMonitor::NwDesktopCaptureMonitor()
      : started_(false) {
  }

  void NwDesktopCaptureMonitor::Start(bool screens, bool windows) {
    if (started_) {
      return;
    }

    started_ = true;

    webrtc::DesktopCaptureOptions options = webrtc::DesktopCaptureOptions::CreateDefault();
    options.set_disable_effects(false);

    if (screens) {
      std::unique_ptr<DesktopMediaList> screen_media_list =
        std::make_unique<NativeDesktopMediaList>(
          DesktopMediaList::Type::kScreen,
          webrtc::DesktopCapturer::CreateScreenCapturer(options));
      media_list_.push_back(std::move(screen_media_list));
    }

    if (windows) {
      std::unique_ptr<DesktopMediaList> window_media_list =
        std::make_unique<NativeDesktopMediaList>(
          DesktopMediaList::Type::kWindow,
          webrtc::DesktopCapturer::CreateWindowCapturer(options));
      media_list_.push_back(std::move(window_media_list));
    }

    for (auto& media_list : media_list_) {
      media_list->StartUpdating(this);
    }
  }

  void NwDesktopCaptureMonitor::Stop() {
    started_ = false;
    media_list_.clear();
  }

  bool NwDesktopCaptureMonitor::IsStarted() {
    return started_;
  }

  int NwDesktopCaptureMonitor::GetPrimaryMonitorIndex() {
  #ifdef _WIN32
    int count=0;
    for (int i = 0;; ++i) {
      DISPLAY_DEVICE device;
      device.cb = sizeof(device);
      BOOL ret = EnumDisplayDevices(NULL, i, &device, 0);
      if(!ret)
        break;
      if (device.StateFlags & DISPLAY_DEVICE_ACTIVE){
        if (device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE){
          return count;
        }
        count++;
      }
    }
  #endif
    return -1;
  }

void NwDesktopCaptureMonitor::OnSourceAdded(DesktopMediaList* list, int index) {
    DesktopMediaList::Source src = list->GetSource(index);

    std::string type;
    switch(src.id.type) {
    case content::DesktopMediaID::TYPE_WINDOW:
      type = "window";
      break;
    case content::DesktopMediaID::TYPE_SCREEN:
      type = "screen";
      break;
    case content::DesktopMediaID::TYPE_NONE:
      type = "none";
      break;
    default:
      type = "unknown";
      break;
    }

    std::vector<base::Value> args = nwapi::nw__screen::OnSourceAdded::Create(
      src.id.ToString(),
      base::UTF16ToUTF8(src.name),
      index,
      type,
      src.id.type == content::DesktopMediaID::TYPE_SCREEN && GetPrimaryMonitorIndex() == index);

    DispatchEvent(
      events::HistogramValue::UNKNOWN,
      nwapi::nw__screen::OnSourceAdded::kEventName,
      std::move(args));
  }

void NwDesktopCaptureMonitor::OnSourceRemoved(DesktopMediaList* list, int index) {
    std::vector<base::Value> args = nwapi::nw__screen::OnSourceRemoved::Create(index);
    DispatchEvent(
      events::HistogramValue::UNKNOWN,
      nwapi::nw__screen::OnSourceRemoved::kEventName,
      std::move(args));
  }

void NwDesktopCaptureMonitor::OnSourceMoved(DesktopMediaList* list, int old_index, int new_index) {
    DesktopMediaList::Source src = list->GetSource(new_index);
    std::vector<base::Value> args = nwapi::nw__screen::OnSourceOrderChanged::Create(
      src.id.ToString(),
      new_index,
      old_index);
    DispatchEvent(
      events::HistogramValue::UNKNOWN,
      nwapi::nw__screen::OnSourceOrderChanged::kEventName,
      std::move(args));
  }

void NwDesktopCaptureMonitor::OnSourceNameChanged(DesktopMediaList* list, int index) {
    DesktopMediaList::Source src = list->GetSource(index);
    std::vector<base::Value> args = nwapi::nw__screen::OnSourceNameChanged::Create(
      src.id.ToString(),
      base::UTF16ToUTF8(src.name));
    DispatchEvent(
      events::HistogramValue::UNKNOWN,
      nwapi::nw__screen::OnSourceNameChanged::kEventName,
      std::move(args));
  }

void NwDesktopCaptureMonitor::OnSourcePreviewChanged(DesktopMediaList* list, size_t index) {
}

void NwDesktopCaptureMonitor::OnSourceThumbnailChanged(DesktopMediaList* list, int index) {
    std::string base64;

    DesktopMediaList::Source src = list->GetSource(index);
    SkBitmap bitmap = src.thumbnail.GetRepresentation(1).GetBitmap();
    std::vector<unsigned char> data;
    bool success = gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &data);
    if (success){
      base::StringPiece raw_str(reinterpret_cast<const char*>(&data[0]), data.size());
      base::Base64Encode(raw_str, &base64);
    }

    std::vector<base::Value> args = nwapi::nw__screen::OnSourceThumbnailChanged::Create(
      src.id.ToString(),
      base64);
    DispatchEvent(
      events::HistogramValue::UNKNOWN,
      nwapi::nw__screen::OnSourceThumbnailChanged::kEventName,
      std::move(args));
  }

  NwScreenStartMonitorFunction::NwScreenStartMonitorFunction() {}

  bool NwScreenStartMonitorFunction::RunNWSync(base::ListValue* response, std::string* error) {
    bool screens, windows;
    EXTENSION_FUNCTION_VALIDATE(args().size() >= 2);
    EXTENSION_FUNCTION_VALIDATE(args()[0].is_bool() && args()[1].is_bool());
    screens = args()[0].GetBool();
    windows = args()[1].GetBool();
    NwDesktopCaptureMonitor::GetInstance()->Start(screens, windows);
    return true;
  }

  NwScreenStopMonitorFunction::NwScreenStopMonitorFunction() {}

  bool NwScreenStopMonitorFunction::RunNWSync(base::ListValue* response, std::string* error) {
    NwDesktopCaptureMonitor::GetInstance()->Stop();
    return true;
  }

  NwScreenIsMonitorStartedFunction::NwScreenIsMonitorStartedFunction() {}

  bool NwScreenIsMonitorStartedFunction::RunNWSync(base::ListValue* response, std::string* error) {
    response->Append(NwDesktopCaptureMonitor::GetInstance()->IsStarted());
    return true;
  }

  NwScreenRegisterStreamFunction::NwScreenRegisterStreamFunction() {}

  bool NwScreenRegisterStreamFunction::RunNWSync(base::ListValue* response, std::string* error) {
    std::string id;
    EXTENSION_FUNCTION_VALIDATE(args().size() >= 1);
    EXTENSION_FUNCTION_VALIDATE(args()[0].is_string());
    id = args()[0].GetString();

    // following code is modified from `DesktopCaptureChooseDesktopMediaFunctionBase::OnPickerDialogResults`
    // in chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc

    content::DesktopMediaID source = content::DesktopMediaID::Parse(id);
    content::WebContents* web_contents = GetSenderWebContents();
    if (!source.is_null() && web_contents) {
      std::string result;
      source.audio_share = true;
      content::DesktopStreamsRegistry* registry = content::DesktopStreamsRegistry::GetInstance();
      // TODO(miu): Once render_frame_host() is being set, we should register the
      // exact RenderFrame requesting the stream, not the main RenderFrame.  With
      // that change, also update
      // MediaCaptureDevicesDispatcher::ProcessDesktopCaptureAccessRequest().
      // http://crbug.com/304341
      content::RenderFrameHost* const main_frame = web_contents->GetMainFrame();
      result = registry->RegisterStream(main_frame->GetProcess()->GetID(),
                                        main_frame->GetRoutingID(),
                                        url::Origin::Create(web_contents->GetURL().GetOrigin()),
                                        source,
                                        extension()->name(), content::kRegistryStreamTypeDesktop);
      response->Append(result);
    }
    return true;
  }

} // extensions
<commit_msg>port to new DesktopMediaListObserver implementation<commit_after>#include "nw_screen_api.h"

#if defined(OS_WIN)
#include "windows.h"
#endif

#include "base/lazy_instance.h"
#include "base/values.h"
#include "content/nw/src/api/nw_screen.h"
#include "extensions/browser/extensions_browser_client.h"
#include "ui/display/display_observer.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"

// For desktop capture APIs
#include "base/base64.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/media/webrtc/desktop_media_list_observer.h"
#include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
#include "chrome/browser/media/webrtc/native_desktop_media_list.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/desktop_streams_registry.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"

using namespace extensions::nwapi::nw__screen;
using namespace content;

namespace extensions {

  class NwDesktopCaptureMonitor : public DesktopMediaListObserver {
  public:
    static NwDesktopCaptureMonitor* GetInstance();

    NwDesktopCaptureMonitor();
    void Start(bool screens, bool windows);
    void Stop();
    bool IsStarted();

  private:
    int GetPrimaryMonitorIndex();
    // DesktopMediaListObserver implementation.
    void OnSourceAdded(int index) override;
    void OnSourceRemoved(int index) override;
    void OnSourceMoved(int old_index, int new_index) override;
    void OnSourceNameChanged(int index) override;
    void OnSourceThumbnailChanged(int index) override;
    void OnSourcePreviewChanged(size_t index) override;

    bool started_;
    std::vector<std::unique_ptr<DesktopMediaList>> media_list_;

    DISALLOW_COPY_AND_ASSIGN(NwDesktopCaptureMonitor);
  };

  class NwScreenDisplayObserver: public display::DisplayObserver {
  public:
    static NwScreenDisplayObserver* GetInstance();
    NwScreenDisplayObserver();

  private:
    ~NwScreenDisplayObserver() override;
    // gfx::DisplayObserver implementation.
    void OnDisplayMetricsChanged(const display::Display& display, uint32_t changed_metrics) override;
    void OnDisplayAdded(const display::Display& new_display) override;
    void OnDisplayRemoved(const display::Display& old_display) override;

    DISALLOW_COPY_AND_ASSIGN(NwScreenDisplayObserver);
  };

  namespace {

    // Helper function to convert display::Display to nwapi::nw__screen::Display
    std::unique_ptr<nwapi::nw__screen::Display> ConvertGfxDisplay(const display::Display& gfx_display) {
      std::unique_ptr<nwapi::nw__screen::Display> displayResult(new nwapi::nw__screen::Display);

      displayResult->id = gfx_display.id();
      displayResult->scale_factor = gfx_display.device_scale_factor();
      displayResult->is_built_in = gfx_display.IsInternal();
      displayResult->rotation = gfx_display.RotationAsDegree();
      displayResult->touch_support = (int)gfx_display.touch_support();

      gfx::Rect rect = gfx_display.bounds();
      DisplayGeometry& bounds = displayResult->bounds;
      bounds.x = rect.x();
      bounds.y = rect.y();
      bounds.width = rect.width();
      bounds.height = rect.height();

      rect = gfx_display.work_area();
      DisplayGeometry& work_area = displayResult->work_area;
      work_area.x = rect.x();
      work_area.y = rect.y();
      work_area.width = rect.width();
      work_area.height = rect.height();

      return displayResult;
    }

    void DispatchEvent(
        events::HistogramValue histogram_value,
        const std::string& event_name,
        std::vector<base::Value> args) {
      DCHECK_CURRENTLY_ON(BrowserThread::UI);
      //std::unique_ptr<base::ListValue> arg_list(std::move(args));
      ExtensionsBrowserClient::Get()->
        BroadcastEventToRenderers(
                                  histogram_value, event_name,
                                  std::make_unique<base::ListValue>(std::move(args)),
                                  false);
    }

    // Lazy initialize screen event listeners until first call
    base::LazyInstance<NwScreenDisplayObserver>::Leaky
      g_display_observer = LAZY_INSTANCE_INITIALIZER;

    base::LazyInstance<NwDesktopCaptureMonitor>::Leaky
      g_desktop_capture_monitor = LAZY_INSTANCE_INITIALIZER;

  }

  // static
  NwScreenDisplayObserver* NwScreenDisplayObserver::GetInstance() {
    return g_display_observer.Pointer();
  }

  NwScreenDisplayObserver::NwScreenDisplayObserver() {
    display::Screen* screen = display::Screen::GetScreen();
    if (screen) {
      screen->AddObserver(this);
    }
  }

  NwScreenDisplayObserver::~NwScreenDisplayObserver() {
    display::Screen* screen = display::Screen::GetScreen();
    if (screen) {
      screen->RemoveObserver(this);
    }
  }

  // Called when the |display|'s bound has changed.
  void NwScreenDisplayObserver::OnDisplayMetricsChanged(const display::Display& display,
    uint32_t changed_metrics) {
    std::vector<base::Value> args =
      nwapi::nw__screen::OnDisplayBoundsChanged::Create(*ConvertGfxDisplay(display),
                                                        changed_metrics);
    DispatchEvent(
      events::HistogramValue::UNKNOWN,
      nwapi::nw__screen::OnDisplayBoundsChanged::kEventName,
      std::move(args));
  }

  // Called when |new_display| has been added.
  void NwScreenDisplayObserver::OnDisplayAdded(const display::Display& new_display) {
    std::vector<base::Value> args =
      nwapi::nw__screen::OnDisplayAdded::Create(*ConvertGfxDisplay(new_display));
    DispatchEvent(
      events::HistogramValue::UNKNOWN,
      nwapi::nw__screen::OnDisplayAdded::kEventName,
      std::move(args));
  }

  // Called when |old_display| has been removed.
  void NwScreenDisplayObserver::OnDisplayRemoved(const display::Display& old_display) {
    std::vector<base::Value> args =
      nwapi::nw__screen::OnDisplayRemoved::Create(*ConvertGfxDisplay(old_display));
    DispatchEvent(
      events::HistogramValue::UNKNOWN,
      nwapi::nw__screen::OnDisplayRemoved::kEventName,
      std::move(args));
  }

  NwScreenGetScreensFunction::NwScreenGetScreensFunction() {}

  bool NwScreenGetScreensFunction::RunNWSync(base::ListValue* response, std::string* error) {
    const std::vector<display::Display>& displays = display::Screen::GetScreen()->GetAllDisplays();

    for (size_t i=0; i<displays.size(); i++) {
      response->Append(ConvertGfxDisplay(displays[i])->ToValue());
    }

    return true;
  }

  NwScreenInitEventListenersFunction::NwScreenInitEventListenersFunction() {}

  bool NwScreenInitEventListenersFunction::RunNWSync(base::ListValue* response, std::string* error) {
    NwScreenDisplayObserver::GetInstance();
    return true;
  }

  NwDesktopCaptureMonitor* NwDesktopCaptureMonitor::GetInstance() {
    return g_desktop_capture_monitor.Pointer();
  }

  NwDesktopCaptureMonitor::NwDesktopCaptureMonitor()
      : started_(false) {
  }

  void NwDesktopCaptureMonitor::Start(bool screens, bool windows) {
    if (started_) {
      return;
    }

    started_ = true;

    webrtc::DesktopCaptureOptions options = webrtc::DesktopCaptureOptions::CreateDefault();
    options.set_disable_effects(false);

    if (screens) {
      std::unique_ptr<DesktopMediaList> screen_media_list =
        std::make_unique<NativeDesktopMediaList>(
          DesktopMediaList::Type::kScreen,
          webrtc::DesktopCapturer::CreateScreenCapturer(options));
      media_list_.push_back(std::move(screen_media_list));
    }

    if (windows) {
      std::unique_ptr<DesktopMediaList> window_media_list =
        std::make_unique<NativeDesktopMediaList>(
          DesktopMediaList::Type::kWindow,
          webrtc::DesktopCapturer::CreateWindowCapturer(options));
      media_list_.push_back(std::move(window_media_list));
    }

    for (auto& media_list : media_list_) {
      media_list->StartUpdating(this);
    }
  }

  void NwDesktopCaptureMonitor::Stop() {
    started_ = false;
    media_list_.clear();
  }

  bool NwDesktopCaptureMonitor::IsStarted() {
    return started_;
  }

  int NwDesktopCaptureMonitor::GetPrimaryMonitorIndex() {
  #ifdef _WIN32
    int count=0;
    for (int i = 0;; ++i) {
      DISPLAY_DEVICE device;
      device.cb = sizeof(device);
      BOOL ret = EnumDisplayDevices(NULL, i, &device, 0);
      if(!ret)
        break;
      if (device.StateFlags & DISPLAY_DEVICE_ACTIVE){
        if (device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE){
          return count;
        }
        count++;
      }
    }
  #endif
    return -1;
  }

void NwDesktopCaptureMonitor::OnSourceAdded(int index) {
    DesktopMediaList::Source src = media_list_[0]->GetSource(index);

    std::string type;
    switch(src.id.type) {
    case content::DesktopMediaID::TYPE_WINDOW:
      type = "window";
      break;
    case content::DesktopMediaID::TYPE_SCREEN:
      type = "screen";
      break;
    case content::DesktopMediaID::TYPE_NONE:
      type = "none";
      break;
    default:
      type = "unknown";
      break;
    }

    std::vector<base::Value> args = nwapi::nw__screen::OnSourceAdded::Create(
      src.id.ToString(),
      base::UTF16ToUTF8(src.name),
      index,
      type,
      src.id.type == content::DesktopMediaID::TYPE_SCREEN && GetPrimaryMonitorIndex() == index);

    DispatchEvent(
      events::HistogramValue::UNKNOWN,
      nwapi::nw__screen::OnSourceAdded::kEventName,
      std::move(args));
  }

void NwDesktopCaptureMonitor::OnSourceRemoved(int index) {
    std::vector<base::Value> args = nwapi::nw__screen::OnSourceRemoved::Create(index);
    DispatchEvent(
      events::HistogramValue::UNKNOWN,
      nwapi::nw__screen::OnSourceRemoved::kEventName,
      std::move(args));
  }

void NwDesktopCaptureMonitor::OnSourceMoved(int old_index, int new_index) {
    DesktopMediaList::Source src = media_list_[0]->GetSource(new_index);
    std::vector<base::Value> args = nwapi::nw__screen::OnSourceOrderChanged::Create(
      src.id.ToString(),
      new_index,
      old_index);
    DispatchEvent(
      events::HistogramValue::UNKNOWN,
      nwapi::nw__screen::OnSourceOrderChanged::kEventName,
      std::move(args));
  }

void NwDesktopCaptureMonitor::OnSourceNameChanged(int index) {
    DesktopMediaList::Source src = media_list_[0]->GetSource(index);
    std::vector<base::Value> args = nwapi::nw__screen::OnSourceNameChanged::Create(
      src.id.ToString(),
      base::UTF16ToUTF8(src.name));
    DispatchEvent(
      events::HistogramValue::UNKNOWN,
      nwapi::nw__screen::OnSourceNameChanged::kEventName,
      std::move(args));
  }

void NwDesktopCaptureMonitor::OnSourcePreviewChanged(size_t index) {
}

void NwDesktopCaptureMonitor::OnSourceThumbnailChanged(int index) {
    std::string base64;

    DesktopMediaList::Source src = media_list_[0]->GetSource(index);
    SkBitmap bitmap = src.thumbnail.GetRepresentation(1).GetBitmap();
    std::vector<unsigned char> data;
    bool success = gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &data);
    if (success){
      base::StringPiece raw_str(reinterpret_cast<const char*>(&data[0]), data.size());
      base::Base64Encode(raw_str, &base64);
    }

    std::vector<base::Value> args = nwapi::nw__screen::OnSourceThumbnailChanged::Create(
      src.id.ToString(),
      base64);
    DispatchEvent(
      events::HistogramValue::UNKNOWN,
      nwapi::nw__screen::OnSourceThumbnailChanged::kEventName,
      std::move(args));
  }

  NwScreenStartMonitorFunction::NwScreenStartMonitorFunction() {}

  bool NwScreenStartMonitorFunction::RunNWSync(base::ListValue* response, std::string* error) {
    bool screens, windows;
    EXTENSION_FUNCTION_VALIDATE(args().size() >= 2);
    EXTENSION_FUNCTION_VALIDATE(args()[0].is_bool() && args()[1].is_bool());
    screens = args()[0].GetBool();
    windows = args()[1].GetBool();
    NwDesktopCaptureMonitor::GetInstance()->Start(screens, windows);
    return true;
  }

  NwScreenStopMonitorFunction::NwScreenStopMonitorFunction() {}

  bool NwScreenStopMonitorFunction::RunNWSync(base::ListValue* response, std::string* error) {
    NwDesktopCaptureMonitor::GetInstance()->Stop();
    return true;
  }

  NwScreenIsMonitorStartedFunction::NwScreenIsMonitorStartedFunction() {}

  bool NwScreenIsMonitorStartedFunction::RunNWSync(base::ListValue* response, std::string* error) {
    response->Append(NwDesktopCaptureMonitor::GetInstance()->IsStarted());
    return true;
  }

  NwScreenRegisterStreamFunction::NwScreenRegisterStreamFunction() {}

  bool NwScreenRegisterStreamFunction::RunNWSync(base::ListValue* response, std::string* error) {
    std::string id;
    EXTENSION_FUNCTION_VALIDATE(args().size() >= 1);
    EXTENSION_FUNCTION_VALIDATE(args()[0].is_string());
    id = args()[0].GetString();

    // following code is modified from `DesktopCaptureChooseDesktopMediaFunctionBase::OnPickerDialogResults`
    // in chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc

    content::DesktopMediaID source = content::DesktopMediaID::Parse(id);
    content::WebContents* web_contents = GetSenderWebContents();
    if (!source.is_null() && web_contents) {
      std::string result;
      source.audio_share = true;
      content::DesktopStreamsRegistry* registry = content::DesktopStreamsRegistry::GetInstance();
      // TODO(miu): Once render_frame_host() is being set, we should register the
      // exact RenderFrame requesting the stream, not the main RenderFrame.  With
      // that change, also update
      // MediaCaptureDevicesDispatcher::ProcessDesktopCaptureAccessRequest().
      // http://crbug.com/304341
      content::RenderFrameHost* const main_frame = web_contents->GetMainFrame();
      result = registry->RegisterStream(main_frame->GetProcess()->GetID(),
                                        main_frame->GetRoutingID(),
                                        url::Origin::Create(web_contents->GetURL().GetOrigin()),
                                        source,
                                        extension()->name(), content::kRegistryStreamTypeDesktop);
      response->Append(result);
    }
    return true;
  }

} // extensions
<|endoftext|>


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

#include "chrome/browser/window_sizer.h"

#include <gtk/gtk.h>

#include "base/logging.h"
#include "chrome/browser/browser.h"

// How much horizontal and vertical offset there is between newly
// opened windows. We don't care on Linux since the window manager generally
// does a good job of window placement.
const int WindowSizer::kWindowTilePixels = 0;

// An implementation of WindowSizer::MonitorInfoProvider that gets the actual
// monitor information from X via GDK.
class DefaultMonitorInfoProvider : public WindowSizer::MonitorInfoProvider {
 public:
  DefaultMonitorInfoProvider() { }

  virtual gfx::Rect GetPrimaryMonitorWorkArea() const {
    gfx::Rect rect;
    if (GetScreenWorkArea(&rect))
      return rect.Intersect(GetPrimaryMonitorBounds());

    // Return the best we've got.
    return GetPrimaryMonitorBounds();
  }

  virtual gfx::Rect GetPrimaryMonitorBounds() const {
    GdkScreen* screen = gdk_screen_get_default();
    GdkRectangle rect;
    gdk_screen_get_monitor_geometry(screen, 0, &rect);
    return gfx::Rect(rect);
  }

  virtual gfx::Rect GetMonitorWorkAreaMatching(
      const gfx::Rect& match_rect) const {
    // TODO(thestig) Implement multi-monitor support.
    return GetPrimaryMonitorWorkArea();
  }

  virtual gfx::Point GetBoundsOffsetMatching(
      const gfx::Rect& match_rect) const {
    // TODO(thestig) Implement multi-monitor support.
    return GetPrimaryMonitorWorkArea().origin();
  }

  void UpdateWorkAreas() {
    // TODO(thestig) Implement multi-monitor support.
    work_areas_.clear();
    work_areas_.push_back(GetPrimaryMonitorBounds());
  }

 private:
  // Get the available screen space as a gfx::Rect, or return false if
  // if it's unavailable (i.e. the window manager doesn't support
  // retrieving this).
  bool GetScreenWorkArea(gfx::Rect* out_rect) const {
    gboolean ok;
    guchar* raw_data = NULL;
    gint data_len = 0;
    ok = gdk_property_get(gdk_get_default_root_window(),  // a gdk window
                          gdk_atom_intern("_NET_WORKAREA", FALSE),  // property
                          gdk_atom_intern("CARDINAL", FALSE),  // property type
                          0,  // byte offset into property
                          0xff,  // property length to retrieve
                          false,  // delete property after retrieval?
                          NULL,  // returned property type
                          NULL,  // returned data format
                          &data_len,  // returned data len
                          &raw_data);  // returned data
    if (!ok)
      return false;

    // We expect to get four longs back: x1, y1, x2, y2.
    if (data_len != 4 * sizeof(glong)) {
      NOTREACHED();
      g_free(raw_data);
      return false;
    }

    glong* data = reinterpret_cast<glong*>(raw_data);
    gint x = data[0];
    gint y = data[1];
    gint width = data[0] + data[2];
    gint height = data[1] + data[3];
    g_free(raw_data);

    out_rect->SetRect(x, y, width, height);
    return true;
  }

  DISALLOW_COPY_AND_ASSIGN(DefaultMonitorInfoProvider);
};

// static
WindowSizer::MonitorInfoProvider*
WindowSizer::CreateDefaultMonitorInfoProvider() {
  return new DefaultMonitorInfoProvider();
}
<commit_msg>Fix comparison in window_sizer_linux. There can be multiple desktops so data_len can be greater.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/window_sizer.h"

#include <gtk/gtk.h>

#include "base/logging.h"
#include "chrome/browser/browser.h"

// How much horizontal and vertical offset there is between newly
// opened windows. We don't care on Linux since the window manager generally
// does a good job of window placement.
const int WindowSizer::kWindowTilePixels = 0;

// An implementation of WindowSizer::MonitorInfoProvider that gets the actual
// monitor information from X via GDK.
class DefaultMonitorInfoProvider : public WindowSizer::MonitorInfoProvider {
 public:
  DefaultMonitorInfoProvider() { }

  virtual gfx::Rect GetPrimaryMonitorWorkArea() const {
    gfx::Rect rect;
    if (GetScreenWorkArea(&rect))
      return rect.Intersect(GetPrimaryMonitorBounds());

    // Return the best we've got.
    return GetPrimaryMonitorBounds();
  }

  virtual gfx::Rect GetPrimaryMonitorBounds() const {
    GdkScreen* screen = gdk_screen_get_default();
    GdkRectangle rect;
    gdk_screen_get_monitor_geometry(screen, 0, &rect);
    return gfx::Rect(rect);
  }

  virtual gfx::Rect GetMonitorWorkAreaMatching(
      const gfx::Rect& match_rect) const {
    // TODO(thestig) Implement multi-monitor support.
    return GetPrimaryMonitorWorkArea();
  }

  virtual gfx::Point GetBoundsOffsetMatching(
      const gfx::Rect& match_rect) const {
    // TODO(thestig) Implement multi-monitor support.
    return GetPrimaryMonitorWorkArea().origin();
  }

  void UpdateWorkAreas() {
    // TODO(thestig) Implement multi-monitor support.
    work_areas_.clear();
    work_areas_.push_back(GetPrimaryMonitorBounds());
  }

 private:
  // Get the available screen space as a gfx::Rect, or return false if
  // if it's unavailable (i.e. the window manager doesn't support
  // retrieving this).
  // TODO(thestig) Use _NET_CURRENT_DESKTOP here as well?
  bool GetScreenWorkArea(gfx::Rect* out_rect) const {
    gboolean ok;
    guchar* raw_data = NULL;
    gint data_len = 0;
    ok = gdk_property_get(gdk_get_default_root_window(),  // a gdk window
                          gdk_atom_intern("_NET_WORKAREA", FALSE),  // property
                          gdk_atom_intern("CARDINAL", FALSE),  // property type
                          0,  // byte offset into property
                          0xff,  // property length to retrieve
                          false,  // delete property after retrieval?
                          NULL,  // returned property type
                          NULL,  // returned data format
                          &data_len,  // returned data len
                          &raw_data);  // returned data
    if (!ok)
      return false;

    // We expect to get four longs back: x1, y1, x2, y2.
    if (data_len < static_cast<gint>(4 * sizeof(glong))) {
      NOTREACHED();
      g_free(raw_data);
      return false;
    }

    glong* data = reinterpret_cast<glong*>(raw_data);
    gint x = data[0];
    gint y = data[1];
    gint width = data[0] + data[2];
    gint height = data[1] + data[3];
    g_free(raw_data);

    out_rect->SetRect(x, y, width, height);
    return true;
  }

  DISALLOW_COPY_AND_ASSIGN(DefaultMonitorInfoProvider);
};

// static
WindowSizer::MonitorInfoProvider*
WindowSizer::CreateDefaultMonitorInfoProvider() {
  return new DefaultMonitorInfoProvider();
}
<|endoftext|>


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

#include "chrome/common/chrome_version_info.h"

#include "base/basictypes.h"
#include "base/file_version_info.h"
#include "base/string_util.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"

namespace chrome {

#if defined(OS_WIN) || defined(OS_MACOSX)
// On Windows and Mac, we get the Chrome version info by querying
// FileVersionInfo for the current module.

VersionInfo::VersionInfo() {
  // The current module is already loaded in memory, so this will be cheap.
  base::ThreadRestrictions::ScopedAllowIO allow_io;
  version_info_.reset(FileVersionInfo::CreateFileVersionInfoForCurrentModule());
}

VersionInfo::~VersionInfo() {
}

bool VersionInfo::is_valid() const {
  return version_info_.get() != NULL;
}

std::string VersionInfo::Name() const {
  if (!is_valid())
    return std::string();
  return UTF16ToASCII(version_info_->product_name());
}

std::string VersionInfo::Version() const {
  if (!is_valid())
    return std::string();
  return UTF16ToASCII(version_info_->product_version());
}

std::string VersionInfo::LastChange() const {
  if (!is_valid())
    return std::string();
  return UTF16ToASCII(version_info_->last_change());
}

bool VersionInfo::IsOfficialBuild() const {
  if (!is_valid())
    return false;
  return version_info_->is_official_build();
}

#elif defined(OS_POSIX)
// We get chrome version information from chrome_version_info_posix.h,
// a generated header.

#include "chrome/common/chrome_version_info_posix.h"

VersionInfo::VersionInfo() {
}

VersionInfo::~VersionInfo() {
}

bool VersionInfo::is_valid() const {
  return true;
}

std::string VersionInfo::Name() const {
  return PRODUCT_NAME;
}

std::string VersionInfo::Version() const {
  return PRODUCT_VERSION;
}

std::string VersionInfo::LastChange() const {
  return LAST_CHANGE;
}

bool VersionInfo::IsOfficialBuild() const {
  return OFFICIAL_BUILD;
}

#endif

std::string VersionInfo::CreateVersionString() const {
  std::string current_version;
  if (is_valid()) {
    current_version += Version();
#if !defined(GOOGLE_CHROME_BUILD)
    current_version += " (";
    current_version += l10n_util::GetStringUTF8(IDS_ABOUT_VERSION_UNOFFICIAL);
    current_version += " ";
    current_version += LastChange();
    current_version += " ";
    current_version += OSType();
    current_version += ")";
#endif
    std::string modifier = GetVersionStringModifier();
    if (!modifier.empty())
      current_version += " " + modifier;
  }
  return current_version;
}

std::string VersionInfo::OSType() const {
#if defined(OS_WIN)
  return "Windows";
#elif defined(OS_MACOSX)
  return "Mac OS X";
#elif defined(OS_CHROMEOS)
  return UTF16ToASCII(l10n_util::GetStringUTF16(IDS_PRODUCT_OS_NAME));
#elif defined(OS_LINUX)
  return "Linux";
#elif defined(OS_FREEBSD)
  return "FreeBSD";
#elif defined(OS_OPENBSD)
  return "OpenBSD";
#elif defined(OS_SOLARIS)
  return "Solaris";
#else
  return "Unknown";
#endif
}

}  // namespace chrome
<commit_msg>Use UTF16ToUTF8 instead of UTF16ToASCII for version strings.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/common/chrome_version_info.h"

#include "base/basictypes.h"
#include "base/file_version_info.h"
#include "base/string_util.h"
#include "base/threading/thread_restrictions.h"
#include "base/utf_string_conversions.h"
#include "build/build_config.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"

namespace chrome {

#if defined(OS_WIN) || defined(OS_MACOSX)
// On Windows and Mac, we get the Chrome version info by querying
// FileVersionInfo for the current module.

VersionInfo::VersionInfo() {
  // The current module is already loaded in memory, so this will be cheap.
  base::ThreadRestrictions::ScopedAllowIO allow_io;
  version_info_.reset(FileVersionInfo::CreateFileVersionInfoForCurrentModule());
}

VersionInfo::~VersionInfo() {
}

bool VersionInfo::is_valid() const {
  return version_info_.get() != NULL;
}

std::string VersionInfo::Name() const {
  if (!is_valid())
    return std::string();
  return UTF16ToUTF8(version_info_->product_name());
}

std::string VersionInfo::Version() const {
  if (!is_valid())
    return std::string();
  return UTF16ToUTF8(version_info_->product_version());
}

std::string VersionInfo::LastChange() const {
  if (!is_valid())
    return std::string();
  return UTF16ToUTF8(version_info_->last_change());
}

bool VersionInfo::IsOfficialBuild() const {
  if (!is_valid())
    return false;
  return version_info_->is_official_build();
}

#elif defined(OS_POSIX)
// We get chrome version information from chrome_version_info_posix.h,
// a generated header.

#include "chrome/common/chrome_version_info_posix.h"

VersionInfo::VersionInfo() {
}

VersionInfo::~VersionInfo() {
}

bool VersionInfo::is_valid() const {
  return true;
}

std::string VersionInfo::Name() const {
  return PRODUCT_NAME;
}

std::string VersionInfo::Version() const {
  return PRODUCT_VERSION;
}

std::string VersionInfo::LastChange() const {
  return LAST_CHANGE;
}

bool VersionInfo::IsOfficialBuild() const {
  return OFFICIAL_BUILD;
}

#endif

std::string VersionInfo::CreateVersionString() const {
  std::string current_version;
  if (is_valid()) {
    current_version += Version();
#if !defined(GOOGLE_CHROME_BUILD)
    current_version += " (";
    current_version += l10n_util::GetStringUTF8(IDS_ABOUT_VERSION_UNOFFICIAL);
    current_version += " ";
    current_version += LastChange();
    current_version += " ";
    current_version += OSType();
    current_version += ")";
#endif
    std::string modifier = GetVersionStringModifier();
    if (!modifier.empty())
      current_version += " " + modifier;
  }
  return current_version;
}

std::string VersionInfo::OSType() const {
#if defined(OS_WIN)
  return "Windows";
#elif defined(OS_MACOSX)
  return "Mac OS X";
#elif defined(OS_CHROMEOS)
  return UTF16ToASCII(l10n_util::GetStringUTF16(IDS_PRODUCT_OS_NAME));
#elif defined(OS_LINUX)
  return "Linux";
#elif defined(OS_FREEBSD)
  return "FreeBSD";
#elif defined(OS_OPENBSD)
  return "OpenBSD";
#elif defined(OS_SOLARIS)
  return "Solaris";
#else
  return "Unknown";
#endif
}

}  // namespace chrome
<|endoftext|>


<commit_before>/* $Id$ */
/* Author: Wolfgang Bangerth, University of Heidelberg, 1999 */

#include <base/quadrature_lib.h>
#include <base/convergence_table.h>
#include <grid/grid_generator.h>
#include <grid/tria_accessor.h>
#include <grid/tria_iterator.h>
#include <grid/tria_boundary_lib.h>
#include <grid/tria.h>
#include <grid/grid_out.h>
#include <dofs/dof_handler.h>
#include <dofs/dof_accessor.h>
#include <fe/fe_q.h>
#include <fe/fe_values.h>
#include <fe/mapping_q.h>

#include <fstream>

static const long double pi=3.141592653589793238462643;

template <int dim>
void gnuplot_output()
{
  std::cout << "Output of grids into gnuplot files:" << std::endl
	    << "===================================" << std::endl;

  Triangulation<dim> triangulation;
  GridGenerator::hyper_ball (triangulation);
  static const HyperBallBoundary<dim> boundary;
  triangulation.set_boundary (0, boundary);

  GridOut grid_out;
				   // on boundary faces plot 30
				   // additional points per face.
  GridOutFlags::Gnuplot gnuplot_flags(false, 30);
  grid_out.set_flags(gnuplot_flags);

  for (unsigned int refinement=0; refinement<2;
       ++refinement, triangulation.refine_global(1))
    {
      std::cout << "Refinement level: " << refinement << std::endl;
      string filename_base="ball";
      filename_base += ('0'+refinement);

      for (unsigned int order=1; order<4; ++order)
	{
	  std::cout << "Order = " << order;

	  const MappingQ<dim> mapping (order);
	  string filename=filename_base+"_mapping_q";
	  filename += ('0'+order);
	  filename += ".dat";
	  ofstream gnuplot_file(filename.c_str());

	  std::cout << ".   Writing gnuplot file <"
		    << filename << ">..." << std::endl;

	  grid_out.write_gnuplot(triangulation, gnuplot_file, &mapping);
	}
    }
}

template <int dim>
void compute_pi_by_area ()
{
  std::cout << "Computation of Pi by the area:" << std::endl
	    << "==============================" << std::endl;

  const QGauss4<dim> quadrature;
  for (unsigned int order=1; order<5; ++order)
    {
      std::cout << "Order = " << order << std::endl;
      Triangulation<dim> triangulation;
      GridGenerator::hyper_ball (triangulation);

      static const HyperBallBoundary<dim> boundary;
      triangulation.set_boundary (0, boundary);

      const MappingQ<dim> mapping (order);
      const FE_Q<dim>     fe (1);

      DoFHandler<dim> dof_handler (triangulation);

      FEValues<dim> fe_values (mapping, fe, quadrature, update_JxW_values);
      ConvergenceTable table;

      for (unsigned int refinement=0; refinement<6;
	   ++refinement, triangulation.refine_global (1))
	{
	  table.add_value("cells", triangulation.n_active_cells());

	  dof_handler.distribute_dofs (fe);

	  typename DoFHandler<dim>::active_cell_iterator
	    cell = dof_handler.begin_active(),
	    endc = dof_handler.end();
	  long double area = 0;
	  for (; cell!=endc; ++cell)
	    {
	      fe_values.reinit (cell);
	      for (unsigned int i=0; i<fe_values.n_quadrature_points; ++i)
		area += fe_values.JxW (i);
	    };
	  table.add_value("eval.pi", static_cast<double> (area));
	  table.add_value("error", fabs(area-pi));
	};

      table.omit_column_from_convergence_rate_evaluation("cells");
      table.omit_column_from_convergence_rate_evaluation("eval.pi");
      table.evaluate_all_convergence_rates(
	ConvergenceTable::reduction_rate_log2);

      table.set_precision("eval.pi", 16);
      table.set_scientific("error", true);

      table.write_text(std::cout);

      std::cout << std::endl;
    };
};

template <int dim>
void compute_pi_by_perimeter ()
{
  std::cout << "Computation of Pi by the perimeter:" << std::endl
	    << "===================================" << std::endl;

  const QGauss4<dim-1> quadrature;
  for (unsigned int order=1; order<5; ++order)
    {
      std::cout << "Order = " << order << endl;
      Triangulation<dim> triangulation;
      GridGenerator::hyper_ball (triangulation);

      static const HyperBallBoundary<dim> boundary;
      triangulation.set_boundary (0, boundary);

      const MappingQ<dim> mapping (order);
      const FE_Q<dim>     fe (1);

      DoFHandler<dim> dof_handler (triangulation);

      FEFaceValues<dim> fe_face_values (mapping, fe, quadrature, update_JxW_values);
      ConvergenceTable table;

      for (unsigned int refinement=0; refinement<6;
	   ++refinement, triangulation.refine_global (1))
	{
	  table.add_value("cells", triangulation.n_active_cells());

	  dof_handler.distribute_dofs (fe);

	  typename DoFHandler<dim>::active_cell_iterator
	    cell = dof_handler.begin_active(),
	    endc = dof_handler.end();
	  long double perimeter = 0;
	  for (; cell!=endc; ++cell)
	    for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
	      if (cell->face(face_no)->at_boundary())
		{
		  fe_face_values.reinit (cell, face_no);
		  for (unsigned int i=0; i<fe_face_values.n_quadrature_points; ++i)
		    perimeter += fe_face_values.JxW (i);
		};
	  table.add_value("eval.pi", static_cast<double> (perimeter/2.));
	  table.add_value("error", fabs(perimeter/2.-pi));
	};

      table.omit_column_from_convergence_rate_evaluation("cells");
      table.omit_column_from_convergence_rate_evaluation("eval.pi");
      table.evaluate_all_convergence_rates(
	ConvergenceTable::reduction_rate_log2);

      table.set_precision("eval.pi", 16);
      table.set_scientific("error", true);

      table.write_text(std::cout);

      std::cout << std::endl;
    };
};

int main ()
{
  std::cout.precision (16);

  gnuplot_output<2>();

  compute_pi_by_area<2> ();
  compute_pi_by_perimeter<2> ();

  return 0;
};
<commit_msg>Fix date.<commit_after>/* $Id$ */
/* Author: Wolfgang Bangerth, University of Heidelberg, 2001 */

#include <base/quadrature_lib.h>
#include <base/convergence_table.h>
#include <grid/grid_generator.h>
#include <grid/tria_accessor.h>
#include <grid/tria_iterator.h>
#include <grid/tria_boundary_lib.h>
#include <grid/tria.h>
#include <grid/grid_out.h>
#include <dofs/dof_handler.h>
#include <dofs/dof_accessor.h>
#include <fe/fe_q.h>
#include <fe/fe_values.h>
#include <fe/mapping_q.h>

#include <fstream>

static const long double pi=3.141592653589793238462643;

template <int dim>
void gnuplot_output()
{
  std::cout << "Output of grids into gnuplot files:" << std::endl
	    << "===================================" << std::endl;

  Triangulation<dim> triangulation;
  GridGenerator::hyper_ball (triangulation);
  static const HyperBallBoundary<dim> boundary;
  triangulation.set_boundary (0, boundary);

  GridOut grid_out;
				   // on boundary faces plot 30
				   // additional points per face.
  GridOutFlags::Gnuplot gnuplot_flags(false, 30);
  grid_out.set_flags(gnuplot_flags);

  for (unsigned int refinement=0; refinement<2;
       ++refinement, triangulation.refine_global(1))
    {
      std::cout << "Refinement level: " << refinement << std::endl;
      string filename_base="ball";
      filename_base += ('0'+refinement);

      for (unsigned int order=1; order<4; ++order)
	{
	  std::cout << "Order = " << order;

	  const MappingQ<dim> mapping (order);
	  string filename=filename_base+"_mapping_q";
	  filename += ('0'+order);
	  filename += ".dat";
	  ofstream gnuplot_file(filename.c_str());

	  std::cout << ".   Writing gnuplot file <"
		    << filename << ">..." << std::endl;

	  grid_out.write_gnuplot(triangulation, gnuplot_file, &mapping);
	}
    }
}

template <int dim>
void compute_pi_by_area ()
{
  std::cout << "Computation of Pi by the area:" << std::endl
	    << "==============================" << std::endl;

  const QGauss4<dim> quadrature;
  for (unsigned int order=1; order<5; ++order)
    {
      std::cout << "Order = " << order << std::endl;
      Triangulation<dim> triangulation;
      GridGenerator::hyper_ball (triangulation);

      static const HyperBallBoundary<dim> boundary;
      triangulation.set_boundary (0, boundary);

      const MappingQ<dim> mapping (order);
      const FE_Q<dim>     fe (1);

      DoFHandler<dim> dof_handler (triangulation);

      FEValues<dim> fe_values (mapping, fe, quadrature, update_JxW_values);
      ConvergenceTable table;

      for (unsigned int refinement=0; refinement<6;
	   ++refinement, triangulation.refine_global (1))
	{
	  table.add_value("cells", triangulation.n_active_cells());

	  dof_handler.distribute_dofs (fe);

	  typename DoFHandler<dim>::active_cell_iterator
	    cell = dof_handler.begin_active(),
	    endc = dof_handler.end();
	  long double area = 0;
	  for (; cell!=endc; ++cell)
	    {
	      fe_values.reinit (cell);
	      for (unsigned int i=0; i<fe_values.n_quadrature_points; ++i)
		area += fe_values.JxW (i);
	    };
	  table.add_value("eval.pi", static_cast<double> (area));
	  table.add_value("error", fabs(area-pi));
	};

      table.omit_column_from_convergence_rate_evaluation("cells");
      table.omit_column_from_convergence_rate_evaluation("eval.pi");
      table.evaluate_all_convergence_rates(
	ConvergenceTable::reduction_rate_log2);

      table.set_precision("eval.pi", 16);
      table.set_scientific("error", true);

      table.write_text(std::cout);

      std::cout << std::endl;
    };
};

template <int dim>
void compute_pi_by_perimeter ()
{
  std::cout << "Computation of Pi by the perimeter:" << std::endl
	    << "===================================" << std::endl;

  const QGauss4<dim-1> quadrature;
  for (unsigned int order=1; order<5; ++order)
    {
      std::cout << "Order = " << order << endl;
      Triangulation<dim> triangulation;
      GridGenerator::hyper_ball (triangulation);

      static const HyperBallBoundary<dim> boundary;
      triangulation.set_boundary (0, boundary);

      const MappingQ<dim> mapping (order);
      const FE_Q<dim>     fe (1);

      DoFHandler<dim> dof_handler (triangulation);

      FEFaceValues<dim> fe_face_values (mapping, fe, quadrature, update_JxW_values);
      ConvergenceTable table;

      for (unsigned int refinement=0; refinement<6;
	   ++refinement, triangulation.refine_global (1))
	{
	  table.add_value("cells", triangulation.n_active_cells());

	  dof_handler.distribute_dofs (fe);

	  typename DoFHandler<dim>::active_cell_iterator
	    cell = dof_handler.begin_active(),
	    endc = dof_handler.end();
	  long double perimeter = 0;
	  for (; cell!=endc; ++cell)
	    for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
	      if (cell->face(face_no)->at_boundary())
		{
		  fe_face_values.reinit (cell, face_no);
		  for (unsigned int i=0; i<fe_face_values.n_quadrature_points; ++i)
		    perimeter += fe_face_values.JxW (i);
		};
	  table.add_value("eval.pi", static_cast<double> (perimeter/2.));
	  table.add_value("error", fabs(perimeter/2.-pi));
	};

      table.omit_column_from_convergence_rate_evaluation("cells");
      table.omit_column_from_convergence_rate_evaluation("eval.pi");
      table.evaluate_all_convergence_rates(
	ConvergenceTable::reduction_rate_log2);

      table.set_precision("eval.pi", 16);
      table.set_scientific("error", true);

      table.write_text(std::cout);

      std::cout << std::endl;
    };
};

int main ()
{
  std::cout.precision (16);

  gnuplot_output<2>();

  compute_pi_by_area<2> ();
  compute_pi_by_perimeter<2> ();

  return 0;
};
<|endoftext|>


<commit_before>#ifndef __VELBUSMESSAGE_PUSHBUTTONSTATUS_HPP__
#define __VELBUSMESSAGE_PUSHBUTTONSTATUS_HPP__

#include "VelbusMessage.hpp"

namespace VelbusMessage {

class PushButtonStatus : public VelbusMessage {
public:
	char m_just_pressed;
	char m_just_released;
	char m_long_pressed;

protected:
	PushButtonStatus( unsigned char prio, unsigned char addr, unsigned char rtr, std::string const &data)
		throw(FormError);

public:
	static VelbusMessage* factory(unsigned char prio, unsigned char addr, unsigned char rtr, std::string const &data) {
		return new PushButtonStatus(prio, addr, rtr, data);
	}

	virtual std::string data() throw();
	virtual size_t length() throw() { return 4; }
	virtual std::string string() throw();
};

} // Namespace

#endif // __VELBUSMESSAGE_PUSHBUTTONSTATUS_HPP__
<commit_msg>Removed unneeded method<commit_after>#ifndef __VELBUSMESSAGE_PUSHBUTTONSTATUS_HPP__
#define __VELBUSMESSAGE_PUSHBUTTONSTATUS_HPP__

#include "VelbusMessage.hpp"

namespace VelbusMessage {

class PushButtonStatus : public VelbusMessage {
public:
	char m_just_pressed;
	char m_just_released;
	char m_long_pressed;

protected:
	PushButtonStatus( unsigned char prio, unsigned char addr, unsigned char rtr, std::string const &data)
		throw(FormError);

public:
	static VelbusMessage* factory(unsigned char prio, unsigned char addr, unsigned char rtr, std::string const &data) {
		return new PushButtonStatus(prio, addr, rtr, data);
	}

	virtual std::string data() throw();
	virtual std::string string() throw();
};

} // Namespace

#endif // __VELBUSMESSAGE_PUSHBUTTONSTATUS_HPP__
<|endoftext|>


<commit_before>/*
    Copyright (C) 2004, David Faure <faure@kde.org>
    This file is part of the KDE project

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2, 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

#include "kpartsdesignerplugin.h"

#include <kparts/componentfactory.h>
#include <kparts/part.h>
#include <kmimetype.h>
#include <qlayout.h>
#include <kapplication.h>

KPartsGenericPart::KPartsGenericPart( QWidget* parentWidget, const char* name )
    : QWidget( parentWidget, name ), m_part( 0 )
{
    QVBoxLayout* layout = new QVBoxLayout( this );
    layout->setAutoAdd( true );
}

void KPartsGenericPart::load()
{
    if ( m_mimetype.isEmpty() || m_url.isEmpty() )
        return; // not enough info yet
    // Here it crashes in KSycoca::openDatabase when trying to load the stuff from designer itself
    // Not sure why - but it's not really needed anyway.
    if ( !kapp )
        return;
    QString mimetype = m_mimetype;
    if ( mimetype == "auto" )
        mimetype == KMimeType::findByURL( m_url )->name();
    if ( m_part ) {
        delete m_part;
    }
    // "this" is both the parent widget and the parent object
    m_part = KParts::ComponentFactory::createPartInstanceFromQuery<KParts::ReadOnlyPart>( mimetype, QString::null, this, 0, this, 0 );
    if ( m_part ) {
        m_part->openURL( m_url );
        m_part->widget()->show();
    }
}

////

static const char* mykey = "KPartsGenericPart";

QStringList KPartsWidgetPlugin::keys() const {
    return QStringList() << mykey;
}

QWidget * KPartsWidgetPlugin::create( const QString & key, QWidget * parent, const char * name ) {
    if ( key == mykey )
        return new KPartsGenericPart( parent, name );
    return 0;
}

QString KPartsWidgetPlugin::group( const QString & key ) const {
    if ( key == mykey )
        return "Display (KDE)";
    return QString::null;
}

#if 0
QIconSet KPartsWidgetPlugin::iconSet( const QString & key ) const {
  return QIconSet();
}
#endif

QString KPartsWidgetPlugin::includeFile( const QString & key ) const {
    if ( key == mykey )
        return "partplugin.h";
    return QString::null;
}

QString KPartsWidgetPlugin::toolTip( const QString & key ) const {
    if ( key == mykey )
        return "Generic KParts viewer";
    return QString::null;
}

QString KPartsWidgetPlugin::whatsThis( const QString & key ) const {
    if ( key == mykey )
        return "A widget to embed any KParts viewer, given a url and optionally a mimetype";
    return QString::null;
}

bool KPartsWidgetPlugin::isContainer( const QString & /*key*/ ) const {
    return false;
}

KDE_Q_EXPORT_PLUGIN( KPartsWidgetPlugin )

#include "kpartsdesignerplugin.moc"

<commit_msg>Care for the poor souls without kdelibs HEAD...<commit_after>/*
    Copyright (C) 2004, David Faure <faure@kde.org>
    This file is part of the KDE project

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2, 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

#include "kpartsdesignerplugin.h"

#include <kparts/componentfactory.h>
#include <kparts/part.h>
#include <kmimetype.h>
#include <qlayout.h>
#include <kapplication.h>

KPartsGenericPart::KPartsGenericPart( QWidget* parentWidget, const char* name )
    : QWidget( parentWidget, name ), m_part( 0 )
{
    QVBoxLayout* layout = new QVBoxLayout( this );
    layout->setAutoAdd( true );
}

void KPartsGenericPart::load()
{
    if ( m_mimetype.isEmpty() || m_url.isEmpty() )
        return; // not enough info yet
    // Here it crashes in KSycoca::openDatabase when trying to load the stuff from designer itself
    // Not sure why - but it's not really needed anyway.
    if ( !kapp )
        return;
    QString mimetype = m_mimetype;
    if ( mimetype == "auto" )
        mimetype == KMimeType::findByURL( m_url )->name();
    if ( m_part ) {
        delete m_part;
    }
    // "this" is both the parent widget and the parent object
    m_part = KParts::ComponentFactory::createPartInstanceFromQuery<KParts::ReadOnlyPart>( mimetype, QString::null, this, 0, this, 0 );
    if ( m_part ) {
        m_part->openURL( m_url );
        m_part->widget()->show();
    }
}

////

static const char* mykey = "KPartsGenericPart";

QStringList KPartsWidgetPlugin::keys() const {
    return QStringList() << mykey;
}

QWidget * KPartsWidgetPlugin::create( const QString & key, QWidget * parent, const char * name ) {
    if ( key == mykey )
        return new KPartsGenericPart( parent, name );
    return 0;
}

QString KPartsWidgetPlugin::group( const QString & key ) const {
    if ( key == mykey )
        return "Display (KDE)";
    return QString::null;
}

#if 0
QIconSet KPartsWidgetPlugin::iconSet( const QString & key ) const {
  return QIconSet();
}
#endif

QString KPartsWidgetPlugin::includeFile( const QString & key ) const {
    if ( key == mykey )
        return "partplugin.h";
    return QString::null;
}

QString KPartsWidgetPlugin::toolTip( const QString & key ) const {
    if ( key == mykey )
        return "Generic KParts viewer";
    return QString::null;
}

QString KPartsWidgetPlugin::whatsThis( const QString & key ) const {
    if ( key == mykey )
        return "A widget to embed any KParts viewer, given a url and optionally a mimetype";
    return QString::null;
}

bool KPartsWidgetPlugin::isContainer( const QString & /*key*/ ) const {
    return false;
}

/// Duplicated from kdelibs/kdecore/kdemacros.h.in for those with kdelibs < 3.4
#ifndef KDE_Q_EXPORT_PLUGIN
#define KDE_Q_EXPORT_PLUGIN(PLUGIN) \
  Q_EXTERN_C KDE_EXPORT const char* qt_ucm_query_verification_data(); \
  Q_EXTERN_C KDE_EXPORT QUnknownInterface* ucm_instantiate(); \
  Q_EXPORT_PLUGIN(PLUGIN)
#endif

KDE_Q_EXPORT_PLUGIN( KPartsWidgetPlugin )

#include "kpartsdesignerplugin.moc"

<|endoftext|>


<commit_before>/*
** Author(s):
**  - Pierre Roullon <proullon@aldebaran-robotics.com>
**
** Copyright (C) 2012 Aldebaran Robotics
*/

#include <qimessaging/c/api_c.h>
#include <qimessaging/c/qi_c.h>
#include <qimessaging/datastream.hpp>
#include <c/src/message_c_p.h>
#include <gtest/gtest.h>

qi::IDataStream &get_is(qi_message_data_t *m)
{
  if (!m->is)
    m->is = new qi::IDataStream(*m->buff);
  return *(m->is);
}

qi::ODataStream &get_os(qi_message_data_t *m)
{
  if (!m->os)
    m->os = new qi::ODataStream(*m->buff);
  return *(m->os);
}

TEST(TestMessage, SimpleOperation)
{
  qi_message_t*  m = qi_message_create();

  // Yeah, laugh, sounds easy...Beware.
  qi_message_destroy(m);
}

TEST(TestMessage, SimpleWrite)
{
  qi_message_t* m = qi_message_create();
  int magic = 0x42DEAD42;

  // SIGNED TYPES
  qi_message_write_bool(m, true);
  qi_message_write_int8(m, 'a');
  qi_message_write_int8(m, -64);
  qi_message_write_int16(m, 19);
  qi_message_write_int16(m, -19);
  qi_message_write_int32(m, 1123132123);
  qi_message_write_int32(m, -1123132123);
  qi_message_write_int64(m, 4294967297);
  qi_message_write_int64(m, -4294967297);

  // UNSIGNED TYPES
  qi_message_write_uint8(m, 'a');
  qi_message_write_uint16(m, 19);
  qi_message_write_uint32(m, 1123132123);
  qi_message_write_uint64(m, 4294967297);

  // SPECIAL ONES
  qi_message_write_float(m, 3.14957f);
  qi_message_write_double(m, 2.42);
  qi_message_write_string(m, "Easter Egg\t");
  qi_message_write_raw(m, (char *) &magic, 4);

  qi_message_destroy(m);
}

TEST(TestMessage, SimpleRead)
{
  qi_message_t* m = qi_message_create();
  int magic = 0x42DEAD42;
  unsigned int size = 0;
  char *data = (char *) malloc(4);
  memcpy(data, &magic, 4);
  magic = 0;
  ASSERT_TRUE(data != 0);

  // SIGNED TYPES
  qi_message_write_bool(m, true);
  qi_message_write_int8(m, 97);
  qi_message_write_int8(m, -64);
  qi_message_write_int16(m, 19);
  qi_message_write_int16(m, -19);
  qi_message_write_int32(m, 1123132123);
  qi_message_write_int32(m, -1123132123);
  qi_message_write_int64(m, 4294967297);
  qi_message_write_int64(m, -4294967297);
  // UNSIGNED TYPES
  qi_message_write_uint8(m, 'a');
  qi_message_write_uint16(m, 19);
  qi_message_write_uint32(m, 1123132123);
  qi_message_write_uint64(m, 4294967297);
  // SPECIAL ONES
  qi_message_write_float(m, 3.14957f);
  qi_message_write_double(m, 2.42);
  qi_message_write_string(m, "Easter Egg\t");
  qi_message_write_raw(m, data, 4);

  ASSERT_TRUE(qi_message_read_bool(m));
  ASSERT_EQ(97, qi_message_read_int8(m));
  ASSERT_EQ(-64, qi_message_read_int8(m));
  ASSERT_EQ(19, qi_message_read_int16(m));
  ASSERT_EQ(-19, qi_message_read_int16(m));
  ASSERT_EQ(1123132123, qi_message_read_int32(m));
  ASSERT_EQ(-1123132123, qi_message_read_int32(m));
  ASSERT_TRUE(qi_message_read_int64(m) == 4294967297);
  ASSERT_TRUE(qi_message_read_int64(m) == -4294967297);
  ASSERT_TRUE(qi_message_read_int8(m) == 'a');
  ASSERT_TRUE(qi_message_read_uint16(m) == 19);
  ASSERT_TRUE(qi_message_read_uint32(m) == 1123132123);
  ASSERT_TRUE(qi_message_read_uint64(m) == 4294967297);
  ASSERT_EQ(3.14957f, qi_message_read_float(m));
  ASSERT_EQ(2.42, qi_message_read_double(m));
  ASSERT_EQ(0, strcmp(qi_message_read_string(m), "Easter Egg\t"));
  data = qi_message_read_raw(m, &size);
  memcpy(&magic, data, 4);
  ASSERT_EQ(0x42DEAD42, magic);
  ASSERT_EQ((unsigned int) 4, size);

  qi_message_destroy(m);
}

TEST(TestMessage, TestList)
{
  std::list<int> value;
  std::list<int>::iterator it, it2;

  qi_message_t* m= qi_message_create();

  value.push_back(1);
  value.push_back(2);
  value.push_back(3);
  value.push_back(4);
  value.push_back(5);

  get_os((qi_message_data_t*) m) << value;
  // Our buffer travel around...

  // Toh ! a C client :
  // Get list back
  std::list<int> mirror;
  unsigned int i = 0;
  unsigned int size = qi_message_read_list_size(m);
  ASSERT_EQ(value.size(), size);

  while (i < size)
  {
    mirror.push_back(qi_message_read_int32(m));
    i++;
  }

  // Compare
  ASSERT_EQ(value.size(), mirror.size());
  it2 = mirror.begin();
  for (it = value.begin(); it != value.end(); ++it)
  {
    ASSERT_EQ(*it, *it2);
    ASSERT_TRUE(it2 != mirror.end());
    ++it2;
  }

  qi_message_destroy(m);
}

TEST(TestMessage, TestMap)
{
  std::map<std::string, int> value;
  std::map<std::string, int>::iterator it, it2;

  qi_message_t* m= qi_message_create();

  value["Foo"] = 0;
  value["Bar"] = 1;
  value["Cham"] = 2;
  value["Pion"] = 3;

  get_os((qi_message_data_t *) m) << value;

  // Our buffer travel around...

  // Toh ! a C client :
  // Get list back
  std::map<std::string, int> mirror;
  unsigned int i = 0;
  unsigned int size = qi_message_read_list_size(m);
  ASSERT_EQ(value.size(), size);

  while (i < size)
  {
    mirror[qi_message_read_string(m)] = qi_message_read_int32(m);
    i++;
  }

  // Compare
  ASSERT_EQ(value.size(), mirror.size());
  it2 = mirror.begin();
  for (it = value.begin(); it != value.end(); ++it)
  {
    ASSERT_EQ(*it, *it2);
    ASSERT_TRUE(it2 != mirror.end());
    ++it2;
  }

  qi_message_destroy(m);
}
<commit_msg>test: fix test_c_message<commit_after>/*
** Author(s):
**  - Pierre Roullon <proullon@aldebaran-robotics.com>
**
** Copyright (C) 2012 Aldebaran Robotics
*/

#include <qimessaging/c/api_c.h>
#include <qimessaging/c/qi_c.h>
#include <qimessaging/datastream.hpp>
#include <c/src/message_c_p.h>
#include <gtest/gtest.h>

qi::IDataStream &get_is(qi_message_data_t *m)
{
  if (!m->is)
    m->is = new qi::IDataStream(*m->buff);
  return *(m->is);
}

qi::ODataStream &get_os(qi_message_data_t *m)
{
  if (!m->os)
    m->os = new qi::ODataStream(*m->buff);
  return *(m->os);
}

TEST(TestMessage, SimpleOperation)
{
  qi_message_t*  m = qi_message_create();

  // Yeah, laugh, sounds easy...Beware.
  qi_message_destroy(m);
}

TEST(TestMessage, SimpleWrite)
{
  qi_message_t* m = qi_message_create();
  int magic = 0x42DEAD42;

  // SIGNED TYPES
  qi_message_write_bool(m, true);
  qi_message_write_int8(m, 'a');
  qi_message_write_int8(m, -64);
  qi_message_write_int16(m, 19);
  qi_message_write_int16(m, -19);
  qi_message_write_int32(m, 1123132123);
  qi_message_write_int32(m, -1123132123);
  qi_message_write_int64(m, 4294967297);
  qi_message_write_int64(m, -4294967297);

  // UNSIGNED TYPES
  qi_message_write_uint8(m, 'a');
  qi_message_write_uint16(m, 19);
  qi_message_write_uint32(m, 1123132123);
  qi_message_write_uint64(m, 4294967297);

  // SPECIAL ONES
  qi_message_write_float(m, 3.14957f);
  qi_message_write_double(m, 2.42);
  qi_message_write_string(m, "Easter Egg\t");
  qi_message_write_raw(m, (char *) &magic, 4);

  qi_message_destroy(m);
}

TEST(TestMessage, SimpleRead)
{
  qi_message_t* m = qi_message_create();
  int magic = 0x42DEAD42;
  unsigned int size = 0;
  char *data = (char *) malloc(4);
  memcpy(data, &magic, 4);
  magic = 0;
  ASSERT_TRUE(data != 0);

  // SIGNED TYPES
  qi_message_write_bool(m, true);
  qi_message_write_int8(m, 97);
  qi_message_write_int8(m, -64);
  qi_message_write_int16(m, 19);
  qi_message_write_int16(m, -19);
  qi_message_write_int32(m, 1123132123);
  qi_message_write_int32(m, -1123132123);
  qi_message_write_int64(m, 4294967297);
  qi_message_write_int64(m, -4294967297);
  // UNSIGNED TYPES
  qi_message_write_uint8(m, 'a');
  qi_message_write_uint16(m, 19);
  qi_message_write_uint32(m, 1123132123);
  qi_message_write_uint64(m, 4294967297);
  // SPECIAL ONES
  qi_message_write_float(m, 3.14957f);
  qi_message_write_double(m, 2.42);
  qi_message_write_string(m, "Easter Egg\t");
  qi_message_write_raw(m, data, 4);

  ASSERT_TRUE(qi_message_read_bool(m));
  ASSERT_EQ(97, qi_message_read_int8(m));
  ASSERT_EQ(-64, qi_message_read_int8(m));
  ASSERT_EQ(19, qi_message_read_int16(m));
  ASSERT_EQ(-19, qi_message_read_int16(m));
  ASSERT_EQ(1123132123, qi_message_read_int32(m));
  ASSERT_EQ(-1123132123, qi_message_read_int32(m));
  ASSERT_TRUE(qi_message_read_int64(m) == 4294967297);
  ASSERT_TRUE(qi_message_read_int64(m) == -4294967297);
  ASSERT_TRUE(qi_message_read_int8(m) == 'a');
  ASSERT_TRUE(qi_message_read_uint16(m) == 19);
  ASSERT_TRUE(qi_message_read_uint32(m) == 1123132123);
  ASSERT_TRUE(qi_message_read_uint64(m) == 4294967297);
  ASSERT_EQ(3.14957f, qi_message_read_float(m));
  ASSERT_EQ(2.42, qi_message_read_double(m));
  ASSERT_EQ(0, strcmp(qi_message_read_string(m), "Easter Egg\t"));
  data = qi_message_read_raw(m, &size);
  memcpy(&magic, data, 4);
  ASSERT_EQ(0x42DEAD42, magic);
  ASSERT_EQ((unsigned int) 4, size);

  qi_message_destroy(m);
}

TEST(TestMessage, TestList)
{
  std::list<int> value;
  std::list<int>::iterator it, it2;

  qi_message_t* m= qi_message_create();

  value.push_back(1);
  value.push_back(2);
  value.push_back(3);
  value.push_back(4);
  value.push_back(5);

  get_os((qi_message_data_t*) m) << value;
  // Our buffer travel around...

  // Toh ! a C client :
  // Get list back
  std::list<int> mirror;
  unsigned int i = 0;
  unsigned int size = qi_message_read_list_size(m);
  ASSERT_EQ(value.size(), size);

  while (i < size)
  {
    mirror.push_back(qi_message_read_int32(m));
    i++;
  }

  // Compare
  ASSERT_EQ(value.size(), mirror.size());
  it2 = mirror.begin();
  for (it = value.begin(); it != value.end(); ++it)
  {
    ASSERT_EQ(*it, *it2);
    ASSERT_TRUE(it2 != mirror.end());
    ++it2;
  }

  qi_message_destroy(m);
}

TEST(TestMessage, TestMap)
{
  std::map<std::string, int> value;
  std::map<std::string, int>::iterator it, it2;

  qi_message_t* m= qi_message_create();

  value["Foo"] = 0;
  value["Bar"] = 1;
  value["Cham"] = 2;
  value["Pion"] = 3;

  get_os((qi_message_data_t *) m) << value;

  // Our buffer travel around...

  // Toh ! a C client :
  // Get list back
  std::map<std::string, int> mirror;
  unsigned int i;
  unsigned int size = qi_message_read_list_size(m);
  ASSERT_EQ(value.size(), size);

  for (i = 0; i < size; ++i)
  {
    char *k = qi_message_read_string(m);
    unsigned int v = qi_message_read_int32(m);
    mirror[k] = v;
    qi_message_free_string(k);
  }

  // Compare
  ASSERT_EQ(value.size(), mirror.size());
  it2 = mirror.begin();
  for (it = value.begin(); it != value.end(); ++it)
  {
    ASSERT_EQ(*it, *it2);
    ASSERT_TRUE(it2 != mirror.end());
    ++it2;
  }

  qi_message_destroy(m);
}
<|endoftext|>