<commit_before>// Copyright (c) 2010 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/cookie_modal_dialog.h"

#include "app/gtk_util.h"
#include "app/l10n_util.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/gtk/gtk_chrome_cookie_view.h"
#include "chrome/browser/gtk/gtk_chrome_link_button.h"
#include "chrome/browser/gtk/gtk_util.h"
#include "chrome/browser/pref_service.h"
#include "chrome/browser/views/cookie_prompt_view.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/pref_names.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"

namespace {

void OnExpanderActivate(GtkExpander* expander) {
  g_browser_process->local_state()->
      SetBoolean(prefs::kCookiePromptExpanded,
                 gtk_expander_get_expanded(GTK_EXPANDER(expander)));
}

}  // namespace

void CookiePromptModalDialog::CreateAndShowDialog() {
  dialog_ = CreateNativeDialog();
  gtk_widget_show_all(GTK_WIDGET(dialog_));

  // Suggest a minimum size.
  gint width;
  GtkRequisition req;
  gtk_widget_size_request(dialog_, &req);
  gtk_util::GetWidgetSizeFromResources(dialog_, IDS_ALERT_DIALOG_WIDTH_CHARS, 0,
                                       &width, NULL);
  if (width > req.width)
    gtk_widget_set_size_request(dialog_, width, -1);
}

void CookiePromptModalDialog::AcceptWindow() {
  HandleDialogResponse(GTK_DIALOG(dialog_), GTK_RESPONSE_ACCEPT);
}

void CookiePromptModalDialog::CancelWindow() {
  HandleDialogResponse(GTK_DIALOG(dialog_), GTK_RESPONSE_REJECT);
}

NativeDialog CookiePromptModalDialog::CreateNativeDialog() {
  gfx::NativeWindow window = tab_contents_->GetMessageBoxRootWindow();
  CookiePromptModalDialog::DialogType type = dialog_type();
  NativeDialog dialog = gtk_dialog_new_with_buttons(
      l10n_util::GetStringFUTF8(
          type == CookiePromptModalDialog::DIALOG_TYPE_COOKIE ?
          IDS_COOKIE_ALERT_TITLE : IDS_DATA_ALERT_TITLE,
          UTF8ToUTF16(origin().host())).c_str(),
      window,
      static_cast<GtkDialogFlags>(GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR),
      l10n_util::GetStringUTF8(IDS_COOKIE_ALERT_BLOCK_BUTTON).c_str(),
      GTK_RESPONSE_REJECT,
      l10n_util::GetStringUTF8(IDS_COOKIE_ALERT_ALLOW_BUTTON).c_str(),
      GTK_RESPONSE_ACCEPT,
      NULL);
  gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);

  GtkWidget* content_area = GTK_DIALOG(dialog)->vbox;
  gtk_box_set_spacing(GTK_BOX(content_area), gtk_util::kContentAreaSpacing);

  string16 display_host = UTF8ToUTF16(origin().host());
  GtkWidget* label = gtk_util::LeftAlignMisc(gtk_label_new(
      l10n_util::GetStringFUTF8(
          type == CookiePromptModalDialog::DIALOG_TYPE_COOKIE ?
          IDS_COOKIE_ALERT_LABEL : IDS_DATA_ALERT_LABEL,
          display_host).c_str()));
  gtk_box_pack_start(GTK_BOX(content_area), label, FALSE, FALSE, 0);

  // Create a vbox for all the radio buttons so they aren't too far away from
  // each other.
  bool remember_enabled = DecisionPersistable();
  GtkWidget* radio_box = gtk_vbox_new(FALSE, gtk_util::kControlSpacing);
  remember_radio_ = gtk_radio_button_new_with_label(NULL,
      l10n_util::GetStringFUTF8(IDS_COOKIE_ALERT_REMEMBER_RADIO,
                                display_host).c_str());
  gtk_widget_set_sensitive(GTK_WIDGET(remember_radio_), remember_enabled);
  gtk_box_pack_start(GTK_BOX(radio_box), remember_radio_, FALSE, FALSE, 0);

  GtkWidget* ask_radio = gtk_radio_button_new_with_label_from_widget(
      GTK_RADIO_BUTTON(remember_radio_),
      l10n_util::GetStringUTF8(IDS_COOKIE_ALERT_ASK_RADIO).c_str());
  gtk_widget_set_sensitive(GTK_WIDGET(ask_radio), remember_enabled);
  if (!remember_enabled)
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ask_radio), true);
  gtk_box_pack_start(GTK_BOX(radio_box), ask_radio, FALSE, FALSE, 0);

  gtk_box_pack_start(GTK_BOX(content_area), radio_box, FALSE, FALSE, 0);

  GtkWidget* expander = gtk_expander_new(
      l10n_util::GetStringUTF8(IDS_COOKIE_SHOW_DETAILS_LABEL).c_str());
  gtk_expander_set_expanded(GTK_EXPANDER(expander),
                            g_browser_process->local_state()->
                            GetBoolean(prefs::kCookiePromptExpanded));
  g_signal_connect(expander, "notify::expanded",
                   G_CALLBACK(OnExpanderActivate), NULL);

  GtkChromeCookieView* cookie_view = gtk_chrome_cookie_view_new();
  gtk_chrome_cookie_view_clear(cookie_view);
  if (type == CookiePromptModalDialog::DIALOG_TYPE_COOKIE) {
    gtk_chrome_cookie_view_display_cookie_string(cookie_view,
                                                 origin(), cookie_line());
  } else if (type == CookiePromptModalDialog::DIALOG_TYPE_LOCAL_STORAGE) {
    gtk_chrome_cookie_view_display_local_storage_item(
        cookie_view,
        origin().host(),
        local_storage_key(),
        local_storage_value());
  } else if (type == CookiePromptModalDialog::DIALOG_TYPE_DATABASE) {
    gtk_chrome_cookie_view_display_database_accessed(
        cookie_view,
        origin().host(),
        database_name(),
        display_name(),
        estimated_size());
  } else if (type == CookiePromptModalDialog::DIALOG_TYPE_APPCACHE) {
    gtk_chrome_cookie_view_display_appcache_created(
        cookie_view,
        appcache_manifest_url());
  } else {
    NOTIMPLEMENTED();
  }
  gtk_container_add(GTK_CONTAINER(expander), GTK_WIDGET(cookie_view));

  gtk_box_pack_end(GTK_BOX(content_area), GTK_WIDGET(expander),
                   FALSE, FALSE, 0);

  gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
  g_signal_connect(dialog, "response",
                   G_CALLBACK(AppModalDialog::OnDialogResponse),
                   reinterpret_cast<AppModalDialog*>(this));

  gtk_util::MakeAppModalWindowGroup();

  return dialog;
}

void CookiePromptModalDialog::HandleDialogResponse(GtkDialog* dialog,
                                                   gint response_id) {
  bool remember_radio = gtk_toggle_button_get_active(
      GTK_TOGGLE_BUTTON(remember_radio_));
  if (response_id == GTK_RESPONSE_REJECT) {
    BlockSiteData(remember_radio);
  } else if (response_id == GTK_RESPONSE_ACCEPT) {
    // TODO(erg): Needs to use |session_expire_| instead of true.
    AllowSiteData(remember_radio, true);
  } else {
    BlockSiteData(false);
  }
  gtk_widget_destroy(GTK_WIDGET(dialog));

  CompleteDialog();

  gtk_util::AppModalDismissedUngroupWindows();
  delete this;
}
<commit_msg>GTK: Fix app-modality of the cookie ask dialog.<commit_after>// Copyright (c) 2010 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/cookie_modal_dialog.h"

#include "app/gtk_util.h"
#include "app/l10n_util.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/gtk/gtk_chrome_cookie_view.h"
#include "chrome/browser/gtk/gtk_chrome_link_button.h"
#include "chrome/browser/gtk/gtk_util.h"
#include "chrome/browser/pref_service.h"
#include "chrome/browser/views/cookie_prompt_view.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/pref_names.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"

namespace {

void OnExpanderActivate(GtkExpander* expander) {
  g_browser_process->local_state()->
      SetBoolean(prefs::kCookiePromptExpanded,
                 gtk_expander_get_expanded(GTK_EXPANDER(expander)));
}

}  // namespace

void CookiePromptModalDialog::CreateAndShowDialog() {
  dialog_ = CreateNativeDialog();
  gtk_widget_show_all(GTK_WIDGET(dialog_));

  // Suggest a minimum size.
  gint width;
  GtkRequisition req;
  gtk_widget_size_request(dialog_, &req);
  gtk_util::GetWidgetSizeFromResources(dialog_, IDS_ALERT_DIALOG_WIDTH_CHARS, 0,
                                       &width, NULL);
  if (width > req.width)
    gtk_widget_set_size_request(dialog_, width, -1);
}

void CookiePromptModalDialog::AcceptWindow() {
  HandleDialogResponse(GTK_DIALOG(dialog_), GTK_RESPONSE_ACCEPT);
}

void CookiePromptModalDialog::CancelWindow() {
  HandleDialogResponse(GTK_DIALOG(dialog_), GTK_RESPONSE_REJECT);
}

