<commit_before>#pragma once

#include "event_queue/entry.hpp"
#include "event_queue/event.hpp"
#include "event_queue/event_time_stamp.hpp"
#include "hash_utility.hpp"
#include "modifier_flag_manager.hpp"
#include "pointing_button_manager.hpp"

namespace krbn {
namespace event_queue {
class queue {
public:
  queue(const queue&) = delete;

  queue(void) : time_stamp_delay_(0) {
  }

  void emplace_back_event(device_id device_id,
                          const event_time_stamp& event_time_stamp,
                          const class event& event,
                          event_type event_type,
                          const class event& original_event,
                          bool lazy = false) {
    auto t = event_time_stamp;
    t.set_time_stamp(t.get_time_stamp() + time_stamp_delay_);

    events_.emplace_back(device_id,
                         t,
                         event,
                         event_type,
                         original_event,
                         lazy);

    sort_events();

    // Update modifier_flag_manager

    if (auto key_code = event.get_key_code()) {
      if (auto modifier_flag = types::make_modifier_flag(*key_code)) {
        auto type = (event_type == event_type::key_down ? modifier_flag_manager::active_modifier_flag::type::increase
                                                        : modifier_flag_manager::active_modifier_flag::type::decrease);
        modifier_flag_manager::active_modifier_flag active_modifier_flag(type,
                                                                         *modifier_flag,
                                                                         device_id);
        modifier_flag_manager_.push_back_active_modifier_flag(active_modifier_flag);
      }
    }

    if (event.get_type() == event::type::caps_lock_state_changed) {
      if (auto integer_value = event.get_integer_value()) {
        auto type = (*integer_value ? modifier_flag_manager::active_modifier_flag::type::increase_lock
                                    : modifier_flag_manager::active_modifier_flag::type::decrease_lock);
        modifier_flag_manager::active_modifier_flag active_modifier_flag(type,
                                                                         modifier_flag::caps_lock,
                                                                         device_id);
        modifier_flag_manager_.push_back_active_modifier_flag(active_modifier_flag);
      }
    }

    // Update pointing_button_manager

    if (auto pointing_button = event.get_pointing_button()) {
      if (*pointing_button != pointing_button::zero) {
        auto type = (event_type == event_type::key_down ? pointing_button_manager::active_pointing_button::type::increase
                                                        : pointing_button_manager::active_pointing_button::type::decrease);
        pointing_button_manager::active_pointing_button active_pointing_button(type,
                                                                               *pointing_button,
                                                                               device_id);
        pointing_button_manager_.push_back_active_pointing_button(active_pointing_button);
      }
    }

    // Update manipulator_environment
    if (auto frontmost_application = event.get_frontmost_application()) {
      manipulator_environment_.set_frontmost_application(*frontmost_application);
    }
    if (auto input_source_identifiers = event.get_input_source_identifiers()) {
      manipulator_environment_.set_input_source_identifiers(*input_source_identifiers);
    }
    if (event_type == event_type::key_down) {
      if (auto set_variable = event.get_set_variable()) {
        manipulator_environment_.set_variable(set_variable->first,
                                              set_variable->second);
      }
    }
    if (auto keyboard_type = event.get_keyboard_type()) {
      manipulator_environment_.set_keyboard_type(*keyboard_type);
    }
  }

  void push_back_event(const entry& entry) {
    emplace_back_event(entry.get_device_id(),
                       entry.get_event_time_stamp(),
                       entry.get_event(),
                       entry.get_event_type(),
                       entry.get_original_event(),
                       entry.get_lazy());
    events_.back().set_valid(entry.get_valid());
  }

  void clear_events(void) {
    events_.clear();
    time_stamp_delay_ = absolute_time_duration(0);
  }

  entry& get_front_event(void) {
    return events_.front();
  }

  void erase_front_event(void) {
    events_.erase(std::begin(events_));
    if (events_.empty()) {
      time_stamp_delay_ = absolute_time_duration(0);
    }
  }

  bool empty(void) const {
    return events_.empty();
  }

  const std::vector<entry>& get_entries(void) const {
    return events_;
  }

  const modifier_flag_manager& get_modifier_flag_manager(void) const {
    return modifier_flag_manager_;
  }

  void erase_all_active_modifier_flags_except_lock(device_id device_id) {
    modifier_flag_manager_.erase_all_active_modifier_flags_except_lock(device_id);
  }

  void erase_all_active_modifier_flags(device_id device_id) {
    modifier_flag_manager_.erase_all_active_modifier_flags(device_id);
  }

  const pointing_button_manager& get_pointing_button_manager(void) const {
    return pointing_button_manager_;
  }

  void erase_all_active_pointing_buttons_except_lock(device_id device_id) {
    pointing_button_manager_.erase_all_active_pointing_buttons_except_lock(device_id);
  }

  void erase_all_active_pointing_buttons(device_id device_id) {
    pointing_button_manager_.erase_all_active_pointing_buttons(device_id);
  }

  const manipulator_environment& get_manipulator_environment(void) const {
    return manipulator_environment_;
  }

  void enable_manipulator_environment_json_output(const std::string& file_path) {
    manipulator_environment_.enable_json_output(file_path);
  }

  void disable_manipulator_environment_json_output(void) {
    manipulator_environment_.disable_json_output();
  }

  absolute_time_duration get_time_stamp_delay(void) const {
    return time_stamp_delay_;
  }

  void increase_time_stamp_delay(absolute_time_duration value) {
    time_stamp_delay_ += value;
  }

  static bool needs_swap(const entry& v1, const entry& v2) {
    // Some devices are send modifier flag and key at the same HID report.
    // For example, a key sends control+up-arrow by this reports.
    //
    //   modifiers: 0x0
    //   keys: 0x0 0x0 0x0 0x0 0x0 0x0
    //
    //   modifiers: 0x1
    //   keys: 0x52 0x0 0x0 0x0 0x0 0x0
    //
    // In this case, macOS does not guarantee the value event order to be modifier first.
    // At least macOS 10.12 or prior sends the up-arrow event first.
    //
    //   ----------------------------------------
    //   Example of hid value events in a single queue at control+up-arrow
    //
    //   1. up-arrow keydown
    //     usage_page:0x7
    //     usage:0x4f
    //     integer_value:1
    //
    //   2. control keydown
    //     usage_page:0x7
    //     usage:0xe1
    //     integer_value:1
    //
    //   3. up-arrow keyup
    //     usage_page:0x7
    //     usage:0x4f
    //     integer_value:0
    //
    //   4. control keyup
    //     usage_page:0x7
    //     usage:0xe1
    //     integer_value:0
    //   ----------------------------------------
    //
    // These events will not be interpreted as intended in this order.
    // Thus, we have to reorder the events.

    if (v1.get_event_time_stamp().get_time_stamp() == v2.get_event_time_stamp().get_time_stamp()) {
      auto key_code1 = v1.get_event().get_key_code();
      auto key_code2 = v2.get_event().get_key_code();

      if (key_code1 && key_code2) {
        auto modifier_flag1 = types::make_modifier_flag(*key_code1);
        auto modifier_flag2 = types::make_modifier_flag(*key_code2);

        // If either modifier_flag1 or modifier_flag2 is modifier, reorder it before.

        if (!modifier_flag1 && modifier_flag2) {
          // v2 is modifier_flag
          if (v2.get_event_type() == event_type::key_up) {
            return false;
          } else {
            // reorder to v2,v1 if v2 is pressed.
            return true;
          }
        }

        if (modifier_flag1 && !modifier_flag2) {
          // v1 is modifier_flag
          if (v1.get_event_type() == event_type::key_up) {
            // reorder to v2,v1 if v1 is released.
            return true;
          } else {
            return false;
          }
        }
      }
    }

    return false;
  }

  static std::vector<std::pair<boost::optional<hid_value>, entry>> make_entries(const std::vector<hid_value>& hid_values,
                                                                                device_id device_id) {
    std::vector<std::pair<boost::optional<hid_value>, entry>> result;

    // The pointing motion usage (hid_usage::gd_x, hid_usage::gd_y, etc.) are splitted from one HID report.
    // We have to join them into one pointing_motion event to avoid VMware Remote Console problem that VMRC ignores frequently events.

    boost::optional<absolute_time> pointing_motion_time_stamp;
    boost::optional<int> pointing_motion_x;
    boost::optional<int> pointing_motion_y;
    boost::optional<int> pointing_motion_vertical_wheel;
    boost::optional<int> pointing_motion_horizontal_wheel;

    auto emplace_back_pointing_motion_event = [&] {
      if (pointing_motion_time_stamp) {
        pointing_motion pointing_motion(
            pointing_motion_x ? *pointing_motion_x : 0,
            pointing_motion_y ? *pointing_motion_y : 0,
            pointing_motion_vertical_wheel ? *pointing_motion_vertical_wheel : 0,
            pointing_motion_horizontal_wheel ? *pointing_motion_horizontal_wheel : 0);

        event_queue::event event(pointing_motion);

        result.emplace_back(boost::none,
                            entry(device_id,
                                  event_time_stamp(*pointing_motion_time_stamp),
                                  event,
                                  event_type::single,
                                  event));

        pointing_motion_time_stamp = boost::none;
        pointing_motion_x = boost::none;
        pointing_motion_y = boost::none;
        pointing_motion_vertical_wheel = boost::none;
        pointing_motion_horizontal_wheel = boost::none;
      }
    };

    for (const auto& v : hid_values) {
      if (auto usage_page = v.get_hid_usage_page()) {
        if (auto usage = v.get_hid_usage()) {
          if (auto key_code = types::make_key_code(*usage_page, *usage)) {
            event_queue::event event(*key_code);
            result.emplace_back(v,
                                entry(device_id,
                                      event_time_stamp(v.get_time_stamp()),
                                      event,
                                      v.get_integer_value() ? event_type::key_down : event_type::key_up,
                                      event));

          } else if (auto consumer_key_code = types::make_consumer_key_code(*usage_page, *usage)) {
            event_queue::event event(*consumer_key_code);
            result.emplace_back(v,
                                entry(device_id,
                                      event_time_stamp(v.get_time_stamp()),
                                      event,
                                      v.get_integer_value() ? event_type::key_down : event_type::key_up,
                                      event));

          } else if (auto pointing_button = types::make_pointing_button(*usage_page, *usage)) {
            event_queue::event event(*pointing_button);
            result.emplace_back(v,
                                entry(device_id,
                                      event_time_stamp(v.get_time_stamp()),
                                      event,
                                      v.get_integer_value() ? event_type::key_down : event_type::key_up,
                                      event));

          } else if (*usage_page == hid_usage_page::generic_desktop &&
                     *usage == hid_usage::gd_x) {
            if (pointing_motion_x) {
              emplace_back_pointing_motion_event();
            }
            pointing_motion_time_stamp = v.get_time_stamp();
            pointing_motion_x = static_cast<int>(v.get_integer_value());

          } else if (*usage_page == hid_usage_page::generic_desktop &&
                     *usage == hid_usage::gd_y) {
            if (pointing_motion_y) {
              emplace_back_pointing_motion_event();
            }
            pointing_motion_time_stamp = v.get_time_stamp();
            pointing_motion_y = static_cast<int>(v.get_integer_value());

          } else if (*usage_page == hid_usage_page::generic_desktop &&
                     *usage == hid_usage::gd_wheel) {
            if (pointing_motion_vertical_wheel) {
              emplace_back_pointing_motion_event();
            }
            pointing_motion_time_stamp = v.get_time_stamp();
            pointing_motion_vertical_wheel = static_cast<int>(v.get_integer_value());

          } else if (*usage_page == hid_usage_page::consumer &&
                     *usage == hid_usage::csmr_acpan) {
            if (pointing_motion_horizontal_wheel) {
              emplace_back_pointing_motion_event();
            }
            pointing_motion_time_stamp = v.get_time_stamp();
            pointing_motion_horizontal_wheel = static_cast<int>(v.get_integer_value());
          }
        }
      }
    }

    emplace_back_pointing_motion_event();

    return result;
  }

private:
  void sort_events(void) {
    for (size_t i = 0; i < events_.size() - 1;) {
      if (needs_swap(events_[i], events_[i + 1])) {
        std::swap(events_[i], events_[i + 1]);
        if (i > 0) {
          --i;
        }
        continue;
      }
      ++i;
    }
  }

