<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/options/system_page_view.h"

#include <string>
#include <vector>

#include "app/combobox_model.h"
#include "base/stl_util-inl.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/chromeos/options/language_config_view.h"
#include "chrome/browser/pref_member.h"
#include "chrome/browser/profile.h"
#include "chrome/common/pref_names.h"
#include "grit/generated_resources.h"
#include "unicode/timezone.h"
#include "views/controls/button/checkbox.h"
#include "views/controls/button/native_button.h"
#include "views/controls/combobox/combobox.h"
#include "views/controls/slider/slider.h"
#include "views/window/window.h"

namespace chromeos {

////////////////////////////////////////////////////////////////////////////////
// DateTimeSection

// Date/Time section for datetime settings
class DateTimeSection : public SettingsPageSection,
                        public views::Combobox::Listener {
 public:
  explicit DateTimeSection(Profile* profile);
  virtual ~DateTimeSection() {}

  // Overridden from views::Combobox::Listener:
  virtual void ItemChanged(views::Combobox* sender,
                           int prev_index,
                           int new_index);

 protected:
  // SettingsPageSection overrides:
  virtual void InitContents(GridLayout* layout);
  virtual void NotifyPrefChanged(const std::wstring* pref_name);

 private:
  // The combobox model for the list of timezones.
  class TimezoneComboboxModel : public ComboboxModel {
   public:
    TimezoneComboboxModel() {
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("US/Pacific")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("US/Mountain")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("US/Central")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("US/Eastern")));
      // For now, add all the GMT timezones.
      // We may eventually want to use icu::TimeZone::createEnumeration()
      // to list all the timezones and pick the ones we want to show.
      for (int i = 11; i >= -12; i--) {
        // For positive i's, add the extra '+'.
        std::string str = StringPrintf(i > 0 ? "Etc/GMT+%d" : "Etc/GMT%d", i);
        icu::TimeZone* timezone = icu::TimeZone::createTimeZone(
            icu::UnicodeString::fromUTF8(str.c_str()));
        timezones_.push_back(timezone);
      }
    }

    virtual ~TimezoneComboboxModel() {
      STLDeleteElements(&timezones_);
    }

    virtual int GetItemCount() {
      return static_cast<int>(timezones_.size());
    }

    virtual std::wstring GetItemAt(int index) {
      icu::UnicodeString name;
      timezones_[index]->getDisplayName(name);
      std::wstring output;
      UTF16ToWide(name.getBuffer(), name.length(), &output);
      return output;
    }

    virtual std::wstring GetTimeZoneIDAt(int index) {
      icu::UnicodeString id;
      timezones_[index]->getID(id);
      std::wstring output;
      UTF16ToWide(id.getBuffer(), id.length(), &output);
      return output;
    }

   private:
    std::vector<icu::TimeZone*> timezones_;

    DISALLOW_COPY_AND_ASSIGN(TimezoneComboboxModel);
  };

  // Selects the timezone.
  void SelectTimeZone(const std::wstring& id);

  // TimeZone combobox model.
  views::Combobox* timezone_combobox_;

  // Controls for this section:
  TimezoneComboboxModel timezone_combobox_model_;

  // Preferences for this section:
  StringPrefMember timezone_;

  DISALLOW_COPY_AND_ASSIGN(DateTimeSection);
};

DateTimeSection::DateTimeSection(Profile* profile)
    : SettingsPageSection(profile, IDS_OPTIONS_SETTINGS_SECTION_TITLE_DATETIME),
      timezone_combobox_(NULL) {
}

void DateTimeSection::ItemChanged(views::Combobox* sender,
                                  int prev_index,
                                  int new_index) {
  if (new_index == prev_index)
    return;
  timezone_.SetValue(timezone_combobox_model_.GetTimeZoneIDAt(new_index));
}

void DateTimeSection::InitContents(GridLayout* layout) {
  timezone_combobox_ = new views::Combobox(&timezone_combobox_model_);
  timezone_combobox_->set_listener(this);

  layout->StartRow(0, double_column_view_set_id());
  layout->AddView(new views::Label(
      l10n_util::GetString(IDS_OPTIONS_SETTINGS_TIMEZONE_DESCRIPTION)));
  layout->AddView(timezone_combobox_);
  layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);

  // Init member prefs so we can update the controls if prefs change.
  timezone_.Init(prefs::kTimeZone, profile()->GetPrefs(), this);
}

void DateTimeSection::NotifyPrefChanged(const std::wstring* pref_name) {
  if (!pref_name || *pref_name == prefs::kTimeZone) {
    std::wstring timezone = timezone_.GetValue();
    SelectTimeZone(timezone);
  }
}

void DateTimeSection::SelectTimeZone(const std::wstring& id) {
  for (int i = 0; i < timezone_combobox_model_.GetItemCount(); i++) {
    if (timezone_combobox_model_.GetTimeZoneIDAt(i) == id) {
      timezone_combobox_->SetSelectedItem(i);
      return;
    }
  }
}

////////////////////////////////////////////////////////////////////////////////
// TouchpadSection

class TouchpadSection : public SettingsPageSection,
                        public views::ButtonListener,
                        public views::SliderListener {
 public:
  explicit TouchpadSection(Profile* profile);
  virtual ~TouchpadSection() {}

  // Overridden from views::ButtonListener:
  virtual void ButtonPressed(views::Button* sender, const views::Event& event);

  // Overridden from views::SliderListener:
  virtual void SliderValueChanged(views::Slider* sender);

 protected:
  // SettingsPageSection overrides:
  virtual void InitContents(GridLayout* layout);
  virtual void NotifyPrefChanged(const std::wstring* pref_name);

 private:
  // The View that contains the contents of the section.
  views::View* contents_;

  // Controls for this section:
  views::Checkbox* enable_tap_to_click_checkbox_;
  views::Checkbox* enable_vert_edge_scroll_checkbox_;
  views::Slider* speed_factor_slider_;
  views::Slider* sensitivity_slider_;

  // Preferences for this section:
  BooleanPrefMember tap_to_click_enabled_;
  BooleanPrefMember vert_edge_scroll_enabled_;
  IntegerPrefMember speed_factor_;
  IntegerPrefMember sensitivity_;

  DISALLOW_COPY_AND_ASSIGN(TouchpadSection);
};

TouchpadSection::TouchpadSection(Profile* profile)
    : SettingsPageSection(profile, IDS_OPTIONS_SETTINGS_SECTION_TITLE_TOUCHPAD),
      enable_tap_to_click_checkbox_(NULL),
      enable_vert_edge_scroll_checkbox_(NULL),
      speed_factor_slider_(NULL),
      sensitivity_slider_(NULL) {
}

void TouchpadSection::ButtonPressed(
    views::Button* sender, const views::Event& event) {
  if (sender == enable_tap_to_click_checkbox_) {
    bool enabled = enable_tap_to_click_checkbox_->checked();
    UserMetricsRecordAction(enabled ?
                                "Options_TapToClickCheckbox_Enable" :
                                "Options_TapToClickCheckbox_Disable",
                            profile()->GetPrefs());
    tap_to_click_enabled_.SetValue(enabled);
  } else if (sender == enable_vert_edge_scroll_checkbox_) {
    bool enabled = enable_vert_edge_scroll_checkbox_->checked();
    UserMetricsRecordAction(enabled ?
                                "Options_VertEdgeScrollCheckbox_Enable" :
                                "Options_VertEdgeScrollCheckbox_Disable",
                            profile()->GetPrefs());
    vert_edge_scroll_enabled_.SetValue(enabled);
  }
}

void TouchpadSection::SliderValueChanged(views::Slider* sender) {
  if (sender == speed_factor_slider_) {
    double value = speed_factor_slider_->value();
    UserMetricsRecordAction("Options_SpeedFactorSlider_Changed",
                            profile()->GetPrefs());
    speed_factor_.SetValue(value);
  } else if (sender == sensitivity_slider_) {
    double value = sensitivity_slider_->value();
    UserMetricsRecordAction("Options_SensitivitySlider_Changed",
                            profile()->GetPrefs());
    sensitivity_.SetValue(value);
  }
}

void TouchpadSection::InitContents(GridLayout* layout) {
  enable_tap_to_click_checkbox_ = new views::Checkbox(l10n_util::GetString(
      IDS_OPTIONS_SETTINGS_TAP_TO_CLICK_ENABLED_DESCRIPTION));
  enable_tap_to_click_checkbox_->set_listener(this);
  enable_tap_to_click_checkbox_->SetMultiLine(true);
  enable_vert_edge_scroll_checkbox_ = new views::Checkbox(l10n_util::GetString(
      IDS_OPTIONS_SETTINGS_VERT_EDGE_SCROLL_ENABLED_DESCRIPTION));
  enable_vert_edge_scroll_checkbox_->set_listener(this);
  enable_vert_edge_scroll_checkbox_->SetMultiLine(true);
  // Create speed factor slider with values between 1 and 10 step 1
  speed_factor_slider_ = new views::Slider(1, 10, 1,
      static_cast<views::Slider::StyleFlags>(
          views::Slider::STYLE_DRAW_VALUE |
          views::Slider::STYLE_UPDATE_ON_RELEASE),
      this);
  // Create sensitivity slider with values between 1 and 10 step 1
  sensitivity_slider_ = new views::Slider(1, 10, 1,
      static_cast<views::Slider::StyleFlags>(
          views::Slider::STYLE_DRAW_VALUE |
          views::Slider::STYLE_UPDATE_ON_RELEASE),
      this);

  layout->StartRow(0, double_column_view_set_id());
  layout->AddView(new views::Label(
      l10n_util::GetString(IDS_OPTIONS_SETTINGS_SENSITIVITY_DESCRIPTION)));
  layout->AddView(sensitivity_slider_);
  layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
  layout->StartRow(0, double_column_view_set_id());
  layout->AddView(new views::Label(
      l10n_util::GetString(IDS_OPTIONS_SETTINGS_SPEED_FACTOR_DESCRIPTION)));
  layout->AddView(speed_factor_slider_);
  layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
  layout->StartRow(0, single_column_view_set_id());
  layout->AddView(enable_tap_to_click_checkbox_);
  layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
  layout->StartRow(0, single_column_view_set_id());
  layout->AddView(enable_vert_edge_scroll_checkbox_);
  layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing);

  // Init member prefs so we can update the controls if prefs change.
  tap_to_click_enabled_.Init(prefs::kTapToClickEnabled,
                             profile()->GetPrefs(), this);
  vert_edge_scroll_enabled_.Init(prefs::kVertEdgeScrollEnabled,
                                 profile()->GetPrefs(), this);
  speed_factor_.Init(prefs::kTouchpadSpeedFactor,
                     profile()->GetPrefs(), this);
  sensitivity_.Init(prefs::kTouchpadSensitivity,
                    profile()->GetPrefs(), this);
}