NativeDialog CookiePromptModalDialog::CreateNativeDialog() {
  gtk_util::MakeAppModalWindowGroup();

  gfx::NativeWindow window = tab_contents_->GetMessageBoxRootWindow();
  CookiePromptModalDialog::DialogType type = dialog_type();
  NativeDialog dialog = gtk_dialog_new_with_buttons(
      l10n_util::GetStringFUTF8(
          type == CookiePromptModalDialog::DIALOG_TYPE_COOKIE ?
          IDS_COOKIE_ALERT_TITLE : IDS_DATA_ALERT_TITLE,
          UTF8ToUTF16(origin().host())).c_str(),
      window,
      static_cast<GtkDialogFlags>(GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR),
      l10n_util::GetStringUTF8(IDS_COOKIE_ALERT_BLOCK_BUTTON).c_str(),
      GTK_RESPONSE_REJECT,
      l10n_util::GetStringUTF8(IDS_COOKIE_ALERT_ALLOW_BUTTON).c_str(),
      GTK_RESPONSE_ACCEPT,
      NULL);
  gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);

  GtkWidget* content_area = GTK_DIALOG(dialog)->vbox;
  gtk_box_set_spacing(GTK_BOX(content_area), gtk_util::kContentAreaSpacing);

  string16 display_host = UTF8ToUTF16(origin().host());
  GtkWidget* label = gtk_util::LeftAlignMisc(gtk_label_new(
      l10n_util::GetStringFUTF8(
          type == CookiePromptModalDialog::DIALOG_TYPE_COOKIE ?
          IDS_COOKIE_ALERT_LABEL : IDS_DATA_ALERT_LABEL,
          display_host).c_str()));
  gtk_box_pack_start(GTK_BOX(content_area), label, FALSE, FALSE, 0);

  // Create a vbox for all the radio buttons so they aren't too far away from
  // each other.
  bool remember_enabled = DecisionPersistable();
  GtkWidget* radio_box = gtk_vbox_new(FALSE, gtk_util::kControlSpacing);
  remember_radio_ = gtk_radio_button_new_with_label(NULL,
      l10n_util::GetStringFUTF8(IDS_COOKIE_ALERT_REMEMBER_RADIO,
                                display_host).c_str());
  gtk_widget_set_sensitive(GTK_WIDGET(remember_radio_), remember_enabled);
  gtk_box_pack_start(GTK_BOX(radio_box), remember_radio_, FALSE, FALSE, 0);

  GtkWidget* ask_radio = gtk_radio_button_new_with_label_from_widget(
      GTK_RADIO_BUTTON(remember_radio_),
      l10n_util::GetStringUTF8(IDS_COOKIE_ALERT_ASK_RADIO).c_str());
  gtk_widget_set_sensitive(GTK_WIDGET(ask_radio), remember_enabled);
  if (!remember_enabled)
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ask_radio), true);
  gtk_box_pack_start(GTK_BOX(radio_box), ask_radio, FALSE, FALSE, 0);

  gtk_box_pack_start(GTK_BOX(content_area), radio_box, FALSE, FALSE, 0);

  GtkWidget* expander = gtk_expander_new(
      l10n_util::GetStringUTF8(IDS_COOKIE_SHOW_DETAILS_LABEL).c_str());
  gtk_expander_set_expanded(GTK_EXPANDER(expander),
                            g_browser_process->local_state()->
                            GetBoolean(prefs::kCookiePromptExpanded));
  g_signal_connect(expander, "notify::expanded",
                   G_CALLBACK(OnExpanderActivate), NULL);

  GtkChromeCookieView* cookie_view = gtk_chrome_cookie_view_new();
  gtk_chrome_cookie_view_clear(cookie_view);
  if (type == CookiePromptModalDialog::DIALOG_TYPE_COOKIE) {
    gtk_chrome_cookie_view_display_cookie_string(cookie_view,
                                                 origin(), cookie_line());
  } else if (type == CookiePromptModalDialog::DIALOG_TYPE_LOCAL_STORAGE) {
    gtk_chrome_cookie_view_display_local_storage_item(
        cookie_view,
        origin().host(),
        local_storage_key(),
        local_storage_value());
  } else if (type == CookiePromptModalDialog::DIALOG_TYPE_DATABASE) {
    gtk_chrome_cookie_view_display_database_accessed(
        cookie_view,
        origin().host(),
        database_name(),
        display_name(),
        estimated_size());
  } else if (type == CookiePromptModalDialog::DIALOG_TYPE_APPCACHE) {
    gtk_chrome_cookie_view_display_appcache_created(
        cookie_view,
        appcache_manifest_url());
  } else {
    NOTIMPLEMENTED();
  }
  gtk_container_add(GTK_CONTAINER(expander), GTK_WIDGET(cookie_view));

  gtk_box_pack_end(GTK_BOX(content_area), GTK_WIDGET(expander),
                   FALSE, FALSE, 0);

  gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
  g_signal_connect(dialog, "response",
                   G_CALLBACK(AppModalDialog::OnDialogResponse),
                   reinterpret_cast<AppModalDialog*>(this));

  return dialog;
}

void CookiePromptModalDialog::HandleDialogResponse(GtkDialog* dialog,
                                                   gint response_id) {
  bool remember_radio = gtk_toggle_button_get_active(
      GTK_TOGGLE_BUTTON(remember_radio_));
  if (response_id == GTK_RESPONSE_REJECT) {
    BlockSiteData(remember_radio);
  } else if (response_id == GTK_RESPONSE_ACCEPT) {
    // TODO(erg): Needs to use |session_expire_| instead of true.
    AllowSiteData(remember_radio, true);
  } else {
    BlockSiteData(false);
  }
  gtk_widget_destroy(GTK_WIDGET(dialog));

  CompleteDialog();

  gtk_util::AppModalDismissedUngroupWindows();
  delete this;
}
<|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 <Carbon/Carbon.h>

#include "build/build_config.h"

#include <vector>

#include "base/logging.h"
#include "base/mac_util.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/plugin_process_host.h"

void PluginProcessHost::OnPluginSelectWindow(uint32 window_id,
                                             gfx::Rect window_rect,
                                             bool modal) {
  plugin_visible_windows_set_.insert(window_id);
  if (modal)
    plugin_modal_windows_set_.insert(window_id);
}

void PluginProcessHost::OnPluginShowWindow(uint32 window_id,
                                           gfx::Rect window_rect,
                                           bool modal) {
  plugin_visible_windows_set_.insert(window_id);
  if (modal)
    plugin_modal_windows_set_.insert(window_id);
  CGRect window_bounds = {
    { window_rect.x(), window_rect.y() },
    { window_rect.width(), window_rect.height() }
  };
  CGRect main_display_bounds = CGDisplayBounds(CGMainDisplayID());
  if (CGRectEqualToRect(window_bounds, main_display_bounds)) {
    plugin_fullscreen_windows_set_.insert(window_id);
    // If the plugin has just shown a window that's the same dimensions as
    // the main display, hide the menubar so that it has the whole screen.
    ChromeThread::PostTask(
        ChromeThread::UI, FROM_HERE,
        NewRunnableFunction(mac_util::RequestFullScreen));
  }
}

void PluginProcessHost::OnPluginHideWindow(uint32 window_id,
                                           gfx::Rect window_rect) {
  plugin_visible_windows_set_.erase(window_id);
  plugin_modal_windows_set_.erase(window_id);
  if (plugin_fullscreen_windows_set_.find(window_id) !=
      plugin_fullscreen_windows_set_.end()) {
    plugin_fullscreen_windows_set_.erase(window_id);
    ChromeThread::PostTask(
        ChromeThread::UI, FROM_HERE,
        NewRunnableFunction(mac_util::ReleaseFullScreen));
  }
}

void PluginProcessHost::OnPluginDisposeWindow(uint32 window_id,
                                              gfx::Rect window_rect) {
  OnPluginHideWindow(window_id, window_rect);
}

void PluginProcessHost::OnAppActivation() {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));

  // If our plugin process has any modal windows up, we need to bring it forward
  // so that they act more like an in-process modal window would.
  if (!plugin_modal_windows_set_.empty()) {
    ChromeThread::PostTask(
        ChromeThread::UI, FROM_HERE,
        NewRunnableFunction(mac_util::ActivateProcess, handle()));
  }
}
<commit_msg>Only request full-screen once per plugin window<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 <Carbon/Carbon.h>

#include "build/build_config.h"

#include <vector>

#include "base/logging.h"
#include "base/mac_util.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/plugin_process_host.h"

void PluginProcessHost::OnPluginSelectWindow(uint32 window_id,
                                             gfx::Rect window_rect,
                                             bool modal) {
  plugin_visible_windows_set_.insert(window_id);
  if (modal)
    plugin_modal_windows_set_.insert(window_id);
}

void PluginProcessHost::OnPluginShowWindow(uint32 window_id,
                                           gfx::Rect window_rect,
                                           bool modal) {
  plugin_visible_windows_set_.insert(window_id);
  if (modal)
    plugin_modal_windows_set_.insert(window_id);
  CGRect window_bounds = {
    { window_rect.x(), window_rect.y() },
    { window_rect.width(), window_rect.height() }
  };
  CGRect main_display_bounds = CGDisplayBounds(CGMainDisplayID());
  if (CGRectEqualToRect(window_bounds, main_display_bounds) &&
      (plugin_fullscreen_windows_set_.find(window_id) ==
       plugin_fullscreen_windows_set_.end())) {
    plugin_fullscreen_windows_set_.insert(window_id);
    // If the plugin has just shown a window that's the same dimensions as
    // the main display, hide the menubar so that it has the whole screen.
    // (but only if we haven't already seen this fullscreen window, since
    // otherwise our refcounting can get skewed).
    ChromeThread::PostTask(
        ChromeThread::UI, FROM_HERE,
        NewRunnableFunction(mac_util::RequestFullScreen));
  }
}

void PluginProcessHost::OnPluginHideWindow(uint32 window_id,
                                           gfx::Rect window_rect) {
  plugin_visible_windows_set_.erase(window_id);
  plugin_modal_windows_set_.erase(window_id);
  if (plugin_fullscreen_windows_set_.find(window_id) !=
      plugin_fullscreen_windows_set_.end()) {
    plugin_fullscreen_windows_set_.erase(window_id);
    ChromeThread::PostTask(
        ChromeThread::UI, FROM_HERE,
        NewRunnableFunction(mac_util::ReleaseFullScreen));
  }
}

void PluginProcessHost::OnPluginDisposeWindow(uint32 window_id,
                                              gfx::Rect window_rect) {
  OnPluginHideWindow(window_id, window_rect);
}

void PluginProcessHost::OnAppActivation() {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));

  // If our plugin process has any modal windows up, we need to bring it forward
  // so that they act more like an in-process modal window would.
  if (!plugin_modal_windows_set_.empty()) {
    ChromeThread::PostTask(
        ChromeThread::UI, FROM_HERE,
        NewRunnableFunction(mac_util::ActivateProcess, handle()));
  }
}
<|endoftext|>


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

#include "chrome/browser/printing/print_settings.h"

#include "base/atomic_sequence_num.h"
#include "base/logging.h"
#include "chrome/browser/printing/units.h"
#include "chrome/common/render_messages.h"

