<commit_before>#include "pch.h"
#include "Servo.h"
#include <EGL/egl.h>
#include "../DefaultUrl.h"

namespace winrt::servo {

void on_load_started() { sServo->Delegate().OnServoLoadStarted(); }

void on_load_ended() { sServo->Delegate().OnServoLoadEnded(); }

void on_history_changed(bool back, bool forward) {
  sServo->Delegate().OnServoHistoryChanged(back, forward);
}

void on_shutdown_complete() { sServo->Delegate().OnServoShutdownComplete(); }

void on_title_changed(const char *title) {
  sServo->Delegate().OnServoTitleChanged(char2hstring(title));
}

void on_url_changed(const char *url) {
  sServo->Delegate().OnServoURLChanged(char2hstring(url));
}

void wakeup() { sServo->Delegate().WakeUp(); }

bool on_allow_navigation(const char *url) {
  return sServo->Delegate().OnServoAllowNavigation(char2hstring(url));
};

void on_animating_changed(bool aAnimating) {
  sServo->Delegate().OnServoAnimatingChanged(aAnimating);
}

void on_panic(const char *backtrace) {
  if (sLogHandle != INVALID_HANDLE_VALUE) {
    CloseHandle(sLogHandle);
    sLogHandle = INVALID_HANDLE_VALUE;
  }
  throw hresult_error(E_FAIL, char2hstring(backtrace));
}

void on_ime_state_changed(bool aShow) {
  sServo->Delegate().OnServoIMEStateChanged(aShow);
}

void set_clipboard_contents(const char *) {
  // FIXME
}

const char *get_clipboard_contents() {
  // FIXME
  return nullptr;
}

void on_media_session_metadata(const char *title, const char *album,
                               const char *artist) {
  return sServo->Delegate().OnServoMediaSessionMetadata(
      char2hstring(title), char2hstring(album), char2hstring(artist));
}

void on_media_session_playback_state_change(
    const capi::CMediaSessionPlaybackState state) {
  return sServo->Delegate().OnServoMediaSessionPlaybackStateChange(state);
}

void prompt_alert(const char *message, bool trusted) {
  sServo->Delegate().OnServoPromptAlert(char2hstring(message), trusted);
}

void show_context_menu(const char *title, const char *const *items_list,
                       uint32_t items_size) {
  std::optional<hstring> opt_title = {};
  if (title != nullptr) {
    opt_title = char2hstring(title);
  }
  std::vector<winrt::hstring> items;
  for (uint32_t i = 0; i < items_size; i++) {
    items.push_back(char2hstring(items_list[i]));
  }
  sServo->Delegate().OnServoShowContextMenu(opt_title, items);
}

void on_devtools_started(Servo::DevtoolsServerState result,
                         const unsigned int port) {
  sServo->Delegate().OnServoDevtoolsStarted(
      result == Servo::DevtoolsServerState::Started, port);
}

void on_log_output(const char *buffer, uint32_t buffer_length) {
  OutputDebugStringA(buffer);

  if (sLogHandle == INVALID_HANDLE_VALUE) {
    return;
  }

  DWORD bytesWritten;
  auto writeResult =
      WriteFile(sLogHandle, buffer, buffer_length, &bytesWritten, nullptr);

  if (writeResult == FALSE || bytesWritten != buffer_length)
    throw std::runtime_error(
        "Failed to write log message to the log file: error code " +
        std::to_string(GetLastError()));
}

Servo::PromptResult prompt_ok_cancel(const char *message, bool trusted) {
  return sServo->Delegate().OnServoPromptOkCancel(char2hstring(message),
                                                  trusted);
}

Servo::PromptResult prompt_yes_no(const char *message, bool trusted) {
  return sServo->Delegate().OnServoPromptYesNo(char2hstring(message), trusted);
}

const char *prompt_input(const char *message, const char *default,
                         bool trusted) {
  auto input = sServo->Delegate().OnServoPromptInput(
      char2hstring(message), char2hstring(default), trusted);
  if (input.has_value()) {
    return *hstring2char(*input);
  } else {
    return nullptr;
  }
}

Servo::Servo(hstring url, hstring args, GLsizei width, GLsizei height,
             EGLNativeWindowType eglNativeWindow, float dpi,
             ServoDelegate &aDelegate)
    : mWindowHeight(height), mWindowWidth(width), mDelegate(aDelegate) {
  SetEnvironmentVariableA("PreviewRuntimeEnabled", "1");

  Windows::Storage::ApplicationDataContainer localSettings =
      Windows::Storage::ApplicationData::Current().LocalSettings();
  if (!localSettings.Containers().HasKey(L"servoUserPrefs")) {
    Windows::Storage::ApplicationDataContainer container =
        localSettings.CreateContainer(
            L"servoUserPrefs",
            Windows::Storage::ApplicationDataCreateDisposition::Always);
  }

  auto prefs = localSettings.Containers().Lookup(L"servoUserPrefs");

  if (!prefs.Values().HasKey(L"shell.homepage")) {
    prefs.Values().Insert(L"shell.homepage", box_value(DEFAULT_URL));
  }

  if (!prefs.Values().HasKey(L"dom.webxr.enabled")) {
    prefs.Values().Insert(L"dom.webxr.enabled", box_value(true));
  }

  std::vector<capi::CPref> cprefs;

  for (auto pref : prefs.Values()) {
    auto key = *hstring2char(pref.Key());
    auto value = pref.Value();
    auto type = value.as<Windows::Foundation::IPropertyValue>().Type();
    capi::CPref pref;
    pref.key = key;
    pref.pref_type = capi::CPrefType::Missing;
    pref.value = NULL;
    if (type == Windows::Foundation::PropertyType::Boolean) {
      pref.pref_type = capi::CPrefType::Bool;
      auto val = unbox_value<bool>(value);
      pref.value = &val;
    } else if (type == Windows::Foundation::PropertyType::String) {
      pref.pref_type = capi::CPrefType::Str;
      pref.value = *hstring2char(unbox_value<hstring>(value));
    } else if (type == Windows::Foundation::PropertyType::Int64) {
      pref.pref_type = capi::CPrefType::Int;
      auto val = unbox_value<int64_t>(value);
      pref.value = &val;
    } else if (type == Windows::Foundation::PropertyType::Double) {
      pref.pref_type = capi::CPrefType::Float;
      auto val = unbox_value<double>(value);
      pref.value = &val;
    } else if (type == Windows::Foundation::PropertyType::Empty) {
      pref.pref_type = capi::CPrefType::Missing;
    } else {
      log("skipping pref %s. Unknown type", key);
      continue;
    }
    cprefs.push_back(pref);
  }

  capi::CPrefList prefsList = {cprefs.size(), cprefs.data()};

  capi::CInitOptions o;
  o.prefs = &prefsList;
  o.args = *hstring2char(args + L"--devtools");
  o.width = mWindowWidth;
  o.height = mWindowHeight;
  o.density = dpi;
  o.enable_subpixel_text_antialiasing = false;
  o.native_widget = eglNativeWindow;

  // Note about logs:
  // By default: all modules are enabled. Only warn level-logs are displayed.
  // To change the log level, add "--vslogger-level debug" to o.args.
  // To only print logs from specific modules, add their names to pfilters.
  // For example:
  // static char *pfilters[] = {
  //   "servo",
  //   "simpleservo",
  //   "script::dom::bindings::error", // Show JS errors by default.
  //   "canvas::webgl_thread", // Show GL errors by default.
  //   "compositing",
  //   "constellation",
  // };
  // o.vslogger_mod_list = pfilters;
  // o.vslogger_mod_size = sizeof(pfilters) / sizeof(pfilters[0]);

  o.vslogger_mod_list = NULL;
  o.vslogger_mod_size = 0;

  sServo = this; // FIXME;

#ifndef _DEBUG
  char buffer[1024];
  bool logToFile = GetEnvironmentVariableA("FirefoxRealityLogStdout", buffer,
                                           sizeof(buffer)) != 0;
#else
  bool logToFile = true;
#endif
  if (logToFile) {
    auto current = winrt::Windows::Storage::ApplicationData::Current();
    auto filePath =
        std::wstring(current.LocalFolder().Path()) + L"\\stdout.txt";
    sLogHandle =
        CreateFile2(filePath.c_str(), GENERIC_WRITE, 0, CREATE_ALWAYS, nullptr);
    if (sLogHandle == INVALID_HANDLE_VALUE) {
      throw std::runtime_error("Failed to open the log file: error code " +
                               std::to_string(GetLastError()));
    }

    if (SetFilePointer(sLogHandle, 0, nullptr, FILE_END) ==
        INVALID_SET_FILE_POINTER) {
      throw std::runtime_error(
          "Failed to set file pointer to the end of file: error code " +
          std::to_string(GetLastError()));
    }
  }

  capi::CHostCallbacks c;
  c.on_load_started = &on_load_started;
  c.on_load_ended = &on_load_ended;
  c.on_title_changed = &on_title_changed;
  c.on_url_changed = &on_url_changed;
  c.on_history_changed = &on_history_changed;
  c.on_animating_changed = &on_animating_changed;
  c.on_shutdown_complete = &on_shutdown_complete;
  c.on_allow_navigation = &on_allow_navigation;
  c.on_ime_state_changed = &on_ime_state_changed;
  c.get_clipboard_contents = &get_clipboard_contents;
  c.set_clipboard_contents = &set_clipboard_contents;
  c.on_media_session_metadata = &on_media_session_metadata;
  c.on_media_session_playback_state_change =
      &on_media_session_playback_state_change;
  c.prompt_alert = &prompt_alert;
  c.prompt_ok_cancel = &prompt_ok_cancel;
  c.prompt_yes_no = &prompt_yes_no;
  c.prompt_input = &prompt_input;
  c.on_devtools_started = &on_devtools_started;
  c.show_context_menu = &show_context_menu;
  c.on_log_output = &on_log_output;

  capi::register_panic_handler(&on_panic);

  capi::init_with_egl(o, &wakeup, c);
}

Servo::~Servo() {
  sServo = nullptr;
  if (sLogHandle != INVALID_HANDLE_VALUE)
    CloseHandle(sLogHandle);
}

Servo::PrefTuple Servo::SetFloatPref(hstring key, double val) {
  auto ckey = *hstring2char(key);
  capi::set_float_pref(ckey, val);
  auto updatedPref = WrapPref(capi::get_pref(ckey));
  SaveUserPref(updatedPref);
  return updatedPref;
}

Servo::PrefTuple Servo::SetIntPref(hstring key, int64_t val) {
  auto ckey = *hstring2char(key);
  capi::set_int_pref(ckey, val);
  auto updatedPref = WrapPref(capi::get_pref(ckey));
  SaveUserPref(updatedPref);
  return updatedPref;
}

Servo::PrefTuple Servo::SetBoolPref(hstring key, bool val) {
  auto ckey = *hstring2char(key);
  capi::set_bool_pref(ckey, val);
  auto updatedPref = WrapPref(capi::get_pref(ckey));
  SaveUserPref(updatedPref);
  return updatedPref;
}

Servo::PrefTuple Servo::SetStringPref(hstring key, hstring val) {
  auto ckey = *hstring2char(key);
  auto cval = *hstring2char(val);
  capi::set_str_pref(ckey, cval);
  auto updatedPref = WrapPref(capi::get_pref(ckey));
  SaveUserPref(updatedPref);
  return updatedPref;
}

Servo::PrefTuple Servo::ResetPref(hstring key) {
  auto ckey = *hstring2char(key);
  capi::reset_pref(ckey);
  auto updatedPref = WrapPref(capi::get_pref(ckey));
  SaveUserPref(updatedPref);
  return updatedPref;
}

void Servo::SaveUserPref(PrefTuple pref) {
  auto localSettings =
      Windows::Storage::ApplicationData::Current().LocalSettings();
  auto values = localSettings.Containers().Lookup(L"servoUserPrefs").Values();
  auto [key, val, isDefault] = pref;
  if (isDefault) {
    values.Remove(key);
  } else {
    values.Insert(key, val);
  }
}

Servo::PrefTuple Servo::WrapPref(capi::CPref pref) {
  winrt::Windows::Foundation::IInspectable val;
  if (pref.pref_type == capi::CPrefType::Bool) {
    val = box_value(*(capi::get_pref_as_bool(pref.value)));
  } else if (pref.pref_type == capi::CPrefType::Int) {
    val = box_value(*(capi::get_pref_as_int(pref.value)));
  } else if (pref.pref_type == capi::CPrefType::Float) {
    val = box_value(*(capi::get_pref_as_float(pref.value)));
  } else if (pref.pref_type == capi::CPrefType::Str) {
    val = box_value(char2hstring(capi::get_pref_as_str(pref.value)));
  }
  auto key = char2hstring(pref.key);
  auto isDefault = pref.is_default;
  Servo::PrefTuple t{key, val, isDefault};
  return t;
}

Servo::PrefTuple Servo::GetPref(hstring key) {
  auto ckey = *hstring2char(key);
  return WrapPref(capi::get_pref(ckey));
}

std::vector<Servo::PrefTuple> Servo::GetPrefs() {
  if (sServo == nullptr) {
    return {};
  }
  auto prefs = capi::get_prefs();
  std::vector<
      std::tuple<hstring, winrt::Windows::Foundation::IInspectable, bool>>
      vec;
  for (auto i = 0; i < prefs.len; i++) {
    auto pref = WrapPref(prefs.list[i]);
    vec.push_back(pref);
  }
  return vec;
}

winrt::hstring char2hstring(const char *c_str) {
  // FIXME: any better way of doing this?
  auto str = std::string(c_str);
  int size_needed =
      MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
  std::wstring str2(size_needed, 0);
  MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &str2[0],
                      size_needed);
  winrt::hstring str3{str2};
  return str3;
}