  std::vector<entry> events_;
  modifier_flag_manager modifier_flag_manager_;
  pointing_button_manager pointing_button_manager_;
  manipulator_environment manipulator_environment_;
  absolute_time_duration time_stamp_delay_;
};
} // namespace event_queue
} // namespace krbn
<commit_msg>support caps_lock_state_changed in event_queue::queue::make_entries<commit_after>#pragma once

#include "event_queue/entry.hpp"
#include "event_queue/event.hpp"
#include "event_queue/event_time_stamp.hpp"
#include "hash_utility.hpp"
#include "modifier_flag_manager.hpp"
#include "pointing_button_manager.hpp"

namespace krbn {
namespace event_queue {
class queue {
public:
  queue(const queue&) = delete;

  queue(void) : time_stamp_delay_(0) {
  }

  void emplace_back_event(device_id device_id,
                          const event_time_stamp& event_time_stamp,
                          const class event& event,
                          event_type event_type,
                          const class event& original_event,
                          bool lazy = false) {
    auto t = event_time_stamp;
    t.set_time_stamp(t.get_time_stamp() + time_stamp_delay_);

    events_.emplace_back(device_id,
                         t,
                         event,
                         event_type,
                         original_event,
                         lazy);

    sort_events();

    // Update modifier_flag_manager

    if (auto key_code = event.get_key_code()) {
      if (auto modifier_flag = types::make_modifier_flag(*key_code)) {
        auto type = (event_type == event_type::key_down ? modifier_flag_manager::active_modifier_flag::type::increase
                                                        : modifier_flag_manager::active_modifier_flag::type::decrease);
        modifier_flag_manager::active_modifier_flag active_modifier_flag(type,
                                                                         *modifier_flag,
                                                                         device_id);
        modifier_flag_manager_.push_back_active_modifier_flag(active_modifier_flag);
      }
    }

    if (event.get_type() == event::type::caps_lock_state_changed) {
      if (auto integer_value = event.get_integer_value()) {
        auto type = (*integer_value ? modifier_flag_manager::active_modifier_flag::type::increase_lock
                                    : modifier_flag_manager::active_modifier_flag::type::decrease_lock);
        modifier_flag_manager::active_modifier_flag active_modifier_flag(type,
                                                                         modifier_flag::caps_lock,
                                                                         device_id);
        modifier_flag_manager_.push_back_active_modifier_flag(active_modifier_flag);
      }
    }

    // Update pointing_button_manager

    if (auto pointing_button = event.get_pointing_button()) {
      if (*pointing_button != pointing_button::zero) {
        auto type = (event_type == event_type::key_down ? pointing_button_manager::active_pointing_button::type::increase
                                                        : pointing_button_manager::active_pointing_button::type::decrease);
        pointing_button_manager::active_pointing_button active_pointing_button(type,
                                                                               *pointing_button,
                                                                               device_id);
        pointing_button_manager_.push_back_active_pointing_button(active_pointing_button);
      }
    }

    // Update manipulator_environment
    if (auto frontmost_application = event.get_frontmost_application()) {
      manipulator_environment_.set_frontmost_application(*frontmost_application);
    }
    if (auto input_source_identifiers = event.get_input_source_identifiers()) {
      manipulator_environment_.set_input_source_identifiers(*input_source_identifiers);
    }
    if (event_type == event_type::key_down) {
      if (auto set_variable = event.get_set_variable()) {
        manipulator_environment_.set_variable(set_variable->first,
                                              set_variable->second);
      }
    }
    if (auto keyboard_type = event.get_keyboard_type()) {
      manipulator_environment_.set_keyboard_type(*keyboard_type);
    }
  }

  void push_back_event(const entry& entry) {
    emplace_back_event(entry.get_device_id(),
                       entry.get_event_time_stamp(),
                       entry.get_event(),
                       entry.get_event_type(),
                       entry.get_original_event(),
                       entry.get_lazy());
    events_.back().set_valid(entry.get_valid());
  }

  void clear_events(void) {
    events_.clear();
    time_stamp_delay_ = absolute_time_duration(0);
  }

  entry& get_front_event(void) {
    return events_.front();
  }

  void erase_front_event(void) {
    events_.erase(std::begin(events_));
    if (events_.empty()) {
      time_stamp_delay_ = absolute_time_duration(0);
    }
  }

  bool empty(void) const {
    return events_.empty();
  }

  const std::vector<entry>& get_entries(void) const {
    return events_;
  }

  const modifier_flag_manager& get_modifier_flag_manager(void) const {
    return modifier_flag_manager_;
  }

  void erase_all_active_modifier_flags_except_lock(device_id device_id) {
    modifier_flag_manager_.erase_all_active_modifier_flags_except_lock(device_id);
  }

  void erase_all_active_modifier_flags(device_id device_id) {
    modifier_flag_manager_.erase_all_active_modifier_flags(device_id);
  }

  const pointing_button_manager& get_pointing_button_manager(void) const {
    return pointing_button_manager_;
  }

  void erase_all_active_pointing_buttons_except_lock(device_id device_id) {
    pointing_button_manager_.erase_all_active_pointing_buttons_except_lock(device_id);
  }

  void erase_all_active_pointing_buttons(device_id device_id) {
    pointing_button_manager_.erase_all_active_pointing_buttons(device_id);
  }

  const manipulator_environment& get_manipulator_environment(void) const {
    return manipulator_environment_;
  }

  void enable_manipulator_environment_json_output(const std::string& file_path) {
    manipulator_environment_.enable_json_output(file_path);
  }

  void disable_manipulator_environment_json_output(void) {
    manipulator_environment_.disable_json_output();
  }

  absolute_time_duration get_time_stamp_delay(void) const {
    return time_stamp_delay_;
  }

  void increase_time_stamp_delay(absolute_time_duration value) {
    time_stamp_delay_ += value;
  }

  static bool needs_swap(const entry& v1, const entry& v2) {
    // Some devices are send modifier flag and key at the same HID report.
    // For example, a key sends control+up-arrow by this reports.
    //
    //   modifiers: 0x0
    //   keys: 0x0 0x0 0x0 0x0 0x0 0x0
    //
    //   modifiers: 0x1
    //   keys: 0x52 0x0 0x0 0x0 0x0 0x0
    //
    // In this case, macOS does not guarantee the value event order to be modifier first.
    // At least macOS 10.12 or prior sends the up-arrow event first.
    //
    //   ----------------------------------------
    //   Example of hid value events in a single queue at control+up-arrow
    //
    //   1. up-arrow keydown
    //     usage_page:0x7
    //     usage:0x4f
    //     integer_value:1
    //
    //   2. control keydown
    //     usage_page:0x7
    //     usage:0xe1
    //     integer_value:1
    //
    //   3. up-arrow keyup
    //     usage_page:0x7
    //     usage:0x4f
    //     integer_value:0
    //
    //   4. control keyup
    //     usage_page:0x7
    //     usage:0xe1
    //     integer_value:0
    //   ----------------------------------------
    //
    // These events will not be interpreted as intended in this order.
    // Thus, we have to reorder the events.

    if (v1.get_event_time_stamp().get_time_stamp() == v2.get_event_time_stamp().get_time_stamp()) {
      auto key_code1 = v1.get_event().get_key_code();
      auto key_code2 = v2.get_event().get_key_code();

      if (key_code1 && key_code2) {
        auto modifier_flag1 = types::make_modifier_flag(*key_code1);
        auto modifier_flag2 = types::make_modifier_flag(*key_code2);

        // If either modifier_flag1 or modifier_flag2 is modifier, reorder it before.

        if (!modifier_flag1 && modifier_flag2) {
          // v2 is modifier_flag
          if (v2.get_event_type() == event_type::key_up) {
            return false;
          } else {
            // reorder to v2,v1 if v2 is pressed.
            return true;
          }
        }

        if (modifier_flag1 && !modifier_flag2) {
          // v1 is modifier_flag
          if (v1.get_event_type() == event_type::key_up) {
            // reorder to v2,v1 if v1 is released.
            return true;
          } else {
            return false;
          }
        }
      }
    }

    return false;
  }