namespace printing {

// Global SequenceNumber used for generating unique cookie values.
static base::AtomicSequenceNumber cookie_seq;

PrintSettings::PrintSettings()
    : min_shrink(1.25),
      max_shrink(2.0),
      desired_dpi(72),
      dpi_(0),
      landscape_(false) {
}

void PrintSettings::Clear() {
  ranges.clear();
  min_shrink = 1.25;
  max_shrink = 2.;
  desired_dpi = 72;
  printer_name_.clear();
  device_name_.clear();
  page_setup_cmm_.Clear();
  page_setup_pixels_.Clear();
  dpi_ = 0;
  landscape_ = false;
}

#ifdef WIN32
void PrintSettings::Init(HDC hdc,
                         const DEVMODE& dev_mode,
                         const PageRanges& new_ranges,
                         const std::wstring& new_device_name) {
  DCHECK(hdc);
  printer_name_ = dev_mode.dmDeviceName;
  device_name_ = new_device_name;
  ranges = new_ranges;
  landscape_ = dev_mode.dmOrientation == DMORIENT_LANDSCAPE;

  int old_dpi = dpi_;
  dpi_ = GetDeviceCaps(hdc, LOGPIXELSX);
  // No printer device is known to advertise different dpi in X and Y axis; even
  // the fax device using the 200x100 dpi setting. It's ought to break so many
  // applications that it's not even needed to care about. WebKit doesn't
  // support different dpi settings in X and Y axis.
  DCHECK_EQ(dpi_, GetDeviceCaps(hdc, LOGPIXELSY));

  DCHECK_EQ(GetDeviceCaps(hdc, SCALINGFACTORX), 0);
  DCHECK_EQ(GetDeviceCaps(hdc, SCALINGFACTORY), 0);

  // Initialize page_setup_pixels_.
  gfx::Size physical_size_pixels(GetDeviceCaps(hdc, PHYSICALWIDTH),
                                 GetDeviceCaps(hdc, PHYSICALHEIGHT));
  gfx::Rect printable_area_pixels(GetDeviceCaps(hdc, PHYSICALOFFSETX),
                                  GetDeviceCaps(hdc, PHYSICALOFFSETY),
                                  GetDeviceCaps(hdc, HORZRES),
                                  GetDeviceCaps(hdc, VERTRES));
  // Hard-code text_height = 0.5cm = ~1/5 of inch
  page_setup_pixels_.Init(physical_size_pixels, printable_area_pixels,
                          ConvertUnit(500, kHundrethsMMPerInch, dpi_));

  // Initialize page_setup_cmm_.
  // In theory, we should be using HORZSIZE and VERTSIZE but their value is
  // so wrong it's useless. So read the values in dpi unit and convert them back
  // in 0.01 mm.
  gfx::Size physical_size_cmm(
      ConvertUnit(physical_size_pixels.width(), dpi_, kHundrethsMMPerInch),
      ConvertUnit(physical_size_pixels.height(), dpi_, kHundrethsMMPerInch));
  gfx::Rect printable_area_cmm(
      ConvertUnit(printable_area_pixels.x(), dpi_, kHundrethsMMPerInch),
      ConvertUnit(printable_area_pixels.y(), dpi_, kHundrethsMMPerInch),
      ConvertUnit(printable_area_pixels.width(), dpi_, kHundrethsMMPerInch),
      ConvertUnit(printable_area_pixels.bottom(), dpi_, kHundrethsMMPerInch));

  static const int kRoundingTolerance = 5;
  // Some printers may advertise a slightly larger printable area than the
  // physical area. This is mostly due to integer calculation and rounding.
  if (physical_size_cmm.height() > printable_area_cmm.bottom() &&
      physical_size_cmm.height() <= (printable_area_cmm.bottom() +
                                     kRoundingTolerance)) {
    physical_size_cmm.set_height(printable_area_cmm.bottom());
  }
  if (physical_size_cmm.width() > printable_area_cmm.right() &&
      physical_size_cmm.width() <= (printable_area_cmm.right() +
                                    kRoundingTolerance)) {
    physical_size_cmm.set_width(printable_area_cmm.right());
  }
  page_setup_cmm_.Init(physical_size_cmm, printable_area_cmm, 500);
}
#endif

void PrintSettings::UpdateMarginsMetric(const PageMargins& new_margins) {
  // Apply the new margins in 0.01 mm unit.
  page_setup_cmm_.SetRequestedMargins(new_margins);

  // Converts the margins in dpi unit and apply those too.
  PageMargins pixels_margins;
  pixels_margins.header = ConvertUnit(new_margins.header, kHundrethsMMPerInch,
                                      dpi_);
  pixels_margins.footer = ConvertUnit(new_margins.footer, kHundrethsMMPerInch,
                                      dpi_);
  pixels_margins.left = ConvertUnit(new_margins.left, kHundrethsMMPerInch,
                                    dpi_);
  pixels_margins.top = ConvertUnit(new_margins.top, kHundrethsMMPerInch, dpi_);
  pixels_margins.right = ConvertUnit(new_margins.right, kHundrethsMMPerInch,
                                     dpi_);
  pixels_margins.bottom = ConvertUnit(new_margins.bottom, kHundrethsMMPerInch,
                                      dpi_);
  page_setup_pixels_.SetRequestedMargins(pixels_margins);
}

void PrintSettings::UpdateMarginsMilliInch(const PageMargins& new_margins) {
  // Convert margins from thousandth inches to cmm (0.01mm).
  PageMargins cmm_margins;
  cmm_margins.header =
      ConvertMilliInchToHundredThousanthMeter(new_margins.header);
  cmm_margins.footer =
      ConvertMilliInchToHundredThousanthMeter(new_margins.footer);
  cmm_margins.left = ConvertMilliInchToHundredThousanthMeter(new_margins.left);
  cmm_margins.top = ConvertMilliInchToHundredThousanthMeter(new_margins.top);
  cmm_margins.right =
      ConvertMilliInchToHundredThousanthMeter(new_margins.right);
  cmm_margins.bottom =
      ConvertMilliInchToHundredThousanthMeter(new_margins.bottom);
  UpdateMarginsMetric(cmm_margins);
}

void PrintSettings::RenderParams(ViewMsg_Print_Params* params) const {
  DCHECK(params);
  params->printable_size.SetSize(page_setup_pixels_.content_area().width(),
                                 page_setup_pixels_.content_area().height());
  params->dpi = dpi_;
  // Currently hardcoded at 1.25. See PrintSettings' constructor.
  params->min_shrink = min_shrink;
  // Currently hardcoded at 2.0. See PrintSettings' constructor.
  params->max_shrink = max_shrink;
  // Currently hardcoded at 72dpi. See PrintSettings' constructor.
  params->desired_dpi = desired_dpi;
  // Always use an invalid cookie.
  params->document_cookie = 0;
}

bool PrintSettings::Equals(const PrintSettings& rhs) const {
  // Do not test the display device name (printer_name_) for equality since it
  // may sometimes be chopped off at 30 chars. As long as device_name is the
  // same, that's fine.
  return ranges == rhs.ranges &&
      min_shrink == rhs.min_shrink &&
      max_shrink == rhs.max_shrink &&
      desired_dpi == rhs.desired_dpi &&
      overlays.Equals(rhs.overlays) &&
      device_name_ == rhs.device_name_ &&
      page_setup_pixels_.Equals(rhs.page_setup_pixels_) &&
      page_setup_cmm_.Equals(rhs.page_setup_cmm_) &&
      dpi_ == rhs.dpi_ &&
      landscape_ == rhs.landscape_;
}

int PrintSettings::NewCookie() {
  return cookie_seq.GetNext();
}

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

#include "chrome/browser/printing/print_settings.h"

#include "base/atomic_sequence_num.h"
#include "base/logging.h"
#include "chrome/browser/printing/units.h"
#include "chrome/common/render_messages.h"

namespace printing {

// Global SequenceNumber used for generating unique cookie values.
static base::AtomicSequenceNumber cookie_seq;

PrintSettings::PrintSettings()
    : min_shrink(1.25),
      max_shrink(2.0),
      desired_dpi(72),
      dpi_(0),
      landscape_(false) {
}

void PrintSettings::Clear() {
  ranges.clear();
  min_shrink = 1.25;
  max_shrink = 2.;
  desired_dpi = 72;
  printer_name_.clear();
  device_name_.clear();
  page_setup_cmm_.Clear();
  page_setup_pixels_.Clear();
  dpi_ = 0;
  landscape_ = false;
}

#ifdef WIN32
void PrintSettings::Init(HDC hdc,
                         const DEVMODE& dev_mode,
                         const PageRanges& new_ranges,
                         const std::wstring& new_device_name) {
  DCHECK(hdc);
  printer_name_ = dev_mode.dmDeviceName;
  device_name_ = new_device_name;
  ranges = new_ranges;
  landscape_ = dev_mode.dmOrientation == DMORIENT_LANDSCAPE;

  int old_dpi = dpi_;
  dpi_ = GetDeviceCaps(hdc, LOGPIXELSX);
  // No printer device is known to advertise different dpi in X and Y axis; even
  // the fax device using the 200x100 dpi setting. It's ought to break so many
  // applications that it's not even needed to care about. WebKit doesn't
  // support different dpi settings in X and Y axis.
  DCHECK_EQ(dpi_, GetDeviceCaps(hdc, LOGPIXELSY));

  DCHECK_EQ(GetDeviceCaps(hdc, SCALINGFACTORX), 0);
  DCHECK_EQ(GetDeviceCaps(hdc, SCALINGFACTORY), 0);

  // Initialize page_setup_pixels_.
  gfx::Size physical_size_pixels(GetDeviceCaps(hdc, PHYSICALWIDTH),
                                 GetDeviceCaps(hdc, PHYSICALHEIGHT));
  gfx::Rect printable_area_pixels(GetDeviceCaps(hdc, PHYSICALOFFSETX),
                                  GetDeviceCaps(hdc, PHYSICALOFFSETY),
                                  GetDeviceCaps(hdc, HORZRES),
                                  GetDeviceCaps(hdc, VERTRES));
  // Hard-code text_height = 0.5cm = ~1/5 of inch
  page_setup_pixels_.Init(physical_size_pixels, printable_area_pixels,
                          ConvertUnit(500, kHundrethsMMPerInch, dpi_));

  // Initialize page_setup_cmm_.
  // In theory, we should be using HORZSIZE and VERTSIZE but their value is
  // so wrong it's useless. So read the values in dpi unit and convert them back
  // in 0.01 mm.
  gfx::Size physical_size_cmm(
      ConvertUnit(physical_size_pixels.width(), dpi_, kHundrethsMMPerInch),
      ConvertUnit(physical_size_pixels.height(), dpi_, kHundrethsMMPerInch));
  gfx::Rect printable_area_cmm(
      ConvertUnit(printable_area_pixels.x(), dpi_, kHundrethsMMPerInch),
      ConvertUnit(printable_area_pixels.y(), dpi_, kHundrethsMMPerInch),
      ConvertUnit(printable_area_pixels.width(), dpi_, kHundrethsMMPerInch),
      ConvertUnit(printable_area_pixels.bottom(), dpi_, kHundrethsMMPerInch));

  static const int kRoundingTolerance = 5;
  // Some printers may advertise a slightly larger printable area than the
  // physical area. This is mostly due to integer calculation and rounding.
  if (physical_size_cmm.height() > printable_area_cmm.bottom() &&
      physical_size_cmm.height() <= (printable_area_cmm.bottom() +
                                     kRoundingTolerance)) {
    physical_size_cmm.set_height(printable_area_cmm.bottom());
  }
  if (physical_size_cmm.width() > printable_area_cmm.right() &&
      physical_size_cmm.width() <= (printable_area_cmm.right() +
                                    kRoundingTolerance)) {
    physical_size_cmm.set_width(printable_area_cmm.right());
  }
  page_setup_cmm_.Init(physical_size_cmm, printable_area_cmm, 500);
}
#endif

void PrintSettings::UpdateMarginsMetric(const PageMargins& new_margins) {
  // Apply the new margins in 0.01 mm unit.
  page_setup_cmm_.SetRequestedMargins(new_margins);

  // Converts the margins in dpi unit and apply those too.
  PageMargins pixels_margins;
  pixels_margins.header = ConvertUnit(new_margins.header, kHundrethsMMPerInch,
                                      dpi_);
  pixels_margins.footer = ConvertUnit(new_margins.footer, kHundrethsMMPerInch,
                                      dpi_);
  pixels_margins.left = ConvertUnit(new_margins.left, kHundrethsMMPerInch,
                                    dpi_);
  pixels_margins.top = ConvertUnit(new_margins.top, kHundrethsMMPerInch, dpi_);
  pixels_margins.right = ConvertUnit(new_margins.right, kHundrethsMMPerInch,
                                     dpi_);
  pixels_margins.bottom = ConvertUnit(new_margins.bottom, kHundrethsMMPerInch,
                                      dpi_);
  page_setup_pixels_.SetRequestedMargins(pixels_margins);
}

void PrintSettings::UpdateMarginsMilliInch(const PageMargins& new_margins) {
  // Convert margins from thousandth inches to cmm (0.01mm).
  PageMargins cmm_margins;
  cmm_margins.header =
      ConvertMilliInchToHundredThousanthMeter(new_margins.header);
  cmm_margins.footer =
      ConvertMilliInchToHundredThousanthMeter(new_margins.footer);
  cmm_margins.left = ConvertMilliInchToHundredThousanthMeter(new_margins.left);
  cmm_margins.top = ConvertMilliInchToHundredThousanthMeter(new_margins.top);
  cmm_margins.right =
      ConvertMilliInchToHundredThousanthMeter(new_margins.right);
  cmm_margins.bottom =
      ConvertMilliInchToHundredThousanthMeter(new_margins.bottom);
  UpdateMarginsMetric(cmm_margins);
}

void PrintSettings::RenderParams(ViewMsg_Print_Params* params) const {
  DCHECK(params);
  params->printable_size.SetSize(page_setup_pixels_.content_area().width(),
                                 page_setup_pixels_.content_area().height());
  params->dpi = dpi_;
  // Currently hardcoded at 1.25. See PrintSettings' constructor.
  params->min_shrink = min_shrink;
  // Currently hardcoded at 2.0. See PrintSettings' constructor.
  params->max_shrink = max_shrink;
  // Currently hardcoded at 72dpi. See PrintSettings' constructor.
  params->desired_dpi = desired_dpi;
  // Always use an invalid cookie.
  params->document_cookie = 0;
}

bool PrintSettings::Equals(const PrintSettings& rhs) const {
  // Do not test the display device name (printer_name_) for equality since it
  // may sometimes be chopped off at 30 chars. As long as device_name is the
  // same, that's fine.
  return ranges == rhs.ranges &&
      min_shrink == rhs.min_shrink &&
      max_shrink == rhs.max_shrink &&
      desired_dpi == rhs.desired_dpi &&
      overlays.Equals(rhs.overlays) &&
      device_name_ == rhs.device_name_ &&
      page_setup_pixels_.Equals(rhs.page_setup_pixels_) &&
      page_setup_cmm_.Equals(rhs.page_setup_cmm_) &&
      dpi_ == rhs.dpi_ &&
      landscape_ == rhs.landscape_;
}

int PrintSettings::NewCookie() {
  // A cookie of 0 is used to mark a document as unassigned, count from 1.
  return cookie_seq.GetNext() + 1;
}

}  // namespace printing
<|endoftext|>


<commit_before><commit_msg>control: minor refactor in latteral control<commit_after><|endoftext|>


<commit_before>/**
 *  \file
 *  \remark This file is part of VITA.
 *
 *  \copyright Copyright (C) 2015 EOS di Manlio Morini.
 *
 *  \license
 *  This Source Code Form is subject to the terms of the Mozilla Public
 *  License, v. 2.0. If a copy of the MPL was not distributed with this file,
 *  You can obtain one at http://mozilla.org/MPL/2.0/
 */

#include <cstdlib>
#include <sstream>

#include "kernel/ga/i_ga.h"
#include "kernel/ga/interpreter.h"
#include "kernel/ga/ga_evaluator.h"
#include "kernel/ga/ga_search.h"
#include "kernel/evolution.h"
#include "kernel/problem.h"

#if !defined(MASTER_TEST_SET)
#define BOOST_TEST_MODULE t_ga_perf
#include <boost/test/unit_test.hpp>

using namespace boost;

#include "factory_fixture5.h"
#endif

BOOST_FIXTURE_TEST_SUITE(t_ga2, F_FACTORY5_NO_INIT)

// Test problem 7 from "An Efficient Constraint Handling Method for Genetic
// Algorithms"
BOOST_AUTO_TEST_CASE(Search_TestProblem7)
{
  env.individuals = 100;
  env.generations = 2000;
  env.f_threashold = {0, 0};
  env.verbosity = 1;

  vita::problem prob;
  prob.env = env;
  prob.env.stat_dir = ".";
  prob.env.stat_layers = true;
  prob.sset.insert(vita::ga::parameter(0, -2.3, 2.3));
  prob.sset.insert(vita::ga::parameter(1, -2.3, 2.3));
  prob.sset.insert(vita::ga::parameter(2, -3.2, 3.2));
  prob.sset.insert(vita::ga::parameter(3, -3.2, 3.2));
  prob.sset.insert(vita::ga::parameter(4, -3.2, 3.2));

  auto f = [](const std::vector<double> &x)
           {
             return -std::exp(x[0] * x[1] * x[2] * x[3] * x[4]);
           };

  auto p = [](const vita::i_ga &prg)
    {
      auto h1 = [](const std::vector<double> &x)
      {
        return x[0] * x[0] + x[1] * x[1] + x[2] * x[2] + x[3] * x[3] +
               x[4] * x[4] - 10.0;
      };
      auto h2 = [](const std::vector<double> &x)
      {
        return x[1] * x[2] - 5.0 * x[3] * x[4];
      };
      auto h3 = [](const std::vector<double> &x)
      {
        return x[0] * x[0] * x[0] + x[1] * x[1] * x[1] + 1.0;
      };

      const double delta(0.01);

      double r(0.0);

      const auto c1(std::abs(h1(prg)));
      if (c1 > delta)
        r += c1;

      const auto c2(std::abs(h2(prg)));
      if (c2 > delta)
        r += c2;

      const auto c3(std::abs(h3(prg)));
      if (c3 > delta)
        r += c3;

      for (unsigned i(0), size(prg.size()); i < size; ++i)
      {
        if (prg[i] < -2.3)
          r += -2.3 - prg[i];
        else if (prg[i] > 3.2)
          r += prg[i] - 3.2;
      }

      return r;
    };

  vita::ga_search<vita::i_ga, vita::de_es, decltype(f)> s(prob, f, p);
  BOOST_REQUIRE(s.debug(true));
  const auto res(s.run(10));

  BOOST_CHECK_CLOSE(-f(res), 0.053950, 2.0);
  BOOST_CHECK_CLOSE(res[0], -1.717143, 1.0);
  BOOST_CHECK_CLOSE(res[1], 1.595709, 1.0);
  BOOST_CHECK_CLOSE(res[2], 1.827247, 1.0);
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>[TEST] Fixed compilation error for test/ga_perf<commit_after>/**
 *  \file
 *  \remark This file is part of VITA.
 *
 *  \copyright Copyright (C) 2015-2017 EOS di Manlio Morini.
 *
 *  \license
 *  This Source Code Form is subject to the terms of the Mozilla Public
 *  License, v. 2.0. If a copy of the MPL was not distributed with this file,
 *  You can obtain one at http://mozilla.org/MPL/2.0/
 */

#include <cstdlib>
#include <sstream>

#include "kernel/ga/evaluator.h"
#include "kernel/ga/i_de.h"
#include "kernel/ga/search.h"
#include "kernel/evolution.h"
#include "kernel/problem.h"

#if !defined(MASTER_TEST_SET)
#define BOOST_TEST_MODULE t_de_perf
#include <boost/test/unit_test.hpp>

using namespace boost;

#include "factory_fixture5.h"
#endif

BOOST_FIXTURE_TEST_SUITE(t_de7, F_FACTORY5_NO_INIT)

// Test problem 7 from "An Efficient Constraint Handling Method for Genetic
// Algorithms"
BOOST_AUTO_TEST_CASE(Search_TestProblem7, * boost::unit_test::tolerance(1.0))
{
  vita::print.verbosity(vita::log::L_WARNING);

  vita::problem prob;
  prob.env.individuals = 100;
  prob.env.generations = 2000;
  prob.env.threshold.fitness = {0, 0};
  prob.env.stat.dir = ".";
  prob.env.stat.layers = true;
  prob.sset.insert(vita::ga::parameter(0, -2.3, 2.3));
  prob.sset.insert(vita::ga::parameter(1, -2.3, 2.3));
  prob.sset.insert(vita::ga::parameter(2, -3.2, 3.2));
  prob.sset.insert(vita::ga::parameter(3, -3.2, 3.2));
  prob.sset.insert(vita::ga::parameter(4, -3.2, 3.2));

  auto f = [](const std::vector<double> &x)
           {
             return -std::exp(x[0] * x[1] * x[2] * x[3] * x[4]);
           };

  auto p = [](const vita::i_de &prg)
    {
      auto h1 = [](const std::vector<double> &x)
      {
        return x[0] * x[0] + x[1] * x[1] + x[2] * x[2] + x[3] * x[3] +
               x[4] * x[4] - 10.0;
      };
      auto h2 = [](const std::vector<double> &x)
      {
        return x[1] * x[2] - 5.0 * x[3] * x[4];
      };
      auto h3 = [](const std::vector<double> &x)
      {
        return x[0] * x[0] * x[0] + x[1] * x[1] * x[1] + 1.0;
      };

      const double delta(0.01);

      double r(0.0);

      const auto c1(std::abs(h1(prg)));
      if (c1 > delta)
        r += c1;

      const auto c2(std::abs(h2(prg)));
      if (c2 > delta)
        r += c2;

      const auto c3(std::abs(h3(prg)));
      if (c3 > delta)
        r += c3;

      for (const auto &pi : prg)
      {
        if (pi < -2.3)
          r += -2.3 - pi;
        else if (pi > 3.2)
          r += pi - 3.2;
      }

      return r;
    };

  vita::ga_search<vita::i_de, vita::de_es, decltype(f)> s(prob, f, p);
  BOOST_TEST(s.debug());
  const auto res(s.run(10).best.solution);

  BOOST_TEST(-f(res) == 0.053950);
  BOOST_TEST(res[0] == -1.717143);
  BOOST_TEST(res[1] == 1.595709);
  BOOST_TEST(res[2] == 1.827247);
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>// Copyright (c) 2006-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/shell_integration.h"

#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <string>
#include <vector>

#include "app/gfx/codec/png_codec.h"
#include "base/command_line.h"
#include "base/eintr_wrapper.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/i18n/file_util_icu.h"
#include "base/message_loop.h"
#include "base/path_service.h"
#include "base/process_util.h"
#include "base/scoped_temp_dir.h"
#include "base/string_tokenizer.h"
#include "base/string_util.h"
#include "base/task.h"
#include "base/thread.h"
#include "chrome/browser/browser_process.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_plugin_util.h"
#include "chrome/common/chrome_switches.h"
#include "googleurl/src/gurl.h"

namespace {

const char* GetDesktopName() {
#if defined(GOOGLE_CHROME_BUILD)
  return "google-chrome.desktop";
#else  // CHROMIUM_BUILD
  static const char* name = NULL;
  if (!name) {
    // Allow $CHROME_DESKTOP to override the built-in value, so that development
    // versions can set themselves as the default without interfering with
    // non-official, packaged versions using the built-in value.
    name = getenv("CHROME_DESKTOP");
    if (!name)
      name = "chromium-browser.desktop";
  }
  return name;
#endif
}

// Helper to launch xdg scripts. We don't want them to ask any questions on the
// terminal etc.
bool LaunchXdgUtility(const std::vector<std::string>& argv) {
  // xdg-settings internally runs xdg-mime, which uses mv to move newly-created
  // files on top of originals after making changes to them. In the event that
  // the original files are owned by another user (e.g. root, which can happen
  // if they are updated within sudo), mv will prompt the user to confirm if
  // standard input is a terminal (otherwise it just does it). So make sure it's
  // not, to avoid locking everything up waiting for mv.
  int devnull = open("/dev/null", O_RDONLY);
  if (devnull < 0)
    return false;
  base::file_handle_mapping_vector no_stdin;
  no_stdin.push_back(std::make_pair(devnull, STDIN_FILENO));

  base::ProcessHandle handle;
  if (!base::LaunchApp(argv, no_stdin, false, &handle)) {
    close(devnull);
    return false;
  }
  close(devnull);

  int success_code;
  base::WaitForExitCode(handle, &success_code);
  return success_code == EXIT_SUCCESS;
}

bool GetDesktopShortcutTemplate(std::string* output) {
  std::vector<FilePath> search_paths;

  const char* xdg_data_home = getenv("XDG_DATA_HOME");
  if (xdg_data_home)
    search_paths.push_back(FilePath(xdg_data_home));

  const char* xdg_data_dirs = getenv("XDG_DATA_DIRS");
  if (xdg_data_dirs) {
    CStringTokenizer tokenizer(xdg_data_dirs,
                               xdg_data_dirs + strlen(xdg_data_dirs), ":");
    while (tokenizer.GetNext()) {
      FilePath data_dir(tokenizer.token());
      search_paths.push_back(data_dir);
      search_paths.push_back(data_dir.Append("applications"));
    }
  }

  std::string template_filename(GetDesktopName());
  for (std::vector<FilePath>::const_iterator i = search_paths.begin();
       i != search_paths.end(); ++i) {
    FilePath path = (*i).Append(template_filename);
    if (file_util::PathExists(path))
      return file_util::ReadFileToString(path, output);
  }

  return false;
}

class CreateDesktopShortcutTask : public Task {
 public:
  CreateDesktopShortcutTask(const ShellIntegration::ShortcutInfo& shortcut_info)
      : shortcut_info_(shortcut_info) {
  }

  virtual void Run() {
    // TODO(phajdan.jr): Report errors from this function, possibly as infobars.
    std::string template_contents;
    if (!GetDesktopShortcutTemplate(&template_contents))
      return;

    FilePath shortcut_filename =
        ShellIntegration::GetDesktopShortcutFilename(shortcut_info_.url);
    if (shortcut_filename.empty())
      return;

    std::string icon_name = CreateIcon(shortcut_filename);

    std::string contents = ShellIntegration::GetDesktopFileContents(
        template_contents, shortcut_info_.url, shortcut_info_.title,
        icon_name);

    if (shortcut_info_.create_on_desktop)
      CreateOnDesktop(shortcut_filename, contents);

    if (shortcut_info_.create_in_applications_menu)
      CreateInApplicationsMenu(shortcut_filename, contents);
  }

 private:
  std::string CreateIcon(const FilePath& shortcut_filename) {
    if (shortcut_info_.favicon.isNull())
      return std::string();

    // TODO(phajdan.jr): Report errors from this function, possibly as infobars.
    ScopedTempDir temp_dir;
    if (!temp_dir.CreateUniqueTempDir())
      return std::string();

    FilePath temp_file_path = temp_dir.path().Append(
        shortcut_filename.ReplaceExtension("png"));

    std::vector<unsigned char> png_data;
    gfx::PNGCodec::EncodeBGRASkBitmap(shortcut_info_.favicon, false, &png_data);
    int bytes_written = file_util::WriteFile(temp_file_path,
        reinterpret_cast<char*>(png_data.data()), png_data.size());

    if (bytes_written != static_cast<int>(png_data.size()))
      return std::string();

    std::vector<std::string> argv;
    argv.push_back("xdg-icon-resource");
    argv.push_back("install");

    // Always install in user mode, even if someone runs the browser as root
    // (people do that).
    argv.push_back("--mode");
    argv.push_back("user");

    argv.push_back("--size");
    argv.push_back(IntToString(shortcut_info_.favicon.width()));

    argv.push_back(temp_file_path.value());
    std::string icon_name = temp_file_path.BaseName().RemoveExtension().value();
    argv.push_back(icon_name);
    LaunchXdgUtility(argv);
    return icon_name;
  }

  void CreateOnDesktop(const FilePath& shortcut_filename,
                       const std::string& contents) {
    // TODO(phajdan.jr): Report errors from this function, possibly as infobars.

    // Make sure that we will later call openat in a secure way.
    DCHECK_EQ(shortcut_filename.BaseName().value(), shortcut_filename.value());

    FilePath desktop_path;
    if (!PathService::Get(chrome::DIR_USER_DESKTOP, &desktop_path))
      return;

    int desktop_fd = open(desktop_path.value().c_str(), O_RDONLY | O_DIRECTORY);
    if (desktop_fd < 0)
      return;

    int fd = openat(desktop_fd, shortcut_filename.value().c_str(),
                    O_CREAT | O_EXCL | O_WRONLY,
                    S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
    if (fd < 0) {
      HANDLE_EINTR(close(desktop_fd));
      return;
    }

    ssize_t bytes_written = file_util::WriteFileDescriptor(fd, contents.data(),
                                                           contents.length());
    HANDLE_EINTR(close(fd));

    if (bytes_written != static_cast<ssize_t>(contents.length())) {
      // Delete the file. No shortuct is better than corrupted one. Use unlinkat
      // to make sure we're deleting the file in the directory we think we are.
      // Even if an attacker manager to put something other at
      // |shortcut_filename| we'll just undo his action.
      unlinkat(desktop_fd, shortcut_filename.value().c_str(), 0);
    }

    HANDLE_EINTR(close(desktop_fd));
  }

  void CreateInApplicationsMenu(const FilePath& shortcut_filename,
                                const std::string& contents) {
    // TODO(phajdan.jr): Report errors from this function, possibly as infobars.
    ScopedTempDir temp_dir;
    if (!temp_dir.CreateUniqueTempDir())
      return;

    FilePath temp_file_path = temp_dir.path().Append(shortcut_filename);

    int bytes_written = file_util::WriteFile(temp_file_path, contents.data(),
                                             contents.length());

    if (bytes_written != static_cast<int>(contents.length()))
      return;

    std::vector<std::string> argv;
    argv.push_back("xdg-desktop-menu");
    argv.push_back("install");

    // Always install in user mode, even if someone runs the browser as root
    // (people do that).
    argv.push_back("--mode");
    argv.push_back("user");

    argv.push_back(temp_file_path.value());
    LaunchXdgUtility(argv);
  }

  const ShellIntegration::ShortcutInfo shortcut_info_;

  DISALLOW_COPY_AND_ASSIGN(CreateDesktopShortcutTask);
};

}  // namespace

// We delegate the difficulty of setting the default browser in Linux desktop
// environments to a new xdg utility, xdg-settings. We have to include a copy of
// it for this to work, obviously, but that's actually the suggested approach
// for xdg utilities anyway.

bool ShellIntegration::SetAsDefaultBrowser() {
  std::vector<std::string> argv;
  argv.push_back("xdg-settings");
  argv.push_back("set");
  argv.push_back("default-web-browser");
  argv.push_back(GetDesktopName());
  return LaunchXdgUtility(argv);
}

ShellIntegration::DefaultBrowserState ShellIntegration::IsDefaultBrowser() {
  std::vector<std::string> argv;
  argv.push_back("xdg-settings");
  argv.push_back("check");
  argv.push_back("default-web-browser");
  argv.push_back(GetDesktopName());

  std::string reply;
  if (!base::GetAppOutput(CommandLine(argv), &reply)) {
    // xdg-settings failed: we can't determine or set the default browser.
    return UNKNOWN_DEFAULT_BROWSER;
  }

  // Allow any reply that starts with "yes".
  return (reply.find("yes") == 0) ? IS_DEFAULT_BROWSER : NOT_DEFAULT_BROWSER;
}

bool ShellIntegration::IsFirefoxDefaultBrowser() {
  std::vector<std::string> argv;
  argv.push_back("xdg-settings");
  argv.push_back("get");
  argv.push_back("default-web-browser");

  std::string browser;
  // We don't care about the return value here.
  base::GetAppOutput(CommandLine(argv), &browser);
  return browser.find("irefox") != std::string::npos;
}

FilePath ShellIntegration::GetDesktopShortcutFilename(const GURL& url) {
  // Use a prefix, because xdg-desktop-menu requires it.
  std::wstring filename_wide =
      std::wstring(chrome::kBrowserProcessExecutableName) + L"-" +
      UTF8ToWide(url.spec());
  file_util::ReplaceIllegalCharacters(&filename_wide, '_');

  FilePath desktop_path;
  if (!PathService::Get(chrome::DIR_USER_DESKTOP, &desktop_path))
    return FilePath();

  FilePath filepath = desktop_path.Append(
      FilePath::FromWStringHack(filename_wide));
  FilePath alternative_filepath(filepath.value() + ".desktop");
  for (size_t i = 1; i < 100; ++i) {
    if (file_util::PathExists(FilePath(alternative_filepath))) {
      alternative_filepath = FilePath(filepath.value() + "_" + IntToString(i) +
                                      ".desktop");
    } else {
      return FilePath(alternative_filepath).BaseName();
    }
  }

  return FilePath();
}

std::string ShellIntegration::GetDesktopFileContents(
    const std::string& template_contents, const GURL& url,
    const string16& title, const std::string& icon_name) {
  // See http://standards.freedesktop.org/desktop-entry-spec/latest/
  // Although not required by the spec, Nautilus on Ubuntu Karmic creates its
  // launchers with an xdg-open shebang. Follow that convention.
  std::string output_buffer("#!/usr/bin/env xdg-open\n");
  StringTokenizer tokenizer(template_contents, "\n");
  while (tokenizer.GetNext()) {
    if (tokenizer.token().substr(0, 5) == "Exec=") {
      std::string exec_path = tokenizer.token().substr(5);
      StringTokenizer exec_tokenizer(exec_path, " ");
      std::string final_path;
      while (exec_tokenizer.GetNext()) {
        if (exec_tokenizer.token() != "%U")
          final_path += exec_tokenizer.token() + " ";
      }
      std::string switches;
      CPB_GetCommandLineArgumentsCommon(url.spec().c_str(), &switches);
      output_buffer += std::string("Exec=") + final_path + switches + "\n";
    } else if (tokenizer.token().substr(0, 5) == "Name=") {
      std::string final_title = UTF16ToUTF8(title);
      // Make sure no endline characters can slip in and possibly introduce
      // additional lines (like Exec, which makes it a security risk). Also
      // use the URL as a default when the title is empty.
      if (final_title.empty() ||
          final_title.find("\n") != std::string::npos ||
          final_title.find("\r") != std::string::npos) {
        final_title = url.spec();
      }
      output_buffer += StringPrintf("Name=%s\n", final_title.c_str());
    } else if (tokenizer.token().substr(0, 11) == "GenericName" ||
               tokenizer.token().substr(0, 7) == "Comment" ||
               tokenizer.token().substr(0, 1) == "#") {
      // Skip comment lines.
    } else if (tokenizer.token().substr(0, 5) == "Icon=" &&
               !icon_name.empty()) {
      output_buffer += StringPrintf("Icon=%s\n", icon_name.c_str());
    } else {
      output_buffer += tokenizer.token() + "\n";
    }
  }
  return output_buffer;
}

void ShellIntegration::CreateDesktopShortcut(
    const ShortcutInfo& shortcut_info) {
  g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE,
      new CreateDesktopShortcutTask(shortcut_info));
}
<commit_msg>Fix creating desktop shortcuts for systems with empty or incomplete XDG_DATA_DIRS.<commit_after>// Copyright (c) 2006-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/shell_integration.h"

#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <string>
#include <vector>

#include "app/gfx/codec/png_codec.h"
#include "base/command_line.h"
#include "base/eintr_wrapper.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/i18n/file_util_icu.h"
#include "base/message_loop.h"
#include "base/path_service.h"
#include "base/process_util.h"
#include "base/scoped_temp_dir.h"
#include "base/string_tokenizer.h"
#include "base/string_util.h"
#include "base/task.h"
#include "base/thread.h"
#include "chrome/browser/browser_process.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_plugin_util.h"
#include "chrome/common/chrome_switches.h"
#include "googleurl/src/gurl.h"

namespace {

const char* GetDesktopName() {
#if defined(GOOGLE_CHROME_BUILD)
  return "google-chrome.desktop";
#else  // CHROMIUM_BUILD
  static const char* name = NULL;
  if (!name) {
    // Allow $CHROME_DESKTOP to override the built-in value, so that development
    // versions can set themselves as the default without interfering with
    // non-official, packaged versions using the built-in value.
    name = getenv("CHROME_DESKTOP");
    if (!name)
      name = "chromium-browser.desktop";
  }
  return name;
#endif
}

// Helper to launch xdg scripts. We don't want them to ask any questions on the
// terminal etc.
bool LaunchXdgUtility(const std::vector<std::string>& argv) {
  // xdg-settings internally runs xdg-mime, which uses mv to move newly-created
  // files on top of originals after making changes to them. In the event that
  // the original files are owned by another user (e.g. root, which can happen
  // if they are updated within sudo), mv will prompt the user to confirm if
  // standard input is a terminal (otherwise it just does it). So make sure it's
  // not, to avoid locking everything up waiting for mv.
  int devnull = open("/dev/null", O_RDONLY);
  if (devnull < 0)
    return false;
  base::file_handle_mapping_vector no_stdin;
  no_stdin.push_back(std::make_pair(devnull, STDIN_FILENO));

  base::ProcessHandle handle;
  if (!base::LaunchApp(argv, no_stdin, false, &handle)) {
    close(devnull);
    return false;
  }
  close(devnull);

  int success_code;
  base::WaitForExitCode(handle, &success_code);
  return success_code == EXIT_SUCCESS;
}

bool GetDesktopShortcutTemplate(std::string* output) {
  std::vector<FilePath> search_paths;

  const char* xdg_data_home = getenv("XDG_DATA_HOME");
  if (xdg_data_home)
    search_paths.push_back(FilePath(xdg_data_home));

  const char* xdg_data_dirs = getenv("XDG_DATA_DIRS");
  if (xdg_data_dirs) {
    CStringTokenizer tokenizer(xdg_data_dirs,
                               xdg_data_dirs + strlen(xdg_data_dirs), ":");
    while (tokenizer.GetNext()) {
      FilePath data_dir(tokenizer.token());
      search_paths.push_back(data_dir);
      search_paths.push_back(data_dir.Append("applications"));
    }
  }

  // Add some fallback paths for systems which don't have XDG_DATA_DIRS or have
  // it incomplete.
  search_paths.push_back(FilePath("/usr/share/applications"));
  search_paths.push_back(FilePath("/usr/local/share/applications"));

  std::string template_filename(GetDesktopName());
  for (std::vector<FilePath>::const_iterator i = search_paths.begin();
       i != search_paths.end(); ++i) {
    FilePath path = (*i).Append(template_filename);
    if (file_util::PathExists(path))
      return file_util::ReadFileToString(path, output);
  }

  return false;
}

class CreateDesktopShortcutTask : public Task {
 public:
  CreateDesktopShortcutTask(const ShellIntegration::ShortcutInfo& shortcut_info)
      : shortcut_info_(shortcut_info) {
  }

  virtual void Run() {
    // TODO(phajdan.jr): Report errors from this function, possibly as infobars.
    std::string template_contents;
    if (!GetDesktopShortcutTemplate(&template_contents))
      return;

    FilePath shortcut_filename =
        ShellIntegration::GetDesktopShortcutFilename(shortcut_info_.url);
    if (shortcut_filename.empty())
      return;

    std::string icon_name = CreateIcon(shortcut_filename);

    std::string contents = ShellIntegration::GetDesktopFileContents(
        template_contents, shortcut_info_.url, shortcut_info_.title,
        icon_name);

    if (shortcut_info_.create_on_desktop)
      CreateOnDesktop(shortcut_filename, contents);

    if (shortcut_info_.create_in_applications_menu)
      CreateInApplicationsMenu(shortcut_filename, contents);
  }

 private:
  std::string CreateIcon(const FilePath& shortcut_filename) {
    if (shortcut_info_.favicon.isNull())
      return std::string();

    // TODO(phajdan.jr): Report errors from this function, possibly as infobars.
    ScopedTempDir temp_dir;
    if (!temp_dir.CreateUniqueTempDir())
      return std::string();

    FilePath temp_file_path = temp_dir.path().Append(
        shortcut_filename.ReplaceExtension("png"));

    std::vector<unsigned char> png_data;
    gfx::PNGCodec::EncodeBGRASkBitmap(shortcut_info_.favicon, false, &png_data);
    int bytes_written = file_util::WriteFile(temp_file_path,
        reinterpret_cast<char*>(png_data.data()), png_data.size());

    if (bytes_written != static_cast<int>(png_data.size()))
      return std::string();

    std::vector<std::string> argv;
    argv.push_back("xdg-icon-resource");
    argv.push_back("install");

    // Always install in user mode, even if someone runs the browser as root
    // (people do that).
    argv.push_back("--mode");
    argv.push_back("user");

    argv.push_back("--size");
    argv.push_back(IntToString(shortcut_info_.favicon.width()));

    argv.push_back(temp_file_path.value());
    std::string icon_name = temp_file_path.BaseName().RemoveExtension().value();
    argv.push_back(icon_name);
    LaunchXdgUtility(argv);
    return icon_name;
  }

  void CreateOnDesktop(const FilePath& shortcut_filename,
                       const std::string& contents) {
    // TODO(phajdan.jr): Report errors from this function, possibly as infobars.

    // Make sure that we will later call openat in a secure way.
    DCHECK_EQ(shortcut_filename.BaseName().value(), shortcut_filename.value());

    FilePath desktop_path;
    if (!PathService::Get(chrome::DIR_USER_DESKTOP, &desktop_path))
      return;

    int desktop_fd = open(desktop_path.value().c_str(), O_RDONLY | O_DIRECTORY);
    if (desktop_fd < 0)
      return;

    int fd = openat(desktop_fd, shortcut_filename.value().c_str(),
                    O_CREAT | O_EXCL | O_WRONLY,
                    S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
    if (fd < 0) {
      HANDLE_EINTR(close(desktop_fd));
      return;
    }

    ssize_t bytes_written = file_util::WriteFileDescriptor(fd, contents.data(),
                                                           contents.length());
    HANDLE_EINTR(close(fd));

    if (bytes_written != static_cast<ssize_t>(contents.length())) {
      // Delete the file. No shortuct is better than corrupted one. Use unlinkat
      // to make sure we're deleting the file in the directory we think we are.
      // Even if an attacker manager to put something other at
      // |shortcut_filename| we'll just undo his action.
      unlinkat(desktop_fd, shortcut_filename.value().c_str(), 0);
    }

    HANDLE_EINTR(close(desktop_fd));
  }

  void CreateInApplicationsMenu(const FilePath& shortcut_filename,
                                const std::string& contents) {
    // TODO(phajdan.jr): Report errors from this function, possibly as infobars.
    ScopedTempDir temp_dir;
    if (!temp_dir.CreateUniqueTempDir())
      return;

    FilePath temp_file_path = temp_dir.path().Append(shortcut_filename);

    int bytes_written = file_util::WriteFile(temp_file_path, contents.data(),
                                             contents.length());

    if (bytes_written != static_cast<int>(contents.length()))
      return;

    std::vector<std::string> argv;
    argv.push_back("xdg-desktop-menu");
    argv.push_back("install");

    // Always install in user mode, even if someone runs the browser as root
    // (people do that).
    argv.push_back("--mode");
    argv.push_back("user");

    argv.push_back(temp_file_path.value());
    LaunchXdgUtility(argv);
  }

  const ShellIntegration::ShortcutInfo shortcut_info_;

  DISALLOW_COPY_AND_ASSIGN(CreateDesktopShortcutTask);
};

}  // namespace

// We delegate the difficulty of setting the default browser in Linux desktop
// environments to a new xdg utility, xdg-settings. We have to include a copy of
// it for this to work, obviously, but that's actually the suggested approach
// for xdg utilities anyway.

bool ShellIntegration::SetAsDefaultBrowser() {
  std::vector<std::string> argv;
  argv.push_back("xdg-settings");
  argv.push_back("set");
  argv.push_back("default-web-browser");
  argv.push_back(GetDesktopName());
  return LaunchXdgUtility(argv);
}

ShellIntegration::DefaultBrowserState ShellIntegration::IsDefaultBrowser() {
  std::vector<std::string> argv;
  argv.push_back("xdg-settings");
  argv.push_back("check");
  argv.push_back("default-web-browser");
  argv.push_back(GetDesktopName());

  std::string reply;
  if (!base::GetAppOutput(CommandLine(argv), &reply)) {
    // xdg-settings failed: we can't determine or set the default browser.
    return UNKNOWN_DEFAULT_BROWSER;
  }

  // Allow any reply that starts with "yes".
  return (reply.find("yes") == 0) ? IS_DEFAULT_BROWSER : NOT_DEFAULT_BROWSER;
}

bool ShellIntegration::IsFirefoxDefaultBrowser() {
  std::vector<std::string> argv;
  argv.push_back("xdg-settings");
  argv.push_back("get");
  argv.push_back("default-web-browser");

  std::string browser;
  // We don't care about the return value here.
  base::GetAppOutput(CommandLine(argv), &browser);
  return browser.find("irefox") != std::string::npos;
}

FilePath ShellIntegration::GetDesktopShortcutFilename(const GURL& url) {
  // Use a prefix, because xdg-desktop-menu requires it.
  std::wstring filename_wide =
      std::wstring(chrome::kBrowserProcessExecutableName) + L"-" +
      UTF8ToWide(url.spec());
  file_util::ReplaceIllegalCharacters(&filename_wide, '_');

  FilePath desktop_path;
  if (!PathService::Get(chrome::DIR_USER_DESKTOP, &desktop_path))
    return FilePath();

  FilePath filepath = desktop_path.Append(
      FilePath::FromWStringHack(filename_wide));
  FilePath alternative_filepath(filepath.value() + ".desktop");
  for (size_t i = 1; i < 100; ++i) {
    if (file_util::PathExists(FilePath(alternative_filepath))) {
      alternative_filepath = FilePath(filepath.value() + "_" + IntToString(i) +
                                      ".desktop");
    } else {
      return FilePath(alternative_filepath).BaseName();
    }
  }

  return FilePath();
}

std::string ShellIntegration::GetDesktopFileContents(
    const std::string& template_contents, const GURL& url,
    const string16& title, const std::string& icon_name) {
  // See http://standards.freedesktop.org/desktop-entry-spec/latest/
  // Although not required by the spec, Nautilus on Ubuntu Karmic creates its
  // launchers with an xdg-open shebang. Follow that convention.
  std::string output_buffer("#!/usr/bin/env xdg-open\n");
  StringTokenizer tokenizer(template_contents, "\n");
  while (tokenizer.GetNext()) {
    if (tokenizer.token().substr(0, 5) == "Exec=") {
      std::string exec_path = tokenizer.token().substr(5);
      StringTokenizer exec_tokenizer(exec_path, " ");
      std::string final_path;
      while (exec_tokenizer.GetNext()) {
        if (exec_tokenizer.token() != "%U")
          final_path += exec_tokenizer.token() + " ";
      }
      std::string switches;
      CPB_GetCommandLineArgumentsCommon(url.spec().c_str(), &switches);
      output_buffer += std::string("Exec=") + final_path + switches + "\n";
    } else if (tokenizer.token().substr(0, 5) == "Name=") {
      std::string final_title = UTF16ToUTF8(title);
      // Make sure no endline characters can slip in and possibly introduce
      // additional lines (like Exec, which makes it a security risk). Also
      // use the URL as a default when the title is empty.
      if (final_title.empty() ||
          final_title.find("\n") != std::string::npos ||
          final_title.find("\r") != std::string::npos) {
        final_title = url.spec();
      }
      output_buffer += StringPrintf("Name=%s\n", final_title.c_str());
    } else if (tokenizer.token().substr(0, 11) == "GenericName" ||
               tokenizer.token().substr(0, 7) == "Comment" ||
               tokenizer.token().substr(0, 1) == "#") {
      // Skip comment lines.
    } else if (tokenizer.token().substr(0, 5) == "Icon=" &&
               !icon_name.empty()) {
      output_buffer += StringPrintf("Icon=%s\n", icon_name.c_str());
    } else {
      output_buffer += tokenizer.token() + "\n";
    }
  }
  return output_buffer;
}

void ShellIntegration::CreateDesktopShortcut(
    const ShortcutInfo& shortcut_info) {
  g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE,
      new CreateDesktopShortcutTask(shortcut_info));
}
<|endoftext|>


<commit_before>#pragma once
#include <cstdint>
#include <nlohmann/json.hpp>
#include <vector>

#include "DatatypeEnum.hpp"
#include "RawBuffer.hpp"

namespace dai {

/// RawCameraControl structure
struct RawCameraControl : public RawBuffer {
    enum class Command : uint8_t {
        START_STREAM = 1,
        STOP_STREAM = 2,
        STILL_CAPTURE = 3,
        MOVE_LENS = 4, /* [1] lens position: 0-255
                        */
        AF_TRIGGER = 5,
        AE_MANUAL = 6, /* [1] exposure time [us]
                        * [2] sensitivity [iso]
                        * [3] frame duration [us]
                        */
        AE_AUTO = 7,
        AWB_MODE = 8,                  /* [1] awb_mode: AutoWhiteBalanceMode
                                        */
        SCENE_MODE = 9,                /* [1] scene_mode: SceneMode
                                        */
        ANTIBANDING_MODE = 10,         /* [1] antibanding_mode: AntiBandingMode
                                        */
        EXPOSURE_COMPENSATION = 11,    /* [1] value
                                        */
        AE_LOCK = 13,                  /* [1] ae_lock_mode: bool
                                        */
        AE_TARGET_FPS_RANGE = 14,      /* [1] min_fps
                                        * [2] max_fps
                                        */
        AWB_LOCK = 16,                 /* [1] awb_lock_mode: bool
                                        */
        CAPTURE_INTENT = 17,           /* [1] capture_intent_mode: CaptureIntent
                                        */
        CONTROL_MODE = 18,             /* [1] control_mode: ControlMode
                                        */
        FRAME_DURATION = 21,           /* [1] frame_duration
                                        */
        SENSITIVITY = 23,              /* [1] iso_val
                                        */
        EFFECT_MODE = 24,              /* [1] effect_mode: EffectMode
                                        */
        AF_MODE = 26,                  /* [1] af_mode: AutoFocusMode
                                        */
        NOISE_REDUCTION_STRENGTH = 27, /* [1] value
                                        */
        SATURATION = 28,               /* [1] value
                                        */
        BRIGHTNESS = 31,               /* [1] value
                                        */
        STREAM_FORMAT = 33,            /* [1] format
                                        */
        RESOLUTION = 34,               /* [1] width
                                        * [2] height
                                        */
        SHARPNESS = 35,                /* [1] value
                                        */
        CUSTOM_USECASE = 40,           /* [1] value
                                        */
        CUSTOM_CAPT_MODE = 41,         /* [1] value
                                        */
        CUSTOM_EXP_BRACKETS = 42,      /* [1] val1
                                        * [2] val2
                                        * [3] val3
                                        */
        CUSTOM_CAPTURE = 43,           /* [1] value
                                        */
        CONTRAST = 44,                 /* [1] value
                                        */
        AE_REGION = 45,                /* [1] x
                                        * [2] y
                                        * [3] width
                                        * [4] height
                                        * [5] priority
                                        */
        AF_REGION = 46,                /* [1] x
                                        * [2] y
                                        * [3] width
                                        * [4] height
                                        * [5] priority
                                        */
        LUMA_DENOISE = 47,             /* [1] value
                                        */
        CHROMA_DENOISE = 48,           /* [1] value
                                        */
        EXTERNAL_TRIGGER = 50,
    };

    enum class AutoFocusMode : uint8_t {
        /// Autofocus disabled. Suitable for manual focus
        OFF = 0,
        /// Runs autofocus once at startup, and at subsequent trigger commands
        AUTO,
        /// TODO
        MACRO,
        /// Runs autofocus when the scene is detected as out-of-focus
        CONTINUOUS_VIDEO,
        CONTINUOUS_PICTURE,
        EDOF,
    };

    enum class AutoWhiteBalanceMode : uint8_t {
        OFF = 0,
        AUTO,
        INCANDESCENT,
        FLUORESCENT,
        WARM_FLUORESCENT,
        DAYLIGHT,
        CLOUDY_DAYLIGHT,
        TWILIGHT,
        SHADE,
    };

    enum class SceneMode : uint8_t {
        UNSUPPORTED = 0,
        FACE_PRIORITY,
        ACTION,
        PORTRAIT,
        LANDSCAPE,
        NIGHT,
        NIGHT_PORTRAIT,
        THEATRE,
        BEACH,
        SNOW,
        SUNSET,
        STEADYPHOTO,
        FIREWORKS,
        SPORTS,
        PARTY,
        CANDLELIGHT,
        BARCODE,
    };

    enum class AntiBandingMode : uint8_t {
        OFF = 0,
        MAINS_50_HZ,
        MAINS_60_HZ,
        AUTO,
    };

    enum class CaptureIntent : uint8_t {
        CUSTOM = 0,
        PREVIEW,
        STILL_CAPTURE,
        VIDEO_RECORD,
        VIDEO_SNAPSHOT,
        ZERO_SHUTTER_LAG,
    };

    enum class ControlMode : uint8_t {
        OFF = 0,
        AUTO,
        USE_SCENE_MODE,
    };

    enum class EffectMode : uint8_t {
        OFF = 0,
        MONO,
        NEGATIVE,
        SOLARIZE,
        SEPIA,
        POSTERIZE,
        WHITEBOARD,
        BLACKBOARD,
        AQUA,
    };

    struct ManualExposureParams {
        uint32_t exposureTimeUs;
        uint32_t sensitivityIso;
        uint32_t frameDurationUs;

        NLOHMANN_DEFINE_TYPE_INTRUSIVE(ManualExposureParams, exposureTimeUs, sensitivityIso, frameDurationUs);
    };

    // AE_REGION / AF_REGION
    struct RegionParams {
        uint16_t x;
        uint16_t y;
        uint16_t width;
        uint16_t height;
        // Set to 1 for now. TODO
        uint32_t priority;

        NLOHMANN_DEFINE_TYPE_INTRUSIVE(RegionParams, x, y, width, height, priority);
    };

    uint64_t cmdMask = 0;

    AutoFocusMode autoFocusMode = AutoFocusMode::CONTINUOUS_VIDEO;

    /**
     * Lens/VCM position, range: 0..255. Used with `autoFocusMode = OFF`.
     * With current IMX378 modules:
     * - max 255: macro focus, at 8cm distance
     * - infinite focus at about 120..130 (may vary from module to module)
     * - lower values lead to out-of-focus (lens too close to the sensor array)
     */
    uint8_t lensPosition = 0;

    ManualExposureParams expManual;
    RegionParams aeRegion, afRegion;
    AutoWhiteBalanceMode awbMode;
    SceneMode sceneMode;
    AntiBandingMode antiBandingMode;
    EffectMode effectMode;
    bool aeLockMode;
    bool awbLockMode;
    int8_t expCompensation;  //  -9 ..  9
    int8_t brightness;       // -10 .. 10
    int8_t contrast;         // -10 .. 10
    int8_t saturation;       // -10 .. 10
    uint8_t sharpness;       //   0 ..  4
    uint8_t lumaDenoise;     //   0 ..  4
    uint8_t chromaDenoise;   //   0 ..  4
    uint8_t lowPowerNumFramesBurst;

    void setCommand(Command cmd, bool value = true) {
        uint64_t mask = 1ull << (uint8_t)cmd;
        if(value) {
            cmdMask |= mask;
        } else {
            cmdMask &= ~mask;
        }
    }
    void clearCommand(Command cmd) {
        setCommand(cmd, false);
    }
    bool getCommand(Command cmd) {
        return !!(cmdMask & (1ull << (uint8_t)cmd));
    }

    void serialize(std::vector<std::uint8_t>& metadata, DatatypeEnum& datatype) const override {
        nlohmann::json j = *this;
        metadata = nlohmann::json::to_msgpack(j);
        datatype = DatatypeEnum::CameraControl;
    };

    NLOHMANN_DEFINE_TYPE_INTRUSIVE(RawCameraControl,
                                   cmdMask,
                                   autoFocusMode,
                                   lensPosition,
                                   expManual,
                                   aeRegion,
                                   afRegion,
                                   awbMode,
                                   sceneMode,
                                   antiBandingMode,
                                   aeLockMode,
                                   awbLockMode,
                                   effectMode,
                                   expCompensation,
                                   brightness,
                                   contrast,
                                   saturation,
                                   sharpness,
                                   lumaDenoise,
                                   chromaDenoise,
                                   lowPowerNumFramesBurst);
};

}  // namespace dai
<commit_msg>RawCameraControl: add lowPowerNumFramesDiscard<commit_after>#pragma once
#include <cstdint>
#include <nlohmann/json.hpp>
#include <vector>

#include "DatatypeEnum.hpp"
#include "RawBuffer.hpp"

namespace dai {

/// RawCameraControl structure
struct RawCameraControl : public RawBuffer {
    enum class Command : uint8_t {
        START_STREAM = 1,
        STOP_STREAM = 2,
        STILL_CAPTURE = 3,
        MOVE_LENS = 4, /* [1] lens position: 0-255
                        */
        AF_TRIGGER = 5,
        AE_MANUAL = 6, /* [1] exposure time [us]
                        * [2] sensitivity [iso]
                        * [3] frame duration [us]
                        */
        AE_AUTO = 7,
        AWB_MODE = 8,                  /* [1] awb_mode: AutoWhiteBalanceMode
                                        */
        SCENE_MODE = 9,                /* [1] scene_mode: SceneMode
                                        */
        ANTIBANDING_MODE = 10,         /* [1] antibanding_mode: AntiBandingMode
                                        */
        EXPOSURE_COMPENSATION = 11,    /* [1] value
                                        */
        AE_LOCK = 13,                  /* [1] ae_lock_mode: bool
                                        */
        AE_TARGET_FPS_RANGE = 14,      /* [1] min_fps
                                        * [2] max_fps
                                        */
        AWB_LOCK = 16,                 /* [1] awb_lock_mode: bool
                                        */
        CAPTURE_INTENT = 17,           /* [1] capture_intent_mode: CaptureIntent
                                        */
        CONTROL_MODE = 18,             /* [1] control_mode: ControlMode
                                        */
        FRAME_DURATION = 21,           /* [1] frame_duration
                                        */
        SENSITIVITY = 23,              /* [1] iso_val
                                        */
        EFFECT_MODE = 24,              /* [1] effect_mode: EffectMode
                                        */
        AF_MODE = 26,                  /* [1] af_mode: AutoFocusMode
                                        */
        NOISE_REDUCTION_STRENGTH = 27, /* [1] value
                                        */
        SATURATION = 28,               /* [1] value
                                        */
        BRIGHTNESS = 31,               /* [1] value
                                        */
        STREAM_FORMAT = 33,            /* [1] format
                                        */
        RESOLUTION = 34,               /* [1] width
                                        * [2] height
                                        */
        SHARPNESS = 35,                /* [1] value
                                        */
        CUSTOM_USECASE = 40,           /* [1] value
                                        */
        CUSTOM_CAPT_MODE = 41,         /* [1] value
                                        */
        CUSTOM_EXP_BRACKETS = 42,      /* [1] val1
                                        * [2] val2
                                        * [3] val3
                                        */
        CUSTOM_CAPTURE = 43,           /* [1] value
                                        */
        CONTRAST = 44,                 /* [1] value
                                        */
        AE_REGION = 45,                /* [1] x
                                        * [2] y
                                        * [3] width
                                        * [4] height
                                        * [5] priority
                                        */
        AF_REGION = 46,                /* [1] x
                                        * [2] y
                                        * [3] width
                                        * [4] height
                                        * [5] priority
                                        */
        LUMA_DENOISE = 47,             /* [1] value
                                        */
        CHROMA_DENOISE = 48,           /* [1] value
                                        */
        EXTERNAL_TRIGGER = 50,
    };

    enum class AutoFocusMode : uint8_t {
        /// Autofocus disabled. Suitable for manual focus
        OFF = 0,
        /// Runs autofocus once at startup, and at subsequent trigger commands
        AUTO,
        /// TODO
        MACRO,
        /// Runs autofocus when the scene is detected as out-of-focus
        CONTINUOUS_VIDEO,
        CONTINUOUS_PICTURE,
        EDOF,
    };

    enum class AutoWhiteBalanceMode : uint8_t {
        OFF = 0,
        AUTO,
        INCANDESCENT,
        FLUORESCENT,
        WARM_FLUORESCENT,
        DAYLIGHT,
        CLOUDY_DAYLIGHT,
        TWILIGHT,
        SHADE,
    };

    enum class SceneMode : uint8_t {
        UNSUPPORTED = 0,
        FACE_PRIORITY,
        ACTION,
        PORTRAIT,
        LANDSCAPE,
        NIGHT,
        NIGHT_PORTRAIT,
        THEATRE,
        BEACH,
        SNOW,
        SUNSET,
        STEADYPHOTO,
        FIREWORKS,
        SPORTS,
        PARTY,
        CANDLELIGHT,
        BARCODE,
    };

    enum class AntiBandingMode : uint8_t {
        OFF = 0,
        MAINS_50_HZ,
        MAINS_60_HZ,
        AUTO,
    };

    enum class CaptureIntent : uint8_t {
        CUSTOM = 0,
        PREVIEW,
        STILL_CAPTURE,
        VIDEO_RECORD,
        VIDEO_SNAPSHOT,
        ZERO_SHUTTER_LAG,
    };

    enum class ControlMode : uint8_t {
        OFF = 0,
        AUTO,
        USE_SCENE_MODE,
    };

    enum class EffectMode : uint8_t {
        OFF = 0,
        MONO,
        NEGATIVE,
        SOLARIZE,
        SEPIA,
        POSTERIZE,
        WHITEBOARD,
        BLACKBOARD,
        AQUA,
    };

    struct ManualExposureParams {
        uint32_t exposureTimeUs;
        uint32_t sensitivityIso;
        uint32_t frameDurationUs;

        NLOHMANN_DEFINE_TYPE_INTRUSIVE(ManualExposureParams, exposureTimeUs, sensitivityIso, frameDurationUs);
    };

    // AE_REGION / AF_REGION
    struct RegionParams {
        uint16_t x;
        uint16_t y;
        uint16_t width;
        uint16_t height;
        // Set to 1 for now. TODO
        uint32_t priority;

        NLOHMANN_DEFINE_TYPE_INTRUSIVE(RegionParams, x, y, width, height, priority);
    };

    uint64_t cmdMask = 0;

    AutoFocusMode autoFocusMode = AutoFocusMode::CONTINUOUS_VIDEO;

    /**
     * Lens/VCM position, range: 0..255. Used with `autoFocusMode = OFF`.
     * With current IMX378 modules:
     * - max 255: macro focus, at 8cm distance
     * - infinite focus at about 120..130 (may vary from module to module)
     * - lower values lead to out-of-focus (lens too close to the sensor array)
     */
    uint8_t lensPosition = 0;

    ManualExposureParams expManual;
    RegionParams aeRegion, afRegion;
    AutoWhiteBalanceMode awbMode;
    SceneMode sceneMode;
    AntiBandingMode antiBandingMode;
    EffectMode effectMode;
    bool aeLockMode;
    bool awbLockMode;
    int8_t expCompensation;  //  -9 ..  9
    int8_t brightness;       // -10 .. 10
    int8_t contrast;         // -10 .. 10
    int8_t saturation;       // -10 .. 10
    uint8_t sharpness;       //   0 ..  4
    uint8_t lumaDenoise;     //   0 ..  4
    uint8_t chromaDenoise;   //   0 ..  4
    uint8_t lowPowerNumFramesBurst;
    uint8_t lowPowerNumFramesDiscard;

    void setCommand(Command cmd, bool value = true) {
        uint64_t mask = 1ull << (uint8_t)cmd;
        if(value) {
            cmdMask |= mask;
        } else {
            cmdMask &= ~mask;
        }
    }
    void clearCommand(Command cmd) {
        setCommand(cmd, false);
    }
    bool getCommand(Command cmd) {
        return !!(cmdMask & (1ull << (uint8_t)cmd));
    }

    void serialize(std::vector<std::uint8_t>& metadata, DatatypeEnum& datatype) const override {
        nlohmann::json j = *this;
        metadata = nlohmann::json::to_msgpack(j);
        datatype = DatatypeEnum::CameraControl;
    };

    NLOHMANN_DEFINE_TYPE_INTRUSIVE(RawCameraControl,
                                   cmdMask,
                                   autoFocusMode,
                                   lensPosition,
                                   expManual,
                                   aeRegion,
                                   afRegion,
                                   awbMode,
                                   sceneMode,
                                   antiBandingMode,
                                   aeLockMode,
                                   awbLockMode,
                                   effectMode,
                                   expCompensation,
                                   brightness,
                                   contrast,
                                   saturation,
                                   sharpness,
                                   lumaDenoise,
                                   chromaDenoise,
                                   lowPowerNumFramesBurst,
                                   lowPowerNumFramesDiscard);
};

}  // namespace dai
<|endoftext|>