std::unique_ptr<char *> hstring2char(hstring hstr) {
  const wchar_t *wc = hstr.c_str();
  size_t size = hstr.size() + 1;
  char *str = new char[size];
  size_t converted = 0;
  wcstombs_s(&converted, str, size, wc, hstr.size());
  return std::make_unique<char *>(str);
}

} // namespace winrt::servo
<commit_msg>Don't force using the preview Windows MixedReality runtime.<commit_after>#include "pch.h"
#include "Servo.h"
#include <EGL/egl.h>
#include "../DefaultUrl.h"

namespace winrt::servo {

void on_load_started() { sServo->Delegate().OnServoLoadStarted(); }

void on_load_ended() { sServo->Delegate().OnServoLoadEnded(); }

void on_history_changed(bool back, bool forward) {
  sServo->Delegate().OnServoHistoryChanged(back, forward);
}

void on_shutdown_complete() { sServo->Delegate().OnServoShutdownComplete(); }

void on_title_changed(const char *title) {
  sServo->Delegate().OnServoTitleChanged(char2hstring(title));
}

void on_url_changed(const char *url) {
  sServo->Delegate().OnServoURLChanged(char2hstring(url));
}

void wakeup() { sServo->Delegate().WakeUp(); }

bool on_allow_navigation(const char *url) {
  return sServo->Delegate().OnServoAllowNavigation(char2hstring(url));
};

void on_animating_changed(bool aAnimating) {
  sServo->Delegate().OnServoAnimatingChanged(aAnimating);
}

void on_panic(const char *backtrace) {
  if (sLogHandle != INVALID_HANDLE_VALUE) {
    CloseHandle(sLogHandle);
    sLogHandle = INVALID_HANDLE_VALUE;
  }
  throw hresult_error(E_FAIL, char2hstring(backtrace));
}

void on_ime_state_changed(bool aShow) {
  sServo->Delegate().OnServoIMEStateChanged(aShow);
}

void set_clipboard_contents(const char *) {
  // FIXME
}

const char *get_clipboard_contents() {
  // FIXME
  return nullptr;
}

void on_media_session_metadata(const char *title, const char *album,
                               const char *artist) {
  return sServo->Delegate().OnServoMediaSessionMetadata(
      char2hstring(title), char2hstring(album), char2hstring(artist));
}

void on_media_session_playback_state_change(
    const capi::CMediaSessionPlaybackState state) {
  return sServo->Delegate().OnServoMediaSessionPlaybackStateChange(state);
}

void prompt_alert(const char *message, bool trusted) {
  sServo->Delegate().OnServoPromptAlert(char2hstring(message), trusted);
}

void show_context_menu(const char *title, const char *const *items_list,
                       uint32_t items_size) {
  std::optional<hstring> opt_title = {};
  if (title != nullptr) {
    opt_title = char2hstring(title);
  }
  std::vector<winrt::hstring> items;
  for (uint32_t i = 0; i < items_size; i++) {
    items.push_back(char2hstring(items_list[i]));
  }
  sServo->Delegate().OnServoShowContextMenu(opt_title, items);
}

void on_devtools_started(Servo::DevtoolsServerState result,
                         const unsigned int port) {
  sServo->Delegate().OnServoDevtoolsStarted(
      result == Servo::DevtoolsServerState::Started, port);
}

void on_log_output(const char *buffer, uint32_t buffer_length) {
  OutputDebugStringA(buffer);

  if (sLogHandle == INVALID_HANDLE_VALUE) {
    return;
  }

  DWORD bytesWritten;
  auto writeResult =
      WriteFile(sLogHandle, buffer, buffer_length, &bytesWritten, nullptr);

  if (writeResult == FALSE || bytesWritten != buffer_length)
    throw std::runtime_error(
        "Failed to write log message to the log file: error code " +
        std::to_string(GetLastError()));
}

Servo::PromptResult prompt_ok_cancel(const char *message, bool trusted) {
  return sServo->Delegate().OnServoPromptOkCancel(char2hstring(message),
                                                  trusted);
}

Servo::PromptResult prompt_yes_no(const char *message, bool trusted) {
  return sServo->Delegate().OnServoPromptYesNo(char2hstring(message), trusted);
}

const char *prompt_input(const char *message, const char *default,
                         bool trusted) {
  auto input = sServo->Delegate().OnServoPromptInput(
      char2hstring(message), char2hstring(default), trusted);
  if (input.has_value()) {
    return *hstring2char(*input);
  } else {
    return nullptr;
  }
}

Servo::Servo(hstring url, hstring args, GLsizei width, GLsizei height,
             EGLNativeWindowType eglNativeWindow, float dpi,
             ServoDelegate &aDelegate)
    : mWindowHeight(height), mWindowWidth(width), mDelegate(aDelegate) {
  Windows::Storage::ApplicationDataContainer localSettings =
      Windows::Storage::ApplicationData::Current().LocalSettings();
  if (!localSettings.Containers().HasKey(L"servoUserPrefs")) {
    Windows::Storage::ApplicationDataContainer container =
        localSettings.CreateContainer(
            L"servoUserPrefs",
            Windows::Storage::ApplicationDataCreateDisposition::Always);
  }

  auto prefs = localSettings.Containers().Lookup(L"servoUserPrefs");

  if (!prefs.Values().HasKey(L"shell.homepage")) {
    prefs.Values().Insert(L"shell.homepage", box_value(DEFAULT_URL));
  }

  if (!prefs.Values().HasKey(L"dom.webxr.enabled")) {
    prefs.Values().Insert(L"dom.webxr.enabled", box_value(true));
  }

  std::vector<capi::CPref> cprefs;

  for (auto pref : prefs.Values()) {
    auto key = *hstring2char(pref.Key());
    auto value = pref.Value();
    auto type = value.as<Windows::Foundation::IPropertyValue>().Type();
    capi::CPref pref;
    pref.key = key;
    pref.pref_type = capi::CPrefType::Missing;
    pref.value = NULL;
    if (type == Windows::Foundation::PropertyType::Boolean) {
      pref.pref_type = capi::CPrefType::Bool;
      auto val = unbox_value<bool>(value);
      pref.value = &val;
    } else if (type == Windows::Foundation::PropertyType::String) {
      pref.pref_type = capi::CPrefType::Str;
      pref.value = *hstring2char(unbox_value<hstring>(value));
    } else if (type == Windows::Foundation::PropertyType::Int64) {
      pref.pref_type = capi::CPrefType::Int;
      auto val = unbox_value<int64_t>(value);
      pref.value = &val;
    } else if (type == Windows::Foundation::PropertyType::Double) {
      pref.pref_type = capi::CPrefType::Float;
      auto val = unbox_value<double>(value);
      pref.value = &val;
    } else if (type == Windows::Foundation::PropertyType::Empty) {
      pref.pref_type = capi::CPrefType::Missing;
    } else {
      log("skipping pref %s. Unknown type", key);
      continue;
    }
    cprefs.push_back(pref);
  }

  capi::CPrefList prefsList = {cprefs.size(), cprefs.data()};

  capi::CInitOptions o;
  o.prefs = &prefsList;
  o.args = *hstring2char(args + L"--devtools");
  o.width = mWindowWidth;
  o.height = mWindowHeight;
  o.density = dpi;
  o.enable_subpixel_text_antialiasing = false;
  o.native_widget = eglNativeWindow;

  // Note about logs:
  // By default: all modules are enabled. Only warn level-logs are displayed.
  // To change the log level, add "--vslogger-level debug" to o.args.
  // To only print logs from specific modules, add their names to pfilters.
  // For example:
  // static char *pfilters[] = {
  //   "servo",
  //   "simpleservo",
  //   "script::dom::bindings::error", // Show JS errors by default.
  //   "canvas::webgl_thread", // Show GL errors by default.
  //   "compositing",
  //   "constellation",
  // };
  // o.vslogger_mod_list = pfilters;
  // o.vslogger_mod_size = sizeof(pfilters) / sizeof(pfilters[0]);

  o.vslogger_mod_list = NULL;
  o.vslogger_mod_size = 0;

  sServo = this; // FIXME;

#ifndef _DEBUG
  char buffer[1024];
  bool logToFile = GetEnvironmentVariableA("FirefoxRealityLogStdout", buffer,
                                           sizeof(buffer)) != 0;
#else
  bool logToFile = true;
#endif
  if (logToFile) {
    auto current = winrt::Windows::Storage::ApplicationData::Current();
    auto filePath =
        std::wstring(current.LocalFolder().Path()) + L"\\stdout.txt";
    sLogHandle =
        CreateFile2(filePath.c_str(), GENERIC_WRITE, 0, CREATE_ALWAYS, nullptr);
    if (sLogHandle == INVALID_HANDLE_VALUE) {
      throw std::runtime_error("Failed to open the log file: error code " +
                               std::to_string(GetLastError()));
    }

    if (SetFilePointer(sLogHandle, 0, nullptr, FILE_END) ==
        INVALID_SET_FILE_POINTER) {
      throw std::runtime_error(
          "Failed to set file pointer to the end of file: error code " +
          std::to_string(GetLastError()));
    }
  }

  capi::CHostCallbacks c;
  c.on_load_started = &on_load_started;
  c.on_load_ended = &on_load_ended;
  c.on_title_changed = &on_title_changed;
  c.on_url_changed = &on_url_changed;
  c.on_history_changed = &on_history_changed;
  c.on_animating_changed = &on_animating_changed;
  c.on_shutdown_complete = &on_shutdown_complete;
  c.on_allow_navigation = &on_allow_navigation;
  c.on_ime_state_changed = &on_ime_state_changed;
  c.get_clipboard_contents = &get_clipboard_contents;
  c.set_clipboard_contents = &set_clipboard_contents;
  c.on_media_session_metadata = &on_media_session_metadata;
  c.on_media_session_playback_state_change =
      &on_media_session_playback_state_change;
  c.prompt_alert = &prompt_alert;
  c.prompt_ok_cancel = &prompt_ok_cancel;
  c.prompt_yes_no = &prompt_yes_no;
  c.prompt_input = &prompt_input;
  c.on_devtools_started = &on_devtools_started;
  c.show_context_menu = &show_context_menu;
  c.on_log_output = &on_log_output;

  capi::register_panic_handler(&on_panic);

  capi::init_with_egl(o, &wakeup, c);
}

Servo::~Servo() {
  sServo = nullptr;
  if (sLogHandle != INVALID_HANDLE_VALUE)
    CloseHandle(sLogHandle);
}

Servo::PrefTuple Servo::SetFloatPref(hstring key, double val) {
  auto ckey = *hstring2char(key);
  capi::set_float_pref(ckey, val);
  auto updatedPref = WrapPref(capi::get_pref(ckey));
  SaveUserPref(updatedPref);
  return updatedPref;
}

Servo::PrefTuple Servo::SetIntPref(hstring key, int64_t val) {
  auto ckey = *hstring2char(key);
  capi::set_int_pref(ckey, val);
  auto updatedPref = WrapPref(capi::get_pref(ckey));
  SaveUserPref(updatedPref);
  return updatedPref;
}

Servo::PrefTuple Servo::SetBoolPref(hstring key, bool val) {
  auto ckey = *hstring2char(key);
  capi::set_bool_pref(ckey, val);
  auto updatedPref = WrapPref(capi::get_pref(ckey));
  SaveUserPref(updatedPref);
  return updatedPref;
}

Servo::PrefTuple Servo::SetStringPref(hstring key, hstring val) {
  auto ckey = *hstring2char(key);
  auto cval = *hstring2char(val);
  capi::set_str_pref(ckey, cval);
  auto updatedPref = WrapPref(capi::get_pref(ckey));
  SaveUserPref(updatedPref);
  return updatedPref;
}

Servo::PrefTuple Servo::ResetPref(hstring key) {
  auto ckey = *hstring2char(key);
  capi::reset_pref(ckey);
  auto updatedPref = WrapPref(capi::get_pref(ckey));
  SaveUserPref(updatedPref);
  return updatedPref;
}

void Servo::SaveUserPref(PrefTuple pref) {
  auto localSettings =
      Windows::Storage::ApplicationData::Current().LocalSettings();
  auto values = localSettings.Containers().Lookup(L"servoUserPrefs").Values();
  auto [key, val, isDefault] = pref;
  if (isDefault) {
    values.Remove(key);
  } else {
    values.Insert(key, val);
  }
}

Servo::PrefTuple Servo::WrapPref(capi::CPref pref) {
  winrt::Windows::Foundation::IInspectable val;
  if (pref.pref_type == capi::CPrefType::Bool) {
    val = box_value(*(capi::get_pref_as_bool(pref.value)));
  } else if (pref.pref_type == capi::CPrefType::Int) {
    val = box_value(*(capi::get_pref_as_int(pref.value)));
  } else if (pref.pref_type == capi::CPrefType::Float) {
    val = box_value(*(capi::get_pref_as_float(pref.value)));
  } else if (pref.pref_type == capi::CPrefType::Str) {
    val = box_value(char2hstring(capi::get_pref_as_str(pref.value)));
  }
  auto key = char2hstring(pref.key);
  auto isDefault = pref.is_default;
  Servo::PrefTuple t{key, val, isDefault};
  return t;
}

Servo::PrefTuple Servo::GetPref(hstring key) {
  auto ckey = *hstring2char(key);
  return WrapPref(capi::get_pref(ckey));
}

std::vector<Servo::PrefTuple> Servo::GetPrefs() {
  if (sServo == nullptr) {
    return {};
  }
  auto prefs = capi::get_prefs();
  std::vector<
      std::tuple<hstring, winrt::Windows::Foundation::IInspectable, bool>>
      vec;
  for (auto i = 0; i < prefs.len; i++) {
    auto pref = WrapPref(prefs.list[i]);
    vec.push_back(pref);
  }
  return vec;
}

winrt::hstring char2hstring(const char *c_str) {
  // FIXME: any better way of doing this?
  auto str = std::string(c_str);
  int size_needed =
      MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
  std::wstring str2(size_needed, 0);
  MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &str2[0],
                      size_needed);
  winrt::hstring str3{str2};
  return str3;
}