  static std::vector<std::pair<boost::optional<hid_value>, entry>> make_entries(const std::vector<hid_value>& hid_values,
                                                                                device_id device_id) {
    std::vector<std::pair<boost::optional<hid_value>, entry>> result;

    // The pointing motion usage (hid_usage::gd_x, hid_usage::gd_y, etc.) are splitted from one HID report.
    // We have to join them into one pointing_motion event to avoid VMware Remote Console problem that VMRC ignores frequently events.

    boost::optional<absolute_time> pointing_motion_time_stamp;
    boost::optional<int> pointing_motion_x;
    boost::optional<int> pointing_motion_y;
    boost::optional<int> pointing_motion_vertical_wheel;
    boost::optional<int> pointing_motion_horizontal_wheel;

    auto emplace_back_pointing_motion_event = [&] {
      if (pointing_motion_time_stamp) {
        pointing_motion pointing_motion(
            pointing_motion_x ? *pointing_motion_x : 0,
            pointing_motion_y ? *pointing_motion_y : 0,
            pointing_motion_vertical_wheel ? *pointing_motion_vertical_wheel : 0,
            pointing_motion_horizontal_wheel ? *pointing_motion_horizontal_wheel : 0);

        event_queue::event event(pointing_motion);

        result.emplace_back(boost::none,
                            entry(device_id,
                                  event_time_stamp(*pointing_motion_time_stamp),
                                  event,
                                  event_type::single,
                                  event));

        pointing_motion_time_stamp = boost::none;
        pointing_motion_x = boost::none;
        pointing_motion_y = boost::none;
        pointing_motion_vertical_wheel = boost::none;
        pointing_motion_horizontal_wheel = boost::none;
      }
    };

    for (const auto& v : hid_values) {
      if (auto usage_page = v.get_hid_usage_page()) {
        if (auto usage = v.get_hid_usage()) {
          if (auto key_code = types::make_key_code(*usage_page, *usage)) {
            event_queue::event event(*key_code);
            result.emplace_back(v,
                                entry(device_id,
                                      event_time_stamp(v.get_time_stamp()),
                                      event,
                                      v.get_integer_value() ? event_type::key_down : event_type::key_up,
                                      event));

          } else if (auto consumer_key_code = types::make_consumer_key_code(*usage_page, *usage)) {
            event_queue::event event(*consumer_key_code);
            result.emplace_back(v,
                                entry(device_id,
                                      event_time_stamp(v.get_time_stamp()),
                                      event,
                                      v.get_integer_value() ? event_type::key_down : event_type::key_up,
                                      event));

          } else if (auto pointing_button = types::make_pointing_button(*usage_page, *usage)) {
            event_queue::event event(*pointing_button);
            result.emplace_back(v,
                                entry(device_id,
                                      event_time_stamp(v.get_time_stamp()),
                                      event,
                                      v.get_integer_value() ? event_type::key_down : event_type::key_up,
                                      event));

          } else if (*usage_page == hid_usage_page::generic_desktop &&
                     *usage == hid_usage::gd_x) {
            if (pointing_motion_x) {
              emplace_back_pointing_motion_event();
            }
            pointing_motion_time_stamp = v.get_time_stamp();
            pointing_motion_x = static_cast<int>(v.get_integer_value());

          } else if (*usage_page == hid_usage_page::generic_desktop &&
                     *usage == hid_usage::gd_y) {
            if (pointing_motion_y) {
              emplace_back_pointing_motion_event();
            }
            pointing_motion_time_stamp = v.get_time_stamp();
            pointing_motion_y = static_cast<int>(v.get_integer_value());

          } else if (*usage_page == hid_usage_page::generic_desktop &&
                     *usage == hid_usage::gd_wheel) {
            if (pointing_motion_vertical_wheel) {
              emplace_back_pointing_motion_event();
            }
            pointing_motion_time_stamp = v.get_time_stamp();
            pointing_motion_vertical_wheel = static_cast<int>(v.get_integer_value());

          } else if (*usage_page == hid_usage_page::consumer &&
                     *usage == hid_usage::csmr_acpan) {
            if (pointing_motion_horizontal_wheel) {
              emplace_back_pointing_motion_event();
            }
            pointing_motion_time_stamp = v.get_time_stamp();
            pointing_motion_horizontal_wheel = static_cast<int>(v.get_integer_value());
          } else if (*usage_page == hid_usage_page::leds &&
                     *usage == hid_usage::led_caps_lock) {
            event_queue::event event(event_queue::event::type::caps_lock_state_changed,
                                     v.get_integer_value());
            result.emplace_back(v,
                                entry(device_id,
                                      event_time_stamp(v.get_time_stamp()),
                                      event,
                                      event_type::single,
                                      event));
          }
        }
      }
    }

    emplace_back_pointing_motion_event();

    return result;
  }

private:
  void sort_events(void) {
    for (size_t i = 0; i < events_.size() - 1;) {
      if (needs_swap(events_[i], events_[i + 1])) {
        std::swap(events_[i], events_[i + 1]);
        if (i > 0) {
          --i;
        }
        continue;
      }
      ++i;
    }
  }

  std::vector<entry> events_;
  modifier_flag_manager modifier_flag_manager_;
  pointing_button_manager pointing_button_manager_;
  manipulator_environment manipulator_environment_;
  absolute_time_duration time_stamp_delay_;
};
} // namespace event_queue
} // namespace krbn
<|endoftext|>


<commit_before>// Copyright (c) 2012 Intel Corp
// Copyright (c) 2012 The Chromium Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell co
// pies of the Software, and to permit persons to whom the Software is furnished
//  to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in al
// l copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM
// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
//  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
//  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "content/nw/src/shell_browser_main_parts.h"

#include "base/bind.h"
#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
#include "chrome/common/chrome_switches.h"
#include "content/nw/src/api/app/app.h"
#include "content/nw/src/api/dispatcher_host.h"
#include "content/nw/src/breakpad_linux.h"
#include "content/nw/src/browser/printing/print_job_manager.h"
#include "content/nw/src/browser/shell_devtools_delegate.h"
#include "content/nw/src/common/shell_switches.h"
#include "content/nw/src/nw_package.h"
#include "content/nw/src/nw_shell.h"
#include "content/nw/src/shell_browser_context.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
#include "grit/net_resources.h"
#include "net/base/net_module.h"
#include "net/proxy/proxy_resolver_v8.h"
#include "ui/base/resource/resource_bundle.h"

#if !defined(OS_WIN)
#include <sys/resource.h>
#endif

#if defined(TOOLKIT_GTK)
#include "content/nw/src/browser/printing/print_dialog_gtk.h"
#endif

#if defined(USE_AURA)
#include "ui/aura/env.h"
#include "ui/gfx/screen.h"
#include "ui/views/test/desktop_test_views_delegate.h"
#include "ui/views/widget/desktop_aura/desktop_screen.h"
#endif  // defined(USE_AURA)

using base::MessageLoop;

namespace {

#if !defined(OS_WIN)
// Sets the file descriptor soft limit to |max_descriptors| or the OS hard
// limit, whichever is lower.
void SetFileDescriptorLimit(unsigned int max_descriptors) {
  struct rlimit limits;
  if (getrlimit(RLIMIT_NOFILE, &limits) == 0) {
    unsigned int new_limit = max_descriptors;
    if (limits.rlim_max > 0 && limits.rlim_max < max_descriptors) {
      new_limit = limits.rlim_max;
    }
    limits.rlim_cur = new_limit;
    if (setrlimit(RLIMIT_NOFILE, &limits) != 0) {
      PLOG(INFO) << "Failed to set file descriptor limit";
    }
  } else {
    PLOG(INFO) << "Failed to get file descriptor limit";
  }
}

#endif

base::StringPiece PlatformResourceProvider(int key) {
  if (key == IDR_DIR_HEADER_HTML) {
    base::StringPiece html_data =
        ui::ResourceBundle::GetSharedInstance().GetRawDataResource(
            IDR_DIR_HEADER_HTML);
    return html_data;
  }
  return base::StringPiece();
}

}  // namespace

namespace content {

ShellBrowserMainParts::ShellBrowserMainParts(
    const MainFunctionParams& parameters)
    : BrowserMainParts(),
      parameters_(parameters),
      run_message_loop_(true),
      devtools_delegate_(NULL),
      notify_result_(ProcessSingleton::PROCESS_NONE)
{
#if defined(ENABLE_PRINTING)
  // Must be created after the NotificationService.
  print_job_manager_.reset(new printing::PrintJobManager);
#endif
}

ShellBrowserMainParts::~ShellBrowserMainParts() {
}

#if !defined(OS_MACOSX)
void ShellBrowserMainParts::PreMainMessageLoopStart() {
}
#endif

void ShellBrowserMainParts::PreMainMessageLoopRun() {

#if !defined(OS_MACOSX)
  Init();
#endif

  if (parameters_.ui_task) {
    parameters_.ui_task->Run();
    delete parameters_.ui_task;
    run_message_loop_ = false;
  }
}

bool ShellBrowserMainParts::MainMessageLoopRun(int* result_code)  {
  return !run_message_loop_;
}

void ShellBrowserMainParts::PostMainMessageLoopRun() {
  if (devtools_delegate_)
    devtools_delegate_->Stop();
  if (notify_result_ == ProcessSingleton::PROCESS_NONE)
    process_singleton_->Cleanup();

  browser_context_.reset();
  off_the_record_browser_context_.reset();
}

void ShellBrowserMainParts::PostMainMessageLoopStart() {
#if defined(TOOLKIT_GTK)
  printing::PrintingContextLinux::SetCreatePrintDialogFunction(
      &PrintDialogGtk::CreatePrintDialog);
#endif
}

int ShellBrowserMainParts::PreCreateThreads() {
  net::ProxyResolverV8::RememberDefaultIsolate();
#if defined(USE_AURA)
  gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE,
                                 views::CreateDesktopScreen());
#endif
  return 0;
}

void ShellBrowserMainParts::PostDestroyThreads() {
#if defined(USE_AURA)
  aura::Env::DeleteInstance();
  delete views::ViewsDelegate::views_delegate;
#endif
}

void ShellBrowserMainParts::ToolkitInitialized() {
#if defined(USE_AURA)
  aura::Env::CreateInstance();

  DCHECK(!views::ViewsDelegate::views_delegate);
  new views::DesktopTestViewsDelegate;
#endif
}