void TouchpadSection::NotifyPrefChanged(const std::wstring* pref_name) {
  if (!pref_name || *pref_name == prefs::kTapToClickEnabled) {
    bool enabled =  tap_to_click_enabled_.GetValue();
    enable_tap_to_click_checkbox_->SetChecked(enabled);
  }
  if (!pref_name || *pref_name == prefs::kVertEdgeScrollEnabled) {
    bool enabled =  vert_edge_scroll_enabled_.GetValue();
    enable_vert_edge_scroll_checkbox_->SetChecked(enabled);
  }
  if (!pref_name || *pref_name == prefs::kTouchpadSpeedFactor) {
    double value =  speed_factor_.GetValue();
    speed_factor_slider_->SetValue(value);
  }
  if (!pref_name || *pref_name == prefs::kTouchpadSensitivity) {
    double value =  sensitivity_.GetValue();
    sensitivity_slider_->SetValue(value);
  }
}

////////////////////////////////////////////////////////////////////////////////
// LanguageSection

// TextInput section for text input settings.
class LanguageSection : public SettingsPageSection,
                        public views::ButtonListener {
 public:
  explicit LanguageSection(Profile* profile);
  virtual ~LanguageSection() {}

 private:
  // Overridden from SettingsPageSection:
  virtual void InitContents(GridLayout* layout);

  // Overridden from views::ButtonListener:
  virtual void ButtonPressed(views::Button* sender,
                             const views::Event& event);

  views::NativeButton* customize_languages_button_;

  DISALLOW_COPY_AND_ASSIGN(LanguageSection);
};

LanguageSection::LanguageSection(Profile* profile)
    : SettingsPageSection(profile,
                          IDS_OPTIONS_SETTINGS_SECTION_TITLE_LANGUAGE) {
}

void LanguageSection::InitContents(GridLayout* layout) {
  // Add the customize button.
  layout->StartRow(0, single_column_view_set_id());
  customize_languages_button_ = new views::NativeButton(
      this,
      l10n_util::GetString(IDS_OPTIONS_SETTINGS_LANGUAGES_CUSTOMIZE));
  layout->AddView(customize_languages_button_, 1, 1,
                  GridLayout::LEADING, GridLayout::CENTER);
}

void LanguageSection::ButtonPressed(
    views::Button* sender, const views::Event& event) {
  if (sender == customize_languages_button_) {
    views::Window* window = views::Window::CreateChromeWindow(
        NULL,
        gfx::Rect(),
        new LanguageConfigView());
    window->SetIsAlwaysOnTop(true);
    window->Show();
  }
}

////////////////////////////////////////////////////////////////////////////////
// SystemPageView

////////////////////////////////////////////////////////////////////////////////
// SystemPageView, SettingsPageView implementation:

void SystemPageView::InitControlLayout() {
  GridLayout* layout = CreatePanelGridLayout(this);
  SetLayoutManager(layout);

  int single_column_view_set_id = 0;
  ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id);
  column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
                        GridLayout::USE_PREF, 0, 0);

  layout->StartRow(0, single_column_view_set_id);
  layout->AddView(new DateTimeSection(profile()));
  layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
  layout->StartRow(0, single_column_view_set_id);
  layout->AddView(new TouchpadSection(profile()));
  layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
  layout->StartRow(0, single_column_view_set_id);
  layout->AddView(new LanguageSection(profile()));
  layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
}

}  // namespace chromeos
<commit_msg>Update timezone with a default list of timezones. BUG=none TEST=manually change timezones in the options page and see the clock change to the correct timezone (after a minute) Review URL: http://codereview.chromium.org/1107004<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/options/system_page_view.h"

#include <string>
#include <vector>

#include "app/combobox_model.h"
#include "base/stl_util-inl.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/chromeos/options/language_config_view.h"
#include "chrome/browser/pref_member.h"
#include "chrome/browser/profile.h"
#include "chrome/common/pref_names.h"
#include "grit/generated_resources.h"
#include "unicode/timezone.h"
#include "views/controls/button/checkbox.h"
#include "views/controls/button/native_button.h"
#include "views/controls/combobox/combobox.h"
#include "views/controls/slider/slider.h"
#include "views/window/window.h"

namespace chromeos {

////////////////////////////////////////////////////////////////////////////////
// DateTimeSection

// Date/Time section for datetime settings
class DateTimeSection : public SettingsPageSection,
                        public views::Combobox::Listener {
 public:
  explicit DateTimeSection(Profile* profile);
  virtual ~DateTimeSection() {}

  // Overridden from views::Combobox::Listener:
  virtual void ItemChanged(views::Combobox* sender,
                           int prev_index,
                           int new_index);

 protected:
  // SettingsPageSection overrides:
  virtual void InitContents(GridLayout* layout);
  virtual void NotifyPrefChanged(const std::wstring* pref_name);

 private:
  // The combobox model for the list of timezones.
  class TimezoneComboboxModel : public ComboboxModel {
   public:
    TimezoneComboboxModel() {
      // TODO(chocobo): For now, add all the GMT timezones.
      // We may eventually want to use icu::TimeZone::createEnumeration()
      // to list all the timezones and pick the ones we want to show.
      // NOTE: This currently does not handle daylight savings properly
      // b/c this is just a manually selected list of timezones that
      // happen to span the GMT-11 to GMT+12 Today. When daylight savings
      // kick in, this list might have more than one timezone in the same
      // GMT bucket.
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("Pacific/Samoa")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("US/Hawaii")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("US/Alaska")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("US/Pacific")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("US/Mountain")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("US/Central")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("US/Eastern")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("America/Santiago")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("America/Sao_Paulo")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("Atlantic/South_Georgia")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("Atlantic/Cape_Verde")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("Europe/London")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("Europe/Rome")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("Europe/Helsinki")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("Europe/Moscow")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("Asia/Dubai")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("Asia/Karachi")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("Asia/Dhaka")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("Asia/Bangkok")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("Asia/Hong_Kong")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("Asia/Tokyo")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("Australia/Sydney")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("Asia/Magadan")));
      timezones_.push_back(icu::TimeZone::createTimeZone(
          icu::UnicodeString::fromUTF8("Pacific/Auckland")));
    }

    virtual ~TimezoneComboboxModel() {
      STLDeleteElements(&timezones_);
    }

    virtual int GetItemCount() {
      return static_cast<int>(timezones_.size());
    }

    virtual std::wstring GetItemAt(int index) {
      icu::UnicodeString name;
      timezones_[index]->getDisplayName(name);
      std::wstring output;
      UTF16ToWide(name.getBuffer(), name.length(), &output);
      int hour_offset = timezones_[index]->getRawOffset() / 3600000;
      return StringPrintf(hour_offset == 0 ? L"(GMT) " : (hour_offset > 0 ?
          L"(GMT+%d) " : L"(GMT%d) "), hour_offset) + output;
    }

    virtual std::wstring GetTimeZoneIDAt(int index) {
      icu::UnicodeString id;
      timezones_[index]->getID(id);
      std::wstring output;
      UTF16ToWide(id.getBuffer(), id.length(), &output);
      return output;
    }

   private:
    std::vector<icu::TimeZone*> timezones_;

    DISALLOW_COPY_AND_ASSIGN(TimezoneComboboxModel);
  };

  // Selects the timezone.
  void SelectTimeZone(const std::wstring& id);

  // TimeZone combobox model.
  views::Combobox* timezone_combobox_;

  // Controls for this section:
  TimezoneComboboxModel timezone_combobox_model_;

  // Preferences for this section:
  StringPrefMember timezone_;

  DISALLOW_COPY_AND_ASSIGN(DateTimeSection);
};

DateTimeSection::DateTimeSection(Profile* profile)
    : SettingsPageSection(profile, IDS_OPTIONS_SETTINGS_SECTION_TITLE_DATETIME),
      timezone_combobox_(NULL) {
}

void DateTimeSection::ItemChanged(views::Combobox* sender,
                                  int prev_index,
                                  int new_index) {
  if (new_index == prev_index)
    return;
  timezone_.SetValue(timezone_combobox_model_.GetTimeZoneIDAt(new_index));
}

void DateTimeSection::InitContents(GridLayout* layout) {
  timezone_combobox_ = new views::Combobox(&timezone_combobox_model_);
  timezone_combobox_->set_listener(this);

  layout->StartRow(0, double_column_view_set_id());
  layout->AddView(new views::Label(
      l10n_util::GetString(IDS_OPTIONS_SETTINGS_TIMEZONE_DESCRIPTION)));
  layout->AddView(timezone_combobox_);
  layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);

  // Init member prefs so we can update the controls if prefs change.
  timezone_.Init(prefs::kTimeZone, profile()->GetPrefs(), this);
}

void DateTimeSection::NotifyPrefChanged(const std::wstring* pref_name) {
  if (!pref_name || *pref_name == prefs::kTimeZone) {
    std::wstring timezone = timezone_.GetValue();
    SelectTimeZone(timezone);
  }
}

void DateTimeSection::SelectTimeZone(const std::wstring& id) {
  for (int i = 0; i < timezone_combobox_model_.GetItemCount(); i++) {
    if (timezone_combobox_model_.GetTimeZoneIDAt(i) == id) {
      timezone_combobox_->SetSelectedItem(i);
      return;
    }
  }
}

////////////////////////////////////////////////////////////////////////////////
// TouchpadSection

class TouchpadSection : public SettingsPageSection,
                        public views::ButtonListener,
                        public views::SliderListener {
 public:
  explicit TouchpadSection(Profile* profile);
  virtual ~TouchpadSection() {}

  // Overridden from views::ButtonListener:
  virtual void ButtonPressed(views::Button* sender, const views::Event& event);

  // Overridden from views::SliderListener:
  virtual void SliderValueChanged(views::Slider* sender);

 protected:
  // SettingsPageSection overrides:
  virtual void InitContents(GridLayout* layout);
  virtual void NotifyPrefChanged(const std::wstring* pref_name);

 private:
  // The View that contains the contents of the section.
  views::View* contents_;

  // Controls for this section:
  views::Checkbox* enable_tap_to_click_checkbox_;
  views::Checkbox* enable_vert_edge_scroll_checkbox_;
  views::Slider* speed_factor_slider_;
  views::Slider* sensitivity_slider_;

  // Preferences for this section:
  BooleanPrefMember tap_to_click_enabled_;
  BooleanPrefMember vert_edge_scroll_enabled_;
  IntegerPrefMember speed_factor_;
  IntegerPrefMember sensitivity_;

  DISALLOW_COPY_AND_ASSIGN(TouchpadSection);
};

TouchpadSection::TouchpadSection(Profile* profile)
    : SettingsPageSection(profile, IDS_OPTIONS_SETTINGS_SECTION_TITLE_TOUCHPAD),
      enable_tap_to_click_checkbox_(NULL),
      enable_vert_edge_scroll_checkbox_(NULL),
      speed_factor_slider_(NULL),
      sensitivity_slider_(NULL) {
}

void TouchpadSection::ButtonPressed(
    views::Button* sender, const views::Event& event) {
  if (sender == enable_tap_to_click_checkbox_) {
    bool enabled = enable_tap_to_click_checkbox_->checked();
    UserMetricsRecordAction(enabled ?
                                "Options_TapToClickCheckbox_Enable" :
                                "Options_TapToClickCheckbox_Disable",
                            profile()->GetPrefs());
    tap_to_click_enabled_.SetValue(enabled);
  } else if (sender == enable_vert_edge_scroll_checkbox_) {
    bool enabled = enable_vert_edge_scroll_checkbox_->checked();
    UserMetricsRecordAction(enabled ?
                                "Options_VertEdgeScrollCheckbox_Enable" :
                                "Options_VertEdgeScrollCheckbox_Disable",
                            profile()->GetPrefs());
    vert_edge_scroll_enabled_.SetValue(enabled);
  }
}