std::unique_ptr<char *> hstring2char(hstring hstr) {
  const wchar_t *wc = hstr.c_str();
  size_t size = hstr.size() + 1;
  char *str = new char[size];
  size_t converted = 0;
  wcstombs_s(&converted, str, size, wc, hstr.size());
  return std::make_unique<char *>(str);
}

} // namespace winrt::servo
<|endoftext|>


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

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

#ifdef SW_DLLIMPLEMENTATION
#undef SW_DLLIMPLEMENTATION
#endif

#ifndef _SWTYPES_HXX
#include <swtypes.hxx>
#endif

#ifndef _CUSTOMIZEADDRESSLISTDIALOG_HXX
#include <customizeaddresslistdialog.hxx>
#endif
#ifndef _CREATEADDRESSLISTDIALOG_HXX
#include <createaddresslistdialog.hxx>
#endif
#ifndef _SV_SCRBAR_HXX
#include <vcl/scrbar.hxx>
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#include <customizeaddresslistdialog.hrc>
#include <dbui.hrc>
#include <helpid.h>

/*-- 13.04.2004 14:27:21---------------------------------------------------

  -----------------------------------------------------------------------*/
SwCustomizeAddressListDialog::SwCustomizeAddressListDialog(
        Window* pParent, const SwCSVData& rOldData) :
    SfxModalDialog(pParent, SW_RES(DLG_MM_CUSTOMIZE_ADDRESS_LIST)),
#pragma warning (disable : 4355)
    m_aFieldsFT( this, ResId(    FT_FIELDS)),
    m_aFieldsLB( this, ResId(    LB_FIELDS)),
    m_aAddPB( this, ResId(       PB_ADD)),
    m_aDeletePB( this, ResId(    PB_DELETE)),
    m_aRenamePB( this, ResId(    PB_RENAME)),
    m_aUpPB( this, ResId(        PB_UP)),
    m_aDownPB( this, ResId(      PB_DOWN)),
    m_aSeparatorFL( this, ResId( FL_SEPARATOR)),
    m_aOK( this, ResId(          PB_OK)),
    m_aCancel( this, ResId(      PB_CANCEL)),
    m_aHelp( this, ResId(        PB_HELP)),
#pragma warning (default : 4355)
    m_pNewData( new SwCSVData(rOldData))
{
    FreeResource();
    m_aFieldsLB.SetSelectHdl(LINK(this, SwCustomizeAddressListDialog, ListBoxSelectHdl_Impl));
    Link aAddRenameLk = LINK(this, SwCustomizeAddressListDialog, AddRenameHdl_Impl );
    m_aAddPB.SetClickHdl(aAddRenameLk);
    m_aRenamePB.SetClickHdl(aAddRenameLk);
    m_aDeletePB.SetClickHdl(LINK(this, SwCustomizeAddressListDialog, DeleteHdl_Impl ));
    Link aUpDownLk = LINK(this, SwCustomizeAddressListDialog, UpDownHdl_Impl);
    m_aUpPB.SetClickHdl(aUpDownLk);
    m_aDownPB.SetClickHdl(aUpDownLk);

    ::std::vector< ::rtl::OUString >::iterator aHeaderIter;

    for(aHeaderIter = m_pNewData->aDBColumnHeaders.begin();
                aHeaderIter != m_pNewData->aDBColumnHeaders.end(); ++aHeaderIter)
        m_aFieldsLB.InsertEntry(*aHeaderIter);

    m_aFieldsLB.SelectEntryPos(0);
    UpdateButtons();
}
/*-- 13.04.2004 14:34:07---------------------------------------------------

  -----------------------------------------------------------------------*/
SwCustomizeAddressListDialog::~SwCustomizeAddressListDialog()
{
}

/*-- 12.08.2004 12:58:00---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK(SwCustomizeAddressListDialog, ListBoxSelectHdl_Impl, ListBox*, EMPTYARG)
{
    UpdateButtons();
    return 0;
}
/*-- 13.04.2004 15:02:14---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK(SwCustomizeAddressListDialog, AddRenameHdl_Impl, PushButton*, pButton)
{
    bool bRename = pButton == &m_aRenamePB;
    USHORT nPos = m_aFieldsLB.GetSelectEntryPos();
    if(nPos == LISTBOX_ENTRY_NOTFOUND)
        nPos = 0;

    SwAddRenameEntryDialog* pDlg =
            new SwAddRenameEntryDialog(pButton, bRename, m_pNewData->aDBColumnHeaders);
    if(bRename)
    {
        String aTemp = m_aFieldsLB.GetEntry(nPos);
        pDlg->SetFieldName(aTemp);
    }
    if(RET_OK == pDlg->Execute())
    {
        String sNew = pDlg->GetFieldName();
        if(bRename)
        {
            m_pNewData->aDBColumnHeaders[nPos] = sNew;
            m_aFieldsLB.RemoveEntry(nPos);
        }
        else
        {
            if ( m_aFieldsLB.GetSelectEntryPos() != LISTBOX_ENTRY_NOTFOUND )
                ++nPos; // append the new entry behind the selected
            //add the new column
            m_pNewData->aDBColumnHeaders.insert(m_pNewData->aDBColumnHeaders.begin() + nPos, sNew);
            //add a new entry into all data arrays
            String sTemp;
            ::std::vector< ::std::vector< ::rtl::OUString > >::iterator aDataIter;
            for( aDataIter = m_pNewData->aDBData.begin(); aDataIter != m_pNewData->aDBData.end(); ++aDataIter)
                aDataIter->insert(aDataIter->begin() + nPos, sTemp);

        }

        m_aFieldsLB.InsertEntry(sNew, nPos);
        m_aFieldsLB.SelectEntryPos(nPos);
    }
    delete pDlg;
    UpdateButtons();
    return 0;
}
/*-- 13.04.2004 15:02:14---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK(SwCustomizeAddressListDialog, DeleteHdl_Impl, PushButton*, pButton)
{
    USHORT nPos = m_aFieldsLB.GetSelectEntryPos();
    m_aFieldsLB.RemoveEntry(m_aFieldsLB.GetSelectEntryPos());
    m_aFieldsLB.SelectEntryPos(nPos > m_aFieldsLB.GetEntryCount() - 1 ? nPos - 1 : nPos);

    //remove the column
    m_pNewData->aDBColumnHeaders.erase(m_pNewData->aDBColumnHeaders.begin() + nPos);
    //remove the data
    ::std::vector< ::std::vector< ::rtl::OUString > >::iterator aDataIter;
    for( aDataIter = m_pNewData->aDBData.begin(); aDataIter != m_pNewData->aDBData.end(); ++aDataIter)
        aDataIter->erase(aDataIter->begin() + nPos);

    UpdateButtons();
    return 0;
}
/*-- 13.04.2004 15:02:15---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK(SwCustomizeAddressListDialog, UpDownHdl_Impl, PushButton*, pButton)
{
    USHORT nPos;
    USHORT nOldPos = nPos = m_aFieldsLB.GetSelectEntryPos();
    String aTemp = m_aFieldsLB.GetEntry(nPos);
    m_aFieldsLB.RemoveEntry( nPos );
    if(pButton == &m_aUpPB)
        --nPos;
    else
        ++nPos;
    m_aFieldsLB.InsertEntry(aTemp, nPos);
    m_aFieldsLB.SelectEntryPos(nPos);
    //align m_pNewData
    ::rtl::OUString sHeader = m_pNewData->aDBColumnHeaders[nOldPos];
    m_pNewData->aDBColumnHeaders.erase(m_pNewData->aDBColumnHeaders.begin() + nOldPos);
    m_pNewData->aDBColumnHeaders.insert(m_pNewData->aDBColumnHeaders.begin() + nPos, sHeader);
    ::std::vector< ::std::vector< ::rtl::OUString > >::iterator aDataIter;
    for( aDataIter = m_pNewData->aDBData.begin(); aDataIter != m_pNewData->aDBData.end(); ++aDataIter)
    {
        ::rtl::OUString sData = (*aDataIter)[nOldPos];
        aDataIter->erase(aDataIter->begin() + nOldPos);
        aDataIter->insert(aDataIter->begin() + nPos, sData);
    }

    UpdateButtons();
    return 0;
}
/*-- 19.04.2004 14:51:49---------------------------------------------------

  -----------------------------------------------------------------------*/
void SwCustomizeAddressListDialog::UpdateButtons()
{
    USHORT nPos = m_aFieldsLB.GetSelectEntryPos();
    USHORT nEntries = m_aFieldsLB.GetEntryCount();
    m_aUpPB.Enable(nPos > 0 && nEntries > 0);
    m_aDownPB.Enable(nPos < nEntries -1);
    m_aDeletePB.Enable(nEntries > 0);
    m_aRenamePB.Enable(nEntries > 0);
}
/*-- 19.04.2004 14:51:49---------------------------------------------------

  -----------------------------------------------------------------------*/
SwCSVData*    SwCustomizeAddressListDialog::GetNewData()
{
    return m_pNewData;
}

/*-- 13.04.2004 13:48:41---------------------------------------------------

  -----------------------------------------------------------------------*/
SwAddRenameEntryDialog::SwAddRenameEntryDialog(
        Window* pParent, bool bRename, const ::std::vector< ::rtl::OUString >& rCSVHeader) :
    SfxModalDialog(pParent, SW_RES(DLG_MM_ADD_RENAME_ENTRY)),
#pragma warning (disable : 4355)
    m_aFieldNameFT( this, ResId( FT_FIELDNAME)),
    m_aFieldNameED( this, ResId( ED_FIELDNAME)),
    m_aOK( this, ResId(          PB_OK)),
    m_aCancel( this, ResId(      PB_CANCEL)),
    m_aHelp( this, ResId(        PB_HELP)),