void ShellBrowserMainParts::Init() {
  package_.reset(new nw::Package());
  CommandLine& command_line = *CommandLine::ForCurrentProcess();

  browser_context_.reset(new ShellBrowserContext(false, package()));
  browser_context_->PreMainMessageLoopRun();

  off_the_record_browser_context_.reset(
      new ShellBrowserContext(true, package()));

  process_singleton_.reset(new ProcessSingleton(browser_context_->GetPath(),
                                                base::Bind(&ShellBrowserMainParts::ProcessSingletonNotificationCallback, base::Unretained(this))));
  notify_result_ = process_singleton_->NotifyOtherProcessOrCreate();

  // Quit if the other existing instance want to handle it.
  if (notify_result_ == ProcessSingleton::PROCESS_NOTIFIED) {
    MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
    return;
  }

  net::NetModule::SetResourceProvider(PlatformResourceProvider);

  int port = 0;
  // See if the user specified a port on the command line (useful for
  // automation). If not, use an ephemeral port by specifying 0.

  if (command_line.HasSwitch(switches::kRemoteDebuggingPort)) {
    int temp_port;
    std::string port_str =
        command_line.GetSwitchValueASCII(switches::kRemoteDebuggingPort);
    if (base::StringToInt(port_str, &temp_port) &&
        temp_port > 0 && temp_port < 65535) {
      port = temp_port;
    } else {
      DLOG(WARNING) << "Invalid http debugger port number " << temp_port;
    }
  }
  devtools_delegate_ = new ShellDevToolsDelegate(browser_context_.get(), port);

  Shell::Create(browser_context_.get(),
                package()->GetStartupURL(),
                NULL,
                MSG_ROUTING_NONE,
                NULL);
}

bool ShellBrowserMainParts::ProcessSingletonNotificationCallback(
    const CommandLine& command_line,
    const base::FilePath& current_directory) {

  // Don't reuse current instance if 'single-instance' is specified to false.
  bool single_instance;
  if (package_->root()->GetBoolean(switches::kmSingleInstance,
                                   &single_instance) &&
      !single_instance)
    return false;

#if defined(OS_WIN)
  std::string cmd = base::UTF16ToUTF8(command_line.GetCommandLineString());
#else
  std::string cmd = command_line.GetCommandLineString();
#endif
  static const char* const kSwitchNames[] = {
    switches::kNoSandbox,
    switches::kProcessPerTab,
    switches::kEnableExperimentalWebPlatformFeatures,
    //    switches::kEnableCssShaders,
    switches::kAllowFileAccessFromFiles,
  };
  for (size_t i = 0; i < arraysize(kSwitchNames); ++i) {
    ReplaceSubstringsAfterOffset(&cmd, 0, std::string(" --") + kSwitchNames[i], "");
  }

#if 0
  nwapi::App::EmitOpenEvent(UTF16ToUTF8(cmd));
#else
  nwapi::App::EmitOpenEvent(cmd);
#endif

  return true;
}

printing::PrintJobManager* ShellBrowserMainParts::print_job_manager() {
  // TODO(abarth): DCHECK(CalledOnValidThread());
  // http://code.google.com/p/chromium/issues/detail?id=6828
  // print_job_manager_ is initialized in the constructor and destroyed in the
  // destructor, so it should always be valid.
  DCHECK(print_job_manager_.get());
  return print_job_manager_.get();
}

void ShellBrowserMainParts::PreEarlyInitialization() {
#if !defined(OS_WIN)
  // see chrome_browser_main_posix.cc
  CommandLine& command_line = *CommandLine::ForCurrentProcess();
  const std::string fd_limit_string =
      command_line.GetSwitchValueASCII(switches::kFileDescriptorLimit);
  int fd_limit = 0;
  if (!fd_limit_string.empty()) {
    base::StringToInt(fd_limit_string, &fd_limit);
  }
#if defined(OS_MACOSX)
  // We use quite a few file descriptors for our IPC, and the default limit on
  // the Mac is low (256), so bump it up if there is no explicit override.
  if (fd_limit == 0) {
    fd_limit = 1024;
  }
#endif  // OS_MACOSX
  if (fd_limit > 0)
    SetFileDescriptorLimit(fd_limit);
#endif // !OS_WIN
}

}  // namespace content
<commit_msg>Initialize Package earlier to evaluate commandline args earlier (fixes #1743). On package initialization, flags from "chromium-args" are added to the Chromium commandline. Previously, the Package object was initialized in the "PreMainMessageLoopRun" step. As the GPU flags are already evaluated in the "BrowserThreadsStarted" step (which is before that), this was too late for flags like "--ignore-gpu-blacklist".<commit_after>// Copyright (c) 2012 Intel Corp
// Copyright (c) 2012 The Chromium Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell co
// pies of the Software, and to permit persons to whom the Software is furnished
//  to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in al
// l copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM
// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
//  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
//  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "content/nw/src/shell_browser_main_parts.h"

#include "base/bind.h"
#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
#include "chrome/common/chrome_switches.h"
#include "content/nw/src/api/app/app.h"
#include "content/nw/src/api/dispatcher_host.h"
#include "content/nw/src/breakpad_linux.h"
#include "content/nw/src/browser/printing/print_job_manager.h"
#include "content/nw/src/browser/shell_devtools_delegate.h"
#include "content/nw/src/common/shell_switches.h"
#include "content/nw/src/nw_package.h"
#include "content/nw/src/nw_shell.h"
#include "content/nw/src/shell_browser_context.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
#include "grit/net_resources.h"
#include "net/base/net_module.h"
#include "net/proxy/proxy_resolver_v8.h"
#include "ui/base/resource/resource_bundle.h"

#if !defined(OS_WIN)
#include <sys/resource.h>
#endif

#if defined(TOOLKIT_GTK)
#include "content/nw/src/browser/printing/print_dialog_gtk.h"
#endif

#if defined(USE_AURA)
#include "ui/aura/env.h"
#include "ui/gfx/screen.h"
#include "ui/views/test/desktop_test_views_delegate.h"
#include "ui/views/widget/desktop_aura/desktop_screen.h"
#endif  // defined(USE_AURA)

using base::MessageLoop;

namespace {

#if !defined(OS_WIN)
// Sets the file descriptor soft limit to |max_descriptors| or the OS hard
// limit, whichever is lower.
void SetFileDescriptorLimit(unsigned int max_descriptors) {
  struct rlimit limits;
  if (getrlimit(RLIMIT_NOFILE, &limits) == 0) {
    unsigned int new_limit = max_descriptors;
    if (limits.rlim_max > 0 && limits.rlim_max < max_descriptors) {
      new_limit = limits.rlim_max;
    }
    limits.rlim_cur = new_limit;
    if (setrlimit(RLIMIT_NOFILE, &limits) != 0) {
      PLOG(INFO) << "Failed to set file descriptor limit";
    }
  } else {
    PLOG(INFO) << "Failed to get file descriptor limit";
  }
}

#endif

base::StringPiece PlatformResourceProvider(int key) {
  if (key == IDR_DIR_HEADER_HTML) {
    base::StringPiece html_data =
        ui::ResourceBundle::GetSharedInstance().GetRawDataResource(
            IDR_DIR_HEADER_HTML);
    return html_data;
  }
  return base::StringPiece();
}

}  // namespace

namespace content {

ShellBrowserMainParts::ShellBrowserMainParts(
    const MainFunctionParams& parameters)
    : BrowserMainParts(),
      parameters_(parameters),
      run_message_loop_(true),
      devtools_delegate_(NULL),
      notify_result_(ProcessSingleton::PROCESS_NONE)
{
#if defined(ENABLE_PRINTING)
  // Must be created after the NotificationService.
  print_job_manager_.reset(new printing::PrintJobManager);
#endif
}

ShellBrowserMainParts::~ShellBrowserMainParts() {
}

#if !defined(OS_MACOSX)
void ShellBrowserMainParts::PreMainMessageLoopStart() {
}
#endif

void ShellBrowserMainParts::PreMainMessageLoopRun() {

#if !defined(OS_MACOSX)
  Init();
#endif

  if (parameters_.ui_task) {
    parameters_.ui_task->Run();
    delete parameters_.ui_task;
    run_message_loop_ = false;
  }
}

bool ShellBrowserMainParts::MainMessageLoopRun(int* result_code)  {
  return !run_message_loop_;
}

void ShellBrowserMainParts::PostMainMessageLoopRun() {
  if (devtools_delegate_)
    devtools_delegate_->Stop();
  if (notify_result_ == ProcessSingleton::PROCESS_NONE)
    process_singleton_->Cleanup();

  browser_context_.reset();
  off_the_record_browser_context_.reset();
}

void ShellBrowserMainParts::PostMainMessageLoopStart() {
#if defined(TOOLKIT_GTK)
  printing::PrintingContextLinux::SetCreatePrintDialogFunction(
      &PrintDialogGtk::CreatePrintDialog);
#endif
}

int ShellBrowserMainParts::PreCreateThreads() {
  net::ProxyResolverV8::RememberDefaultIsolate();
#if defined(USE_AURA)
  gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE,
                                 views::CreateDesktopScreen());
#endif
  package_.reset(new nw::Package());
  return 0;
}

void ShellBrowserMainParts::PostDestroyThreads() {
#if defined(USE_AURA)
  aura::Env::DeleteInstance();
  delete views::ViewsDelegate::views_delegate;
#endif
}

void ShellBrowserMainParts::ToolkitInitialized() {
#if defined(USE_AURA)
  aura::Env::CreateInstance();

  DCHECK(!views::ViewsDelegate::views_delegate);
  new views::DesktopTestViewsDelegate;
#endif
}

void ShellBrowserMainParts::Init() {
  CommandLine& command_line = *CommandLine::ForCurrentProcess();

  browser_context_.reset(new ShellBrowserContext(false, package()));
  browser_context_->PreMainMessageLoopRun();

  off_the_record_browser_context_.reset(
      new ShellBrowserContext(true, package()));

  process_singleton_.reset(new ProcessSingleton(browser_context_->GetPath(),
                                                base::Bind(&ShellBrowserMainParts::ProcessSingletonNotificationCallback, base::Unretained(this))));
  notify_result_ = process_singleton_->NotifyOtherProcessOrCreate();

  // Quit if the other existing instance want to handle it.
  if (notify_result_ == ProcessSingleton::PROCESS_NOTIFIED) {
    MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
    return;
  }

  net::NetModule::SetResourceProvider(PlatformResourceProvider);

  int port = 0;
  // See if the user specified a port on the command line (useful for
  // automation). If not, use an ephemeral port by specifying 0.

  if (command_line.HasSwitch(switches::kRemoteDebuggingPort)) {
    int temp_port;
    std::string port_str =
        command_line.GetSwitchValueASCII(switches::kRemoteDebuggingPort);
    if (base::StringToInt(port_str, &temp_port) &&
        temp_port > 0 && temp_port < 65535) {
      port = temp_port;
    } else {
      DLOG(WARNING) << "Invalid http debugger port number " << temp_port;
    }
  }
  devtools_delegate_ = new ShellDevToolsDelegate(browser_context_.get(), port);

  Shell::Create(browser_context_.get(),
                package()->GetStartupURL(),
                NULL,
                MSG_ROUTING_NONE,
                NULL);
}

bool ShellBrowserMainParts::ProcessSingletonNotificationCallback(
    const CommandLine& command_line,
    const base::FilePath& current_directory) {

  // Don't reuse current instance if 'single-instance' is specified to false.
  bool single_instance;
  if (package_->root()->GetBoolean(switches::kmSingleInstance,
                                   &single_instance) &&
      !single_instance)
    return false;

#if defined(OS_WIN)
  std::string cmd = base::UTF16ToUTF8(command_line.GetCommandLineString());
#else
  std::string cmd = command_line.GetCommandLineString();
#endif
  static const char* const kSwitchNames[] = {
    switches::kNoSandbox,
    switches::kProcessPerTab,
    switches::kEnableExperimentalWebPlatformFeatures,
    //    switches::kEnableCssShaders,
    switches::kAllowFileAccessFromFiles,
  };
  for (size_t i = 0; i < arraysize(kSwitchNames); ++i) {
    ReplaceSubstringsAfterOffset(&cmd, 0, std::string(" --") + kSwitchNames[i], "");
  }

#if 0
  nwapi::App::EmitOpenEvent(UTF16ToUTF8(cmd));
#else
  nwapi::App::EmitOpenEvent(cmd);
#endif

  return true;
}

printing::PrintJobManager* ShellBrowserMainParts::print_job_manager() {
  // TODO(abarth): DCHECK(CalledOnValidThread());
  // http://code.google.com/p/chromium/issues/detail?id=6828
  // print_job_manager_ is initialized in the constructor and destroyed in the
  // destructor, so it should always be valid.
  DCHECK(print_job_manager_.get());
  return print_job_manager_.get();
}

void ShellBrowserMainParts::PreEarlyInitialization() {
#if !defined(OS_WIN)
  // see chrome_browser_main_posix.cc
  CommandLine& command_line = *CommandLine::ForCurrentProcess();
  const std::string fd_limit_string =
      command_line.GetSwitchValueASCII(switches::kFileDescriptorLimit);
  int fd_limit = 0;
  if (!fd_limit_string.empty()) {
    base::StringToInt(fd_limit_string, &fd_limit);
  }
#if defined(OS_MACOSX)
  // We use quite a few file descriptors for our IPC, and the default limit on
  // the Mac is low (256), so bump it up if there is no explicit override.
  if (fd_limit == 0) {
    fd_limit = 1024;
  }
#endif  // OS_MACOSX
  if (fd_limit > 0)
    SetFileDescriptorLimit(fd_limit);
#endif // !OS_WIN
}

}  // namespace content
<|endoftext|>


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