void TouchpadSection::SliderValueChanged(views::Slider* sender) {
  if (sender == speed_factor_slider_) {
    double value = speed_factor_slider_->value();
    UserMetricsRecordAction("Options_SpeedFactorSlider_Changed",
                            profile()->GetPrefs());
    speed_factor_.SetValue(value);
  } else if (sender == sensitivity_slider_) {
    double value = sensitivity_slider_->value();
    UserMetricsRecordAction("Options_SensitivitySlider_Changed",
                            profile()->GetPrefs());
    sensitivity_.SetValue(value);
  }
}

void TouchpadSection::InitContents(GridLayout* layout) {
  enable_tap_to_click_checkbox_ = new views::Checkbox(l10n_util::GetString(
      IDS_OPTIONS_SETTINGS_TAP_TO_CLICK_ENABLED_DESCRIPTION));
  enable_tap_to_click_checkbox_->set_listener(this);
  enable_tap_to_click_checkbox_->SetMultiLine(true);
  enable_vert_edge_scroll_checkbox_ = new views::Checkbox(l10n_util::GetString(
      IDS_OPTIONS_SETTINGS_VERT_EDGE_SCROLL_ENABLED_DESCRIPTION));
  enable_vert_edge_scroll_checkbox_->set_listener(this);
  enable_vert_edge_scroll_checkbox_->SetMultiLine(true);
  // Create speed factor slider with values between 1 and 10 step 1
  speed_factor_slider_ = new views::Slider(1, 10, 1,
      static_cast<views::Slider::StyleFlags>(
          views::Slider::STYLE_DRAW_VALUE |
          views::Slider::STYLE_UPDATE_ON_RELEASE),
      this);
  // Create sensitivity slider with values between 1 and 10 step 1
  sensitivity_slider_ = new views::Slider(1, 10, 1,
      static_cast<views::Slider::StyleFlags>(
          views::Slider::STYLE_DRAW_VALUE |
          views::Slider::STYLE_UPDATE_ON_RELEASE),
      this);

  layout->StartRow(0, double_column_view_set_id());
  layout->AddView(new views::Label(
      l10n_util::GetString(IDS_OPTIONS_SETTINGS_SENSITIVITY_DESCRIPTION)));
  layout->AddView(sensitivity_slider_);
  layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
  layout->StartRow(0, double_column_view_set_id());
  layout->AddView(new views::Label(
      l10n_util::GetString(IDS_OPTIONS_SETTINGS_SPEED_FACTOR_DESCRIPTION)));
  layout->AddView(speed_factor_slider_);
  layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
  layout->StartRow(0, single_column_view_set_id());
  layout->AddView(enable_tap_to_click_checkbox_);
  layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
  layout->StartRow(0, single_column_view_set_id());
  layout->AddView(enable_vert_edge_scroll_checkbox_);
  layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing);

  // Init member prefs so we can update the controls if prefs change.
  tap_to_click_enabled_.Init(prefs::kTapToClickEnabled,
                             profile()->GetPrefs(), this);
  vert_edge_scroll_enabled_.Init(prefs::kVertEdgeScrollEnabled,
                                 profile()->GetPrefs(), this);
  speed_factor_.Init(prefs::kTouchpadSpeedFactor,
                     profile()->GetPrefs(), this);
  sensitivity_.Init(prefs::kTouchpadSensitivity,
                    profile()->GetPrefs(), this);
}

void TouchpadSection::NotifyPrefChanged(const std::wstring* pref_name) {
  if (!pref_name || *pref_name == prefs::kTapToClickEnabled) {
    bool enabled =  tap_to_click_enabled_.GetValue();
    enable_tap_to_click_checkbox_->SetChecked(enabled);
  }
  if (!pref_name || *pref_name == prefs::kVertEdgeScrollEnabled) {
    bool enabled =  vert_edge_scroll_enabled_.GetValue();
    enable_vert_edge_scroll_checkbox_->SetChecked(enabled);
  }
  if (!pref_name || *pref_name == prefs::kTouchpadSpeedFactor) {
    double value =  speed_factor_.GetValue();
    speed_factor_slider_->SetValue(value);
  }
  if (!pref_name || *pref_name == prefs::kTouchpadSensitivity) {
    double value =  sensitivity_.GetValue();
    sensitivity_slider_->SetValue(value);
  }
}

////////////////////////////////////////////////////////////////////////////////
// LanguageSection

// TextInput section for text input settings.
class LanguageSection : public SettingsPageSection,
                        public views::ButtonListener {
 public:
  explicit LanguageSection(Profile* profile);
  virtual ~LanguageSection() {}

 private:
  // Overridden from SettingsPageSection:
  virtual void InitContents(GridLayout* layout);

  // Overridden from views::ButtonListener:
  virtual void ButtonPressed(views::Button* sender,
                             const views::Event& event);

  views::NativeButton* customize_languages_button_;

  DISALLOW_COPY_AND_ASSIGN(LanguageSection);
};

LanguageSection::LanguageSection(Profile* profile)
    : SettingsPageSection(profile,
                          IDS_OPTIONS_SETTINGS_SECTION_TITLE_LANGUAGE) {
}

void LanguageSection::InitContents(GridLayout* layout) {
  // Add the customize button.
  layout->StartRow(0, single_column_view_set_id());
  customize_languages_button_ = new views::NativeButton(
      this,
      l10n_util::GetString(IDS_OPTIONS_SETTINGS_LANGUAGES_CUSTOMIZE));
  layout->AddView(customize_languages_button_, 1, 1,
                  GridLayout::LEADING, GridLayout::CENTER);
}

void LanguageSection::ButtonPressed(
    views::Button* sender, const views::Event& event) {
  if (sender == customize_languages_button_) {
    views::Window* window = views::Window::CreateChromeWindow(
        NULL,
        gfx::Rect(),
        new LanguageConfigView());
    window->SetIsAlwaysOnTop(true);
    window->Show();
  }
}

////////////////////////////////////////////////////////////////////////////////
// SystemPageView

////////////////////////////////////////////////////////////////////////////////
// SystemPageView, SettingsPageView implementation:

void SystemPageView::InitControlLayout() {
  GridLayout* layout = CreatePanelGridLayout(this);
  SetLayoutManager(layout);

  int single_column_view_set_id = 0;
  ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id);
  column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
                        GridLayout::USE_PREF, 0, 0);

  layout->StartRow(0, single_column_view_set_id);
  layout->AddView(new DateTimeSection(profile()));
  layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
  layout->StartRow(0, single_column_view_set_id);
  layout->AddView(new TouchpadSection(profile()));
  layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
  layout->StartRow(0, single_column_view_set_id);
  layout->AddView(new LanguageSection(profile()));
  layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
}

}  // namespace chromeos
<|endoftext|>


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

#ifndef _CPPCANVAS_CANVASGRAPHIC_HXX
#define _CPPCANVAS_CANVASGRAPHIC_HXX

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

#ifndef BOOST_SHARED_PTR_HPP_INCLUDED
#include <boost/shared_ptr.hpp>
#endif

#ifndef _CPPCANVAS_COLOR_HXX
#include <cppcanvas/color.hxx>
#endif
#ifndef _CPPCANVAS_CANVAS_HXX
#include <cppcanvas/canvas.hxx>
#endif

namespace basegfx
{
    class B2DHomMatrix;
    class B2DPolyPolygon;
}

/* Definition of CanvasGraphic interface */

namespace cppcanvas
{
    // forward declaration, since PolyPolygon also derives from CanvasGraphic
    typedef ::boost::shared_ptr< class PolyPolygon > PolyPolygonSharedPtr;

    /** This interface defines basic properties of
        objects that can be painted on a Canvas
     */
    class CanvasGraphic
    {
    public:

        /** These enums determine how the primitive color is combined
            with the background. When performing this calculations, it
            is assumed that all color values are premultiplied with
            the corresponding alpha values (if no alpha is specified,
            1.0 is assumed). Then, the following general compositing
            operation is performed:

            C = Ca * Fa + Cb * Fb

            where C is the result color, Ca and Cb are the input
            colors, premultiplied with alpha, and Fa and Fb are
            described for the different composite modes (wherein Aa
            and Ab denote source and destination alpha, respectively).
        */
        enum CompositeOp
        {
            /// Clear destination. Fa = Fb = 0.
            CLEAR,

            /// Copy source as-is to destination. Fa = 1, Fb = 0.
            SOURCE,

            /// Leave destination as-is.  Fa = 0, Fb = 1.
            DESTINATION,

            /// Copy source over destination. Fa = 1, Fb = 1-Aa.
            OVER,

            /// Copy source under destination. Fa = 1-Ab, Fb = 1.
            UNDER,

            /// Copy source to destination, but limited to where the destination is. Fa = Ab, Fb = 0.
            INSIDE,

            /// Leave destination as is, but only where source was. Fa = 0, Fb = Aa.
            INSIDE_REVERSE,

            /// Copy source to destination, but limited to where destination is not. Fa = 1-Ab, Fb = 0.
            OUTSIDE,

            /// Leave destination as is, but only where source has not been. Fa = 0, Fb = 1-Aa.
            OUTSIDE_REVERSE,

            /// Copy source over destination, but only where destination is. Keep destination. Fa = Ab, Fb = 1-Aa.
            ATOP,

            /// Copy destination over source, but only where source is. Keep source. Fa = 1-Ab, Fb = Aa.
            ATOP_REVERSE,

            /// Take only parts where either source or destination, but not both are. Fa = 1-Ab, Fb = 1-Aa.
            XOR,

            /** simply add contributions of both source and destination. The
                resulting color values are limited to the permissible color
                range, and clipped to the maximal value, if exceeded. Fa = 1, Fb = 1.
            */
            ADD,

            /// Fa = min(1,(1-Ab)/Aa), Fb = 1
            SATURATE
        };

        virtual ~CanvasGraphic() {}

        /** Set object transformation matrix
         */
        virtual void                        setTransformation( const ::basegfx::B2DHomMatrix& rMatrix ) = 0;
        /** Get object transformation matrix
         */
        virtual ::basegfx::B2DHomMatrix     getTransformation() const = 0;

        /** Set object clipping polygon
         */
        virtual void                        setClip( const PolyPolygonSharedPtr& rClipPoly ) = 0;
        /** Get object clipping polygon
         */
        virtual PolyPolygonSharedPtr        getClip() const = 0;

        /** Set object color
         */
        virtual void                        setRGBAColor( Color::IntSRGBA ) = 0;
        /** Get object color
         */
        virtual Color::IntSRGBA             getRGBAColor() const = 0;

        /** Set object composite mode
         */
        virtual void                        setCompositeOp( CompositeOp aOp ) = 0;
        /** Get object composite mode
         */
        virtual CompositeOp                 getCompositeOp() const = 0;