#pragma warning (default : 4355)
    m_rCSVHeader(rCSVHeader)
{
    if(bRename)
        SetText(String(ResId(ST_RENAME_TITLE)));
    else
        m_aOK.SetText(String(ResId(ST_ADD_BUTTON)));
    FreeResource();
    m_aFieldNameED.SetModifyHdl(LINK(this, SwAddRenameEntryDialog, ModifyHdl_Impl));
    ModifyHdl_Impl( &m_aFieldNameED );
}
/*-- 13.04.2004 13:48:41---------------------------------------------------

  -----------------------------------------------------------------------*/
SwAddRenameEntryDialog::~SwAddRenameEntryDialog()
{
}
/*-- 19.04.2004 15:31:34---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK(SwAddRenameEntryDialog, ModifyHdl_Impl, Edit*, pEdit)
{
    ::rtl::OUString sEntry = pEdit->GetText();
    BOOL bFound = sEntry.getLength() ? FALSE : TRUE;

    if(!bFound)
    {
        ::std::vector< ::rtl::OUString >::const_iterator aHeaderIter;
        for(aHeaderIter = m_rCSVHeader.begin();
                    aHeaderIter != m_rCSVHeader.end();
                    ++aHeaderIter)
            if(*aHeaderIter == sEntry)
            {
                bFound = TRUE;
                break;
            }
    }
    m_aOK.Enable(!bFound);
    return 0;
}
<commit_msg>INTEGRATION: CWS residcleanup (1.6.240); FILE MERGED 2007/03/04 17:02:57 pl 1.6.240.1: #i73635# ResId cleanup<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: customizeaddresslistdialog.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2007-04-26 08:52:52 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#ifdef SW_DLLIMPLEMENTATION
#undef SW_DLLIMPLEMENTATION
#endif

#ifndef _SWTYPES_HXX
#include <swtypes.hxx>
#endif

#ifndef _CUSTOMIZEADDRESSLISTDIALOG_HXX
#include <customizeaddresslistdialog.hxx>
#endif
#ifndef _CREATEADDRESSLISTDIALOG_HXX
#include <createaddresslistdialog.hxx>
#endif
#ifndef _SV_SCRBAR_HXX
#include <vcl/scrbar.hxx>
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#include <customizeaddresslistdialog.hrc>
#include <dbui.hrc>
#include <helpid.h>

/*-- 13.04.2004 14:27:21---------------------------------------------------

  -----------------------------------------------------------------------*/
SwCustomizeAddressListDialog::SwCustomizeAddressListDialog(
        Window* pParent, const SwCSVData& rOldData) :
    SfxModalDialog(pParent, SW_RES(DLG_MM_CUSTOMIZE_ADDRESS_LIST)),
#pragma warning (disable : 4355)
    m_aFieldsFT( this, SW_RES(    FT_FIELDS)),
    m_aFieldsLB( this, SW_RES(    LB_FIELDS)),
    m_aAddPB( this, SW_RES(       PB_ADD)),
    m_aDeletePB( this, SW_RES(    PB_DELETE)),
    m_aRenamePB( this, SW_RES(    PB_RENAME)),
    m_aUpPB( this, SW_RES(        PB_UP)),
    m_aDownPB( this, SW_RES(      PB_DOWN)),
    m_aSeparatorFL( this, SW_RES( FL_SEPARATOR)),
    m_aOK( this, SW_RES(          PB_OK)),
    m_aCancel( this, SW_RES(      PB_CANCEL)),
    m_aHelp( this, SW_RES(        PB_HELP)),
#pragma warning (default : 4355)
    m_pNewData( new SwCSVData(rOldData))
{
    FreeResource();
    m_aFieldsLB.SetSelectHdl(LINK(this, SwCustomizeAddressListDialog, ListBoxSelectHdl_Impl));
    Link aAddRenameLk = LINK(this, SwCustomizeAddressListDialog, AddRenameHdl_Impl );
    m_aAddPB.SetClickHdl(aAddRenameLk);
    m_aRenamePB.SetClickHdl(aAddRenameLk);
    m_aDeletePB.SetClickHdl(LINK(this, SwCustomizeAddressListDialog, DeleteHdl_Impl ));
    Link aUpDownLk = LINK(this, SwCustomizeAddressListDialog, UpDownHdl_Impl);
    m_aUpPB.SetClickHdl(aUpDownLk);
    m_aDownPB.SetClickHdl(aUpDownLk);

    ::std::vector< ::rtl::OUString >::iterator aHeaderIter;

    for(aHeaderIter = m_pNewData->aDBColumnHeaders.begin();
                aHeaderIter != m_pNewData->aDBColumnHeaders.end(); ++aHeaderIter)
        m_aFieldsLB.InsertEntry(*aHeaderIter);

    m_aFieldsLB.SelectEntryPos(0);
    UpdateButtons();
}
/*-- 13.04.2004 14:34:07---------------------------------------------------

  -----------------------------------------------------------------------*/
SwCustomizeAddressListDialog::~SwCustomizeAddressListDialog()
{
}

/*-- 12.08.2004 12:58:00---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK(SwCustomizeAddressListDialog, ListBoxSelectHdl_Impl, ListBox*, EMPTYARG)
{
    UpdateButtons();
    return 0;
}
/*-- 13.04.2004 15:02:14---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK(SwCustomizeAddressListDialog, AddRenameHdl_Impl, PushButton*, pButton)
{
    bool bRename = pButton == &m_aRenamePB;
    USHORT nPos = m_aFieldsLB.GetSelectEntryPos();
    if(nPos == LISTBOX_ENTRY_NOTFOUND)
        nPos = 0;

    SwAddRenameEntryDialog* pDlg =
            new SwAddRenameEntryDialog(pButton, bRename, m_pNewData->aDBColumnHeaders);
    if(bRename)
    {
        String aTemp = m_aFieldsLB.GetEntry(nPos);
        pDlg->SetFieldName(aTemp);
    }
    if(RET_OK == pDlg->Execute())
    {
        String sNew = pDlg->GetFieldName();
        if(bRename)
        {
            m_pNewData->aDBColumnHeaders[nPos] = sNew;
            m_aFieldsLB.RemoveEntry(nPos);
        }
        else
        {
            if ( m_aFieldsLB.GetSelectEntryPos() != LISTBOX_ENTRY_NOTFOUND )
                ++nPos; // append the new entry behind the selected
            //add the new column
            m_pNewData->aDBColumnHeaders.insert(m_pNewData->aDBColumnHeaders.begin() + nPos, sNew);
            //add a new entry into all data arrays
            String sTemp;
            ::std::vector< ::std::vector< ::rtl::OUString > >::iterator aDataIter;
            for( aDataIter = m_pNewData->aDBData.begin(); aDataIter != m_pNewData->aDBData.end(); ++aDataIter)
                aDataIter->insert(aDataIter->begin() + nPos, sTemp);

        }

        m_aFieldsLB.InsertEntry(sNew, nPos);
        m_aFieldsLB.SelectEntryPos(nPos);
    }
    delete pDlg;
    UpdateButtons();
    return 0;
}
/*-- 13.04.2004 15:02:14---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK(SwCustomizeAddressListDialog, DeleteHdl_Impl, PushButton*, pButton)
{
    USHORT nPos = m_aFieldsLB.GetSelectEntryPos();
    m_aFieldsLB.RemoveEntry(m_aFieldsLB.GetSelectEntryPos());
    m_aFieldsLB.SelectEntryPos(nPos > m_aFieldsLB.GetEntryCount() - 1 ? nPos - 1 : nPos);

    //remove the column
    m_pNewData->aDBColumnHeaders.erase(m_pNewData->aDBColumnHeaders.begin() + nPos);
    //remove the data
    ::std::vector< ::std::vector< ::rtl::OUString > >::iterator aDataIter;
    for( aDataIter = m_pNewData->aDBData.begin(); aDataIter != m_pNewData->aDBData.end(); ++aDataIter)
        aDataIter->erase(aDataIter->begin() + nPos);

    UpdateButtons();
    return 0;
}
/*-- 13.04.2004 15:02:15---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK(SwCustomizeAddressListDialog, UpDownHdl_Impl, PushButton*, pButton)
{
    USHORT nPos;
    USHORT nOldPos = nPos = m_aFieldsLB.GetSelectEntryPos();
    String aTemp = m_aFieldsLB.GetEntry(nPos);
    m_aFieldsLB.RemoveEntry( nPos );
    if(pButton == &m_aUpPB)
        --nPos;
    else
        ++nPos;
    m_aFieldsLB.InsertEntry(aTemp, nPos);
    m_aFieldsLB.SelectEntryPos(nPos);
    //align m_pNewData
    ::rtl::OUString sHeader = m_pNewData->aDBColumnHeaders[nOldPos];
    m_pNewData->aDBColumnHeaders.erase(m_pNewData->aDBColumnHeaders.begin() + nOldPos);
    m_pNewData->aDBColumnHeaders.insert(m_pNewData->aDBColumnHeaders.begin() + nPos, sHeader);
    ::std::vector< ::std::vector< ::rtl::OUString > >::iterator aDataIter;
    for( aDataIter = m_pNewData->aDBData.begin(); aDataIter != m_pNewData->aDBData.end(); ++aDataIter)
    {
        ::rtl::OUString sData = (*aDataIter)[nOldPos];
        aDataIter->erase(aDataIter->begin() + nOldPos);
        aDataIter->insert(aDataIter->begin() + nPos, sData);
    }

    UpdateButtons();
    return 0;
}
/*-- 19.04.2004 14:51:49---------------------------------------------------

  -----------------------------------------------------------------------*/
void SwCustomizeAddressListDialog::UpdateButtons()
{
    USHORT nPos = m_aFieldsLB.GetSelectEntryPos();
    USHORT nEntries = m_aFieldsLB.GetEntryCount();
    m_aUpPB.Enable(nPos > 0 && nEntries > 0);
    m_aDownPB.Enable(nPos < nEntries -1);
    m_aDeletePB.Enable(nEntries > 0);
    m_aRenamePB.Enable(nEntries > 0);
}
/*-- 19.04.2004 14:51:49---------------------------------------------------

  -----------------------------------------------------------------------*/
SwCSVData*    SwCustomizeAddressListDialog::GetNewData()
{
    return m_pNewData;
}

/*-- 13.04.2004 13:48:41---------------------------------------------------

  -----------------------------------------------------------------------*/
SwAddRenameEntryDialog::SwAddRenameEntryDialog(
        Window* pParent, bool bRename, const ::std::vector< ::rtl::OUString >& rCSVHeader) :
    SfxModalDialog(pParent, SW_RES(DLG_MM_ADD_RENAME_ENTRY)),
#pragma warning (disable : 4355)
    m_aFieldNameFT( this, SW_RES( FT_FIELDNAME)),
    m_aFieldNameED( this, SW_RES( ED_FIELDNAME)),
    m_aOK( this, SW_RES(          PB_OK)),
    m_aCancel( this, SW_RES(      PB_CANCEL)),
    m_aHelp( this, SW_RES(        PB_HELP)),
#pragma warning (default : 4355)
    m_rCSVHeader(rCSVHeader)
{
    if(bRename)
        SetText(String(SW_RES(ST_RENAME_TITLE)));
    else
        m_aOK.SetText(String(SW_RES(ST_ADD_BUTTON)));
    FreeResource();
    m_aFieldNameED.SetModifyHdl(LINK(this, SwAddRenameEntryDialog, ModifyHdl_Impl));
    ModifyHdl_Impl( &m_aFieldNameED );
}
/*-- 13.04.2004 13:48:41---------------------------------------------------

  -----------------------------------------------------------------------*/