#ifndef RPTUI_DATETIME_HXX
#include "DateTime.hxx"
#endif
#ifndef RPTUI_DATETIME_HRC
#include "DateTime.hrc"
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _RPTUI_DLGRESID_HRC
#include "RptResId.hrc"
#endif
#ifndef _RPTUI_SLOTID_HRC_
#include "rptui_slotid.hrc"
#endif
#ifndef _RPTUI_MODULE_HELPER_DBU_HXX_
#include "ModuleHelper.hxx"
#endif
#ifndef RTPUI_REPORTDESIGN_HELPID_HRC
#include "helpids.hrc"
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#ifndef _GLOBLMN_HRC
#include <svx/globlmn.hrc>
#endif
#ifndef _SBASLTID_HRC
#include <svx/svxids.hrc>
#endif
#ifndef _DBHELPER_DBCONVERSION_HXX_
#include <connectivity/dbconversion.hxx>
#endif
#ifndef INCLUDED_SVTOOLS_SYSLOCALE_HXX
#include <svtools/syslocale.hxx>
#endif
#ifndef RPTUI_TOOLS_HXX
#include "UITools.hxx"
#endif
#ifndef _REPORT_RPTUIDEF_HXX
#include "RptDef.hxx"
#endif
#ifndef REPORTDESIGN_SHARED_UISTRINGS_HRC
#include "uistrings.hrc"
#endif
#ifndef RPTUI_REPORTCONTROLLER_HXX
#include "ReportController.hxx"
#endif
#ifndef _COM_SUN_STAR_REPORT_XFORMATTEDFIELD_HPP_
#include <com/sun/star/report/XFormattedField.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_TIME_HPP_
#include <com/sun/star/util/Time.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_NUMBERFORMAT_HPP_
#include <com/sun/star/util/NumberFormat.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATPREVIEWER_HPP_
#include <com/sun/star/util/XNumberFormatPreviewer.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTYPES_HPP_
#include <com/sun/star/util/XNumberFormatTypes.hpp>
#endif
#ifndef _COM_SUN_STAR_I18N_NUMBERFORMATINDEX_HPP_
#include <com/sun/star/i18n/NumberFormatIndex.hpp>
#endif
#ifndef _COMPHELPER_NUMBERS_HXX_
#include <comphelper/numbers.hxx>
#endif
#include <algorithm>

namespace rptui
{
using namespace ::com::sun::star;
using namespace ::comphelper;

DBG_NAME( rpt_ODateTimeDialog )
//========================================================================
// class ODateTimeDialog
//========================================================================
ODateTimeDialog::ODateTimeDialog( Window* _pParent
                                           ,const uno::Reference< report::XSection >& _xHoldAlive
                                           ,OReportController* _pController)
    : ModalDialog( _pParent, ModuleRes(RID_DATETIME_DLG) )
    ,m_aFLDate(this, ModuleRes(FL_DATE      ) )
    ,m_aDate(this,   ModuleRes(CB_DATE      ) )
    ,m_aDateF1(this, ModuleRes(RB_DATE_F1   ) )
    ,m_aDateF2(this, ModuleRes(RB_DATE_F2   ) )
    ,m_aDateF3(this, ModuleRes(RB_DATE_F3   ) )
    ,m_aFLTime(this, ModuleRes(FL_TIME      ) )
    ,m_aTime(this,   ModuleRes(CB_TIME      ) )
    ,m_aTimeF1(this, ModuleRes(RB_TIME_F1   ) )
    ,m_aTimeF2(this, ModuleRes(RB_TIME_F2   ) )
    ,m_aTimeF3(this, ModuleRes(RB_TIME_F3   ) )
    ,m_aFL1(this,ModuleRes(FL_SEPARATOR1) )
    ,m_aPB_OK(this,     ModuleRes(PB_OK))
    ,m_aPB_CANCEL(this, ModuleRes(PB_CANCEL))
    ,m_aPB_Help(this,   ModuleRes(PB_HELP))
    ,m_pController(_pController)
    ,m_xHoldAlive(_xHoldAlive)
{
    DBG_CTOR( rpt_ODateTimeDialog,NULL);

    try
    {
        SvtSysLocale aSysLocale;
        m_nLocale = aSysLocale.GetLocaleData().getLocale();
    }
    catch(uno::Exception&)
    {
    }
    m_aDateF1.SetText(getFormatString(i18n::NumberFormatIndex::DATE_SYSTEM_LONG));
    m_aDateF2.SetText(getFormatString(i18n::NumberFormatIndex::DATE_SYS_DMMMYYYY));
    m_aDateF3.SetText(getFormatString(i18n::NumberFormatIndex::DATE_SYSTEM_SHORT));

    m_aTimeF1.SetText(getFormatString(i18n::NumberFormatIndex::TIME_HHMMSS));
    m_aTimeF2.SetText(getFormatString(i18n::NumberFormatIndex::TIME_HHMMSSAMPM));
    m_aTimeF3.SetText(getFormatString(i18n::NumberFormatIndex::TIME_HHMM));

    CheckBox* pCheckBoxes[] = { &m_aDate,&m_aTime};
    for ( size_t i = 0 ; i < sizeof(pCheckBoxes)/sizeof(pCheckBoxes[0]); ++i)
        pCheckBoxes[i]->SetClickHdl(LINK(this,ODateTimeDialog,CBClickHdl));

    FreeResource();
}

//------------------------------------------------------------------------
ODateTimeDialog::~ODateTimeDialog()
{
    DBG_DTOR( rpt_ODateTimeDialog,NULL);
}
// -----------------------------------------------------------------------------
short ODateTimeDialog::Execute()
{
    DBG_CHKTHIS( rpt_ODateTimeDialog,NULL);
    short nRet = ModalDialog::Execute();
    if ( nRet == RET_OK && (m_aDate.IsChecked() || m_aTime.IsChecked()) )
    {
        try
        {
            sal_Int32 nLength = 0;
            uno::Sequence<beans::PropertyValue> aValues( 4 );
            aValues[nLength].Name = PROPERTY_SECTION;
            aValues[nLength++].Value <<= m_xHoldAlive;

            aValues[nLength].Name = PROPERTY_STATE;
            aValues[nLength++].Value <<= m_aTime.IsChecked();

            aValues[nLength].Name = PROPERTY_FORMATKEYDATE;
            aValues[nLength++].Value <<= getFormatKey(getFormatIndex(sal_True));

            aValues[nLength].Name = PROPERTY_FORMATKEYTIME;
            aValues[nLength++].Value <<= getFormatKey(getFormatIndex(sal_False));

            m_pController->executeChecked(SID_DATETIME,aValues);
        }
        catch(uno::Exception&)
        {
            nRet = RET_NO;
        }
    }
    return nRet;
}
// -----------------------------------------------------------------------------
::rtl::OUString ODateTimeDialog::getFormatString(::sal_Int16 _nNumberFormatIndex)
{
    DBG_CHKTHIS( rpt_ODateTimeDialog,NULL);
    uno::Reference< util::XNumberFormatter> xNumberFormatter = m_pController->getNumberFormatter();
    uno::Reference< util::XNumberFormats> xFormats = xNumberFormatter->getNumberFormatsSupplier()->getNumberFormats();
    uno::Reference< util::XNumberFormatTypes> xNumType(xFormats,uno::UNO_QUERY);
    sal_Int32 nFormatKey = xNumType->getFormatIndex(_nNumberFormatIndex,m_nLocale);

    uno::Reference< beans::XPropertySet> xFormSet = xFormats->getByKey(nFormatKey);
    OSL_ENSURE(xFormSet.is(),"XPropertySet is null!");
    ::rtl::OUString sFormat;
    xFormSet->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FormatString"))) >>= sFormat;

    lang::Locale aLocale;
    ::comphelper::getNumberFormatProperty(xNumberFormatter,nFormatKey,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Locale"))) >>= aLocale;

    double nValue = 0;
    if ( _nNumberFormatIndex >= i18n::NumberFormatIndex::TIME_START )
    {
        Time aCurrentTime;
        nValue = ::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toTime(aCurrentTime.GetTime()));
    }
    else
    {
        Date aCurrentDate;
        static ::com::sun::star::util::Date STANDARD_DB_DATE(31,12,1899);
        nValue = ::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDate(static_cast<sal_Int32>(aCurrentDate.GetDate())),STANDARD_DB_DATE);
    }