        /** Render to parent canvas

            This method renders the content to the parent canvas,
            i.e. the canvas this object was constructed for.

            @return whether the rendering finished successfully.
         */
        virtual bool draw() const = 0;

    };

    typedef ::boost::shared_ptr< ::cppcanvas::CanvasGraphic > CanvasGraphicSharedPtr;
}

#endif /* _CPPCANVAS_CANVASGRAPHIC_HXX */
<commit_msg>INTEGRATION: CWS canvas02 (1.3.24); FILE MERGED 2005/10/09 09:08:04 thb 1.3.24.2: RESYNC: (1.3-1.4); FILE MERGED 2005/08/19 11:06:08 thb 1.3.24.1: #i53538# Changed clip setting to use basegfx polygon (cppcanvas::PolyPolygon contains reference back to canvas)<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: canvasgraphic.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: kz $ $Date: 2005-11-02 13:38:39 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _CPPCANVAS_CANVASGRAPHIC_HXX
#define _CPPCANVAS_CANVASGRAPHIC_HXX

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

#ifndef BOOST_SHARED_PTR_HPP_INCLUDED
#include <boost/shared_ptr.hpp>
#endif

#ifndef _CPPCANVAS_COLOR_HXX
#include <cppcanvas/color.hxx>
#endif
#ifndef _CPPCANVAS_CANVAS_HXX
#include <cppcanvas/canvas.hxx>
#endif

namespace basegfx
{
    class B2DHomMatrix;
    class B2DPolyPolygon;
}

/* Definition of CanvasGraphic interface */

namespace cppcanvas
{
    // forward declaration, since PolyPolygon also derives from CanvasGraphic
    typedef ::boost::shared_ptr< class PolyPolygon > PolyPolygonSharedPtr;

    /** This interface defines basic properties of
        objects that can be painted on a Canvas
     */
    class CanvasGraphic
    {
    public:

        /** These enums determine how the primitive color is combined
            with the background. When performing this calculations, it
            is assumed that all color values are premultiplied with
            the corresponding alpha values (if no alpha is specified,
            1.0 is assumed). Then, the following general compositing
            operation is performed:

            C = Ca * Fa + Cb * Fb

            where C is the result color, Ca and Cb are the input
            colors, premultiplied with alpha, and Fa and Fb are
            described for the different composite modes (wherein Aa
            and Ab denote source and destination alpha, respectively).
        */
        enum CompositeOp
        {
            /// Clear destination. Fa = Fb = 0.
            CLEAR,

            /// Copy source as-is to destination. Fa = 1, Fb = 0.
            SOURCE,

            /// Leave destination as-is.  Fa = 0, Fb = 1.
            DESTINATION,

            /// Copy source over destination. Fa = 1, Fb = 1-Aa.
            OVER,

            /// Copy source under destination. Fa = 1-Ab, Fb = 1.
            UNDER,

            /// Copy source to destination, but limited to where the destination is. Fa = Ab, Fb = 0.
            INSIDE,

            /// Leave destination as is, but only where source was. Fa = 0, Fb = Aa.
            INSIDE_REVERSE,

            /// Copy source to destination, but limited to where destination is not. Fa = 1-Ab, Fb = 0.
            OUTSIDE,

            /// Leave destination as is, but only where source has not been. Fa = 0, Fb = 1-Aa.
            OUTSIDE_REVERSE,

            /// Copy source over destination, but only where destination is. Keep destination. Fa = Ab, Fb = 1-Aa.
            ATOP,

            /// Copy destination over source, but only where source is. Keep source. Fa = 1-Ab, Fb = Aa.
            ATOP_REVERSE,

            /// Take only parts where either source or destination, but not both are. Fa = 1-Ab, Fb = 1-Aa.
            XOR,

            /** simply add contributions of both source and destination. The
                resulting color values are limited to the permissible color
                range, and clipped to the maximal value, if exceeded. Fa = 1, Fb = 1.
            */
            ADD,

            /// Fa = min(1,(1-Ab)/Aa), Fb = 1
            SATURATE
        };

        virtual ~CanvasGraphic() {}

        /** Set object transformation matrix
         */
        virtual void                        setTransformation( const ::basegfx::B2DHomMatrix& rMatrix ) = 0;
        /** Get object transformation matrix
         */
        virtual ::basegfx::B2DHomMatrix     getTransformation() const = 0;

        /** Set object clipping polygon
         */
        virtual void                        setClip( const ::basegfx::B2DPolyPolygon& rClipPoly ) = 0;
        /** Get object clipping polygon
         */
        virtual ::basegfx::B2DPolyPolygon   getClip() const = 0;

        /** Set object color
         */
        virtual void                        setRGBAColor( Color::IntSRGBA ) = 0;
        /** Get object color
         */
        virtual Color::IntSRGBA             getRGBAColor() const = 0;

        /** Set object composite mode
         */
        virtual void                        setCompositeOp( CompositeOp aOp ) = 0;
        /** Get object composite mode
         */
        virtual CompositeOp                 getCompositeOp() const = 0;

        /** Render to parent canvas

            This method renders the content to the parent canvas,
            i.e. the canvas this object was constructed for.

            @return whether the rendering finished successfully.
         */
        virtual bool draw() const = 0;

    };

    typedef ::boost::shared_ptr< ::cppcanvas::CanvasGraphic > CanvasGraphicSharedPtr;
}

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


<commit_before><commit_msg>Delimit: Fix compile error due to ambigious cast<commit_after><|endoftext|>


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

// A test harness for the implementation report of
//       the CSS2.1 Conformance Test Suite
// http://test.csswg.org/suites/css2.1/20110323/

#include <unistd.h>
#include <sys/wait.h>

#include <cstring>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

#include <boost/version.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/file_descriptor.hpp>

enum {
    INTERACTIVE,
    HEADLESS,
    REPORT,
    UPDATE
};

int processOutput(std::istream& stream, std::string& result)
{
    std::string output;
    bool completed = false;
    while (std::getline(stream, output)) {
        if (!completed) {
            if (output == "## complete")
                completed = true;
            continue;
        }
        if (output == "##")
            break;
        result += output + '\n';
    }
    return 0;
}

int runTest(int argc, char* argv[], std::string url, std::string& result)
{
    int pipefd[2];
    pipe(pipefd);

    pid_t pid = fork();
    if (pid == -1) {
        std::cerr << "error: no more process to create\n";
        return -1;
    }
    if (pid == 0) {
        close(1);
        dup(pipefd[1]);
        close(pipefd[0]);

        url = "http://localhost:8000/" + url;
        argv[argc - 1] = strdup(url.c_str());
        execvp(argv[0], argv);
        exit(EXIT_FAILURE);
    }
    close(pipefd[1]);

#if 104400 <= BOOST_VERSION
    boost::iostreams::stream<boost::iostreams::file_descriptor_source> stream(pipefd[0], boost::iostreams::close_handle);
#else
    boost::iostreams::stream<boost::iostreams::file_descriptor_source> stream(pipefd[0], true);
#endif
    processOutput(stream, result);
    return pid;
}

void killTest(int pid)
{
    int status;
    kill(pid, SIGTERM);
    if (wait(&status) == -1)
        std::cerr << "error: failed to wait for a test process to complete\n";
}

bool loadLog(const std::string& path, std::string& result, std::string& log)
{
    std::ifstream file(path.c_str());
    if (!file) {
        result = "?";
        return false;
    }
    std::string line;
    std::getline(file, line);
    size_t pos = line.find('\t');
    if (pos != std::string::npos)
        result = line.substr(pos + 1);
    else {
        result = "?";
        return false;
    }
    log.clear();
    while (std::getline(file, line))
        log += line + '\n';
    return true;
}

bool saveLog(const std::string& path, const std::string& url, const std::string& result, const std::string& log)
{
    std::ofstream file(path.c_str(), std::ios_base::out | std::ios_base::trunc);
    if (!file) {
        std::cerr << "error: failed to open the report file\n";
        return false;
    }
    file << "# " << url.c_str() << '\t' << result << '\n' << log;
    file.flush();
    file.close();
    return true;
}

int main(int argc, char* argv[])
{
    int mode = HEADLESS;

    int argi = 1;
    while (*argv[argi] == '-') {
        switch (argv[argi][1]) {
        case 'i':
            mode = INTERACTIVE;
            break;
        case 'r':
            mode = REPORT;
            break;
        case 'u':
            mode = UPDATE;
            break;
        default:
            break;
        }
        ++argi;
    }

    if (argc < argi + 2) {
        std::cout << "usage: " << argv[0] << " [-i] report.data command [argument ...]\n";
        return EXIT_FAILURE;
    }

    std::ifstream data(argv[argi]);
    if (!data) {
        std::cerr << "error: " << argv[argi] << ": no such file\n";
        return EXIT_FAILURE;
    }

    std::ofstream report("report.data", std::ios_base::out | std::ios_base::trunc);
    if (!report) {
        std::cerr << "error: failed to open the report file\n";
        return EXIT_FAILURE;
    }

    char* args[argc - argi + 1];
    for (int i = 2; i < argc; ++i)
        args[i - 2] = argv[i + argi - 1];
    args[argc - argi] = 0;

    std::string result;
    std::string url;
    std::string undo;
    bool redo = false;
    while (data) {
        if (result == "undo") {
            std::swap(url, undo);
            redo = true;
        } else if (redo) {
            std::swap(url, undo);
            redo = false;
        } else {
            std::string line;
            std::getline(data, line);
            if (line.empty() || line[0] == '#' || line == "testname    result  comment") {
                report << line << '\n';
                continue;
            }
            undo = url;
            std::stringstream s(line, std::stringstream::in);
            s >> url;
        }
        if (url.empty())
            continue;

        std::string path(url);
        size_t pos = path.rfind('.');
        if (pos != std::string::npos) {
            path.erase(pos);
            path += ".log";
        }
        std::string evaluation;
        std::string log;
        loadLog(path, evaluation, log);

        pid_t pid = -1;
        std::string output;
        switch (mode) {
        case REPORT:
            break;
        case UPDATE:
            if (evaluation[0] == '?')
                break;
            // FALL THROUGH
        default:
            pid = runTest(argc - argi, args, url, output);
            break;
        }

        if (0 < pid && output.empty())
            result = "fatal";
        else if (mode == INTERACTIVE) {
            std::cout << "## complete\n" << output;
            std::cout << '[' << url << "] ";
            if (evaluation.empty() || evaluation[0] == '?')
                std::cout << "pass? ";
            else {
                std::cout << evaluation << "? ";
                if (evaluation != "pass")
                    std::cout << '\a';
            }
            std::getline(std::cin, result);
            if (result.empty()) {
                if (evaluation.empty() || evaluation[0] == '?')
                    result = "pass";
                else
                    result = evaluation;
            } else if (result == "p" || result == "\x1b")
                result = "pass";
            else if (result == "f")
                result = "fail";
            else if (result == "i")
                result = "invalid";
            else if (result == "k") // keep
                result = evaluation;
            else if (result == "n")
                result = "na";
            else if (result == "s")
                result = "skip";
            else if (result == "u")
                result = "uncertain";
            else if (result == "q" || result == "quit")
                break;
            else if (result == "z")
                result = "undo";
            if (result != "undo" && !saveLog(path, url, result, output)) {
                std::cerr << "error: failed to open the report file\n";
                return EXIT_FAILURE;
            }
        } else if (mode == HEADLESS) {
            if (evaluation != "?" && output != log)
                result = "uncertain";
            else
                result = evaluation;
            std::cout << url << '\t' << result << '\n';
        } else if (mode == REPORT) {
            result = evaluation;
            std::cout << url << '\t' << result << '\n';
        } else if (mode == UPDATE) {
            result = evaluation;
            if (result[0] != '?') {
                if (!saveLog(path, url, result, output)) {
                    std::cerr << "error: failed to open the report file\n";
                    return EXIT_FAILURE;
                }
                std::cout << url << '\t' << result << '\n';
            }
        }

        if (0 < pid)
            killTest(pid);

        if (result != "undo")
            report << url << '\t' << result << '\n';
    }
    report.close();
}
<commit_msg>(harness) : Support #userstyle directive.<commit_after>/*
 * Copyright 2011, 2012 Esrille Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// A test harness for the implementation report of