SwAddRenameEntryDialog::~SwAddRenameEntryDialog()
{
}
/*-- 19.04.2004 15:31:34---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK(SwAddRenameEntryDialog, ModifyHdl_Impl, Edit*, pEdit)
{
    ::rtl::OUString sEntry = pEdit->GetText();
    BOOL bFound = sEntry.getLength() ? FALSE : TRUE;

    if(!bFound)
    {
        ::std::vector< ::rtl::OUString >::const_iterator aHeaderIter;
        for(aHeaderIter = m_rCSVHeader.begin();
                    aHeaderIter != m_rCSVHeader.end();
                    ++aHeaderIter)
            if(*aHeaderIter == sEntry)
            {
                bFound = TRUE;
                break;
            }
    }
    m_aOK.Enable(!bFound);
    return 0;
}
<|endoftext|>


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

#include "CppUTest/TestHarness.h"
#undef malloc
#undef free
#undef calloc
#undef realloc
#undef strdup
#undef strndup

#include "CppUTest/PlatformSpecificFunctions.h"

void (*PlatformSpecificRunTestInASeperateProcess)(UtestShell*, TestPlugin*, TestResult*) = NULL;
int (*PlatformSpecificFork)() = NULL;
int (*PlatformSpecificWaitPid)(int, int*, int) = NULL;

TestOutput::WorkingEnvironment PlatformSpecificGetWorkingEnvironment()
{
    return TestOutput::eclipse;
}

void (*PlatformSpecificLongJmp)() = NULL;
int (*PlatformSpecificSetJmp)(void (*)(void*), void*) = NULL;
void (*PlatformSpecificRestoreJumpBuffer)() = NULL;

long (*GetPlatformSpecificTimeInMillis)() = NULL;
const char* (*GetPlatformSpecificTimeString)() = NULL;

/* IO operations */
PlatformSpecificFile (*PlatformSpecificFOpen)(const char* filename, const char* flag) = NULL;
void (*PlatformSpecificFPuts)(const char* str, PlatformSpecificFile file) = NULL;
void (*PlatformSpecificFClose)(PlatformSpecificFile file) = NULL;

int (*PlatformSpecificPutchar)(int c) = NULL;
void (*PlatformSpecificFlush)(void) = NULL;

int (*PlatformSpecificVSNprintf)(char *str, size_t size, const char* format, va_list va_args_list) = NULL;

/* Dynamic Memory operations */
void* (*PlatformSpecificMalloc)(size_t) = NULL;
void* (*PlatformSpecificRealloc)(void*, size_t) = NULL;
void (*PlatformSpecificFree)(void*) = NULL;
void* (*PlatformSpecificMemCpy)(void*, const void*, size_t) = NULL;
void* (*PlatformSpecificMemset)(void*, int, size_t) = NULL;

double (*PlatformSpecificFabs)(double) = NULL;
int (*PlatformSpecificIsNan)(double) = NULL;
int (*PlatformSpecificIsInf)(double) = NULL;
int (*PlatformSpecificAtExit)(void(*func)(void)) = NULL;

PlatformSpecificMutex (*PlatformSpecificMutexCreate)(void) = NULL;
void (*PlatformSpecificMutexLock)(PlatformSpecificMutex mtx) = NULL;
void (*PlatformSpecificMutexUnlock)(PlatformSpecificMutex mtx) = NULL;
void (*PlatformSpecificMutexDestroy)(PlatformSpecificMutex mtx) = NULL;

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

#include "CppUTest/TestHarness.h"
#undef malloc
#undef free
#undef calloc
#undef realloc
#undef strdup
#undef strndup

#include "CppUTest/PlatformSpecificFunctions.h"

void (*PlatformSpecificRunTestInASeperateProcess)(UtestShell*, TestPlugin*, TestResult*) = NULLPTR;
int (*PlatformSpecificFork)() = NULLPTR;
int (*PlatformSpecificWaitPid)(int, int*, int) = NULLPTR;

TestOutput::WorkingEnvironment PlatformSpecificGetWorkingEnvironment()
{
    return TestOutput::eclipse;
}

void (*PlatformSpecificLongJmp)() = NULLPTR;
int (*PlatformSpecificSetJmp)(void (*)(void*), void*) = NULLPTR;
void (*PlatformSpecificRestoreJumpBuffer)() = NULLPTR;

long (*GetPlatformSpecificTimeInMillis)() = NULLPTR;
const char* (*GetPlatformSpecificTimeString)() = NULLPTR;

/* IO operations */
PlatformSpecificFile (*PlatformSpecificFOpen)(const char* filename, const char* flag) = NULLPTR;
void (*PlatformSpecificFPuts)(const char* str, PlatformSpecificFile file) = NULLPTR;
void (*PlatformSpecificFClose)(PlatformSpecificFile file) = NULLPTR;

int (*PlatformSpecificPutchar)(int c) = NULLPTR;
void (*PlatformSpecificFlush)(void) = NULLPTR;

int (*PlatformSpecificVSNprintf)(char *str, size_t size, const char* format, va_list va_args_list) = NULLPTR;

/* Dynamic Memory operations */
void* (*PlatformSpecificMalloc)(size_t) = NULLPTR;
void* (*PlatformSpecificRealloc)(void*, size_t) = NULLPTR;
void (*PlatformSpecificFree)(void*) = NULLPTR;
void* (*PlatformSpecificMemCpy)(void*, const void*, size_t) = NULLPTR;
void* (*PlatformSpecificMemset)(void*, int, size_t) = NULLPTR;

double (*PlatformSpecificFabs)(double) = NULLPTR;
int (*PlatformSpecificIsNan)(double) = NULLPTR;
int (*PlatformSpecificIsInf)(double) = NULLPTR;
int (*PlatformSpecificAtExit)(void(*func)(void)) = NULLPTR;

PlatformSpecificMutex (*PlatformSpecificMutexCreate)(void) = NULLPTR;
void (*PlatformSpecificMutexLock)(PlatformSpecificMutex mtx) = NULLPTR;
void (*PlatformSpecificMutexUnlock)(PlatformSpecificMutex mtx) = NULLPTR;
void (*PlatformSpecificMutexDestroy)(PlatformSpecificMutex mtx) = NULLPTR;

<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////////////////////////////
// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
///////////////////////////////////////////////////////////////////////////////////////////////////
// Created : 2008-06-22
// Updated : 2008-10-27
// Licence : This source is under MIT License
// File    : glm/gtx/comparison.inl
///////////////////////////////////////////////////////////////////////////////////////////////////

namespace glm{
namespace gtx{
namespace comparison{
/*
template <typename valType>
inline bool operator==
(
	detail::tvec2<valType> const & x,
	detail::tvec2<valType> const & y
)
{
	return glm::all(glm::equal(x, y));
}

template <typename valType>
inline bool operator==
(
	detail::tvec3<valType> const & x,
	detail::tvec3<valType> const & y
)
{
	return glm::all(glm::equal(x, y));
}

template <typename valType>
inline bool operator==
(
	detail::tvec4<valType> const & x,
	detail::tvec4<valType> const & y
)
{
	return glm::all(glm::equal(x, y));
}

template <typename valType>
inline bool operator!=
(
	detail::tvec2<valType> const & x,
	detail::tvec2<valType> const & y
)
{
	return glm::any(glm::notEqual(x, y));
}

template <typename valType>
inline bool operator!=
(
	detail::tvec3<valType> const & x,
	detail::tvec3<valType> const & y
)
{
	return glm::any(glm::notEqual(x, y));
}

template <typename valType>
inline bool operator!=
(
	detail::tvec4<valType> const & x,
	detail::tvec4<valType> const & y
)
{
	return glm::any(glm::notEqual(x, y));
}
*/
}//namespace comparison
}//namespace gtx
}//namespace glm
<commit_msg>Removed file from a previously delete extension<commit_after><|endoftext|>


<commit_before>#ifdef FROGBOY_SDL
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <SDL.h>
#include <string>

#include "frogboy.h"

namespace {
    enum {
        FRAME_INTERVAL = 16,
        SCREEN_SCALE = 8,
        DESKTOP_FIT_BORDER = 64,

        AUDIO_CHANNEL_COUNT = 2,
        AUDIO_FREQUENCY = 48000,
        AUDIO_AMPLITUDE = 15000,
    };

    SDL_Window* window = nullptr;
    SDL_Renderer* renderer = nullptr;
    SDL_Texture* screenTexture = nullptr;
    SDL_Surface* screenSurface = nullptr;
    uint8_t screenBuffer[frogboy::SCREEN_WIDTH * (frogboy::SCREEN_HEIGHT / 8)];

    uint32_t deltaTime = 0;
    uint32_t lastFrame = 0;
    uint32_t lastMouseMove = 0;

    bool windowOpen = false;
    bool windowMaximized = false;
    bool windowFullscreen = false;

    bool pressed[static_cast<size_t>(frogboy::BUTTON_COUNT)];

    struct KeyCode {
        SDL_Keycode code;
        uint16_t mod;
    };

    const KeyCode keycodes[static_cast<size_t>(frogboy::BUTTON_COUNT)] = {
        {SDLK_LEFT, 0},
        {SDLK_RIGHT, 0},
        {SDLK_UP, 0},
        {SDLK_DOWN, 0},
        {SDLK_z, 0},
        {SDLK_x, 0},
        {SDLK_RETURN, 0},
        {SDLK_r, KMOD_CTRL},
    };

    SDL_AudioSpec audioSpecRequested;
    SDL_AudioSpec audioSpecActual;
    SDL_AudioDeviceID audioDevice;

    uint8_t audioChannelNextIndex;

    struct AudioChannel {
        uint32_t sampleCount;
        uint16_t frequency;
        double phase;
    };

    AudioChannel audioChannels[AUDIO_CHANNEL_COUNT];

    void audioCallback(void* userdata, uint8_t* rawBuffer, int rawBufferLength) {
        int16_t* samples = reinterpret_cast<int16_t*>(rawBuffer);
        int sampleCount = rawBufferLength / 2;

        for(int sampleIndex = 0; sampleIndex != sampleCount; ++sampleIndex) {
            int16_t sample = 0;
            for(int channelIndex = 0; channelIndex != AUDIO_CHANNEL_COUNT; ++channelIndex) {
                if(audioChannels[channelIndex].sampleCount > 0) {
                    audioChannels[channelIndex].sampleCount--;
                    sample += sin(static_cast<double>(audioChannels[channelIndex].phase) / static_cast<double>(AUDIO_FREQUENCY) * 2 * M_PI) < 0 ? -AUDIO_AMPLITUDE : AUDIO_AMPLITUDE;
                    audioChannels[channelIndex].phase += audioChannels[channelIndex].frequency;
                }
            }

            samples[sampleIndex] = sample;
        }
    }
}