    uno::Reference< util::XNumberFormatPreviewer> xPreViewer(xNumberFormatter,uno::UNO_QUERY);
    OSL_ENSURE(xPreViewer.is(),"XNumberFormatPreviewer is null!");
    return xPreViewer->convertNumberToPreviewString(sFormat,nValue,aLocale,sal_True);
}
// -----------------------------------------------------------------------------
IMPL_LINK( ODateTimeDialog, CBClickHdl, CheckBox*, _pBox )
{
    DBG_CHKTHIS( rpt_ODateTimeDialog,NULL);

    RadioButton* pRadioButtons[] = { &m_aDateF1,&m_aDateF2,&m_aDateF3, &m_aTimeF1, &m_aTimeF2, &m_aTimeF3};
    int i = 0;
    int nCount = 3;
    sal_Bool bShow = sal_False;
    if ( _pBox == &m_aDate )
    {
        bShow = m_aDate.IsChecked();
    }
    else if ( _pBox == &m_aTime )
    {
        bShow = m_aTime.IsChecked();
        i = 3;
        nCount = sizeof(pRadioButtons)/sizeof(pRadioButtons[0]);
    }

    for (  ; i < nCount ; ++i)
        pRadioButtons[i]->Enable(bShow);
    return 1L;
}
// -----------------------------------------------------------------------------
sal_Int16 ODateTimeDialog::getFormatIndex(sal_Bool _bDate)
{
    DBG_CHKTHIS( rpt_ODateTimeDialog,NULL);
    sal_Int16 nFormat;
    if ( _bDate )
        nFormat = m_aDateF1.IsChecked() ? i18n::NumberFormatIndex::DATE_SYSTEM_LONG : (m_aDateF2.IsChecked() ? i18n::NumberFormatIndex::DATE_SYS_DMMMYYYY : i18n::NumberFormatIndex::DATE_SYSTEM_SHORT);
    else
        nFormat = m_aTimeF1.IsChecked() ? i18n::NumberFormatIndex::TIME_HHMMSS : (m_aTimeF2.IsChecked() ? i18n::NumberFormatIndex::TIME_HHMMSSAMPM : i18n::NumberFormatIndex::TIME_HHMM);
    return nFormat;
}
// -----------------------------------------------------------------------------
sal_Int32 ODateTimeDialog::getFormatKey(::sal_Int16 _nNumberFormatIndex)
{
    uno::Reference< util::XNumberFormatter> xNumberFormatter = m_pController->getNumberFormatter();
    uno::Reference< util::XNumberFormats> xFormats = xNumberFormatter->getNumberFormatsSupplier()->getNumberFormats();
    uno::Reference< util::XNumberFormatTypes> xNumType(xFormats,uno::UNO_QUERY);
    return xNumType->getFormatIndex(_nNumberFormatIndex,m_nLocale);
}
// =============================================================================
} // rptui
// =============================================================================
<commit_msg>INTEGRATION: CWS rpt23fix01 (1.2.2); FILE MERGED 2007/07/16 07:30:42 lla 1.2.2.2: #i78500# insert time control only 2007/07/11 10:19:09 oj 1.2.2.1: #i78504# use own numberformatter<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: DateTime.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2007-08-02 14:36:18 $
 *
 *  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
 *
 ************************************************************************/
#include "precompiled_reportdesign.hxx"

#ifndef RPTUI_DATETIME_HXX
#include "DateTime.hxx"
#endif
#ifndef RPTUI_DATETIME_HRC
#include "DateTime.hrc"
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _RPTUI_DLGRESID_HRC
#include "RptResId.hrc"
#endif
#ifndef _RPTUI_SLOTID_HRC_
#include "rptui_slotid.hrc"
#endif
#ifndef _RPTUI_MODULE_HELPER_DBU_HXX_
#include "ModuleHelper.hxx"
#endif
#ifndef RTPUI_REPORTDESIGN_HELPID_HRC
#include "helpids.hrc"
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#ifndef _GLOBLMN_HRC
#include <svx/globlmn.hrc>
#endif
#ifndef _SBASLTID_HRC
#include <svx/svxids.hrc>
#endif
#ifndef _DBHELPER_DBCONVERSION_HXX_
#include <connectivity/dbconversion.hxx>
#endif
#ifndef INCLUDED_SVTOOLS_SYSLOCALE_HXX
#include <svtools/syslocale.hxx>
#endif
#ifndef RPTUI_TOOLS_HXX
#include "UITools.hxx"
#endif
#ifndef _REPORT_RPTUIDEF_HXX
#include "RptDef.hxx"
#endif
#ifndef REPORTDESIGN_SHARED_UISTRINGS_HRC
#include "uistrings.hrc"
#endif
#ifndef RPTUI_REPORTCONTROLLER_HXX
#include "ReportController.hxx"
#endif
#ifndef _COM_SUN_STAR_REPORT_XFORMATTEDFIELD_HPP_
#include <com/sun/star/report/XFormattedField.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_TIME_HPP_
#include <com/sun/star/util/Time.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_NUMBERFORMAT_HPP_
#include <com/sun/star/util/NumberFormat.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATPREVIEWER_HPP_
#include <com/sun/star/util/XNumberFormatPreviewer.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTYPES_HPP_
#include <com/sun/star/util/XNumberFormatTypes.hpp>
#endif
#ifndef _COM_SUN_STAR_I18N_NUMBERFORMATINDEX_HPP_
#include <com/sun/star/i18n/NumberFormatIndex.hpp>
#endif
#ifndef _COMPHELPER_NUMBERS_HXX_
#include <comphelper/numbers.hxx>
#endif
#include <algorithm>

namespace rptui
{
using namespace ::com::sun::star;
using namespace ::comphelper;

DBG_NAME( rpt_ODateTimeDialog )
//========================================================================
// class ODateTimeDialog
//========================================================================
ODateTimeDialog::ODateTimeDialog( Window* _pParent
                                           ,const uno::Reference< report::XSection >& _xHoldAlive
                                           ,OReportController* _pController)
    : ModalDialog( _pParent, ModuleRes(RID_DATETIME_DLG) )
    ,m_aFLDate(this, ModuleRes(FL_DATE      ) )
    ,m_aDate(this,   ModuleRes(CB_DATE      ) )
    ,m_aDateF1(this, ModuleRes(RB_DATE_F1   ) )
    ,m_aDateF2(this, ModuleRes(RB_DATE_F2   ) )
    ,m_aDateF3(this, ModuleRes(RB_DATE_F3   ) )
    ,m_aFLTime(this, ModuleRes(FL_TIME      ) )
    ,m_aTime(this,   ModuleRes(CB_TIME      ) )
    ,m_aTimeF1(this, ModuleRes(RB_TIME_F1   ) )
    ,m_aTimeF2(this, ModuleRes(RB_TIME_F2   ) )
    ,m_aTimeF3(this, ModuleRes(RB_TIME_F3   ) )
    ,m_aFL1(this,ModuleRes(FL_SEPARATOR1) )
    ,m_aPB_OK(this,     ModuleRes(PB_OK))
    ,m_aPB_CANCEL(this, ModuleRes(PB_CANCEL))
    ,m_aPB_Help(this,   ModuleRes(PB_HELP))
    ,m_pController(_pController)
    ,m_xHoldAlive(_xHoldAlive)
{
    DBG_CTOR( rpt_ODateTimeDialog,NULL);

    try
    {
        SvtSysLocale aSysLocale;
        m_nLocale = aSysLocale.GetLocaleData().getLocale();
    }
    catch(uno::Exception&)
    {
    }
    m_aDateF1.SetText(getFormatString(i18n::NumberFormatIndex::DATE_SYSTEM_LONG));
    m_aDateF2.SetText(getFormatString(i18n::NumberFormatIndex::DATE_SYS_DMMMYYYY));
    m_aDateF3.SetText(getFormatString(i18n::NumberFormatIndex::DATE_SYSTEM_SHORT));

    m_aTimeF1.SetText(getFormatString(i18n::NumberFormatIndex::TIME_HHMMSS));
    m_aTimeF2.SetText(getFormatString(i18n::NumberFormatIndex::TIME_HHMMSSAMPM));
    m_aTimeF3.SetText(getFormatString(i18n::NumberFormatIndex::TIME_HHMM));

    CheckBox* pCheckBoxes[] = { &m_aDate,&m_aTime};
    for ( size_t i = 0 ; i < sizeof(pCheckBoxes)/sizeof(pCheckBoxes[0]); ++i)
        pCheckBoxes[i]->SetClickHdl(LINK(this,ODateTimeDialog,CBClickHdl));

    FreeResource();
}

//------------------------------------------------------------------------
ODateTimeDialog::~ODateTimeDialog()
{
    DBG_DTOR( rpt_ODateTimeDialog,NULL);
}
// -----------------------------------------------------------------------------
short ODateTimeDialog::Execute()
{
    DBG_CHKTHIS( rpt_ODateTimeDialog,NULL);
    short nRet = ModalDialog::Execute();
    if ( nRet == RET_OK && (m_aDate.IsChecked() || m_aTime.IsChecked()) )
    {
        try
        {
            sal_Int32 nLength = 0;
            uno::Sequence<beans::PropertyValue> aValues( 5 );
            aValues[nLength].Name = PROPERTY_SECTION;
            aValues[nLength++].Value <<= m_xHoldAlive;

            aValues[nLength].Name = PROPERTY_TIME_STATE;
            aValues[nLength++].Value <<= m_aTime.IsChecked();

            aValues[nLength].Name = PROPERTY_DATE_STATE;
            aValues[nLength++].Value <<= m_aDate.IsChecked();

            aValues[nLength].Name = PROPERTY_FORMATKEYDATE;
            aValues[nLength++].Value <<= getFormatKey(getFormatIndex(sal_True));

            aValues[nLength].Name = PROPERTY_FORMATKEYTIME;
            aValues[nLength++].Value <<= getFormatKey(getFormatIndex(sal_False));

            m_pController->executeChecked(SID_DATETIME,aValues);
        }
        catch(uno::Exception&)
        {
            nRet = RET_NO;
        }
    }
    return nRet;
}
// -----------------------------------------------------------------------------
::rtl::OUString ODateTimeDialog::getFormatString(::sal_Int16 _nNumberFormatIndex)
{
    DBG_CHKTHIS( rpt_ODateTimeDialog,NULL);
    uno::Reference< util::XNumberFormatter> xNumberFormatter = m_pController->getReportNumberFormatter();
    uno::Reference< util::XNumberFormats> xFormats = xNumberFormatter->getNumberFormatsSupplier()->getNumberFormats();
    uno::Reference< util::XNumberFormatTypes> xNumType(xFormats,uno::UNO_QUERY);
    sal_Int32 nFormatKey = xNumType->getFormatIndex(_nNumberFormatIndex,m_nLocale);

    uno::Reference< beans::XPropertySet> xFormSet = xFormats->getByKey(nFormatKey);
    OSL_ENSURE(xFormSet.is(),"XPropertySet is null!");
    ::rtl::OUString sFormat;
    xFormSet->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FormatString"))) >>= sFormat;

    lang::Locale aLocale;
    ::comphelper::getNumberFormatProperty(xNumberFormatter,nFormatKey,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Locale"))) >>= aLocale;

    double nValue = 0;
    if ( _nNumberFormatIndex >= i18n::NumberFormatIndex::TIME_START )
    {
        Time aCurrentTime;
        nValue = ::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toTime(aCurrentTime.GetTime()));
    }
    else
    {
        Date aCurrentDate;
        static ::com::sun::star::util::Date STANDARD_DB_DATE(31,12,1899);
        nValue = ::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDate(static_cast<sal_Int32>(aCurrentDate.GetDate())),STANDARD_DB_DATE);
    }