//       the CSS2.1 Conformance Test Suite
// http://test.csswg.org/suites/css2.1/20110323/

#include <unistd.h>
#include <sys/wait.h>

#include <cstring>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

#include <boost/version.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/file_descriptor.hpp>

enum {
    INTERACTIVE,
    HEADLESS,
    REPORT,
    UPDATE
};

int processOutput(std::istream& stream, std::string& result)
{
    std::string output;
    bool completed = false;
    while (std::getline(stream, output)) {
        if (!completed) {
            if (output == "## complete")
                completed = true;
            continue;
        }
        if (output == "##")
            break;
        result += output + '\n';
    }
    return 0;
}

int runTest(int argc, char* argv[], std::string userStyle, std::string url, std::string& result)
{
    int pipefd[2];
    pipe(pipefd);

    pid_t pid = fork();
    if (pid == -1) {
        std::cerr << "error: no more process to create\n";
        return -1;
    }
    if (pid == 0) {
        close(1);
        dup(pipefd[1]);
        close(pipefd[0]);
        int argi = argc - 1;
        if (!userStyle.empty())
            argv[argi++] = strdup(userStyle.c_str());
        url = "http://localhost:8000/" + url;
        argv[argi++] = strdup(url.c_str());
        argv[argi] = 0;
        execvp(argv[0], argv);
        exit(EXIT_FAILURE);
    }
    close(pipefd[1]);

#if 104400 <= BOOST_VERSION
    boost::iostreams::stream<boost::iostreams::file_descriptor_source> stream(pipefd[0], boost::iostreams::close_handle);
#else
    boost::iostreams::stream<boost::iostreams::file_descriptor_source> stream(pipefd[0], true);
#endif
    processOutput(stream, result);
    return pid;
}

void killTest(int pid)
{
    int status;
    kill(pid, SIGTERM);
    if (wait(&status) == -1)
        std::cerr << "error: failed to wait for a test process to complete\n";
}

bool loadLog(const std::string& path, std::string& result, std::string& log)
{
    std::ifstream file(path.c_str());
    if (!file) {
        result = "?";
        return false;
    }
    std::string line;
    std::getline(file, line);
    size_t pos = line.find('\t');
    if (pos != std::string::npos)
        result = line.substr(pos + 1);
    else {
        result = "?";
        return false;
    }
    log.clear();
    while (std::getline(file, line))
        log += line + '\n';
    return true;
}

bool saveLog(const std::string& path, const std::string& url, const std::string& result, const std::string& log)
{
    std::ofstream file(path.c_str(), std::ios_base::out | std::ios_base::trunc);
    if (!file) {
        std::cerr << "error: failed to open the report file\n";
        return false;
    }
    file << "# " << url.c_str() << '\t' << result << '\n' << log;
    file.flush();
    file.close();
    return true;
}