namespace frogboy {
    bool init() {
        srand(static_cast<unsigned int>(time(nullptr)));

        if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_AUDIO) != 0) {
            return false;
        }

        int scale = SCREEN_SCALE;
        SDL_DisplayMode dm;
        if (SDL_GetDesktopDisplayMode(0, &dm) == 0) {
            if(dm.w - DESKTOP_FIT_BORDER < SCREEN_WIDTH * scale
            || dm.h - DESKTOP_FIT_BORDER < SCREEN_HEIGHT * scale) {
                int xscale = (dm.w - DESKTOP_FIT_BORDER) / SCREEN_WIDTH;
                int yscale = (dm.h - DESKTOP_FIT_BORDER) / SCREEN_HEIGHT;
                scale = xscale < yscale ? xscale : yscale;

                if(scale < 1) {
                    scale = 1;
                }
            }
        }

        window = SDL_CreateWindow(FROGBOY_APPNAME, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH * scale, SCREEN_HEIGHT * scale, SDL_WINDOW_RESIZABLE);
        if(window == nullptr) {
            return false;
        }

        renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
        if(renderer == nullptr) {
            return false;
        }

        SDL_SetWindowGrab(window, SDL_FALSE);
        SDL_SetRelativeMouseMode(SDL_FALSE);

        SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest");
        SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT);

        screenTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, SCREEN_WIDTH, SCREEN_HEIGHT);
        if(screenTexture == nullptr) {
            return false;
        }

        screenSurface = SDL_CreateRGBSurface(0, SCREEN_WIDTH, SCREEN_HEIGHT, 32, 0, 0, 0, 0);
        if(screenSurface == nullptr) {
            return false;
        }

        memset(&audioSpecRequested, 0, sizeof(audioSpecRequested));
        audioSpecRequested.freq = AUDIO_FREQUENCY;
        audioSpecRequested.format = AUDIO_S16;
        audioSpecRequested.channels = 1;
        audioSpecRequested.samples = 2048;
        audioSpecRequested.callback = audioCallback;

        memset(audioChannels, 0, sizeof(audioChannels));
        audioChannelNextIndex = 0;

        audioDevice = SDL_OpenAudioDevice(nullptr, 0, &audioSpecRequested, &audioSpecActual, 0);
        if(audioDevice == 0) {
            return false;
        }

        clearScreen();
        lastFrame = SDL_GetTicks();
        lastMouseMove = lastFrame;

        windowOpen = true;
        windowMaximized = false;
        windowFullscreen = false;

        memset(pressed, 0, sizeof(pressed));

        SDL_PauseAudioDevice(audioDevice, 0);

        return true;
    }

    void destroy() {
        if(audioDevice > 0) {
            SDL_CloseAudioDevice(audioDevice);
        }
        if(screenTexture != nullptr) {
            SDL_DestroyTexture(screenTexture);
        }
        if(screenSurface != nullptr) {
            SDL_FreeSurface(screenSurface);
        }
        if(renderer != nullptr) {
            SDL_DestroyRenderer(renderer);
        }
        if(window != nullptr) {
            SDL_DestroyWindow(window);
        }
        screenTexture = nullptr;
        screenSurface = nullptr;
        renderer = nullptr;
        window = nullptr;
        SDL_Quit();
    }

    void clearScreen() {
        memset(screenBuffer, 0, sizeof(screenBuffer));
    }

    void refreshScreen() {
        SDL_LockSurface(screenSurface);
        uint32_t black = SDL_MapRGBA(screenSurface->format, 0, 0, 0, 0);
        uint32_t white = SDL_MapRGBA(screenSurface->format, 255, 255, 255, 0);
        uint32_t* surfaceRowPtr = static_cast<uint32_t*>(screenSurface->pixels);
        for(size_t y = 0; y != SCREEN_HEIGHT; ++y) {
            uint32_t* ptr = surfaceRowPtr;
            for(size_t x = 0; x != SCREEN_WIDTH; ++x) {
                size_t shift = y % 8;
                size_t bufferRow = y / 8;
                *ptr = ((screenBuffer[bufferRow * SCREEN_WIDTH + x] >> shift) & 1) == 0 ? black : white;
                ptr++;
            }
            surfaceRowPtr = reinterpret_cast<uint32_t*>(reinterpret_cast<uint8_t*>(surfaceRowPtr) + screenSurface->pitch);
        }
        SDL_UnlockSurface(screenSurface);

        SDL_UpdateTexture(screenTexture, NULL, screenSurface->pixels, screenSurface->pitch);
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
        SDL_RenderClear(renderer);
        SDL_RenderCopy(renderer, screenTexture, NULL, NULL);
        SDL_RenderPresent(renderer);
    }

    void toggleFullscreen() {
        windowFullscreen = !windowFullscreen;
        SDL_SetWindowFullscreen(window, windowFullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
        SDL_ShowCursor(windowFullscreen ? SDL_DISABLE : SDL_ENABLE);
        lastMouseMove = 0;
    }

    bool waitForFrame() {
        if(!windowOpen) {
            return false;
        }

        bool resized = false;

        {
            SDL_Event e;
            while(SDL_PollEvent(&e) != 0) {
                switch(e.type) {
                    case SDL_QUIT:
                        windowOpen = false;
                        break;
                    case SDL_KEYDOWN: {
                        SDL_Keycode sym = e.key.keysym.sym;
                        uint16_t mod = e.key.keysym.mod & (KMOD_CTRL | KMOD_ALT);

                        for(size_t i = 0; i != BUTTON_COUNT; ++i) {
                            const auto& keycode = keycodes[i];
                            if(((keycode.mod == 0 && mod == 0)
                                || (mod & keycode.mod) != 0)
                            && sym == keycode.code) {
                                pressed[i] = true;
                                break;
                            }
                        }

                        if(e.key.repeat == 0
                        && ((e.key.keysym.mod & KMOD_ALT) != 0 && e.key.keysym.sym == SDLK_RETURN
                            || e.key.keysym.sym == SDLK_F11)) {
                            toggleFullscreen();
                        }

                        if(e.key.repeat == 0
                        && e.key.keysym.sym == SDLK_ESCAPE) {
                            if(windowFullscreen) {
                                toggleFullscreen();
                            }
                        }
                        break;
                    }
                    case SDL_KEYUP: {
                        SDL_Keycode sym = e.key.keysym.sym;
                        uint16_t mod = e.key.keysym.mod & (KMOD_CTRL | KMOD_ALT);

                        for(size_t i = 0; i != BUTTON_COUNT; ++i) {
                            const auto& keycode = keycodes[i];
                            if(((keycode.mod == 0 && mod == 0)
                                || (mod & keycode.mod) != 0)
                            && sym == keycode.code) {
                                pressed[i] = false;
                                break;
                            }
                        }
                        break;
                    }
                    case SDL_WINDOWEVENT:
                        switch(e.window.event) {
                            case SDL_WINDOWEVENT_RESIZED: {
                                resized = true;
                                break;
                            }
                            case SDL_WINDOWEVENT_MAXIMIZED: {
                                windowMaximized = true;
                                break;
                            }
                            case SDL_WINDOWEVENT_RESTORED: {
                                windowMaximized = false;
                                resized = true;
                                break;
                            }
                        }
                        break;
                    case SDL_MOUSEMOTION:
                        lastMouseMove = SDL_GetTicks();
                        SDL_ShowCursor(SDL_ENABLE);
                        break;

                    case SDL_MOUSEBUTTONDOWN:
                        if(e.button.button == SDL_BUTTON_LEFT
                        && e.button.clicks == 2) {
                            toggleFullscreen();
                        }
                }
            }
        }

        if(!windowFullscreen && !windowMaximized && resized) {
            int width, height;
            SDL_GetWindowSize(window, &width, &height);
            int xscale = (width + SCREEN_WIDTH / 2) / SCREEN_WIDTH;
            int yscale = (height + SCREEN_HEIGHT / 2) / SCREEN_HEIGHT;

            if(width % SCREEN_WIDTH != 0
            || height % SCREEN_HEIGHT != 0
            || xscale != yscale) {
                int scale = xscale > yscale ? xscale : yscale;
                if(scale < 1) {
                    scale = 1;
                }

                SDL_SetWindowSize(window, scale * SCREEN_WIDTH, scale * SCREEN_HEIGHT);
            }
        }

        if(windowOpen) {
            uint32_t timer = SDL_GetTicks();
            if(lastFrame + FRAME_INTERVAL > timer
            && deltaTime < FRAME_INTERVAL) {
                SDL_Delay(10);
            }

            timer = SDL_GetTicks();
            deltaTime += timer - lastFrame;
            lastFrame = timer;

            if(windowFullscreen && timer - lastMouseMove > 3000) {
                SDL_ShowCursor(SDL_DISABLE);
            }

            if(deltaTime > FRAME_INTERVAL * 3) {
                deltaTime = FRAME_INTERVAL * 3;
            }

            if(deltaTime >= FRAME_INTERVAL) {
                deltaTime -= FRAME_INTERVAL;
                return true;
            }
        }

        return false;
    }

    bool isActive() {
        return windowOpen;
    }

    uint8_t reverseBits(uint8_t value) {
        value = (value & 0xF0) >> 4 | (value & 0x0F) << 4;
        value = (value & 0xCC) >> 2 | (value & 0x33) << 2;
        value = (value & 0xAA) >> 1 | (value & 0x55) << 1;
        return value;
    }

    uint8_t* getScreenBuffer() {
        return screenBuffer;
    }

    void playTone(uint16_t frequency, uint32_t duration) {
        SDL_LockAudioDevice(audioDevice);
        audioChannels[audioChannelNextIndex].frequency = frequency;
        audioChannels[audioChannelNextIndex].sampleCount = duration * AUDIO_FREQUENCY / 1000;
        audioChannels[audioChannelNextIndex].phase = 0;
        SDL_UnlockAudioDevice(audioDevice);

        audioChannelNextIndex = (audioChannelNextIndex + 1) % AUDIO_CHANNEL_COUNT;
    }

    bool isPressed(Button button) {
        return pressed[button];
    }

    int getRandom(int min, int max) {
        return rand() % (max - min + 1) + min;
    }

    struct Save {
        FILE* file;
    };

    Save* saveOpen(SaveOpenMode mode) {
        char* prefPath = SDL_GetPrefPath("eggboycolor", FROGBOY_APPNAME);
        if(prefPath != nullptr) {
            std::string path(prefPath);
            SDL_free(prefPath);

            path += FROGBOY_APPNAME;
            path += ".sav";

            Save* save = new Save();
            if(save != nullptr) {
                FILE* f = nullptr;
                switch(mode) {
                    case SAVE_OPEN_MODE_READ: f = fopen(path.c_str(), "rb"); break;
                    case SAVE_OPEN_MODE_WRITE: f = fopen(path.c_str(), "wb"); break;
                }

                if(f != nullptr) {
                    save->file = f;
                    return save;
                }

                delete save;
            }
        }
        return nullptr;
    }

    void saveReadBytes(Save* save, uint16_t length, void* data) {
        if(data != nullptr) {
            fread(data, length, 1, save->file);
        } else {
            fseek(save->file, length, SEEK_CUR);
        }
    }

    void saveWriteBytes(Save* save, uint16_t length, const void* data) {
        fwrite(data, length, 1, save->file);
    }

    void saveClose(Save* save) {
        fclose(save->file);
        delete save;
    }
}
#endif<commit_msg>SDL version - fix problems with key up and modifiers keys being held at the same time.<commit_after>#ifdef FROGBOY_SDL
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <SDL.h>
#include <string>

#include "frogboy.h"

namespace {
    enum {
        FRAME_INTERVAL = 16,
        SCREEN_SCALE = 8,
        DESKTOP_FIT_BORDER = 64,

        AUDIO_CHANNEL_COUNT = 2,
        AUDIO_FREQUENCY = 48000,
        AUDIO_AMPLITUDE = 15000,
    };

    SDL_Window* window = nullptr;
    SDL_Renderer* renderer = nullptr;
    SDL_Texture* screenTexture = nullptr;
    SDL_Surface* screenSurface = nullptr;
    uint8_t screenBuffer[frogboy::SCREEN_WIDTH * (frogboy::SCREEN_HEIGHT / 8)];

    uint32_t deltaTime = 0;
    uint32_t lastFrame = 0;
    uint32_t lastMouseMove = 0;

    bool windowOpen = false;
    bool windowMaximized = false;
    bool windowFullscreen = false;

    bool pressed[static_cast<size_t>(frogboy::BUTTON_COUNT)];

    struct KeyCode {
        SDL_Keycode code;
        bool ctrl;
        bool alt;
    };

    const KeyCode keycodes[static_cast<size_t>(frogboy::BUTTON_COUNT)] = {
        {SDLK_LEFT, false, false},
        {SDLK_RIGHT, false, false},
        {SDLK_UP, false, false},
        {SDLK_DOWN, false, false},
        {SDLK_z, false, false},
        {SDLK_x, false, false},
        {SDLK_RETURN, false, false},
        {SDLK_r, true, false},
    };

    SDL_AudioSpec audioSpecRequested;
    SDL_AudioSpec audioSpecActual;
    SDL_AudioDeviceID audioDevice;

    uint8_t audioChannelNextIndex;

    struct AudioChannel {
        uint32_t sampleCount;
        uint16_t frequency;
        double phase;
    };

    AudioChannel audioChannels[AUDIO_CHANNEL_COUNT];

    void audioCallback(void* userdata, uint8_t* rawBuffer, int rawBufferLength) {
        int16_t* samples = reinterpret_cast<int16_t*>(rawBuffer);
        int sampleCount = rawBufferLength / 2;

        for(int sampleIndex = 0; sampleIndex != sampleCount; ++sampleIndex) {
            int16_t sample = 0;
            for(int channelIndex = 0; channelIndex != AUDIO_CHANNEL_COUNT; ++channelIndex) {
                if(audioChannels[channelIndex].sampleCount > 0) {
                    audioChannels[channelIndex].sampleCount--;
                    sample += sin(static_cast<double>(audioChannels[channelIndex].phase) / static_cast<double>(AUDIO_FREQUENCY) * 2 * M_PI) < 0 ? -AUDIO_AMPLITUDE : AUDIO_AMPLITUDE;
                    audioChannels[channelIndex].phase += audioChannels[channelIndex].frequency;
                }
            }

            samples[sampleIndex] = sample;
        }
    }
}