    uno::Reference< util::XNumberFormatPreviewer> xPreViewer(xNumberFormatter,uno::UNO_QUERY);
    OSL_ENSURE(xPreViewer.is(),"XNumberFormatPreviewer is null!");
    return xPreViewer->convertNumberToPreviewString(sFormat,nValue,aLocale,sal_True);
}
// -----------------------------------------------------------------------------
IMPL_LINK( ODateTimeDialog, CBClickHdl, CheckBox*, _pBox )
{
    DBG_CHKTHIS( rpt_ODateTimeDialog,NULL);

    RadioButton* pRadioButtons[] = { &m_aDateF1,&m_aDateF2,&m_aDateF3, &m_aTimeF1, &m_aTimeF2, &m_aTimeF3};
    int i = 0;
    int nCount = 3;
    sal_Bool bShow = sal_False;
    if ( _pBox == &m_aDate )
    {
        bShow = m_aDate.IsChecked();
    }
    else if ( _pBox == &m_aTime )
    {
        bShow = m_aTime.IsChecked();
        i = 3;
        nCount = sizeof(pRadioButtons)/sizeof(pRadioButtons[0]);
    }

    for (  ; i < nCount ; ++i)
        pRadioButtons[i]->Enable(bShow);
    return 1L;
}
// -----------------------------------------------------------------------------
sal_Int16 ODateTimeDialog::getFormatIndex(sal_Bool _bDate)
{
    DBG_CHKTHIS( rpt_ODateTimeDialog,NULL);
    sal_Int16 nFormat;
    if ( _bDate )
        nFormat = m_aDateF1.IsChecked() ? i18n::NumberFormatIndex::DATE_SYSTEM_LONG : (m_aDateF2.IsChecked() ? i18n::NumberFormatIndex::DATE_SYS_DMMMYYYY : i18n::NumberFormatIndex::DATE_SYSTEM_SHORT);
    else
        nFormat = m_aTimeF1.IsChecked() ? i18n::NumberFormatIndex::TIME_HHMMSS : (m_aTimeF2.IsChecked() ? i18n::NumberFormatIndex::TIME_HHMMSSAMPM : i18n::NumberFormatIndex::TIME_HHMM);
    return nFormat;
}
// -----------------------------------------------------------------------------
sal_Int32 ODateTimeDialog::getFormatKey(::sal_Int16 _nNumberFormatIndex)
{
    uno::Reference< util::XNumberFormatter> xNumberFormatter = m_pController->getReportNumberFormatter();
    uno::Reference< util::XNumberFormats> xFormats = xNumberFormatter->getNumberFormatsSupplier()->getNumberFormats();
    uno::Reference< util::XNumberFormatTypes> xNumType(xFormats,uno::UNO_QUERY);
    return xNumType->getFormatIndex(_nNumberFormatIndex,m_nLocale);
}
// =============================================================================
} // rptui
// =============================================================================
<|endoftext|>


<commit_before>//  illarionserver - server for the game Illarion
//  Copyright 2011 Illarion e.V.
//
//  This file is part of illarionserver.
//
//  illarionserver is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  illarionserver 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 General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with illarionserver.  If not, see <http://www.gnu.org/licenses/>.

#include "db/ConnectionManager.hpp"
#include "ArmorObjectTable.hpp"
#include <iostream>

ArmorObjectTable::ArmorObjectTable() : m_dataOK(false) {
    reload();
}

void ArmorObjectTable::reload() {
#ifdef DataConnect_DEBUG
    std::cout << "ArmorObjectTable: reload" << std::endl;
#endif

    try {
        ConnectionManager::TransactionHolder transaction = dbmgr->getTransaction();

        std::vector<TYPE_OF_ITEM_ID> ids;
        std::vector<TYPE_OF_BODYPARTS> bodyparts;
        std::vector<TYPE_OF_PUNCTUREARMOR> puncture;
        std::vector<TYPE_OF_STROKEARMOR> stroke;
        std::vector<TYPE_OF_THRUSTARMOR> thrust;
        std::vector<TYPE_OF_MAGICDISTURBANCE> magicdisturbance;
        std::vector<int16_t> absorb;
        std::vector<int16_t> stiffness;
        size_t rows = di::select_all<
                      di::Integer, di::Integer, di::Integer, di::Integer, di::Integer, di::Integer, di::Integer, di::Integer
                      >(transaction, ids, bodyparts, puncture, stroke, thrust, magicdisturbance, absorb, stiffness,
                        "SELECT arm_itemid, arm_bodyparts, arm_puncture, arm_stroke, arm_thrust, arm_magicdisturbance, arm_absorb, arm_stiffness FROM armor");

        if (rows > 0) {
            clearOldTable();
            ArmorStruct temprecord;

            for (size_t i = 0; i < rows; ++i) {
                temprecord.BodyParts = bodyparts[i];
                temprecord.PunctureArmor = puncture[i];
                temprecord.StrokeArmor = stroke[i];
                temprecord.ThrustArmor = thrust[i];
                temprecord.MagicDisturbance = magicdisturbance[i];
                temprecord.Absorb = absorb[i];
                temprecord.Stiffness = stiffness[i];
                m_table[ ids[i] ] = temprecord;
            }

            m_dataOK = true;
        } else {
            m_dataOK = false;
        }

#ifdef DataConnect_DEBUG
        std::cout << "loaded " << rows << " rows into ArmorObjectTable" << std::endl;
#endif

    } catch (...) {
        m_dataOK = false;
    }
}

bool ArmorObjectTable::find(TYPE_OF_ITEM_ID Id, ArmorStruct &ret) {
    TABLE::iterator iterator;
    iterator = m_table.find(Id);

    if (iterator == m_table.end()) {
        return false;
    } else {
        ret = (*iterator).second;
        return true;
    }
}

void ArmorObjectTable::clearOldTable() {
    m_table.clear();
}

ArmorObjectTable::~ArmorObjectTable() {
    clearOldTable();
}
<commit_msg>Implemented new database interface to the armor table loader.<commit_after>//  illarionserver - server for the game Illarion
//  Copyright 2011 Illarion e.V.
//
//  This file is part of illarionserver.
//
//  illarionserver is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  illarionserver 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 General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with illarionserver.  If not, see <http://www.gnu.org/licenses/>.

#include "db/ConnectionManager.hpp"
#include "db/SchemaHelper.hpp"
#include "db/Query.hpp"
#include "db/Result.hpp"

#include "ArmorObjectTable.hpp"
#include "types.hpp"

#include <iostream>
#include <sstream>

ArmorObjectTable::ArmorObjectTable() : m_dataOK(false) {
    reload();
}

void ArmorObjectTable::reload() {
#ifdef DataConnect_DEBUG
    std::cout << "ArmorObjectTable: reload" << std::endl;
#endif

    try {
        Database::PConnection connection =
            Database::ConnectionManager::getInstance()->getConnection();

        std::stringstream ss;
        ss << "SELECT ";
        ss << "\"arm_itemid\", \"arm_bodyparts\", \"arm_puncture\", ";
        ss << "\"arm_stroke\", \"arm_thrust\", \"arm_magicdisturbance\", ";
        ss << "\"arm_absorb\", \"arm_stiffness\" ";
        ss << "FROM ";
        ss << Database::SchemaHelper::getServerSchema() << ".\"armor\";";

        Database::PQuery query = new Database::Query(connection, ss.str());
        Database::Result results = query->execute();

        if (!results.empty()) {
            clearOldTable();
            ArmorStruct temprecord;

            for (Database::Result::ConstIterator itr = results.begin();
                 itr != results.end(); ++itr) {

                temprecord.BodyParts = (TYPE_OF_BODYPARTS) ((*itr)["arm_bodyparts"].as<int16_t>());
                temprecord.PunctureArmor = (TYPE_OF_PUNCTUREARMOR) ((*itr)["arm_puncture"].as<int16_t>());
                temprecord.StrokeArmor = (TYPE_OF_STROKEARMOR) ((*itr)["arm_stroke"].as<int16_t>());
                temprecord.ThrustArmor = (TYPE_OF_THRUSTARMOR) ((*itr)["arm_thrust"].as<int16_t>());
                temprecord.MagicDisturbance = (TYPE_OF_MAGICDISTURBANCE) (*itr)["arm_magicdisturbance"].as<int32_t>();
                temprecord.Absorb = (*itr)["arm_absorb"].as<int16_t>();
                temprecord.Stiffness = (*itr)["arm_stiffness"].as<int16_t>();

                m_table[(TYPE_OF_ITEM_ID) ((*itr)["arm_itemid"].as<TYPE_OF_ITEM_ID>())] = temprecord;
            }
            m_dataOK = true;
        } else {
            m_dataOK = false;
        }

#ifdef DataConnect_DEBUG
        std::cout << "loaded " << rows;
        std::cout << " rows into ArmorObjectTable" << std::endl;
#endif

    } catch (...) {
        m_dataOK = false;
    }
}