int main(int argc, char* argv[])
{
    int mode = HEADLESS;

    int argi = 1;
    while (*argv[argi] == '-') {
        switch (argv[argi][1]) {
        case 'i':
            mode = INTERACTIVE;
            break;
        case 'r':
            mode = REPORT;
            break;
        case 'u':
            mode = UPDATE;
            break;
        default:
            break;
        }
        ++argi;
    }

    if (argc < argi + 2) {
        std::cout << "usage: " << argv[0] << " [-i] report.data command [argument ...]\n";
        return EXIT_FAILURE;
    }

    std::ifstream data(argv[argi]);
    if (!data) {
        std::cerr << "error: " << argv[argi] << ": no such file\n";
        return EXIT_FAILURE;
    }

    std::ofstream report("report.data", std::ios_base::out | std::ios_base::trunc);
    if (!report) {
        std::cerr << "error: failed to open the report file\n";
        return EXIT_FAILURE;
    }

    char* args[argc - argi + 2];
    for (int i = 2; i < argc; ++i)
        args[i - 2] = argv[i + argi - 1];
    args[argc - argi] = args[argc - argi + 1] = 0;

    std::string result;
    std::string url;
    std::string undo;
    std::string userStyle;
    bool redo = false;
    while (data) {
        if (result == "undo") {
            std::swap(url, undo);
            redo = true;
        } else if (redo) {
            std::swap(url, undo);
            redo = false;
        } else {
            std::string line;
            std::getline(data, line);
            if (line.empty() || line == "testname    result  comment") {
                report << line << '\n';
                continue;
            }
            if (line[0] == '#') {
                if (line.compare(1, 9, "userstyle") == 0) {
                    if (10 < line.length()) {
                        std::stringstream s(line.substr(10), std::stringstream::in);
                        s >> userStyle;
                    } else
                        userStyle.clear();
                }
                report << line << '\n';
                continue;
            }
            undo = url;
            std::stringstream s(line, std::stringstream::in);
            s >> url;
        }
        if (url.empty())
            continue;

        std::string path(url);
        size_t pos = path.rfind('.');
        if (pos != std::string::npos) {
            path.erase(pos);
            path += ".log";
        }
        std::string evaluation;
        std::string log;
        loadLog(path, evaluation, log);

        pid_t pid = -1;
        std::string output;
        switch (mode) {
        case REPORT:
            break;
        case UPDATE:
            if (evaluation[0] == '?')
                break;
            // FALL THROUGH
        default:
            pid = runTest(argc - argi, args, userStyle, url, output);
            break;
        }

        if (0 < pid && output.empty())
            result = "fatal";
        else if (mode == INTERACTIVE) {
            std::cout << "## complete\n" << output;
            std::cout << '[' << url << "] ";
            if (evaluation.empty() || evaluation[0] == '?')
                std::cout << "pass? ";
            else {
                std::cout << evaluation << "? ";
                if (evaluation != "pass")
                    std::cout << '\a';
            }
            std::getline(std::cin, result);
            if (result.empty()) {
                if (evaluation.empty() || evaluation[0] == '?')
                    result = "pass";
                else
                    result = evaluation;
            } else if (result == "p" || result == "\x1b")
                result = "pass";
            else if (result == "f")
                result = "fail";
            else if (result == "i")
                result = "invalid";
            else if (result == "k") // keep
                result = evaluation;
            else if (result == "n")
                result = "na";
            else if (result == "s")
                result = "skip";
            else if (result == "u")
                result = "uncertain";
            else if (result == "q" || result == "quit")
                break;
            else if (result == "z")
                result = "undo";
            if (result != "undo" && !saveLog(path, url, result, output)) {
                std::cerr << "error: failed to open the report file\n";
                return EXIT_FAILURE;
            }
        } else if (mode == HEADLESS) {
            if (evaluation != "?" && output != log)
                result = "uncertain";
            else
                result = evaluation;
            std::cout << url << '\t' << result << '\n';
        } else if (mode == REPORT) {
            result = evaluation;
            std::cout << url << '\t' << result << '\n';
        } else if (mode == UPDATE) {
            result = evaluation;
            if (result[0] != '?') {
                if (!saveLog(path, url, result, output)) {
                    std::cerr << "error: failed to open the report file\n";
                    return EXIT_FAILURE;
                }
                std::cout << url << '\t' << result << '\n';
            }
        }

        if (0 < pid)
            killTest(pid);

        if (result != "undo")
            report << url << '\t' << result << '\n';
    }
    report.close();
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2017 Couchbase, Inc
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

/*
 * Unit tests for the ExecutorPool class
 */

#include "executorpool_test.h"

class LambdaTask : public GlobalTask {
public:
    LambdaTask(Taskable& t,
               TaskId taskId,
               double sleeptime,
               bool completeBeforeShutdown,
               std::function<bool()> f)
        : GlobalTask(t, taskId, sleeptime, completeBeforeShutdown), func(f) {
    }

    bool run() override {
        return func();
    }

    std::string getDescription(void) override {
        return "Lambda Task";
    }

protected:
    std::function<bool()> func;
};

MockTaskable::MockTaskable() : policy(HIGH_BUCKET_PRIORITY, 1) {
}

const std::string& MockTaskable::getName() const {
    return name;
}

task_gid_t MockTaskable::getGID() const {
    return 0;
}

bucket_priority_t MockTaskable::getWorkloadPriority() const {
    return HIGH_BUCKET_PRIORITY;
}

void MockTaskable::setWorkloadPriority(bucket_priority_t prio) {
}

WorkLoadPolicy& MockTaskable::getWorkLoadPolicy(void) {
    return policy;
}

void MockTaskable::logQTime(TaskId id, const ProcessClock::duration enqTime) {
}

void MockTaskable::logRunTime(TaskId id, const ProcessClock::duration runTime) {
}

ExTask makeTask(Taskable& taskable, ThreadGate& tg, size_t i) {
    return new LambdaTask(taskable, TaskId::StatSnap, 0, true, [&]() -> bool {
        tg.threadUp();
        return false;
    });
}

TEST_F(ExecutorPoolTest, register_taskable_test) {
    TestExecutorPool pool(10, // MaxThreads
                          NUM_TASK_GROUPS,
                          2, // MaxNumReaders
                          2, // MaxNumWriters
                          2, // MaxNumAuxio
                          2 // MaxNumNonio
                          );

    MockTaskable taskable;
    MockTaskable taskable2;

    ASSERT_EQ(0, pool.getNumWorkersStat());
    ASSERT_EQ(0, pool.getNumBuckets());

    pool.registerTaskable(taskable);

    ASSERT_EQ(8, pool.getNumWorkersStat());
    ASSERT_EQ(1, pool.getNumBuckets());

    pool.registerTaskable(taskable2);

    ASSERT_EQ(8, pool.getNumWorkersStat());
    ASSERT_EQ(2, pool.getNumBuckets());

    pool.unregisterTaskable(taskable2, false);

    ASSERT_EQ(8, pool.getNumWorkersStat());
    ASSERT_EQ(1, pool.getNumBuckets());

    pool.unregisterTaskable(taskable, false);

    ASSERT_EQ(0, pool.getNumWorkersStat());
    ASSERT_EQ(0, pool.getNumBuckets());
}

TEST_F(ExecutorPoolDynamicWorkerTest, decrease_workers) {
    EXPECT_EQ(2, pool->getNumWriters());
    /* Will take ~2s (MIN_SLEEP_TIME while the thread being removed sleeps
     * (having found no work) and we wait to join it.
     */
    pool->setMaxWriters(1);
    EXPECT_EQ(1, pool->getNumWriters());
}

TEST_P(ExecutorPoolTestWithParam, max_threads_test_parameterized) {
    ExpectedThreadCounts expected = GetParam();

    MockTaskable taskable;

    TestExecutorPool pool(expected.maxThreads, // MaxThreads
                          NUM_TASK_GROUPS,
                          0, // MaxNumReaders (0 = use default)
                          0, // MaxNumWriters
                          0, // MaxNumAuxio
                          0 // MaxNumNonio
                          );

    pool.registerTaskable(taskable);

    EXPECT_EQ(expected.reader, pool.getNumReaders());
    EXPECT_EQ(expected.writer, pool.getNumWriters());
    EXPECT_EQ(expected.auxIO, pool.getNumAuxIO());
    EXPECT_EQ(expected.nonIO, pool.getNumNonIO());

    pool.unregisterTaskable(taskable, false);
    pool.shutdown();
}

std::vector<ExpectedThreadCounts> threadCountValues = {{1, 4, 4, 1, 2},
                                                       {2, 4, 4, 1, 2},
                                                       {4, 4, 4, 1, 2},
                                                       {8, 4, 4, 1, 2},
                                                       {10, 4, 4, 1, 3},
                                                       {14, 4, 4, 2, 4},
                                                       {20, 6, 4, 2, 6},
                                                       {24, 7, 4, 3, 7},
                                                       {32, 12, 4, 4, 8},
                                                       {48, 12, 4, 5, 8},
                                                       {64, 12, 4, 7, 8},
                                                       {128, 12, 4, 8, 8}};

INSTANTIATE_TEST_CASE_P(ThreadCountTest,
                        ExecutorPoolTestWithParam,
                        ::testing::ValuesIn(threadCountValues),
                        ::testing::PrintToStringParamName());<commit_msg>MB-22041 [5/N]: Test that workers can be increased<commit_after>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2017 Couchbase, Inc
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

/*
 * Unit tests for the ExecutorPool class
 */

#include "executorpool_test.h"

class LambdaTask : public GlobalTask {
public:
    LambdaTask(Taskable& t,
               TaskId taskId,
               double sleeptime,
               bool completeBeforeShutdown,
               std::function<bool()> f)
        : GlobalTask(t, taskId, sleeptime, completeBeforeShutdown), func(f) {
    }

    bool run() override {
        return func();
    }

    std::string getDescription(void) override {
        return "Lambda Task";
    }

protected:
    std::function<bool()> func;
};

MockTaskable::MockTaskable() : policy(HIGH_BUCKET_PRIORITY, 1) {
}

const std::string& MockTaskable::getName() const {
    return name;
}

task_gid_t MockTaskable::getGID() const {
    return 0;
}

bucket_priority_t MockTaskable::getWorkloadPriority() const {
    return HIGH_BUCKET_PRIORITY;
}

void MockTaskable::setWorkloadPriority(bucket_priority_t prio) {
}

WorkLoadPolicy& MockTaskable::getWorkLoadPolicy(void) {
    return policy;
}

void MockTaskable::logQTime(TaskId id, const ProcessClock::duration enqTime) {
}

void MockTaskable::logRunTime(TaskId id, const ProcessClock::duration runTime) {
}

ExTask makeTask(Taskable& taskable, ThreadGate& tg, size_t i) {
    return new LambdaTask(taskable, TaskId::StatSnap, 0, true, [&]() -> bool {
        tg.threadUp();
        return false;
    });
}

TEST_F(ExecutorPoolTest, register_taskable_test) {
    TestExecutorPool pool(10, // MaxThreads
                          NUM_TASK_GROUPS,
                          2, // MaxNumReaders
                          2, // MaxNumWriters
                          2, // MaxNumAuxio
                          2 // MaxNumNonio
                          );

    MockTaskable taskable;
    MockTaskable taskable2;

    ASSERT_EQ(0, pool.getNumWorkersStat());
    ASSERT_EQ(0, pool.getNumBuckets());

    pool.registerTaskable(taskable);

    ASSERT_EQ(8, pool.getNumWorkersStat());
    ASSERT_EQ(1, pool.getNumBuckets());

    pool.registerTaskable(taskable2);

    ASSERT_EQ(8, pool.getNumWorkersStat());
    ASSERT_EQ(2, pool.getNumBuckets());

    pool.unregisterTaskable(taskable2, false);

    ASSERT_EQ(8, pool.getNumWorkersStat());
    ASSERT_EQ(1, pool.getNumBuckets());

    pool.unregisterTaskable(taskable, false);

    ASSERT_EQ(0, pool.getNumWorkersStat());
    ASSERT_EQ(0, pool.getNumBuckets());
}

/* This test creates an ExecutorPool, and attempts to verify that calls to
 * setMaxWriters are able to dynamically create more workers than were present
 * at initialisation. A ThreadGate is used to confirm that two tasks
 * of type WRITER_TASK_IDX can run concurrently
 *
 */
TEST_F(ExecutorPoolTest, increase_workers) {
    const size_t numReaders = 1;
    const size_t numWriters = 1;
    const size_t numAuxIO = 1;
    const size_t numNonIO = 1;

    const size_t originalWorkers =
            numReaders + numWriters + numAuxIO + numNonIO;

    // This will allow us to check that numWriters + 1 writer tasks can run
    // concurrently after setMaxWriters has been called.
    ThreadGate tg{numWriters + 1};

    TestExecutorPool pool(5, // MaxThreads
                          NUM_TASK_GROUPS,
                          numReaders,
                          numWriters,
                          numAuxIO,
                          numNonIO);

    MockTaskable taskable;
    pool.registerTaskable(taskable);

    std::vector<ExTask> tasks;

    for (size_t i = 0; i < numWriters + 1; ++i) {
        ExTask task = makeTask(taskable, tg, i);
        pool.schedule(task, WRITER_TASK_IDX);
        tasks.push_back(task);
    }

    EXPECT_EQ(numWriters, pool.getNumWriters());
    ASSERT_EQ(originalWorkers, pool.getNumWorkersStat());

    pool.setMaxWriters(numWriters + 1);

    EXPECT_EQ(numWriters + 1, pool.getNumWriters());
    ASSERT_EQ(originalWorkers + 1, pool.getNumWorkersStat());

    tg.waitFor(std::chrono::seconds(10));
    EXPECT_TRUE(tg.isComplete()) << "Timeout waiting for threads to run";

    pool.unregisterTaskable(taskable, false);
}

TEST_F(ExecutorPoolDynamicWorkerTest, decrease_workers) {
    EXPECT_EQ(2, pool->getNumWriters());
    /* Will take ~2s (MIN_SLEEP_TIME while the thread being removed sleeps
     * (having found no work) and we wait to join it.
     */
    pool->setMaxWriters(1);
    EXPECT_EQ(1, pool->getNumWriters());
}

TEST_P(ExecutorPoolTestWithParam, max_threads_test_parameterized) {
    ExpectedThreadCounts expected = GetParam();

    MockTaskable taskable;

    TestExecutorPool pool(expected.maxThreads, // MaxThreads
                          NUM_TASK_GROUPS,
                          0, // MaxNumReaders (0 = use default)
                          0, // MaxNumWriters
                          0, // MaxNumAuxio
                          0 // MaxNumNonio
                          );

    pool.registerTaskable(taskable);

    EXPECT_EQ(expected.reader, pool.getNumReaders());
    EXPECT_EQ(expected.writer, pool.getNumWriters());
    EXPECT_EQ(expected.auxIO, pool.getNumAuxIO());
    EXPECT_EQ(expected.nonIO, pool.getNumNonIO());

    pool.unregisterTaskable(taskable, false);
    pool.shutdown();
}

std::vector<ExpectedThreadCounts> threadCountValues = {{1, 4, 4, 1, 2},
                                                       {2, 4, 4, 1, 2},
                                                       {4, 4, 4, 1, 2},
                                                       {8, 4, 4, 1, 2},
                                                       {10, 4, 4, 1, 3},
                                                       {14, 4, 4, 2, 4},
                                                       {20, 6, 4, 2, 6},
                                                       {24, 7, 4, 3, 7},
                                                       {32, 12, 4, 4, 8},
                                                       {48, 12, 4, 5, 8},
                                                       {64, 12, 4, 7, 8},
                                                       {128, 12, 4, 8, 8}};

INSTANTIATE_TEST_CASE_P(ThreadCountTest,
                        ExecutorPoolTestWithParam,
                        ::testing::ValuesIn(threadCountValues),
                        ::testing::PrintToStringParamName());<|endoftext|>


<commit_before>/* Nom: main.cpp
 * Description: Sous-système de contrôle: responsable de la gestion du dialogue avec l'utilisateur et de l'interface graphique
 * Date: 07.03.2015
 * version : 1.1
 * auteur : PROG II
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "error.h"
#include "sim.h"
#include "main.h"

enum Mode {ERROR, FORCE, INTEGRATION, GRAPHIC, SIMULATION};

int main (int argc, char *argv[])
{
	enum Mode mode;
    read_mode(&mode, argv[1]);

	if(argc!=3)
	{
		//sim.x [Error|Force|Integration|Graphic|Simulation,nom_fichier]; pas encore vraiment compris ce que je dois faire
	}
	else
	{
		switch(mode)
		{
			case ERROR: sim_error(argv[2]);
			break;
			case FORCE: sim_force(argv[2]);
			break;
			case INTEGRATION: sim_integration(argv[2]);
			break;
			case GRAPHIC: sim_graphic(argv[2]);
			break;
			case SIMULATION: sim_simulation(argv[2]);
			break;
		}
	}
	return EXIT_SUCCESS;
}

void read_mode(Mode* mode, char *argv[])
{
	if(strcmp(argv[1], "Error" ) == 0)
    {
		*mode = ERROR;
    }
    else if (strcmp(argv[1], "Force" ) == 0)
    {
		*mode = FORCE;
    }
    else if (strcmp(argv[1], "Integration" ) == 0)
    {
		*mode = INTEGRATION;
    }
    else if (strcmp(argv[1], "Graphic" ) == 0)
    {
		*mode = GRAPHIC;
    }
    else if (strcmp(argv[1], "Simulation" ) == 0)
    {
		*mode = SIMULATION;
    }
}

<commit_msg>in main.cpp toujours problème avec pointeur de enum<commit_after>/* Nom: main.cpp
 * Description: Sous-système de contrôle: responsable de la gestion du dialogue avec l'utilisateur et de l'interface graphique
 * Date: 07.03.2015
 * version : 1.1
 * auteur : PROG II
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "error.h"
#include "sim.h"
#include "main.h"

enum Mode {ERROR, FORCE, INTEGRATION, GRAPHIC, SIMULATION};

int main (int argc, char *argv[])
{
	enum Mode mode;
    read_mode(&mode, argv[1]);  //régler problème du pointeur sur énumération....

	if(argc!=3)
	{
		//sim.x [Error|Force|Integration|Graphic|Simulation,nom_fichier]; pas encore vraiment compris ceque je dois faire
	}
	else
	{
		switch(mode)
		{
			case ERROR: sim_error(argv[2]);
			break;
			case FORCE: sim_force(argv[2]);
			break;
			case INTEGRATION: sim_integration(argv[2]);
			break;
			case GRAPHIC: sim_graphic(argv[2]);
			break;
			case SIMULATION: sim_simulation(argv[2]);
			break;
		}
	}
	return EXIT_SUCCESS;
}

void read_mode(Mode* mode, char *argv[])
{
	if(strcmp(argv[1], "Error" ) == 0)
    {
		*mode = ERROR;
    }
    else if (strcmp(argv[1], "Force" ) == 0)
    {
		*mode = FORCE;
    }
    else if (strcmp(argv[1], "Integration" ) == 0)
    {
		*mode = INTEGRATION;
    }
    else if (strcmp(argv[1], "Graphic" ) == 0)
    {
		*mode = GRAPHIC;
    }
    else if (strcmp(argv[1], "Simulation" ) == 0)
    {
		*mode = SIMULATION;
    }
}

<|endoftext|>


<commit_before><commit_msg>Fix syntax of comments<commit_after><|endoftext|>


<commit_before>// bdls_processutil.cpp                                               -*-C++-*-

// ----------------------------------------------------------------------------
//                                   NOTICE
//
// This component is not up to date with current BDE coding standards, and
// should not be used as an example for new development.
// ----------------------------------------------------------------------------

#include <bdls_processutil.h>

#include <bsls_ident.h>
BSLS_IDENT_RCSID(bdls_processutil_cpp,"$Id$ $CSID$")

#include <bdlsb_memoutstreambuf.h>
#include <bdls_fdstreambuf.h>

#include <bsls_assert.h>
#include <bsls_platform.h>

#include <bsl_iostream.h>

#ifdef BSLS_PLATFORM_OS_WINDOWS
#include <windows.h>
#else
#include <unistd.h>
#endif

#if defined(BSLS_PLATFORM_OS_SOLARIS)
#include <procfs.h>
#include <fcntl.h>
#elif defined(BSLS_PLATFORM_OS_AIX)
#include <sys/procfs.h>
#include <fcntl.h>
#elif defined(BSLS_PLATFORM_OS_LINUX) || defined(BSLS_PLATFORM_OS_CYGWIN)
#include <fcntl.h>
#elif defined(BSLS_PLATFORM_OS_HPUX)
#include <sys/pstat.h>
#elif defined(BSLS_PLATFORM_OS_DARWIN)
#include <libproc.h>
#endif

namespace BloombergLP {

namespace bdls {
                             // ------------------
                             // struct ProcessUtil
                             // ------------------

// CLASS METHODS
int ProcessUtil::getProcessId() {
#ifdef BSLS_PLATFORM_OS_WINDOWS
    return static_cast<int>(GetCurrentProcessId());
#else
    return static_cast<int>(getpid());
#endif
}

int ProcessUtil::getProcessName(bsl::string *result)
{
    BSLS_ASSERT(result);

    result->clear();

#if defined BSLS_PLATFORM_OS_WINDOWS
    int  rc = 0;

    result->resize(MAX_PATH);
    DWORD length = GetModuleFileName(0, &(*result->begin()), result->size());
    if (length > 0) {
        result->resize(length);
    }

    return length <= 0;
#else
# if defined BSLS_PLATFORM_OS_HPUX
    result->resize(256);
    int rc = pstat_getcommandline(&(*result->begin()),
                                  result->size(), 1,
                                  getpid());
    if (rc < 0)
    {
        return -1;
    }

    bsl::string::size_type pos = result->find_first_of(' ');
    if (bsl::string::npos != pos) {
        result->resize(pos);
    }
# elif defined BSLS_PLATFORM_OS_LINUX || defined BSLS_PLATFORM_OS_CYGWIN
    enum { NUM_ELEMENTS = 14 + 16 };  // "/proc/<pid>/cmdline"

    bdlsb::MemOutStreamBuf osb(NUM_ELEMENTS);
    bsl::ostream          os(&osb);
    os << "/proc/" << getpid() << "/cmdline" << bsl::ends;
    const char *procfs = osb.data();

    int fd = open(procfs, O_RDONLY);
    if (fd == -1) {
        return -1;                                                    // RETURN
    }

    FdStreamBuf isb(fd, true, true, true);
    bsl::istream      is(&isb);
    is >> *result;

    bsl::string::size_type pos = result->find_first_of('\0');
    if (bsl::string::npos != pos) {
        result->resize(pos);
    }
# elif defined BSLS_PLATFORM_OS_DARWIN
    char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
    if (proc_pidpath (getpid(), pathbuf, sizeof(pathbuf)) <= 0) {
        return -1;
    }
    result->assign(pathbuf);
# else
#  if defined BSLS_PLATFORM_OS_AIX
    enum { NUM_ELEMENTS = 14 + 16 };  // "/proc/<pid>/psinfo"

    bdlsb::MemOutStreamBuf osb(NUM_ELEMENTS);
    bsl::ostream          os(&osb);
    os << "/proc/" << getpid() << "/psinfo" << bsl::ends;
    const char *procfs = osb.data();
#  else
    const char *procfs = "/proc/self/psinfo";
#  endif
    int fd = open(procfs, O_RDONLY);
    if (fd == -1) {
        return -1;
    }

    psinfo_t psinfo;
    bool readFailed = (sizeof psinfo != read(fd, &psinfo, sizeof psinfo));

    int rc = close(fd);
    if (readFailed || 0 != rc) {
        return -1;
    }

    result->assign(psinfo.pr_psargs);

    bsl::string::size_type pos = result->find_first_of(' ');
    if (bsl::string::npos != pos) {
        result->resize(pos);
    }
# endif
#endif
    return result->empty();
}
}  // close package namespace

}  // close enterprise namespace

// ----------------------------------------------------------------------------
// Copyright 2015 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------
<commit_msg>Publish master to opensource<commit_after>// bdls_processutil.cpp                                               -*-C++-*-

// ----------------------------------------------------------------------------
//                                   NOTICE
//
// This component is not up to date with current BDE coding standards, and
// should not be used as an example for new development.
// ----------------------------------------------------------------------------

#include <bdls_processutil.h>

#include <bsls_ident.h>
BSLS_IDENT_RCSID(bdls_processutil_cpp,"$Id$ $CSID$")

#include <bdlsb_memoutstreambuf.h>

#include <bsls_assert.h>
#include <bsls_platform.h>

#include <bsl_iostream.h>
#include <bsl_fstream.h>

#ifdef BSLS_PLATFORM_OS_WINDOWS
#include <windows.h>
#else
#include <unistd.h>
#endif

#if defined(BSLS_PLATFORM_OS_SOLARIS)
#include <procfs.h>
#include <fcntl.h>
#elif defined(BSLS_PLATFORM_OS_AIX)
#include <sys/procfs.h>
#include <fcntl.h>
#elif defined(BSLS_PLATFORM_OS_LINUX) || defined(BSLS_PLATFORM_OS_CYGWIN)
#include <fcntl.h>
#elif defined(BSLS_PLATFORM_OS_HPUX)
#include <sys/pstat.h>
#elif defined(BSLS_PLATFORM_OS_DARWIN)
#include <libproc.h>
#endif

namespace BloombergLP {

namespace bdls {
                             // ------------------
                             // struct ProcessUtil
                             // ------------------

// CLASS METHODS
int ProcessUtil::getProcessId() {
#ifdef BSLS_PLATFORM_OS_WINDOWS
    return static_cast<int>(GetCurrentProcessId());
#else
    return static_cast<int>(getpid());
#endif
}

int ProcessUtil::getProcessName(bsl::string *result)
{
    BSLS_ASSERT(result);

    result->clear();

#if defined BSLS_PLATFORM_OS_WINDOWS
    int  rc = 0;

    result->resize(MAX_PATH);
    DWORD length = GetModuleFileName(0, &(*result->begin()), result->size());
    if (length > 0) {
        result->resize(length);
    }

    return length <= 0;
#else
# if defined BSLS_PLATFORM_OS_HPUX
    result->resize(256);
    int rc = pstat_getcommandline(&(*result->begin()),
                                  result->size(), 1,
                                  getpid());
    if (rc < 0)
    {
        return -1;
    }

    bsl::string::size_type pos = result->find_first_of(' ');
    if (bsl::string::npos != pos) {
        result->resize(pos);
    }
# elif defined BSLS_PLATFORM_OS_LINUX || defined BSLS_PLATFORM_OS_CYGWIN
    enum { NUM_ELEMENTS = 14 + 16 };  // "/proc/<pid>/cmdline"

    bdlsb::MemOutStreamBuf osb(NUM_ELEMENTS);
    bsl::ostream          os(&osb);
    os << "/proc/" << getpid() << "/cmdline" << bsl::ends;
    const char *procfs = osb.data();

    bsl::ifstream ifs;
    ifs.open(procfs, bsl::ios_base::in | bsl::ios_base::binary);

    if (ifs.fail()) {
        return -1;                                                    // RETURN
    }

    ifs >> *result;

    bsl::string::size_type pos = result->find_first_of('\0');
    if (bsl::string::npos != pos) {
        result->resize(pos);
    }
# elif defined BSLS_PLATFORM_OS_DARWIN
    char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
    if (proc_pidpath (getpid(), pathbuf, sizeof(pathbuf)) <= 0) {
        return -1;
    }
    result->assign(pathbuf);
# else
#  if defined BSLS_PLATFORM_OS_AIX
    enum { NUM_ELEMENTS = 14 + 16 };  // "/proc/<pid>/psinfo"

    bdlsb::MemOutStreamBuf osb(NUM_ELEMENTS);
    bsl::ostream          os(&osb);
    os << "/proc/" << getpid() << "/psinfo" << bsl::ends;
    const char *procfs = osb.data();
#  else
    const char *procfs = "/proc/self/psinfo";
#  endif
    int fd = open(procfs, O_RDONLY);
    if (fd == -1) {
        return -1;
    }

    psinfo_t psinfo;
    bool readFailed = (sizeof psinfo != read(fd, &psinfo, sizeof psinfo));

    int rc = close(fd);
    if (readFailed || 0 != rc) {
        return -1;
    }

    result->assign(psinfo.pr_psargs);

    bsl::string::size_type pos = result->find_first_of(' ');
    if (bsl::string::npos != pos) {
        result->resize(pos);
    }
# endif
#endif
    return result->empty();
}
}  // close package namespace

}  // close enterprise namespace

// ----------------------------------------------------------------------------
// Copyright 2015 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------
<|endoftext|>


<commit_before>// Adobe Leaked Email Chcker
// Date: December 2013
// Author: Jervis Muindi

// Standard Lib Header
#include <iostream>

// Custom Common Code
#include "common/base/flags.h"
#include "common/base/init.h"
#include "common/log/log.h"
#include "common/test/test.h"

#include "alec.h"

TEST(Alec, DummyTest) {
  EXPECT_TRUE( 1 == 2) << "I should fail";
}

int main(int argc, char **argv) {
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<commit_msg>make dummy test pass<commit_after>// Adobe Leaked Email Chcker
// Date: December 2013
// Author: Jervis Muindi

// Standard Lib Header
#include <iostream>

// Custom Common Code
#include "common/base/flags.h"
#include "common/base/init.h"
#include "common/log/log.h"
#include "common/test/test.h"

#include "alec.h"

TEST(Alec, DummyTest) {
  EXPECT_TRUE( 1 == 1) << "I should fail";
}

int main(int argc, char **argv) {
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>#ifndef GLM_FORCE_RADIANS
#define GLM_FORCE_RADIANS
#define DEGREES_TO_RADIANS(x) (x * PI / 180.0f)
#endif

#ifndef RADIANS_TO_DEGREES
#define RADIANS_TO_DEGREES(x) (x * 180.0f / PI)
#endif

#include "camera.hpp"
#include "scene.hpp"
#include "ground_level.hpp"
#include "code/ylikuutio/hierarchy/hierarchy_templates.hpp"

// Include GLM
#ifndef __GLM_GLM_HPP_INCLUDED
#define __GLM_GLM_HPP_INCLUDED
#include <glm/glm.hpp> // glm
#endif

#ifndef __GLM_GTC_MATRIX_TRANSFORM_HPP_INCLUDED
#define __GLM_GTC_MATRIX_TRANSFORM_HPP_INCLUDED
#include <glm/gtc/matrix_transform.hpp>
#endif

namespace yli
{
    namespace ontology
    {
        void Camera::bind_to_parent()
        {
            // get `childID` from `Scene` and set pointer to this `Camera`.
            this->parent->bind_camera(this);
        }

        Camera::~Camera()
        {
            // destructor.

            if (this->parent->get_active_camera() == this)
            {
                // Make this `Camera` no more the active `Camera`.
                this->parent->set_active_camera(nullptr);
            }

            // set pointer to this `Camera` to `nullptr`.
            this->parent->set_camera_pointer(this->childID, nullptr);
        }

        yli::ontology::Entity* Camera::get_parent() const
        {
            return this->parent;
        }

        int32_t Camera::get_number_of_children() const
        {
            return 0;
        }

        int32_t Camera::get_number_of_descendants() const
        {
            return 0;
        }

        glm::mat4& Camera::get_projection_matrix()
        {
            return this->projection_matrix;
        }

        glm::mat4& Camera::get_view_matrix()
        {
            return this->view_matrix;
        }

        float Camera::get_horizontal_angle() const
        {
            return this->horizontal_angle;
        }

        float Camera::get_vertical_angle() const
        {
            return this->vertical_angle;
        }

        bool Camera::compute_and_update_matrices_from_inputs()
        {
            if (!this->universe->is_flight_mode_in_use)
            {
                this->universe->fall_speed += this->universe->gravity;
                this->cartesian_coordinates.y -= this->universe->fall_speed;
            }

            GLfloat FoV = this->universe->get_initialFoV();

            // adjust position according to the ground.
            if (!this->universe->is_flight_mode_in_use)
            {
                if (this->universe->get_terrain_species() != nullptr)
                {
                    GLfloat ground_y = yli::ontology::get_floor_level(
                            static_cast<yli::ontology::Species*>(this->universe->get_terrain_species()),
                            this->cartesian_coordinates);

                    if (!std::isnan(ground_y) && this->cartesian_coordinates.y < ground_y)
                    {
                        this->cartesian_coordinates.y = ground_y;
                        this->universe->fall_speed = 0.0f;
                    }
                }
            }

            if (this->universe->testing_spherical_terrain_in_use)
            {
                // compute spherical coordinates.
                this->spherical_coordinates.rho = sqrt(
                        (this->cartesian_coordinates.x * this->cartesian_coordinates.x) +
                        (this->cartesian_coordinates.y * this->cartesian_coordinates.y) +
                        (this->cartesian_coordinates.z * this->cartesian_coordinates.z));
                this->spherical_coordinates.theta = RADIANS_TO_DEGREES(atan2(sqrt(
                                (this->cartesian_coordinates.x * this->cartesian_coordinates.x) +
                                (this->cartesian_coordinates.y * this->cartesian_coordinates.y)),
                            this->cartesian_coordinates.z));
                this->spherical_coordinates.phi = RADIANS_TO_DEGREES(atan2(
                            this->cartesian_coordinates.y,
                            this->cartesian_coordinates.x));
            }

            glm::vec3 camera_cartesian_coordinates;
            camera_cartesian_coordinates.x = this->cartesian_coordinates.x;
            camera_cartesian_coordinates.y = this->cartesian_coordinates.y;
            camera_cartesian_coordinates.z = this->cartesian_coordinates.z;
            camera_cartesian_coordinates.y += 2.0f;

            // Projection matrix : 45° Field of View, aspect ratio, display range : 0.1 unit <-> 100 units
            this->projection_matrix = glm::perspective(
                    DEGREES_TO_RADIANS(FoV),
                    this->universe->get_aspect_ratio(),
                    0.001f,
                    5000.0f + 2.0f * static_cast<GLfloat>(this->universe->get_planet_radius()));
            // Camera matrix
            this->view_matrix = glm::lookAt(
                    camera_cartesian_coordinates,                   // Camera is here
                    camera_cartesian_coordinates + this->direction, // and looks here : at the same position, plus "direction"
                    this->up);                                      // Head is up (set to 0,-1,0 to look upside-down)

            return true;
        }

        glm::vec3 Camera::get_direction() const
        {
            return this->direction;
        }

        glm::vec3 Camera::get_right() const
        {
            return this->right;
        }

        glm::vec3 Camera::get_up() const
        {
            return this->up;
        }
    }
}
<commit_msg>Bugfix: added missing `#include` lines.<commit_after>#ifndef GLM_FORCE_RADIANS
#define GLM_FORCE_RADIANS
#define DEGREES_TO_RADIANS(x) (x * PI / 180.0f)
#endif

#ifndef RADIANS_TO_DEGREES
#define RADIANS_TO_DEGREES(x) (x * 180.0f / PI)
#endif

#include "entity.hpp"
#include "camera.hpp"
#include "scene.hpp"
#include "ground_level.hpp"
#include "code/ylikuutio/hierarchy/hierarchy_templates.hpp"

// Include GLEW
#ifndef __GL_GLEW_H_INCLUDED
#define __GL_GLEW_H_INCLUDED
#include <GL/glew.h> // GLfloat, GLuint etc.
#endif

// Include GLM
#ifndef __GLM_GLM_HPP_INCLUDED
#define __GLM_GLM_HPP_INCLUDED
#include <glm/glm.hpp> // glm
#endif

#ifndef __GLM_GTC_MATRIX_TRANSFORM_HPP_INCLUDED
#define __GLM_GTC_MATRIX_TRANSFORM_HPP_INCLUDED
#include <glm/gtc/matrix_transform.hpp>
#endif

// Include standard headers
#include <cmath>    // NAN, std::isnan, std::pow
#include <stdint.h> // uint32_t etc.

namespace yli
{
    namespace ontology
    {
        void Camera::bind_to_parent()
        {
            // get `childID` from `Scene` and set pointer to this `Camera`.
            this->parent->bind_camera(this);
        }

        Camera::~Camera()
        {
            // destructor.

            if (this->parent->get_active_camera() == this)
            {
                // Make this `Camera` no more the active `Camera`.
                this->parent->set_active_camera(nullptr);
            }

            // set pointer to this `Camera` to `nullptr`.
            this->parent->set_camera_pointer(this->childID, nullptr);
        }

        yli::ontology::Entity* Camera::get_parent() const
        {
            return this->parent;
        }

        int32_t Camera::get_number_of_children() const
        {
            return 0;
        }

        int32_t Camera::get_number_of_descendants() const
        {
            return 0;
        }

        glm::mat4& Camera::get_projection_matrix()
        {
            return this->projection_matrix;
        }

        glm::mat4& Camera::get_view_matrix()
        {
            return this->view_matrix;
        }

        float Camera::get_horizontal_angle() const
        {
            return this->horizontal_angle;
        }

        float Camera::get_vertical_angle() const
        {
            return this->vertical_angle;
        }

        bool Camera::compute_and_update_matrices_from_inputs()
        {
            if (!this->universe->is_flight_mode_in_use)
            {
                this->universe->fall_speed += this->universe->gravity;
                this->cartesian_coordinates.y -= this->universe->fall_speed;
            }

            GLfloat FoV = this->universe->get_initialFoV();

            // adjust position according to the ground.
            if (!this->universe->is_flight_mode_in_use)
            {
                if (this->universe->get_terrain_species() != nullptr)
                {
                    GLfloat ground_y = yli::ontology::get_floor_level(
                            static_cast<yli::ontology::Species*>(this->universe->get_terrain_species()),
                            this->cartesian_coordinates);

                    if (!std::isnan(ground_y) && this->cartesian_coordinates.y < ground_y)
                    {
                        this->cartesian_coordinates.y = ground_y;
                        this->universe->fall_speed = 0.0f;
                    }
                }
            }

            if (this->universe->testing_spherical_terrain_in_use)
            {
                // compute spherical coordinates.
                this->spherical_coordinates.rho = sqrt(
                        (this->cartesian_coordinates.x * this->cartesian_coordinates.x) +
                        (this->cartesian_coordinates.y * this->cartesian_coordinates.y) +
                        (this->cartesian_coordinates.z * this->cartesian_coordinates.z));
                this->spherical_coordinates.theta = RADIANS_TO_DEGREES(atan2(sqrt(
                                (this->cartesian_coordinates.x * this->cartesian_coordinates.x) +
                                (this->cartesian_coordinates.y * this->cartesian_coordinates.y)),
                            this->cartesian_coordinates.z));
                this->spherical_coordinates.phi = RADIANS_TO_DEGREES(atan2(
                            this->cartesian_coordinates.y,
                            this->cartesian_coordinates.x));
            }

            glm::vec3 camera_cartesian_coordinates;
            camera_cartesian_coordinates.x = this->cartesian_coordinates.x;
            camera_cartesian_coordinates.y = this->cartesian_coordinates.y;
            camera_cartesian_coordinates.z = this->cartesian_coordinates.z;
            camera_cartesian_coordinates.y += 2.0f;

            // Projection matrix : 45° Field of View, aspect ratio, display range : 0.1 unit <-> 100 units
            this->projection_matrix = glm::perspective(
                    DEGREES_TO_RADIANS(FoV),
                    this->universe->get_aspect_ratio(),
                    0.001f,
                    5000.0f + 2.0f * static_cast<GLfloat>(this->universe->get_planet_radius()));
            // Camera matrix
            this->view_matrix = glm::lookAt(
                    camera_cartesian_coordinates,                   // Camera is here
                    camera_cartesian_coordinates + this->direction, // and looks here : at the same position, plus "direction"
                    this->up);                                      // Head is up (set to 0,-1,0 to look upside-down)

            return true;
        }

        glm::vec3 Camera::get_direction() const
        {
            return this->direction;
        }

        glm::vec3 Camera::get_right() const
        {
            return this->right;
        }

        glm::vec3 Camera::get_up() const
        {
            return this->up;
        }
    }
}
<|endoftext|>