namespace frogboy {
    bool init() {
        srand(static_cast<unsigned int>(time(nullptr)));

        if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_AUDIO) != 0) {
            return false;
        }

        int scale = SCREEN_SCALE;
        SDL_DisplayMode dm;
        if (SDL_GetDesktopDisplayMode(0, &dm) == 0) {
            if(dm.w - DESKTOP_FIT_BORDER < SCREEN_WIDTH * scale
            || dm.h - DESKTOP_FIT_BORDER < SCREEN_HEIGHT * scale) {
                int xscale = (dm.w - DESKTOP_FIT_BORDER) / SCREEN_WIDTH;
                int yscale = (dm.h - DESKTOP_FIT_BORDER) / SCREEN_HEIGHT;
                scale = xscale < yscale ? xscale : yscale;

                if(scale < 1) {
                    scale = 1;
                }
            }
        }

        window = SDL_CreateWindow(FROGBOY_APPNAME, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH * scale, SCREEN_HEIGHT * scale, SDL_WINDOW_RESIZABLE);
        if(window == nullptr) {
            return false;
        }

        renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
        if(renderer == nullptr) {
            return false;
        }

        SDL_SetWindowGrab(window, SDL_FALSE);
        SDL_SetRelativeMouseMode(SDL_FALSE);

        SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest");
        SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT);

        screenTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, SCREEN_WIDTH, SCREEN_HEIGHT);
        if(screenTexture == nullptr) {
            return false;
        }

        screenSurface = SDL_CreateRGBSurface(0, SCREEN_WIDTH, SCREEN_HEIGHT, 32, 0, 0, 0, 0);
        if(screenSurface == nullptr) {
            return false;
        }

        memset(&audioSpecRequested, 0, sizeof(audioSpecRequested));
        audioSpecRequested.freq = AUDIO_FREQUENCY;
        audioSpecRequested.format = AUDIO_S16;
        audioSpecRequested.channels = 1;
        audioSpecRequested.samples = 2048;
        audioSpecRequested.callback = audioCallback;

        memset(audioChannels, 0, sizeof(audioChannels));
        audioChannelNextIndex = 0;

        audioDevice = SDL_OpenAudioDevice(nullptr, 0, &audioSpecRequested, &audioSpecActual, 0);
        if(audioDevice == 0) {
            return false;
        }

        clearScreen();
        lastFrame = SDL_GetTicks();
        lastMouseMove = lastFrame;

        windowOpen = true;
        windowMaximized = false;
        windowFullscreen = false;

        memset(pressed, 0, sizeof(pressed));

        SDL_PauseAudioDevice(audioDevice, 0);

        return true;
    }

    void destroy() {
        if(audioDevice > 0) {
            SDL_CloseAudioDevice(audioDevice);
        }
        if(screenTexture != nullptr) {
            SDL_DestroyTexture(screenTexture);
        }
        if(screenSurface != nullptr) {
            SDL_FreeSurface(screenSurface);
        }
        if(renderer != nullptr) {
            SDL_DestroyRenderer(renderer);
        }
        if(window != nullptr) {
            SDL_DestroyWindow(window);
        }
        screenTexture = nullptr;
        screenSurface = nullptr;
        renderer = nullptr;
        window = nullptr;
        SDL_Quit();
    }

    void clearScreen() {
        memset(screenBuffer, 0, sizeof(screenBuffer));
    }

    void refreshScreen() {
        SDL_LockSurface(screenSurface);
        uint32_t black = SDL_MapRGBA(screenSurface->format, 0, 0, 0, 0);
        uint32_t white = SDL_MapRGBA(screenSurface->format, 255, 255, 255, 0);
        uint32_t* surfaceRowPtr = static_cast<uint32_t*>(screenSurface->pixels);
        for(size_t y = 0; y != SCREEN_HEIGHT; ++y) {
            uint32_t* ptr = surfaceRowPtr;
            for(size_t x = 0; x != SCREEN_WIDTH; ++x) {
                size_t shift = y % 8;
                size_t bufferRow = y / 8;
                *ptr = ((screenBuffer[bufferRow * SCREEN_WIDTH + x] >> shift) & 1) == 0 ? black : white;
                ptr++;
            }
            surfaceRowPtr = reinterpret_cast<uint32_t*>(reinterpret_cast<uint8_t*>(surfaceRowPtr) + screenSurface->pitch);
        }
        SDL_UnlockSurface(screenSurface);

        SDL_UpdateTexture(screenTexture, NULL, screenSurface->pixels, screenSurface->pitch);
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
        SDL_RenderClear(renderer);
        SDL_RenderCopy(renderer, screenTexture, NULL, NULL);
        SDL_RenderPresent(renderer);
    }

    void toggleFullscreen() {
        windowFullscreen = !windowFullscreen;
        SDL_SetWindowFullscreen(window, windowFullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
        SDL_ShowCursor(windowFullscreen ? SDL_DISABLE : SDL_ENABLE);
        lastMouseMove = 0;
    }

    bool waitForFrame() {
        if(!windowOpen) {
            return false;
        }

        bool resized = false;

        {
            SDL_Event e;
            while(SDL_PollEvent(&e) != 0) {
                switch(e.type) {
                    case SDL_QUIT:
                        windowOpen = false;
                        break;
                    case SDL_KEYDOWN: {
                        bool handled = false;

                        if(!handled
                        && e.key.repeat == 0
                        && ((e.key.keysym.mod & KMOD_ALT) != 0 && e.key.keysym.sym == SDLK_RETURN
                            || e.key.keysym.sym == SDLK_F11)) {
                            handled = true;
                            toggleFullscreen();
                        }
                        if(!handled
                        && e.key.repeat == 0
                        && e.key.keysym.sym == SDLK_ESCAPE) {
                            handled = true;
                            if(windowFullscreen) {
                                toggleFullscreen();
                            }
                        }

                        for(size_t i = 0; i != BUTTON_COUNT && !handled; ++i) {
                            const auto& keycode = keycodes[i];
                            if((!keycode.ctrl && (e.key.keysym.mod & KMOD_CTRL) == 0
                                || keycode.ctrl && (e.key.keysym.mod & KMOD_CTRL) != 0)
                            && (!keycode.alt && (e.key.keysym.mod & KMOD_ALT) == 0
                                || keycode.alt && (e.key.keysym.mod & KMOD_ALT) != 0)
                            && e.key.keysym.sym == keycode.code) {
                                pressed[i] = true;
                                handled = true;
                                break;
                            }
                        }

                        break;
                    }
                    case SDL_KEYUP: {
                        SDL_Keycode sym = e.key.keysym.sym;
                        uint16_t mod = e.key.keysym.mod & (KMOD_CTRL | KMOD_ALT);

                        for(size_t i = 0; i != BUTTON_COUNT; ++i) {
                            const auto& keycode = keycodes[i];
                            if((!keycode.ctrl
                                || keycode.ctrl && (e.key.keysym.mod & KMOD_CTRL) != 0)
                            && (!keycode.alt
                                || keycode.alt && (e.key.keysym.mod & KMOD_ALT) != 0)
                            && sym == keycode.code) {
                                pressed[i] = false;
                                break;
                            }
                        }
                        break;
                    }
                    case SDL_WINDOWEVENT:
                        switch(e.window.event) {
                            case SDL_WINDOWEVENT_RESIZED: {
                                resized = true;
                                break;
                            }
                            case SDL_WINDOWEVENT_MAXIMIZED: {
                                windowMaximized = true;
                                break;
                            }
                            case SDL_WINDOWEVENT_RESTORED: {
                                windowMaximized = false;
                                resized = true;
                                break;
                            }
                        }
                        break;
                    case SDL_MOUSEMOTION:
                        lastMouseMove = SDL_GetTicks();
                        SDL_ShowCursor(SDL_ENABLE);
                        break;

                    case SDL_MOUSEBUTTONDOWN:
                        if(e.button.button == SDL_BUTTON_LEFT
                        && e.button.clicks == 2) {
                            toggleFullscreen();
                        }
                }
            }
        }

        if(!windowFullscreen && !windowMaximized && resized) {
            int width, height;
            SDL_GetWindowSize(window, &width, &height);
            int xscale = (width + SCREEN_WIDTH / 2) / SCREEN_WIDTH;
            int yscale = (height + SCREEN_HEIGHT / 2) / SCREEN_HEIGHT;

            if(width % SCREEN_WIDTH != 0
            || height % SCREEN_HEIGHT != 0
            || xscale != yscale) {
                int scale = xscale > yscale ? xscale : yscale;
                if(scale < 1) {
                    scale = 1;
                }

                SDL_SetWindowSize(window, scale * SCREEN_WIDTH, scale * SCREEN_HEIGHT);
            }
        }

        if(windowOpen) {
            uint32_t timer = SDL_GetTicks();
            if(lastFrame + FRAME_INTERVAL > timer
            && deltaTime < FRAME_INTERVAL) {
                SDL_Delay(10);
            }

            timer = SDL_GetTicks();
            deltaTime += timer - lastFrame;
            lastFrame = timer;

            if(windowFullscreen && timer - lastMouseMove > 3000) {
                SDL_ShowCursor(SDL_DISABLE);
            }

            if(deltaTime > FRAME_INTERVAL * 3) {
                deltaTime = FRAME_INTERVAL * 3;
            }

            if(deltaTime >= FRAME_INTERVAL) {
                deltaTime -= FRAME_INTERVAL;
                return true;
            }
        }

        return false;
    }

    bool isActive() {
        return windowOpen;
    }

    uint8_t reverseBits(uint8_t value) {
        value = (value & 0xF0) >> 4 | (value & 0x0F) << 4;
        value = (value & 0xCC) >> 2 | (value & 0x33) << 2;
        value = (value & 0xAA) >> 1 | (value & 0x55) << 1;
        return value;
    }

    uint8_t* getScreenBuffer() {
        return screenBuffer;
    }

    void playTone(uint16_t frequency, uint32_t duration) {
        SDL_LockAudioDevice(audioDevice);
        audioChannels[audioChannelNextIndex].frequency = frequency;
        audioChannels[audioChannelNextIndex].sampleCount = duration * AUDIO_FREQUENCY / 1000;
        audioChannels[audioChannelNextIndex].phase = 0;
        SDL_UnlockAudioDevice(audioDevice);

        audioChannelNextIndex = (audioChannelNextIndex + 1) % AUDIO_CHANNEL_COUNT;
    }

    bool isPressed(Button button) {
        return pressed[button];
    }

    int getRandom(int min, int max) {
        return rand() % (max - min + 1) + min;
    }

    struct Save {
        FILE* file;
    };

    Save* saveOpen(SaveOpenMode mode) {
        char* prefPath = SDL_GetPrefPath("eggboycolor", FROGBOY_APPNAME);
        if(prefPath != nullptr) {
            std::string path(prefPath);
            SDL_free(prefPath);

            path += FROGBOY_APPNAME;
            path += ".sav";

            Save* save = new Save();
            if(save != nullptr) {
                FILE* f = nullptr;
                switch(mode) {
                    case SAVE_OPEN_MODE_READ: f = fopen(path.c_str(), "rb"); break;
                    case SAVE_OPEN_MODE_WRITE: f = fopen(path.c_str(), "wb"); break;
                }

                if(f != nullptr) {
                    save->file = f;
                    return save;
                }

                delete save;
            }
        }
        return nullptr;
    }

    void saveReadBytes(Save* save, uint16_t length, void* data) {
        if(data != nullptr) {
            fread(data, length, 1, save->file);
        } else {
            fseek(save->file, length, SEEK_CUR);
        }
    }

    void saveWriteBytes(Save* save, uint16_t length, const void* data) {
        fwrite(data, length, 1, save->file);
    }

    void saveClose(Save* save) {
        fclose(save->file);
        delete save;
    }
}
#endif<|endoftext|>


<commit_before>#include "stdsneezy.h"
#include "obj_casino_chip.h"
#include "games.h"

void deleteChips(TMonster *me)
{
  vector <TThing *> chipl;
  TCasinoChip *chip;

  for(TThing *t=me->getStuff();t;t=t->nextThing){
    if((chip=dynamic_cast<TCasinoChip *>(t))){
      chipl.push_back(t);
    }
  }

  for(unsigned int i=0;i<chipl.size();++i){
    (*chipl[i])--;
    delete chipl[i];
  }
}

struct holdemPlayerInfo {
  sstring name;
  bool enabled;
  int chip;
  bool free_chips;
};

void holdemStatus(TMonster *me, holdemPlayerInfo *hpi)
{
  me->doEmote("suddenly snaps to rigid attention.");
  me->doSay("Name        : %s", hpi->name.c_str());
  me->doSay("Enabled     : %s", hpi->enabled?"<G>YES<1>":"<R>NO<1>");
  me->doSay("Chip        : %s", obj_index[real_object(hpi->chip)].short_desc);
  me->doSay("All systems : <G>NOMINAL<1>");
  me->doEmote("resumes a relaxed pose.");
}