bool ArmorObjectTable::find(TYPE_OF_ITEM_ID Id, ArmorStruct &ret) {
    TABLE::iterator iterator;
    iterator = m_table.find(Id);

    if (iterator == m_table.end()) {
        return false;
    } else {
        ret = (*iterator).second;
        return true;
    }
}

void ArmorObjectTable::clearOldTable() {
    m_table.clear();
}

ArmorObjectTable::~ArmorObjectTable() {
    clearOldTable();
}
<|endoftext|>


<commit_before>/* Copyright 2014 Peter Goodman, all rights reserved. */

/* Copyright 2014 Peter Goodman, all rights reserved. */

#include "clients/util/instrument_memop.h"  // Needs to go first.

GRANARY_USING_NAMESPACE granary;

// Instrument all of the instructions in a basic block.
void MemOpInstrumentationTool::InstrumentBlock(DecodedBasicBlock *bb) {
  MemoryOperand mloc1, mloc2;
  for (auto instr : bb->AppInstructions()) {
    auto num_matched = instr->CountMatchedOperands(ReadOrWriteTo(mloc1),
                                                   ReadOrWriteTo(mloc2));
    if (2 == num_matched) {
      InstrumentMemOp(bb, instr, mloc1);
      InstrumentMemOp(bb, instr, mloc2);
    } else if (1 == num_matched) {
      InstrumentMemOp(bb, instr, mloc1);
    }
  }
}

// Instrument a memory operation.
void MemOpInstrumentationTool::InstrumentMemOp(DecodedBasicBlock *bb,
                                               NativeInstruction *instr,
                                               MemoryOperand &mloc) {
  // Doesn't read from or write to memory.
  if (mloc.IsEffectiveAddress()) return;

  // Reads or writes from an absolute address, not through a register.
  VirtualRegister addr_reg;
  const void *addr_ptr(nullptr);

  if (mloc.MatchRegister(addr_reg)) {
    if (addr_reg.IsSegmentOffset()) {
      InstrumentSegMemOp(bb, instr, mloc, addr_reg);
    } else {
      RegisterOperand reg(addr_reg);
      InstrumentMemOp(bb, instr, mloc, reg);
    }
  } else if (mloc.MatchPointer(addr_ptr)) {
    InstrumentAddrMemOp(bb, instr, mloc, addr_ptr);

  } else if (mloc.IsCompound()) {
    InstrumentCompoundMemOp(bb, instr, mloc);
  }
}

// Instrument a memory operand that accesses some memory through an offset of
// a segment register. We assume that the first quadword stored in the segment
// points to the segment base address.
void MemOpInstrumentationTool::InstrumentSegMemOp(DecodedBasicBlock *bb,
                                                  NativeInstruction *instr,
                                                  MemoryOperand &mloc,
                                                  VirtualRegister seg_offs) {

  VirtualRegister seg_reg;
  GRANARY_IF_DEBUG( auto matched = ) mloc.MatchSegmentRegister(seg_reg);
  GRANARY_ASSERT(matched);

  RegisterOperand offset_op(seg_offs);
  RegisterOperand addr_reg_op(bb->AllocateVirtualRegister());
  RegisterOperand seg_reg_op(seg_reg);
  lir::InlineAssembly asm_(offset_op, addr_reg_op, seg_reg_op);
  asm_.InlineBefore(instr, "MOV r64 %1, m64 %2:[0];"
                           "LEA r64 %1, m64 [%1 + %0];"_x86_64);
  InstrumentMemOp(bb, instr, mloc, addr_reg_op);
}

// Instrument a memory operand that accesses some absolute memory address.
void MemOpInstrumentationTool::InstrumentAddrMemOp(DecodedBasicBlock *bb,
                                                   NativeInstruction *instr,
                                                   MemoryOperand &mloc,
                                                   const void *addr) {
  ImmediateOperand native_addr(addr);
  RegisterOperand addr_reg_op(bb->AllocateVirtualRegister());
  lir::InlineAssembly asm_(native_addr, addr_reg_op);
  asm_.InlineBefore(instr, "MOV r64 %1, i64 %0;"_x86_64);
  InstrumentMemOp(bb, instr, mloc, addr_reg_op);
}

void MemOpInstrumentationTool::InstrumentCompoundMemOp(
    DecodedBasicBlock *bb, NativeInstruction *instr,
    MemoryOperand &mloc) {

  // Track stack pointer propagation.
  VirtualRegister base;
  VirtualRegister addr_reg = bb->AllocateVirtualRegister();
  if (mloc.CountMatchedRegisters(base) &&
      (base.IsStackPointer() || base.IsVirtualStackPointer())) {
    addr_reg.ConvertToVirtualStackPointer();
  }

  RegisterOperand addr_reg_op(addr_reg);
  lir::InlineAssembly asm_(mloc, addr_reg_op);
  asm_.InlineBefore(instr, "LEA r64 %1, m64 %0;"_x86_64);
  InstrumentMemOp(bb, instr, mloc, addr_reg_op);
}
<commit_msg>Minor copyright fix<commit_after>/* Copyright 2014 Peter Goodman, all rights reserved. */

#include "clients/util/instrument_memop.h"  // Needs to go first.

GRANARY_USING_NAMESPACE granary;

// Instrument all of the instructions in a basic block.
void MemOpInstrumentationTool::InstrumentBlock(DecodedBasicBlock *bb) {
  MemoryOperand mloc1, mloc2;
  for (auto instr : bb->AppInstructions()) {
    auto num_matched = instr->CountMatchedOperands(ReadOrWriteTo(mloc1),
                                                   ReadOrWriteTo(mloc2));
    if (2 == num_matched) {
      InstrumentMemOp(bb, instr, mloc1);
      InstrumentMemOp(bb, instr, mloc2);
    } else if (1 == num_matched) {
      InstrumentMemOp(bb, instr, mloc1);
    }
  }
}

// Instrument a memory operation.
void MemOpInstrumentationTool::InstrumentMemOp(DecodedBasicBlock *bb,
                                               NativeInstruction *instr,
                                               MemoryOperand &mloc) {
  // Doesn't read from or write to memory.
  if (mloc.IsEffectiveAddress()) return;

  // Reads or writes from an absolute address, not through a register.
  VirtualRegister addr_reg;
  const void *addr_ptr(nullptr);

  if (mloc.MatchRegister(addr_reg)) {
    if (addr_reg.IsSegmentOffset()) {
      InstrumentSegMemOp(bb, instr, mloc, addr_reg);
    } else {
      RegisterOperand reg(addr_reg);
      InstrumentMemOp(bb, instr, mloc, reg);
    }
  } else if (mloc.MatchPointer(addr_ptr)) {
    InstrumentAddrMemOp(bb, instr, mloc, addr_ptr);

  } else if (mloc.IsCompound()) {
    InstrumentCompoundMemOp(bb, instr, mloc);
  }
}

// Instrument a memory operand that accesses some memory through an offset of
// a segment register. We assume that the first quadword stored in the segment
// points to the segment base address.
void MemOpInstrumentationTool::InstrumentSegMemOp(DecodedBasicBlock *bb,
                                                  NativeInstruction *instr,
                                                  MemoryOperand &mloc,
                                                  VirtualRegister seg_offs) {

  VirtualRegister seg_reg;
  GRANARY_IF_DEBUG( auto matched = ) mloc.MatchSegmentRegister(seg_reg);
  GRANARY_ASSERT(matched);

  RegisterOperand offset_op(seg_offs);
  RegisterOperand addr_reg_op(bb->AllocateVirtualRegister());
  RegisterOperand seg_reg_op(seg_reg);
  lir::InlineAssembly asm_(offset_op, addr_reg_op, seg_reg_op);
  asm_.InlineBefore(instr, "MOV r64 %1, m64 %2:[0];"
                           "LEA r64 %1, m64 [%1 + %0];"_x86_64);
  InstrumentMemOp(bb, instr, mloc, addr_reg_op);
}

// Instrument a memory operand that accesses some absolute memory address.
void MemOpInstrumentationTool::InstrumentAddrMemOp(DecodedBasicBlock *bb,
                                                   NativeInstruction *instr,
                                                   MemoryOperand &mloc,
                                                   const void *addr) {
  ImmediateOperand native_addr(addr);
  RegisterOperand addr_reg_op(bb->AllocateVirtualRegister());
  lir::InlineAssembly asm_(native_addr, addr_reg_op);
  asm_.InlineBefore(instr, "MOV r64 %1, i64 %0;"_x86_64);
  InstrumentMemOp(bb, instr, mloc, addr_reg_op);
}

void MemOpInstrumentationTool::InstrumentCompoundMemOp(
    DecodedBasicBlock *bb, NativeInstruction *instr,
    MemoryOperand &mloc) {

  // Track stack pointer propagation.
  VirtualRegister base;
  VirtualRegister addr_reg = bb->AllocateVirtualRegister();
  if (mloc.CountMatchedRegisters(base) &&
      (base.IsStackPointer() || base.IsVirtualStackPointer())) {
    addr_reg.ConvertToVirtualStackPointer();
  }

  RegisterOperand addr_reg_op(addr_reg);
  lir::InlineAssembly asm_(mloc, addr_reg_op);
  asm_.InlineBefore(instr, "LEA r64 %1, m64 %0;"_x86_64);
  InstrumentMemOp(bb, instr, mloc, addr_reg_op);
}
<|endoftext|>