int holdemPlayer(TBeing *ch, cmdTypeT cmd, const char *argument, TMonster *me, TObj *)
{
  holdemPlayerInfo *hpi;
  sstring arg=sstring(argument).lower(), buf;
  TObj *obj;

  if(!me->act_ptr) {
    if(!(me->act_ptr = new holdemPlayerInfo)) {
     vlogf(LOG_BUG, "failed new of holdem player.");
     return false;
    }
    hpi = static_cast<holdemPlayerInfo *>(me->act_ptr);
    hpi->name="gambler2000";
    hpi->enabled=false;
    hpi->chip=CHIP_100;
    hpi->free_chips=true;
  } else {
    hpi = static_cast<holdemPlayerInfo *>(me->act_ptr);
  }

  arg=one_argument(arg, buf);

  if(cmd == CMD_SAY2 && ch->isImmortal() && buf==hpi->name){
    if(arg=="power up"){
      hpi->enabled=true;
      me->doSay("Gambler 2000 powering up!");
      holdemStatus(me, hpi);
    } else if(arg=="status"){
      holdemStatus(me, hpi);
    } else if(arg=="power down"){
      me->doSay("Gambler 2000 powering down!");
      delete static_cast<holdemPlayerInfo *>(me->act_ptr);
      me->act_ptr = NULL;
    } else if(arg.find("name ", 0)!=sstring::npos){
      arg=one_argument(arg, buf);

      buf=me->name;
      if(buf.find(hpi->name)!=sstring::npos){
	buf.replace(buf.find(hpi->name), hpi->name.length(), arg);
      } else {
	buf += " ";
	buf += arg;
      }

      me->swapToStrung();
      delete me->name;
      me->name=mud_str_dup(buf);

      hpi->name=arg;
      me->doSay("Gambler2000 will now bust a dope rhyme.");
      me->doSay("My name is... huh?");
      me->doSay("My name is... what?");
      me->doSay("My name is %s.", hpi->name.c_str());

    } else if(arg.find("chip ", 0)!=sstring::npos){
      arg=one_argument(arg, buf);
      if(convertTo<int>(arg)==0)
	return false;
      hpi->chip=convertTo<int>(arg);
      me->doSay("All your %s are belong to Gambler2000.",
		obj_index[real_object(hpi->chip)].short_desc);
    } else if(arg=="freechips"){
      if(hpi->free_chips){
	hpi->free_chips=false;
	me->doSay("There ain't no such thing as a free chip.");

	int tcount=0;
	for(TThing *t=me->getStuff();t;t=t->nextThing){
	  if((obj=dynamic_cast<TObj *>(t))){
	    if(obj->objVnum() == hpi->chip)
	      tcount++;
	  }
	}

	me->doSay("I have %s [%i].",
		  obj_index[real_object(hpi->chip)].short_desc, tcount);
      } else {
	hpi->free_chips=true;
	me->doSay("I will now pull chips out of my ass.");
      }
    }
    return true;
  }

  if (cmd == CMD_GENERIC_DESTROYED) {
    delete static_cast<holdemPlayerInfo *>(me->act_ptr);
    me->act_ptr = NULL;
    return FALSE;
  }

  if(cmd != CMD_GENERIC_QUICK_PULSE || !hpi->enabled)
    return false;

  if(hpi->free_chips)
    deleteChips(me);

  if (!me->checkHoldem(true))
    return false;

  if(!gHoldem.isPlaying(me)){
    gHoldem.enter(me);
    return false;
  }

  HoldemPlayer *hp=gHoldem.getPlayer(me->name);

  if(gHoldem.getBetter() != hp)
    return false;

  int handval=gHoldem.handValue(hp);
  TObj *chip;
  vector <TObj *> chipl;

  if(gHoldem.getLastBet()){
    if(gHoldem.getLastBet() != hpi->chip){
      me->doSay("Sorry, I only play with '%s' right now.",
		obj_index[real_object(hpi->chip)].short_desc);
      gHoldem.fold(me);
      return false;
    }

    if(hpi->free_chips){
      for(int i=0;i<gHoldem.getNRaises()+1;++i){
	chip=read_object(gHoldem.getLastBet(), VIRTUAL);
	*me += *chip;
	chipl.push_back(chip);
      }
    }
  } else {
    return false;
  }

  switch(gHoldem.getState()){
    case STATE_NONE:
      break;
    case STATE_DEAL:
      // if someone raised before the flop
      if(gHoldem.getNRaises() > 1){
	// if we have a couple of high cards, we'll call once in awhile
	if((hp->hand[0]->getValAceHi() >= 10) &&
	   (hp->hand[1]->getValAceHi() >= 10) && !::number(0,2)){
	  gHoldem.call(me);
	  return true;
	} else if(handval > 15){
	  // or if we have a pair we'll call
	  gHoldem.call(me);
	  return true;
	} else {
	  // but otherwise fold
	  gHoldem.fold(me);
	}
      }

      // by default we call to see the flop
      gHoldem.call(me);
      return true;
      break;
    case STATE_FLOP:
      if(handval > 30 && ::number(0,1)){
	gHoldem.raise(me, "");
	return true;
      } else if(handval > 15 || !::number(0,3)){
	gHoldem.call(me);
	return true;
      }

      // no hand, may as well fold
      gHoldem.fold(me);
      return true;
      break;
    case STATE_TURN:
    case STATE_RIVER:
      if(handval > 45){
	gHoldem.raise(me, "");
      } else if(handval > 15){
	gHoldem.call(me);
      } else {
	gHoldem.fold(me);
      }

      if(hpi->free_chips)
	deleteChips(me);

      return true;
      break;
  }

  if(hpi->free_chips){
    for(unsigned int i=0;i<chipl.size();++i){
      (*chipl[i])--;
      delete chipl[i];
    }
  }

  gHoldem.fold(me);
  return true;
}

<commit_msg>fixed a couple of bugs<commit_after>#include "stdsneezy.h"
#include "obj_casino_chip.h"
#include "games.h"

void deleteChips(TMonster *me)
{
  vector <TThing *> chipl;
  TCasinoChip *chip;

  for(TThing *t=me->getStuff();t;t=t->nextThing){
    if((chip=dynamic_cast<TCasinoChip *>(t))){
      chipl.push_back(t);
    }
  }

  for(unsigned int i=0;i<chipl.size();++i){
    (*chipl[i])--;
    delete chipl[i];
  }
}

struct holdemPlayerInfo {
  sstring name;
  bool enabled;
  int chip;
  bool free_chips;
};

void holdemStatus(TMonster *me, holdemPlayerInfo *hpi)
{
  me->doEmote("suddenly snaps to rigid attention.");
  me->doSay("Name        : %s", hpi->name.c_str());
  me->doSay("Enabled     : %s", hpi->enabled?"<G>YES<1>":"<R>NO<1>");
  me->doSay("Chip        : %s", obj_index[real_object(hpi->chip)].short_desc);
  me->doSay("All systems : <G>NOMINAL<1>");
  me->doEmote("resumes a relaxed pose.");
}

int holdemPlayer(TBeing *ch, cmdTypeT cmd, const char *argument, TMonster *me, TObj *)
{
  holdemPlayerInfo *hpi;
  sstring arg=sstring(argument).lower(), buf;
  TObj *obj;

  if(!me->act_ptr) {
    if(!(me->act_ptr = new holdemPlayerInfo)) {
     vlogf(LOG_BUG, "failed new of holdem player.");
     return false;
    }
    hpi = static_cast<holdemPlayerInfo *>(me->act_ptr);
    hpi->name="gambler2000";
    hpi->enabled=false;
    hpi->chip=CHIP_100;
    hpi->free_chips=true;
  } else {
    hpi = static_cast<holdemPlayerInfo *>(me->act_ptr);
  }

  arg=one_argument(arg, buf);

  if(cmd == CMD_SAY2 && ch->isImmortal() && buf==hpi->name){
    if(arg=="power up"){
      hpi->enabled=true;
      me->doSay("Gambler 2000 powering up!");
      holdemStatus(me, hpi);
    } else if(arg=="status"){
      holdemStatus(me, hpi);
    } else if(arg=="power down"){
      me->doSay("Gambler 2000 powering down!");
      delete static_cast<holdemPlayerInfo *>(me->act_ptr);
      me->act_ptr = NULL;
    } else if(arg.find("name ", 0)!=sstring::npos){
      arg=one_argument(arg, buf);

      buf=me->name;
      if(buf.find(hpi->name)!=sstring::npos){
	buf.replace(buf.find(hpi->name), hpi->name.length(), arg);
      } else {
	buf += " ";
	buf += arg;
      }

      me->swapToStrung();
      delete me->name;
      me->name=mud_str_dup(buf);

      hpi->name=arg;
      me->doSay("Gambler2000 will now bust a dope rhyme.");
      me->doSay("My name is... huh?");
      me->doSay("My name is... what?");
      me->doSay("My name is %s.", hpi->name.c_str());

    } else if(arg.find("chip ", 0)!=sstring::npos){
      arg=one_argument(arg, buf);
      if(convertTo<int>(arg)==0)
	return false;
      hpi->chip=convertTo<int>(arg);

      if(real_object(hpi->chip)==-1){
	me->doSay("I can't find that chip.");
	hpi->chip=CHIP_100;
      } else {
	me->doSay("All your %s are belong to Gambler2000.",
		  obj_index[real_object(hpi->chip)].short_desc);
      }
    } else if(arg=="freechips"){
      if(hpi->free_chips){
	hpi->free_chips=false;
	me->doSay("There ain't no such thing as a free chip.");

	int tcount=0;
	for(TThing *t=me->getStuff();t;t=t->nextThing){
	  if((obj=dynamic_cast<TObj *>(t))){
	    if(obj->objVnum() == hpi->chip)
	      tcount++;
	  }
	}

	me->doSay("I have %s [%i].",
		  obj_index[real_object(hpi->chip)].short_desc, tcount);
      } else {
	hpi->free_chips=true;
	me->doSay("I will now pull chips out of my ass.");
      }
    }
    return true;
  }

  if (cmd == CMD_GENERIC_DESTROYED) {
    delete static_cast<holdemPlayerInfo *>(me->act_ptr);
    me->act_ptr = NULL;
    return FALSE;
  }

  if(cmd != CMD_GENERIC_QUICK_PULSE || !hpi->enabled)
    return false;

  if(hpi->free_chips)
    deleteChips(me);

  if (!me->checkHoldem(true))
    return false;

  if(!gHoldem.isPlaying(me)){
    gHoldem.enter(me);
    return false;
  }

  HoldemPlayer *hp=gHoldem.getPlayer(me->name);

  if(gHoldem.getBetter() != hp)
    return false;

  int handval=gHoldem.handValue(hp);
  TObj *chip;
  vector <TObj *> chipl;

  if(gHoldem.getLastBet()){
    if(gHoldem.getLastBet() != hpi->chip){
      me->doSay("Sorry, I only play with '%s' right now.",
		obj_index[real_object(hpi->chip)].short_desc);
      gHoldem.fold(me);
      return false;
    }

    if(hpi->free_chips){
      for(int i=0;i<gHoldem.getNRaises()+1;++i){
	chip=read_object(gHoldem.getLastBet(), VIRTUAL);
	*me += *chip;
	chipl.push_back(chip);
      }
    }
  } else {
    return false;
  }

  switch(gHoldem.getState()){
    case STATE_NONE:
      break;
    case STATE_DEAL:
      // if someone raised before the flop
      if(gHoldem.getNRaises() > 1){
	// if we have a couple of high cards, we'll call once in awhile
	if((hp->hand[0]->getValAceHi() >= 10) &&
	   (hp->hand[1]->getValAceHi() >= 10) && !::number(0,2)){
	  gHoldem.call(me);
	  return true;
	} else if(handval > 15){
	  // or if we have a pair we'll call
	  gHoldem.call(me);
	  return true;
	} else {
	  // but otherwise fold
	  gHoldem.fold(me);
	}
      }

      // by default we call to see the flop
      gHoldem.call(me);
      return true;
      break;
    case STATE_FLOP:
      if(handval > 30 && ::number(0,1)){
	gHoldem.raise(me, "");
	gHoldem.call(me); // sometimes raise fails, if he's broke etc
	return true;
      } else if(handval > 15 || !::number(0,3)){
	gHoldem.call(me);
	return true;
      }

      // no hand, may as well fold
      gHoldem.fold(me);
      return true;
      break;
    case STATE_TURN:
    case STATE_RIVER:
      if(handval > 45){
	gHoldem.raise(me, "");
	gHoldem.call(me); // sometimes raise fails, if he's broke etc
      } else if(handval > 15){
	gHoldem.call(me);
      } else {
	gHoldem.fold(me);
      }

      if(hpi->free_chips)
	deleteChips(me);

      return true;
      break;
  }

  if(hpi->free_chips){
    for(unsigned int i=0;i<chipl.size();++i){
      (*chipl[i])--;
      delete chipl[i];
    }
  }

  gHoldem.fold(me);
  return true;
}

<|endoftext|>