<commit_before>// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/ui/win/notify_icon.h"

#include <shobjidl.h>

#include "atom/browser/ui/win/notify_icon_host.h"
#include "base/md5.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/windows_version.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/icon_util.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/views/controls/menu/menu_runner.h"

namespace atom {

NotifyIcon::NotifyIcon(NotifyIconHost* host,
                       UINT id,
                       HWND window,
                       UINT message)
    : host_(host),
      icon_id_(id),
      window_(window),
      message_id_(message),
      menu_model_(NULL),
      has_tray_app_id_hash_(false) {
  // NB: If we have an App Model ID, we should propagate that to the tray.
  // Doing this prevents duplicate items from showing up in the notification
  // preferences (i.e. "Always Show / Show notifications only / etc")
  PWSTR explicit_app_id;
  if (SUCCEEDED(GetCurrentProcessExplicitAppUserModelID(&explicit_app_id))) {
    // GUIDs and MD5 hashes are the same length. So convenient!
    base::MD5Sum(explicit_app_id,
                 sizeof(wchar_t) * wcslen(explicit_app_id),
                 reinterpret_cast<base::MD5Digest*>(&tray_app_id_hash_));
    has_tray_app_id_hash_ = true;
    CoTaskMemFree(explicit_app_id);
  }

  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  icon_data.uFlags |= NIF_MESSAGE;
  icon_data.uCallbackMessage = message_id_;
  BOOL result = Shell_NotifyIcon(NIM_ADD, &icon_data);
  // This can happen if the explorer process isn't running when we try to
  // create the icon for some reason (for example, at startup).
  if (!result)
    LOG(WARNING) << "Unable to create status tray icon.";
}

NotifyIcon::~NotifyIcon() {
  // Remove our icon.
  host_->Remove(this);
  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  Shell_NotifyIcon(NIM_DELETE, &icon_data);
}

void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos,
                                  int modifiers,
                                  bool left_mouse_click,
                                  bool double_button_click) {
  NOTIFYICONIDENTIFIER icon_id;
  memset(&icon_id, 0, sizeof(NOTIFYICONIDENTIFIER));
  icon_id.uID = icon_id_;
  icon_id.hWnd = window_;
  icon_id.cbSize = sizeof(NOTIFYICONIDENTIFIER);
  if (has_tray_app_id_hash_)
    memcpy(reinterpret_cast<void*>(&icon_id.guidItem),
           &tray_app_id_hash_,
           sizeof(GUID));

  RECT rect = { 0 };
  Shell_NotifyIconGetRect(&icon_id, &rect);

  if (left_mouse_click) {
    if (double_button_click)  // double left click
      NotifyDoubleClicked(gfx::Rect(rect), modifiers);
    else  // single left click
      NotifyClicked(gfx::Rect(rect), modifiers);
    return;
  } else if (!double_button_click) {  // single right click
    NotifyRightClicked(gfx::Rect(rect), modifiers);
    PopContextMenu(cursor_pos);
  }
}

void NotifyIcon::ResetIcon() {
  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  // Delete any previously existing icon.
  Shell_NotifyIcon(NIM_DELETE, &icon_data);
  InitIconData(&icon_data);
  icon_data.uFlags |= NIF_MESSAGE;
  icon_data.uCallbackMessage = message_id_;
  icon_data.hIcon = icon_.Get();
  // If we have an image, then set the NIF_ICON flag, which tells
  // Shell_NotifyIcon() to set the image for the status icon it creates.
  if (icon_data.hIcon)
    icon_data.uFlags |= NIF_ICON;
  // Re-add our icon.
  BOOL result = Shell_NotifyIcon(NIM_ADD, &icon_data);
  if (!result)
    LOG(WARNING) << "Unable to re-create status tray icon.";
}

void NotifyIcon::SetImage(const gfx::Image& image) {
  // Create the icon.
  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  icon_data.uFlags |= NIF_ICON;
  icon_.Set(IconUtil::CreateHICONFromSkBitmap(image.AsBitmap()));
  icon_data.hIcon = icon_.Get();
  BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
  if (!result)
    LOG(WARNING) << "Error setting status tray icon image";
}

void NotifyIcon::SetPressedImage(const gfx::Image& image) {
  // Ignore pressed images, since the standard on Windows is to not highlight
  // pressed status icons.
}

void NotifyIcon::SetToolTip(const std::string& tool_tip) {
  // Create the icon.
  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  icon_data.uFlags |= NIF_TIP;
  wcscpy_s(icon_data.szTip, base::UTF8ToUTF16(tool_tip).c_str());
  BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
  if (!result)
    LOG(WARNING) << "Unable to set tooltip for status tray icon";
}

void NotifyIcon::DisplayBalloon(const gfx::Image& icon,
                                const base::string16& title,
                                const base::string16& contents) {
  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  icon_data.uFlags |= NIF_INFO;
  icon_data.dwInfoFlags = NIIF_INFO;
  wcscpy_s(icon_data.szInfoTitle, title.c_str());
  wcscpy_s(icon_data.szInfo, contents.c_str());
  icon_data.uTimeout = 0;

  base::win::Version win_version = base::win::GetVersion();
  if (!icon.IsEmpty() && win_version != base::win::VERSION_PRE_XP) {
    balloon_icon_.Set(IconUtil::CreateHICONFromSkBitmap(icon.AsBitmap()));
    icon_data.hBalloonIcon = balloon_icon_.Get();
    icon_data.dwInfoFlags = NIIF_USER | NIIF_LARGE_ICON;
  }

  BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
  if (!result)
    LOG(WARNING) << "Unable to create status tray balloon.";
}

void NotifyIcon::PopContextMenu(const gfx::Point& pos) {
  // Set our window as the foreground window, so the context menu closes when
  // we click away from it.
  if (!SetForegroundWindow(window_))
    return;

  views::MenuRunner menu_runner(
      menu_model_,
      views::MenuRunner::CONTEXT_MENU | views::MenuRunner::HAS_MNEMONICS);
  ignore_result(menu_runner.RunMenuAt(
      NULL,
      NULL,
      gfx::Rect(pos, gfx::Size()),
      views::MENU_ANCHOR_TOPLEFT,
      ui::MENU_SOURCE_MOUSE));
}

void NotifyIcon::SetContextMenu(ui::SimpleMenuModel* menu_model) {
  menu_model_ = menu_model;
}

void NotifyIcon::InitIconData(NOTIFYICONDATA* icon_data) {
  memset(icon_data, 0, sizeof(NOTIFYICONDATA));
  icon_data->cbSize = sizeof(NOTIFYICONDATA);
  icon_data->hWnd = window_;
  icon_data->uID = icon_id_;

  if (has_tray_app_id_hash_) {
    icon_data->uFlags |= NIF_GUID;
    memcpy(reinterpret_cast<void*>(&icon_data->guidItem),
           &tray_app_id_hash_,
           sizeof(GUID));
  }
}

}  // namespace atom
<commit_msg>Check context menu when calling popContextMenu API.<commit_after>// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/ui/win/notify_icon.h"

#include <shobjidl.h>

#include "atom/browser/ui/win/notify_icon_host.h"
#include "base/md5.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/windows_version.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/icon_util.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/views/controls/menu/menu_runner.h"

namespace atom {

NotifyIcon::NotifyIcon(NotifyIconHost* host,
                       UINT id,
                       HWND window,
                       UINT message)
    : host_(host),
      icon_id_(id),
      window_(window),
      message_id_(message),
      menu_model_(NULL),
      has_tray_app_id_hash_(false) {
  // NB: If we have an App Model ID, we should propagate that to the tray.
  // Doing this prevents duplicate items from showing up in the notification
  // preferences (i.e. "Always Show / Show notifications only / etc")
  PWSTR explicit_app_id;
  if (SUCCEEDED(GetCurrentProcessExplicitAppUserModelID(&explicit_app_id))) {
    // GUIDs and MD5 hashes are the same length. So convenient!
    base::MD5Sum(explicit_app_id,
                 sizeof(wchar_t) * wcslen(explicit_app_id),
                 reinterpret_cast<base::MD5Digest*>(&tray_app_id_hash_));
    has_tray_app_id_hash_ = true;
    CoTaskMemFree(explicit_app_id);
  }

  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  icon_data.uFlags |= NIF_MESSAGE;
  icon_data.uCallbackMessage = message_id_;
  BOOL result = Shell_NotifyIcon(NIM_ADD, &icon_data);
  // This can happen if the explorer process isn't running when we try to
  // create the icon for some reason (for example, at startup).
  if (!result)
    LOG(WARNING) << "Unable to create status tray icon.";
}

NotifyIcon::~NotifyIcon() {
  // Remove our icon.
  host_->Remove(this);
  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  Shell_NotifyIcon(NIM_DELETE, &icon_data);
}

void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos,
                                  int modifiers,
                                  bool left_mouse_click,
                                  bool double_button_click) {
  NOTIFYICONIDENTIFIER icon_id;
  memset(&icon_id, 0, sizeof(NOTIFYICONIDENTIFIER));
  icon_id.uID = icon_id_;
  icon_id.hWnd = window_;
  icon_id.cbSize = sizeof(NOTIFYICONIDENTIFIER);
  if (has_tray_app_id_hash_)
    memcpy(reinterpret_cast<void*>(&icon_id.guidItem),
           &tray_app_id_hash_,
           sizeof(GUID));

  RECT rect = { 0 };
  Shell_NotifyIconGetRect(&icon_id, &rect);

  if (left_mouse_click) {
    if (double_button_click)  // double left click
      NotifyDoubleClicked(gfx::Rect(rect), modifiers);
    else  // single left click
      NotifyClicked(gfx::Rect(rect), modifiers);
    return;
  } else if (!double_button_click) {  // single right click
    NotifyRightClicked(gfx::Rect(rect), modifiers);
    PopContextMenu(cursor_pos);
  }
}

void NotifyIcon::ResetIcon() {
  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  // Delete any previously existing icon.
  Shell_NotifyIcon(NIM_DELETE, &icon_data);
  InitIconData(&icon_data);
  icon_data.uFlags |= NIF_MESSAGE;
  icon_data.uCallbackMessage = message_id_;
  icon_data.hIcon = icon_.Get();
  // If we have an image, then set the NIF_ICON flag, which tells
  // Shell_NotifyIcon() to set the image for the status icon it creates.
  if (icon_data.hIcon)
    icon_data.uFlags |= NIF_ICON;
  // Re-add our icon.
  BOOL result = Shell_NotifyIcon(NIM_ADD, &icon_data);
  if (!result)
    LOG(WARNING) << "Unable to re-create status tray icon.";
}

void NotifyIcon::SetImage(const gfx::Image& image) {
  // Create the icon.
  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  icon_data.uFlags |= NIF_ICON;
  icon_.Set(IconUtil::CreateHICONFromSkBitmap(image.AsBitmap()));
  icon_data.hIcon = icon_.Get();
  BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
  if (!result)
    LOG(WARNING) << "Error setting status tray icon image";
}

void NotifyIcon::SetPressedImage(const gfx::Image& image) {
  // Ignore pressed images, since the standard on Windows is to not highlight
  // pressed status icons.
}

void NotifyIcon::SetToolTip(const std::string& tool_tip) {
  // Create the icon.
  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  icon_data.uFlags |= NIF_TIP;
  wcscpy_s(icon_data.szTip, base::UTF8ToUTF16(tool_tip).c_str());
  BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
  if (!result)
    LOG(WARNING) << "Unable to set tooltip for status tray icon";
}

void NotifyIcon::DisplayBalloon(const gfx::Image& icon,
                                const base::string16& title,
                                const base::string16& contents) {
  NOTIFYICONDATA icon_data;
  InitIconData(&icon_data);
  icon_data.uFlags |= NIF_INFO;
  icon_data.dwInfoFlags = NIIF_INFO;
  wcscpy_s(icon_data.szInfoTitle, title.c_str());
  wcscpy_s(icon_data.szInfo, contents.c_str());
  icon_data.uTimeout = 0;

  base::win::Version win_version = base::win::GetVersion();
  if (!icon.IsEmpty() && win_version != base::win::VERSION_PRE_XP) {
    balloon_icon_.Set(IconUtil::CreateHICONFromSkBitmap(icon.AsBitmap()));
    icon_data.hBalloonIcon = balloon_icon_.Get();
    icon_data.dwInfoFlags = NIIF_USER | NIIF_LARGE_ICON;
  }

  BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
  if (!result)
    LOG(WARNING) << "Unable to create status tray balloon.";
}

void NotifyIcon::PopContextMenu(const gfx::Point& pos) {
  // Returns if context menu isn't set.
  if (!menu_model_)
    return;
  // Set our window as the foreground window, so the context menu closes when
  // we click away from it.
  if (!SetForegroundWindow(window_))
    return;

  views::MenuRunner menu_runner(
      menu_model_,
      views::MenuRunner::CONTEXT_MENU | views::MenuRunner::HAS_MNEMONICS);
  ignore_result(menu_runner.RunMenuAt(
      NULL,
      NULL,
      gfx::Rect(pos, gfx::Size()),
      views::MENU_ANCHOR_TOPLEFT,
      ui::MENU_SOURCE_MOUSE));
}

void NotifyIcon::SetContextMenu(ui::SimpleMenuModel* menu_model) {
  menu_model_ = menu_model;
}

void NotifyIcon::InitIconData(NOTIFYICONDATA* icon_data) {
  memset(icon_data, 0, sizeof(NOTIFYICONDATA));
  icon_data->cbSize = sizeof(NOTIFYICONDATA);
  icon_data->hWnd = window_;
  icon_data->uID = icon_id_;

  if (has_tray_app_id_hash_) {
    icon_data->uFlags |= NIF_GUID;
    memcpy(reinterpret_cast<void*>(&icon_data->guidItem),
           &tray_app_id_hash_,
           sizeof(GUID));
  }
}

}  // namespace atom
<|endoftext|>


<commit_before>#include <cstdio>
#include <list>

#include "pipeline/depsGraph.hpp"

#include "lexerDriver.hpp"
#include "parser.hpp"
#include "parserTag.hpp"

#include "ast/walker.hpp"

#include "intermedia/debug/dumpFunction.hpp"
#include "intermedia/optimizer/optimizer.hpp"
#include "intermedia/praeCompiler/compiler.hpp"
#include "intermedia/scheduler.hpp"
#include "intermedia/verifier/verifier.hpp"

using namespace frma;
using namespace fie;

int main(int argc, char **argv) {
  FILE *      infile;
  std::string filename("???");
  bool        dot = false;
#if defined(DEBUG)
  bool verbose = false;
#endif

  std::list<std::string> args;

  {
    bool doFlags = true;
    for (size_t i = 1; i < argc; ++i) {
      std::string arg(argv[i]);
      if (doFlags) {
#if defined(DEBUG)
        if (arg == "-v")
          verbose = true;
        else
#endif
            if (arg == "--dot")
          dot = true;
        else if (arg == "--")
          doFlags = false;
        else
          args.push_back(arg);
      } else
        args.push_back(arg);
    }
  }
  switch (args.size()) {
  case 0:
    infile   = stdin;
    filename = "<stdin>";
    break;
  case 1:
    infile   = fopen(argv[1], "r");
    filename = argv[1];
    break;
  default:
    std::cerr << "Usage: " << argv[0] << " [input]" << std::endl;
    return 1;
  }

#if defined(NDEBUG)
  try {
#endif
    frma::FormaParserTag tag(filename);
    frma::lexer          lex(tag);
    frma::parser         parse(&tag);

    lex.inFile(infile);

#if defined(DEBUG)
    if (verbose) {
      lex.debug(true);
      parse.set_debug_level(1);
    }
#endif

    bool success = !parse.parse() && tag.errors().empty();

    for (auto r : tag.errors()) r.print(std::cerr);

    // if (tag.prims)
    //   std::cout << tag.prims << std::endl;
    // else if (success)
    //   std::cerr << "WARNING: no output" << std::endl;

    if (success && tag.prims) {
      auto graph = fnew<fps::FDepsGraph>();

      auto assem  = fnew<fie::FIAssembly>();
      auto inputs = fnew<fie::FIInputs>(assem);

      auto sched = fnew<fie::FIScheduler>(graph, inputs);

      sched->schedule(tag.prims);

      if (dot)
        graph->dot(std::cout);
      else
        graph->run();

      // auto assem     = fnew<FIAssembly>();
      // auto verifier  = fnew<FIVerifier>(assem);
      // auto optimizer = fnew<FIOptimizer>();
      // auto dumpFunc  = fnew<FIDumpFunction>(assem, std::cerr);

      // compiler->connect(verifier);

      // fps::connect<FIFunction>(*verifier, *dumpFunc);

      // auto blocks = compiler->compileBlocks(tag.prims);
    }

    std::cerr << tag.errors().size() << " error";
    if (tag.errors().size() != 1) std::cerr << "s";
    std::cerr << "." << std::endl;

    return tag.errors().size() ? 1 : 0;
#if defined(NDEBUG)
  } catch (std::exception &e) {
    std::cerr << e.what() << std::endl;
    return -1;
  }
#endif
}
<commit_msg>Fixed an issue with building outside of debug mode<commit_after>#include <cstdio>
#include <list>

#include "pipeline/depsGraph.hpp"

#include "lexerDriver.hpp"
#include "parser.hpp"
#include "parserTag.hpp"

#include "ast/walker.hpp"

#include "intermedia/debug/dumpFunction.hpp"
#include "intermedia/optimizer/optimizer.hpp"
#include "intermedia/praeCompiler/compiler.hpp"
#include "intermedia/scheduler.hpp"
#include "intermedia/verifier/verifier.hpp"

using namespace frma;
using namespace fie;

int main(int argc, char **argv) {
  FILE *      infile;
  std::string filename("???");
  bool        dot = false;
#if defined(DEBUG)
  bool verbose = false;
#endif

  std::list<std::string> args;

  {
    bool doFlags = true;
    for (size_t i = 1; i < argc; ++i) {
      std::string arg(argv[i]);
      if (doFlags) {
#if defined(DEBUG)
        if (arg == "--verbose" || arg == "-v")
          verbose = true;
        else
#endif
            if (arg == "--dot" || arg == "-d")
          dot = true;
        else if (arg == "--")
          doFlags = false;
        else
          args.push_back(arg);
      } else
        args.push_back(arg);
    }
  }
  switch (args.size()) {
  case 0:
    infile   = stdin;
    filename = "<stdin>";
    break;
  case 1:
    infile   = fopen(argv[1], "r");
    filename = argv[1];
    break;
  default:
    std::cerr << "Usage: " << argv[0] << "[flags] [--] [input]" << std::endl;

    std::cerr << "Flags:\n  \e[1m--verbose, -v\e[0m: Output extra information."
              << std::endl
              << "  \e[1m--dot, -d\e[0m: Output dependency graph as a dotfile."
              << std::endl;
    return 1;
  }

#if defined(NDEBUG)
  try {
#endif
    frma::FormaParserTag tag(filename);
    frma::lexer          lex(tag);
    frma::parser         parse(&tag);

    lex.inFile(infile);

#if defined(DEBUG)
    if (verbose) {
      lex.debug(true);
      parse.set_debug_level(1);
    }
#endif

    bool success = !parse.parse() && tag.errors().empty();

    for (auto r : tag.errors()) r.print(std::cerr);

    // if (tag.prims)
    //   std::cout << tag.prims << std::endl;
    // else if (success)
    //   std::cerr << "WARNING: no output" << std::endl;

    if (success && tag.prims) {
      auto graph = fnew<fps::FDepsGraph>();

      auto assem  = fnew<fie::FIAssembly>();
      auto inputs = fnew<fie::FIInputs>(assem);

      auto sched = fnew<fie::FIScheduler>(graph, inputs);

      sched->schedule(tag.prims);

      if (dot)
        graph->dot(std::cout);
      else
        graph->run();

      // auto assem     = fnew<FIAssembly>();
      // auto verifier  = fnew<FIVerifier>(assem);
      // auto optimizer = fnew<FIOptimizer>();
      // auto dumpFunc  = fnew<FIDumpFunction>(assem, std::cerr);

      // compiler->connect(verifier);

      // fps::connect<FIFunction>(*verifier, *dumpFunc);

      // auto blocks = compiler->compileBlocks(tag.prims);
    }

    std::cerr << tag.errors().size() << " error";
    if (tag.errors().size() != 1) std::cerr << "s";
    std::cerr << "." << std::endl;

    return tag.errors().size() ? 1 : 0;
#if defined(NDEBUG)
  } catch (std::exception &e) {
    std::cerr << e.what() << std::endl;
    return -1;
  }
#endif
}
<|endoftext|>


<commit_before>#include "fringe.h"

inline Fringe add_some_T(Fringe current, int64_t piece, int16_t height, char check_second_row){
  int64_t first_empty = (current & FIRST_BLANK_MASK) >> FIRST_BLANK_OFFSET;
  piece <<= first_empty + 1;
  if (piece & padding_mask) {
    return 0;
  }
  if (piece & current) {
    return 0;
  }
  Fringe added = current | piece;
  int16_t filled = first_empty + height;
  if (filled == WIDTH){
    modulus = (current & MODULUS_MASK) >> MODULUS_OFFSET;
    current = (current >> (WIDTH * 2 + 2)) & FIRST_TWO_ROWS_MASK;
    modulus = (modulus + 1) % MODULUS;
    current = current | (modulus << MODULUS_OFFSET);
  }
  current = current & (~FIRST_BLANK_MASK);
  current = current | (filled << FIRST_BLANK_OFFSET);
  return current;
}

Fringe add_T_1(Fringe current){
  const piece = make_piece(14, 4, 0);
  return add_some_T(current, piece, 3, 0);
}

Fringe add_T_2(Fringe current){
  const piece = make_piece(2, 3, 2);
  return add_some_T(current, piece, 1, 1);
}

Fringe add_T_3(Fringe current){
  const piece = make_piece(2, 7, 0);
  return add_some_T(current, piece, 1, 0);
}

Fringe add_T_4(Fringe current){
  const piece = make_piece(2, 6, 2);
  return add_some_T(current, piece, 1, 0);
}
<commit_msg>Change padding_mask -> PADDING_MASK<commit_after>#include "fringe.h"

inline Fringe add_some_T(Fringe current, int64_t piece, int16_t height, char check_second_row){
  int64_t first_empty = (current & FIRST_BLANK_MASK) >> FIRST_BLANK_OFFSET;
  piece <<= first_empty + 1;
  if (piece & PADDING_MASK) {
    return 0;
  }
  if (piece & current) {
    return 0;
  }
  Fringe added = current | piece;
  int16_t filled = first_empty + height;
  if (filled == WIDTH){
    modulus = (current & MODULUS_MASK) >> MODULUS_OFFSET;
    current = (current >> (WIDTH * 2 + 2)) & FIRST_TWO_ROWS_MASK;
    modulus = (modulus + 1) % MODULUS;
    current = current | (modulus << MODULUS_OFFSET);
  }
  current = current & (~FIRST_BLANK_MASK);
  current = current | (filled << FIRST_BLANK_OFFSET);
  return current;
}

Fringe add_T_1(Fringe current){
  const piece = make_piece(14, 4, 0);
  return add_some_T(current, piece, 3, 0);
}

Fringe add_T_2(Fringe current){
  const piece = make_piece(2, 3, 2);
  return add_some_T(current, piece, 1, 1);
}

Fringe add_T_3(Fringe current){
  const piece = make_piece(2, 7, 0);
  return add_some_T(current, piece, 1, 0);
}

Fringe add_T_4(Fringe current){
  const piece = make_piece(2, 6, 2);
  return add_some_T(current, piece, 1, 0);
}
<|endoftext|>


<commit_before>// Copyright (C) 2011 Oliver Schulz <oliver.schulz@tu-dortmund.de>

// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

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

#include <TROOT.h>
#include <TFile.h>
#include <THashList.h>

#include "../config.h"

#include "util.h"
#include "Selector.h"
#include "Settings.h"
#include "JSON.h"

/*!	\mainpage	Programme to evaluate CPG pulse shape data
	*
	* Syntax: froast COMMAND ... \n
	* Commands:
	*	- settings [-j] INPUTFILE
	*	- map-single INPUT_FILE MAPPERS OUTPUTFILE
	*	- map-multi MAPPER OUTPUTFILE_TAG INPUTFILES
	*	- tabulate ROOT_FILE/TREENAME VAREXP [SELECTION [NENTRIES [STARTENTRY]]]
	*
	* With the settings option the settings from processed ROOT files or .rootrc can be read
	* out and with the -j option converted to json (output on the screen). \n
	* With the map-single option one input file can be processed. See froast::Selector::mapSingle for
	* more information on the input parameters. \n
	* With the map-multi option several input files can be processed. See froast::Selector::mapSingle for
	* more information on the input parameters. \n
*/

using namespace std;
using namespace froast;

int settings(int argc, char *argv[], char *envp[]) {

	int nargs = argc-1;
	char **args = argv+1;

	bool jsonOutput = false;
	if ((nargs >= 1) && (string(args[0]) == "-j")) {
		--nargs; ++args;
		jsonOutput = true;
	}

	if (nargs == 0) {
		if (jsonOutput) {
			THashList *nested = Settings::global().exportNested();
			JSON::write(cout, nested) << endl;
			delete nested;
		} else Settings::global().write(cout);
		return 0;
	} else if (nargs == 1) {
		Settings settings;
		TString inFileName(args[0]);
		TString objSpecSep(".root/");
		if (inFileName.EndsWith(".root") || inFileName.Contains(objSpecSep)) {
			TString rootFileName = inFileName;
			TString settingsName = "";
			int idx = inFileName.Index(objSpecSep);
			if (idx >= 0) {
				rootFileName = inFileName(0, idx + objSpecSep.Length() - 1);
				settingsName = inFileName(idx + objSpecSep.Length(), inFileName.Length() - idx - objSpecSep.Length());
			}
			TFile inFile(rootFileName.Data(), "read");
			if (settingsName.Length() > 0) settings.read(&inFile, settingsName.Data());
			else settings.read(&inFile);
		} else if (inFileName.EndsWith(".rootrc")) {
			settings.read(inFileName.Data());
		} else if (inFileName.EndsWith(".json")) {
			ifstream in(inFileName.Data());
			THashList *nested = JSON::read(in);
			settings.importNested(nested);
			delete nested;
		} else {
			cerr << "Unknown file extension, can't read settings from \"" << inFileName << "\"." << endl;
			return 1;
		}
		if (jsonOutput) {
			THashList *nested = settings.exportNested();
			JSON::write(cout, nested) << endl;
			delete nested;
		} else settings.write(cout);
		return 0;
	} else {
		cerr << "Syntax: " << args[0] << " [-j] ROOT_FILE SETTINGS" << endl;
		return 1;
	}
}

int map_single(int argc, char *argv[], char *envp[]) {
	if (argc != 4) {
		cerr << "Syntax: " << argv[0] << " INPUT_FILE MAPPER OUTPUT_FILE" << endl;
		return 1;
	}
	string inFileName = argv[1];
	string mappers = argv[2];
	string outFileName = argv[3];
	Selector::mapSingle(inFileName, mappers, outFileName);

	return 0;
}

int map_multi(int argc, char *argv[], char *envp[]) {
	const size_t firstInputArg = 3;
	if (argc <= firstInputArg) {
		cerr << "Syntax: " << argv[0] << " MAPPERS TAG [INPUT]..." << endl;
		return 1;
	}
	string mappers = argv[1];
	string tag = argv[2];
	for (size_t arg = firstInputArg; arg < argc; ++arg) {
		// -> inputfilename(s), mappers, filename extension tag, bool noRecompile
		// By default the selector is compiled (++ ROOT compile option).
		// If there are more than one inputfile, the selector is not recompiled
		Selector::mapMulti(argv[arg], mappers, tag, arg > firstInputArg);
	}

	return 0;
}

int reduce(int argc, char *argv[], char *envp[]) {
	const size_t firstInputArg = 3;
	if (argc <= firstInputArg) {
		cerr << "Syntax: " << argv[0] << " MAPPERS OUTPUT_FILE [INPUT]..." << endl;
		return 1;
	}
	string mappers = argv[1];
	string outFileName = argv[2];
	string inFiles = argv[firstInputArg];
	for (size_t arg = firstInputArg+1; arg < argc; ++arg) {
		inFiles+=" ";
		inFiles+=argv[arg];
	}
	Selector::reduce(inFiles, mappers, outFileName);
	return 0;
}

int tabulate(int argc, char *argv[], char *envp[]) {
	int nargs = argc-1;
	char **args = argv+1;

	if (nargs < 2) {
		cerr << "Syntax: " << argv[0] << " [-j] ROOT_FILE/TREENAME VAREXP [SELECTION [NENTRIES [STARTENTRY]]]" << endl;
		return 1;
	}

	TString input(args[0]);
	ssize_t splitPos = input.Last('/');
	if ((splitPos < 0) || (splitPos >= input.Length()-1)) {
		cerr << "Error: No tree name specified."  << endl;
		return 1;
	}
	TString inFileName = input(0, splitPos);
	TString treeName = input(splitPos + 1, input.Length() - splitPos - 1);
	TChain chain(treeName);
	chain.Add(inFileName);

	TString varexp(args[1]);
	const TString selection = (nargs > 2) ? args[2] : "";
	ssize_t nEntries = (nargs > 3) ? atol(args[3]) : -1;
	ssize_t startEntry = (nargs > 4) ? atol(args[4]) : 0;
	Selector::tabulate(&chain, cout, varexp, selection, nEntries, startEntry);

	return 0;
}

int main(int argc, char *argv[], char *envp[]) {
	try {
		// Have to tell ROOT to load vector dlls, otherwise ROOT will produce
		// "is not of a class known to ROOT" errors on creation of STL vector
		// branches:
		gROOT->ProcessLine("#include <vector>");

		gSystem->SetProgname(PACKAGE_TARNAME);

		string progName(argv[0]);

		if (argc < 2) {
			cerr << "Syntax: " << progName << " COMMAND ..." << endl << endl;
			cerr << "Commands: " << endl;
			cerr << "  settings" << endl;
			cerr << "  map-single" << endl;
			cerr << "  map-multi" << endl;
		  cerr << "  reduce" << endl;
			cerr << "  tabulate" << endl;
			return 1;
		}

		string cmd(argv[1]);

		int cmd_argc = argc - 1;
		char **cmd_argv = argv + 1;

		if (cmd == "settings") return settings(cmd_argc, cmd_argv, envp);
		else if (cmd == "map-single") return map_single(cmd_argc, cmd_argv, envp);
		else if (cmd == "map-multi") return map_multi(cmd_argc, cmd_argv, envp);
		else if (cmd == "reduce") return reduce(cmd_argc, cmd_argv, envp);
		else if (cmd == "tabulate") return tabulate(cmd_argc, cmd_argv, envp);
		else {
			cerr << "ERROR: " << progName << " does not support command \"" << cmd << "\"" << endl;
		}
	}
	catch(std::exception &e) {
		cerr << endl << endl << "Exception: " << e.what() << endl << endl;

		return 1;
	}
}
<commit_msg>Small code formatting fix<commit_after>// Copyright (C) 2011 Oliver Schulz <oliver.schulz@tu-dortmund.de>

// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

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

#include <TROOT.h>
#include <TFile.h>
#include <THashList.h>

#include "../config.h"

#include "util.h"
#include "Selector.h"
#include "Settings.h"
#include "JSON.h"

/*!	\mainpage	Programme to evaluate CPG pulse shape data
	*
	* Syntax: froast COMMAND ... \n
	* Commands:
	*	- settings [-j] INPUTFILE
	*	- map-single INPUT_FILE MAPPERS OUTPUTFILE
	*	- map-multi MAPPER OUTPUTFILE_TAG INPUTFILES
	*	- tabulate ROOT_FILE/TREENAME VAREXP [SELECTION [NENTRIES [STARTENTRY]]]
	*
	* With the settings option the settings from processed ROOT files or .rootrc can be read
	* out and with the -j option converted to json (output on the screen). \n
	* With the map-single option one input file can be processed. See froast::Selector::mapSingle for
	* more information on the input parameters. \n
	* With the map-multi option several input files can be processed. See froast::Selector::mapSingle for
	* more information on the input parameters. \n
*/

using namespace std;
using namespace froast;

int settings(int argc, char *argv[], char *envp[]) {

	int nargs = argc-1;
	char **args = argv+1;

	bool jsonOutput = false;
	if ((nargs >= 1) && (string(args[0]) == "-j")) {
		--nargs; ++args;
		jsonOutput = true;
	}

	if (nargs == 0) {
		if (jsonOutput) {
			THashList *nested = Settings::global().exportNested();
			JSON::write(cout, nested) << endl;
			delete nested;
		} else Settings::global().write(cout);
		return 0;
	} else if (nargs == 1) {
		Settings settings;
		TString inFileName(args[0]);
		TString objSpecSep(".root/");
		if (inFileName.EndsWith(".root") || inFileName.Contains(objSpecSep)) {
			TString rootFileName = inFileName;
			TString settingsName = "";
			int idx = inFileName.Index(objSpecSep);
			if (idx >= 0) {
				rootFileName = inFileName(0, idx + objSpecSep.Length() - 1);
				settingsName = inFileName(idx + objSpecSep.Length(), inFileName.Length() - idx - objSpecSep.Length());
			}
			TFile inFile(rootFileName.Data(), "read");
			if (settingsName.Length() > 0) settings.read(&inFile, settingsName.Data());
			else settings.read(&inFile);
		} else if (inFileName.EndsWith(".rootrc")) {
			settings.read(inFileName.Data());
		} else if (inFileName.EndsWith(".json")) {
			ifstream in(inFileName.Data());
			THashList *nested = JSON::read(in);
			settings.importNested(nested);
			delete nested;
		} else {
			cerr << "Unknown file extension, can't read settings from \"" << inFileName << "\"." << endl;
			return 1;
		}
		if (jsonOutput) {
			THashList *nested = settings.exportNested();
			JSON::write(cout, nested) << endl;
			delete nested;
		} else settings.write(cout);
		return 0;
	} else {
		cerr << "Syntax: " << args[0] << " [-j] ROOT_FILE SETTINGS" << endl;
		return 1;
	}
}

int map_single(int argc, char *argv[], char *envp[]) {
	if (argc != 4) {
		cerr << "Syntax: " << argv[0] << " INPUT_FILE MAPPER OUTPUT_FILE" << endl;
		return 1;
	}
	string inFileName = argv[1];
	string mappers = argv[2];
	string outFileName = argv[3];
	Selector::mapSingle(inFileName, mappers, outFileName);

	return 0;
}

int map_multi(int argc, char *argv[], char *envp[]) {
	const size_t firstInputArg = 3;
	if (argc <= firstInputArg) {
		cerr << "Syntax: " << argv[0] << " MAPPERS TAG [INPUT]..." << endl;
		return 1;
	}
	string mappers = argv[1];
	string tag = argv[2];
	for (size_t arg = firstInputArg; arg < argc; ++arg) {
		// -> inputfilename(s), mappers, filename extension tag, bool noRecompile
		// By default the selector is compiled (++ ROOT compile option).
		// If there are more than one inputfile, the selector is not recompiled
		Selector::mapMulti(argv[arg], mappers, tag, arg > firstInputArg);
	}

	return 0;
}

int reduce(int argc, char *argv[], char *envp[]) {
	const size_t firstInputArg = 3;
	if (argc <= firstInputArg) {
		cerr << "Syntax: " << argv[0] << " MAPPERS OUTPUT_FILE [INPUT]..." << endl;
		return 1;
	}
	string mappers = argv[1];
	string outFileName = argv[2];
	string inFiles = argv[firstInputArg];
	for (size_t arg = firstInputArg+1; arg < argc; ++arg) {
		inFiles+=" ";
		inFiles+=argv[arg];
	}
	Selector::reduce(inFiles, mappers, outFileName);
	return 0;
}

int tabulate(int argc, char *argv[], char *envp[]) {
	int nargs = argc-1;
	char **args = argv+1;

	if (nargs < 2) {
		cerr << "Syntax: " << argv[0] << " [-j] ROOT_FILE/TREENAME VAREXP [SELECTION [NENTRIES [STARTENTRY]]]" << endl;
		return 1;
	}

	TString input(args[0]);
	ssize_t splitPos = input.Last('/');
	if ((splitPos < 0) || (splitPos >= input.Length()-1)) {
		cerr << "Error: No tree name specified."  << endl;
		return 1;
	}
	TString inFileName = input(0, splitPos);
	TString treeName = input(splitPos + 1, input.Length() - splitPos - 1);
	TChain chain(treeName);
	chain.Add(inFileName);

	TString varexp(args[1]);
	const TString selection = (nargs > 2) ? args[2] : "";
	ssize_t nEntries = (nargs > 3) ? atol(args[3]) : -1;
	ssize_t startEntry = (nargs > 4) ? atol(args[4]) : 0;
	Selector::tabulate(&chain, cout, varexp, selection, nEntries, startEntry);

	return 0;
}

int main(int argc, char *argv[], char *envp[]) {
	try {
		// Have to tell ROOT to load vector dlls, otherwise ROOT will produce
		// "is not of a class known to ROOT" errors on creation of STL vector
		// branches:
		gROOT->ProcessLine("#include <vector>");

		gSystem->SetProgname(PACKAGE_TARNAME);

		string progName(argv[0]);

		if (argc < 2) {
			cerr << "Syntax: " << progName << " COMMAND ..." << endl << endl;
			cerr << "Commands: " << endl;
			cerr << "  settings" << endl;
			cerr << "  map-single" << endl;
			cerr << "  map-multi" << endl;
			cerr << "  reduce" << endl;
			cerr << "  tabulate" << endl;
			return 1;
		}

		string cmd(argv[1]);

		int cmd_argc = argc - 1;
		char **cmd_argv = argv + 1;

		if (cmd == "settings") return settings(cmd_argc, cmd_argv, envp);
		else if (cmd == "map-single") return map_single(cmd_argc, cmd_argv, envp);
		else if (cmd == "map-multi") return map_multi(cmd_argc, cmd_argv, envp);
		else if (cmd == "reduce") return reduce(cmd_argc, cmd_argv, envp);
		else if (cmd == "tabulate") return tabulate(cmd_argc, cmd_argv, envp);
		else {
			cerr << "ERROR: " << progName << " does not support command \"" << cmd << "\"" << endl;
		}
	}
	catch(std::exception &e) {
		cerr << endl << endl << "Exception: " << e.what() << endl << endl;

		return 1;
	}
}
<|endoftext|>


<commit_before>/*
edX->UBCx: How to Code: Complex Data->The Career Development Series->
Technical Interview->The Question: Given a list of numbers and an integer k,
write a function that returns the kth largest element of the list.
*/

#include <algorithm>
#include <functional>
#include <iostream>
#include <numeric>
#include <optional>
#include <vector>

std::optional<int> kth_largest(std::vector<int> vec,
                               std::vector<int>::size_type k) {
  if ((vec.size() == 0) || (k > vec.size() - 1)) return std::nullopt;
  std::sort(std::begin(vec), std::end(vec), std::greater<int>());
  return vec[k];
}

void check_kth_largest(std::vector<int> const& vec,
                       std::vector<int>::size_type k) {
  if (auto res = kth_largest(vec, k)) {
    std::cout << *res << '\n';
  } else {
    std::cout << "No kth element\n";
  }
}

int main() {
  std::vector<int> vec(10);
  std::iota(std::begin(vec), std::end(vec), 0);

  check_kth_largest(vec, 3);
  check_kth_largest(vec, 10);
}<commit_msg>Use templates.<commit_after>/*
edX->UBCx: How to Code: Complex Data->The Career Development Series->
Technical Interview->The Question: Given a list of numbers and an integer k,
write a function that returns the kth largest element of the list.
*/

#include <algorithm>
#include <functional>
#include <iostream>
#include <numeric>
#include <optional>
#include <vector>

template <typename T>
std::optional<T> kth_largest(std::vector<T> vec,
                             typename std::vector<T>::size_type k) {
  if ((vec.size() == 0) || (k > vec.size() - 1)) return std::nullopt;
  std::sort(std::begin(vec), std::end(vec), std::greater<T>());
  return vec[k];
}

template <typename T>
void check_kth_largest(std::vector<T> const& vec,
                       typename std::vector<T>::size_type k) {
  if (auto res = kth_largest<T>(vec, k)) {
    std::cout << *res << '\n';
  } else {
    std::cout << "No kth element\n";
  }
}

int main() {
  std::vector<int> vec(10);
  std::iota(std::begin(vec), std::end(vec), 0);

  check_kth_largest(vec, 3);
  check_kth_largest(vec, 10);

  return 0;
}<|endoftext|>


<commit_before>/*
 * benchmarks/benchmark-dense-solve.C
 *
 * Copyright (C) 2019 The LinBox group
 * Author: J-G Dumas
 * ========LICENCE========
 * This file is part of the library LinBox.
 *
 * LinBox is free software: you can redistribute it and/or modify
 * it under the terms of the  GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 */

/**\file benchmarks/benchmark-dense-solve.C
   \brief Solving dense linear system over Q or Zp.
   \ingroup benchmarks
*/

#include "linbox/linbox-config.h"
#include <iostream>

#include <givaro/modular.h>
#include "linbox/util/args-parser.h"
#include "linbox/matrix/sparse-matrix.h"
#include "linbox/solutions/solve.h"
#include "linbox/util/matrix-stream.h"
#include "linbox/solutions/methods.h"
#include "linbox/algorithms/vector-fraction.h"

#ifdef _DEBUG
#define _BENCHMARKS_DEBUG_
#endif

using namespace LinBox;

template<typename Field, typename Vector_t>
std::ostream& printVector(std::ostream& out,
                          const Field& F, const Vector_t& v) {
    out << '[';
    for(const auto& it: v) F.write(std::clog, it) << ',';
    return out << ']';
}
template<typename Vector_t>
double& setBitsize(double& size, const Givaro::Integer& q, const Vector_t& v) {
    return size=Givaro::logtwo(q);
}

typedef Givaro::ZRing<Givaro::Integer> Ints;
typedef VectorFraction<Ints> VectorFractionInts;

template<>
std::ostream& printVector(std::ostream& out, const Ints& Z, const VectorFractionInts& v) {
    return Z.write(printVector(out, Z, v.numer) << " / ", v.denom);
}
template<>
double& setBitsize(double& size, const Givaro::Integer& q, const VectorFractionInts& v) {
    return size=Givaro::logtwo(v.denom);
}

template<typename T1, typename T2, typename T3>
void solve(VectorFractionInts& X, const T1& A, const T2& B, const T3& M) {
    solve(X.numer, X.denom, A, B, M);
}

template<typename Field, typename Vector_t=DenseVector<Field>>
void tmain (std::pair<double,double>& timebits, size_t n,
            const Givaro::Integer& q, size_t bits) {
    Field F(q);						// q is ignored for Integers
    typename Field::RandIter G(F,bits);	// bits is ignored for ModularRandIter

#ifdef _BENCHMARKS_DEBUG_
    std::clog << "Setting A ... " << std::endl;
#endif

    Timer chrono;

    chrono.start();
    DenseMatrix<Field> A(F,n,n);
    PAR_BLOCK { FFLAS::pfrand(F,G, n,n,A.getPointer(),n); }
    chrono.stop();

#ifdef _BENCHMARKS_DEBUG_
    std::clog << "... A is " << A.rowdim() << " by " << A.coldim() << ", " << chrono << std::endl;
    if (A.rowdim() <= 20 && A.coldim() <= 20) A.write(std::clog <<"A:=",Tag::FileFormat::Maple) << ';' << std::endl;
#endif

    DenseVector<Field> B(F, A.rowdim());
    PAR_BLOCK { FFLAS::pfrand(F,G, n,1,B.getPointer(),1); }

#ifdef _BENCHMARKS_DEBUG_
    printVector(std::clog << "B is ", F, B) << std::endl;
#endif

        // DenseElimination
    Vector_t X(F, A.coldim());
    chrono.start();
    solve (X, A, B, Method::DenseElimination());
    chrono.stop();

#ifdef _BENCHMARKS_DEBUG_
    printVector(std::clog << "(DenseElimination) Solution is ", F, X) << std::endl;
#endif

    setBitsize(timebits.second, q, X);
    timebits.first=chrono.usertime();
}

int main (int argc, char **argv)
{
    Givaro::Integer q = -1 ;
    size_t nbiter = 3 ;
    size_t n = 500 ;
    size_t bits = 10;
//     size_t p = 0;

    Argument as[] = {
        { 'i', "-i R", "Set number of repetitions.",       TYPE_INT , &nbiter },
        { 'q', "-q Q", "Set the field characteristic (-1 for rationals).", TYPE_INTEGER , &q },
        { 'n', "-n N", "Set the matrix dimension.",      TYPE_INT , &n },
        { 'b', "-b B", "bit size", TYPE_INT , &bits },
//         { 'p', "-p P", "0 for sequential, 1 for 2D iterative, 2 for 2D rec, 3 for 2D rec adaptive, 4 for 3D rec in-place, 5 for 3D rec, 6 for 3D rec adaptive.", TYPE_INT , &p },
        END_OF_ARGUMENTS
    };

    LinBox::parseArguments(argc,argv,as);

    bool ModComp = false;
    if (q > 0) ModComp = true;

    std::vector<std::pair<double,double>> timebits(nbiter);
    for(size_t iter=0; iter<nbiter; ++iter) {

        if (ModComp) {

            tmain<Givaro::Modular<double>>(timebits[iter],n,q,bits);

        } else {
            tmain<Ints,VectorFractionInts>(timebits[iter],n,q,bits);
        }
    }

#ifdef _BENCHMARKS_DEBUG_
    for(const auto& it: timebits)
        std::clog << it.first << "s, " << it.second << " bits" << std::endl;
#endif

    std::sort(timebits.begin(), timebits.end(),
              [](const std::pair<double,double> & a,
                 const std::pair<double,double> & b) -> bool {
        return a.first > b.first; });

    std::cout << "Time: " << timebits[nbiter/2].first
              << " Bitsize: " << timebits[nbiter/2].second;

    FFLAS::writeCommandString(std::cout, as) << std::endl;

    return 0;
}
<commit_msg>spaces<commit_after>/*
 * benchmarks/benchmark-dense-solve.C
 *
 * Copyright (C) 2019 The LinBox group
 * Author: J-G Dumas
 * ========LICENCE========
 * This file is part of the library LinBox.
 *
 * LinBox is free software: you can redistribute it and/or modify
 * it under the terms of the  GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 */

/**\file benchmarks/benchmark-dense-solve.C
   \brief Solving dense linear system over Q or Zp.
   \ingroup benchmarks
*/

#include "linbox/linbox-config.h"
#include <iostream>

#include <givaro/modular.h>
#include "linbox/util/args-parser.h"
#include "linbox/matrix/sparse-matrix.h"
#include "linbox/solutions/solve.h"
#include "linbox/util/matrix-stream.h"
#include "linbox/solutions/methods.h"
#include "linbox/algorithms/vector-fraction.h"

#ifdef _DEBUG
#define _BENCHMARKS_DEBUG_
#endif

using namespace LinBox;

template<typename Field, typename Vector_t>
std::ostream& printVector(std::ostream& out,
                          const Field& F, const Vector_t& v) {
    out << '[';
    for(const auto& it: v) F.write(std::clog, it) << ',';
    return out << ']';
}
template<typename Vector_t>
double& setBitsize(double& size, const Givaro::Integer& q, const Vector_t& v) {
    return size=Givaro::logtwo(q);
}

typedef Givaro::ZRing<Givaro::Integer> Ints;
typedef VectorFraction<Ints> VectorFractionInts;

template<>
std::ostream& printVector(std::ostream& out, const Ints& Z, const VectorFractionInts& v) {
    return Z.write(printVector(out, Z, v.numer) << " / ", v.denom);
}
template<>
double& setBitsize(double& size, const Givaro::Integer& q, const VectorFractionInts& v) {
    return size=Givaro::logtwo(v.denom);
}

template<typename T1, typename T2, typename T3>
void solve(VectorFractionInts& X, const T1& A, const T2& B, const T3& M) {
    solve(X.numer, X.denom, A, B, M);
}

template<typename Field, typename Vector_t=DenseVector<Field>>
void tmain (std::pair<double,double>& timebits, size_t n,
            const Givaro::Integer& q, size_t bits) {
    Field F(q);						// q is ignored for Integers
    typename Field::RandIter G(F,bits);	// bits is ignored for ModularRandIter

#ifdef _BENCHMARKS_DEBUG_
    std::clog << "Setting A ... " << std::endl;
#endif

    Timer chrono;

    chrono.start();
    DenseMatrix<Field> A(F,n,n);
    PAR_BLOCK { FFLAS::pfrand(F,G, n,n,A.getPointer(),n); }
    chrono.stop();

#ifdef _BENCHMARKS_DEBUG_
    std::clog << "... A is " << A.rowdim() << " by " << A.coldim() << ", " << chrono << std::endl;
    if (A.rowdim() <= 20 && A.coldim() <= 20) A.write(std::clog <<"A:=",Tag::FileFormat::Maple) << ';' << std::endl;
#endif

    DenseVector<Field> B(F, A.rowdim());
    PAR_BLOCK { FFLAS::pfrand(F,G, n,1,B.getPointer(),1); }

#ifdef _BENCHMARKS_DEBUG_
    printVector(std::clog << "B is ", F, B) << std::endl;
#endif

        // DenseElimination
    Vector_t X(F, A.coldim());
    chrono.start();
    solve (X, A, B, Method::DenseElimination());
    chrono.stop();

#ifdef _BENCHMARKS_DEBUG_
    printVector(std::clog << "(DenseElimination) Solution is ", F, X) << std::endl;
#endif

    setBitsize(timebits.second, q, X);
    timebits.first=chrono.usertime();
}

int main (int argc, char **argv)
{
    Givaro::Integer q = -1 ;
    size_t nbiter = 3 ;
    size_t n = 500 ;
    size_t bits = 10;
//     size_t p = 0;

    Argument as[] = {
        { 'i', "-i R", "Set number of repetitions.",       TYPE_INT , &nbiter },
        { 'q', "-q Q", "Set the field characteristic (-1 for rationals).", TYPE_INTEGER , &q },
        { 'n', "-n N", "Set the matrix dimension.",      TYPE_INT , &n },
        { 'b', "-b B", "bit size", TYPE_INT , &bits },
//         { 'p', "-p P", "0 for sequential, 1 for 2D iterative, 2 for 2D rec, 3 for 2D rec adaptive, 4 for 3D rec in-place, 5 for 3D rec, 6 for 3D rec adaptive.", TYPE_INT , &p },
        END_OF_ARGUMENTS
    };

    LinBox::parseArguments(argc,argv,as);

    bool ModComp = false;
    if (q > 0) ModComp = true;

    std::vector<std::pair<double,double>> timebits(nbiter);
    for(size_t iter=0; iter<nbiter; ++iter) {
        if (ModComp) {
            tmain<Givaro::Modular<double>>(timebits[iter],n,q,bits);
        } else {
            tmain<Ints,VectorFractionInts>(timebits[iter],n,q,bits);
        }
    }

#ifdef _BENCHMARKS_DEBUG_
    for(const auto& it: timebits)
        std::clog << it.first << "s, " << it.second << " bits" << std::endl;
#endif

    std::sort(timebits.begin(), timebits.end(),
              [](const std::pair<double,double> & a,
                 const std::pair<double,double> & b) -> bool {
        return a.first > b.first; });

    std::cout << "Time: " << timebits[nbiter/2].first
              << " Bitsize: " << timebits[nbiter/2].second;

    FFLAS::writeCommandString(std::cout, as) << std::endl;

    return 0;
}
<|endoftext|>


<commit_before><commit_msg>Setting txture name, and updated effect<commit_after><|endoftext|>


<commit_before>#include "config.h"
#include "intl.h"
#include "ylib.h"
#include "ylocale.h"
#include "yxapp.h"
#include "yxtray.h"
#include "base.h"
#include "debug.h"
#include "sysdep.h"
#include "yprefs.h"
#include "yconfig.h"

char const *ApplicationName = "icewmtray";

#ifdef CONFIG_TASKBAR
YColor *taskBarBg;

XSV(const char *, clrDefaultTaskBar, "rgb:C0/C0/C0")
XIV(bool,         trayDrawBevel,     false)
#endif

class SysTray: public YWindow, public YXTrayNotifier {
public:
    SysTray();
    bool checkMessageEvent(const XClientMessageEvent &message);
    void requestDock();

    void handleUnmap(const XUnmapEvent &) {
        MSG(("hide"));
        if (visible())
            hide();
    }

    void trayChanged();
private:
    Atom icewm_internal_tray;
    Atom manager;
    Atom _NET_SYSTEM_TRAY_OPCODE;
    YXTray *fTray2;
};

class SysTrayApp: public YXApplication {
public:
    SysTrayApp(int *argc, char ***argv,
               const char* configFile = 0,
               const char* overrideTheme = 0);
    ~SysTrayApp();

    void loadConfig();
    bool filterEvent(const XEvent &xev);
    void handleSignal(int sig);

private:
    Atom _ICEWM_ACTION;
    SysTray *tray;
    const char* configFile;
    const char* overrideTheme;
};

static int handler(Display *display, XErrorEvent *xev) {
    DBG {
        char message[80], req[80], number[80];

        sprintf(number, "%d", xev->request_code);
        XGetErrorDatabaseText(display,
                              "XRequest",
                              number, "",
                              req, sizeof(req));
        if (!req[0])
            sprintf(req, "[request_code=%d]", xev->request_code);

        if (XGetErrorText(display,
                          xev->error_code,
                          message, sizeof(message)) !=
                          Success)
            *message = '\0';

        warn("X error %s(0x%lX): %s", req, xev->resourceid, message);
    }
    return 0;
}

SysTrayApp::SysTrayApp(int *argc, char ***argv,
        const char* _configFile, const char* _overrideTheme):
    YXApplication(argc, argv),
    tray(0), configFile(_configFile), overrideTheme(_overrideTheme)
{
    desktop->setStyle(YWindow::wsDesktopAware);
    catchSignal(SIGINT);
    catchSignal(SIGTERM);
    catchSignal(SIGHUP);
    loadConfig();

    XSetErrorHandler(handler);
    tray = new SysTray();

    _ICEWM_ACTION = XInternAtom(xapp->display(), "_ICEWM_ACTION", False);
}

void SysTrayApp::loadConfig() {
#ifdef CONFIG_TASKBAR
#ifndef NO_CONFIGURE
    static cfoption tray_prefs[] = {
        OSV("ColorDefaultTaskBar", &clrDefaultTaskBar, "Background of the taskbar"),
        OBV("TrayDrawBevel",       &trayDrawBevel,     "Surround the tray with plastic border"),
        OK0()
    };

    if (configFile == 0 || *configFile == 0)
        configFile = "preferences";
    if (overrideTheme && *overrideTheme)
        themeName = overrideTheme;
    else
    {
        cfoption theme_prefs[] = {
            OSV("Theme", &themeName, "Theme name"),
            OK0()
        };

        YConfig::findLoadConfigFile(this, theme_prefs, configFile);
        YConfig::findLoadConfigFile(this, theme_prefs, "theme");
    }
    YConfig::findLoadConfigFile(this, tray_prefs, configFile);
    if (themeName != 0) {
        MSG(("themeName=%s", themeName));

        YConfig::findLoadThemeFile(
            this,
            tray_prefs,
            upath("themes").child(themeName));
    }
    YConfig::findLoadConfigFile(this, tray_prefs, "prefoverride");
#endif
    if (taskBarBg)
        delete taskBarBg;
    taskBarBg = new YColor(clrDefaultTaskBar);
#endif
}

SysTrayApp::~SysTrayApp() {

}

bool SysTrayApp::filterEvent(const XEvent &xev) {
#ifdef DEBUG
    extern void logEvent(const XEvent &xev);
    logEvent(xev);
#endif
    if (xev.type == ClientMessage) {
        if (xev.xclient.message_type == _ICEWM_ACTION) {
            MSG(("loadConfig"));
            loadConfig();
            tray->trayChanged();
        } else
            tray->checkMessageEvent(xev.xclient);
        return false;
    } else if (xev.type == MappingNotify) {
            MSG(("tray mapping1"));
        if (xev.xmapping.window == tray->handle()) {
            MSG(("tray mapping"));
        }
    }
    return false;
}

void SysTrayApp::handleSignal(int sig) {
    switch (sig) {
    case SIGHUP:
         // Reload config colors from theme file and notify tray to repaint
         loadConfig();
         tray->trayChanged();
         return;
    case SIGINT:
    case SIGTERM:
        MSG(("exiting."));
        exit(0);
        return;
    }
    YXApplication::handleSignal(sig);
}

SysTray::SysTray(): YWindow(0) {
    desktop->setStyle(YWindow::wsDesktopAware);

    char trayatom[64];
    sprintf(trayatom, "_NET_SYSTEM_TRAY_S%d", xapp->screen());
    fTray2 = new YXTray(this, false, trayatom, this);

    char trayatom2[64];
    sprintf(trayatom2, "_ICEWM_INTTRAY_S%d", xapp->screen());
    icewm_internal_tray =
        XInternAtom(xapp->display(), trayatom2, False);
    manager =
        XInternAtom(xapp->display(), "MANAGER", False);

    _NET_SYSTEM_TRAY_OPCODE =
        XInternAtom(xapp->display(),
                    "_NET_SYSTEM_TRAY_OPCODE",
                    False);

    fTray2->relayout();
    setSize(fTray2->width(),
            fTray2->height());
    fTray2->show();
    requestDock();
}

void SysTray::trayChanged() {
    fTray2->backgroundChanged();
    setSize(fTray2->width(),
            fTray2->height());
    if (fTray2->visible())
        show();
    else
        hide();
}

void SysTray::requestDock() {
    Window w = XGetSelectionOwner(xapp->display(), icewm_internal_tray);

    if (w && w != handle()) {
        XClientMessageEvent xev;
        memset(&xev, 0, sizeof(xev));

        xev.type = ClientMessage;
        xev.window = w;
        xev.message_type = _NET_SYSTEM_TRAY_OPCODE;
        xev.format = 32;
        xev.data.l[0] = CurrentTime;
        xev.data.l[1] = SYSTEM_TRAY_REQUEST_DOCK;
        xev.data.l[2] = handle(); //fTray2->handle();

        XSendEvent(xapp->display(), w, False, StructureNotifyMask, (XEvent *) &xev);
    }
}

bool SysTray::checkMessageEvent(const XClientMessageEvent &message) {
    if (message.message_type == manager && (Atom) message.data.l[1] == icewm_internal_tray) {
        MSG(("requestDock"));
        requestDock();
    }
    return true;
}

static const char* get_help_text() {
    return _(
    "  --notify            Notify parent process by sending signal USR1.\n"
    "  --display=NAME      Use NAME to connect to the X server.\n"
    "  --sync              Synchronize communication with X11 server.\n"
    "\n"
    "  -c, --config=FILE   Load preferences from FILE.\n"
    "  -t, --theme=FILE    Load the theme from FILE.\n"
    );
}

int main(int argc, char **argv) {
    YLocale locale;

    bool notifyParent = false;
    const char* configFile = 0;
    const char* overrideTheme = 0;

    for (char **arg = 1 + argv; arg < argv + argc; ++arg) {
        if (**arg == '-') {
            char* value(0);
            if (is_long_switch(*arg, "notify")) {
                notifyParent = true;
            }
            else if (GetLongArgument(value, "config", arg, argv+argc)
                ||  GetShortArgument(value, "c", arg, argv+argc))
            {
                configFile = value;
            }
            else if (GetLongArgument(value, "theme", arg, argv+argc)
                ||   GetShortArgument(value, "t", arg, argv+argc))
            {
                overrideTheme = value;
            }
            else if (is_help_switch(*arg)) {
                print_help_exit(get_help_text());
            }
            else if (is_version_switch(*arg)) {
                print_version_exit(VERSION);
            }
#ifdef DEBUG
            else if (is_long_switch(*arg, "debug")) {
                debug = 1;
            }
#endif
        }
    }

    SysTrayApp stapp(&argc, &argv, configFile, overrideTheme);

    if (notifyParent) {
        kill(getppid(), SIGUSR1);
    }

    return stapp.mainLoop();
}
<commit_msg>Define getTaskBarBg(). Prevent leaks. Details.<commit_after>#include "config.h"
#include "intl.h"
#include "ylib.h"
#include "ylocale.h"
#include "yxapp.h"
#include "yxtray.h"
#include "base.h"
#include "debug.h"
#include "sysdep.h"
#include "yprefs.h"
#include "yconfig.h"
#include "ypointer.h"

char const *ApplicationName = "icewmtray";

#ifdef CONFIG_TASKBAR
static YColor *taskBarBg;

XSV(const char *, clrDefaultTaskBar, "rgb:C0/C0/C0")
XIV(bool,         trayDrawBevel,     false)

YColor* getTaskBarBg() {
    if (taskBarBg == 0) {
        taskBarBg = new YColor(clrDefaultTaskBar);
    }
    return taskBarBg;
}
#endif

class SysTray: public YWindow, public YXTrayNotifier {
public:
    SysTray();
    bool checkMessageEvent(const XClientMessageEvent &message);
    void requestDock();

    void handleUnmap(const XUnmapEvent &) {
        MSG(("hide"));
        if (visible())
            hide();
    }

    void trayChanged();
private:
    Atom icewm_internal_tray;
    Atom manager;
    Atom _NET_SYSTEM_TRAY_OPCODE;
    osmart<YXTray> fTray2;
};

class SysTrayApp: public YXApplication {
public:
    SysTrayApp(int *argc, char ***argv,
               const char* configFile = 0,
               const char* overrideTheme = 0);
    ~SysTrayApp();

    void loadConfig();
    virtual bool filterEvent(const XEvent &xev);
    virtual void handleSignal(int sig);

private:
    Atom _ICEWM_ACTION;
    osmart<SysTray> tray;
    const char* configFile;
    const char* overrideTheme;
};

static int handler(Display *display, XErrorEvent *xev) {
    DBG {
        char message[80], req[80], number[80];

        sprintf(number, "%d", xev->request_code);
        XGetErrorDatabaseText(display,
                              "XRequest",
                              number, "",
                              req, sizeof(req));
        if (!req[0])
            sprintf(req, "[request_code=%d]", xev->request_code);

        if (XGetErrorText(display,
                          xev->error_code,
                          message, sizeof(message)) !=
                          Success)
            *message = '\0';

        warn("X error %s(0x%lX): %s", req, xev->resourceid, message);
    }
    return 0;
}

SysTrayApp::SysTrayApp(int *argc, char ***argv,
        const char* _configFile, const char* _overrideTheme):
    YXApplication(argc, argv),
    tray(0), configFile(_configFile), overrideTheme(_overrideTheme)
{
    desktop->setStyle(YWindow::wsDesktopAware);
    catchSignal(SIGINT);
    catchSignal(SIGTERM);
    catchSignal(SIGHUP);
    loadConfig();

    XSetErrorHandler(handler);
    tray = new SysTray();

    _ICEWM_ACTION = XInternAtom(xapp->display(), "_ICEWM_ACTION", False);
}

void SysTrayApp::loadConfig() {
#ifdef CONFIG_TASKBAR
#ifndef NO_CONFIGURE
    static cfoption tray_prefs[] = {
        OSV("ColorDefaultTaskBar", &clrDefaultTaskBar, "Background of the taskbar"),
        OBV("TrayDrawBevel",       &trayDrawBevel,     "Surround the tray with plastic border"),
        OK0()
    };

    if (configFile == 0 || *configFile == 0)
        configFile = "preferences";
    if (overrideTheme && *overrideTheme)
        themeName = overrideTheme;
    else
    {
        cfoption theme_prefs[] = {
            OSV("Theme", &themeName, "Theme name"),
            OK0()
        };

        YConfig::findLoadConfigFile(this, theme_prefs, configFile);
        YConfig::findLoadConfigFile(this, theme_prefs, "theme");
    }
    YConfig::findLoadConfigFile(this, tray_prefs, configFile);
    if (themeName != 0) {
        MSG(("themeName=%s", themeName));

        YConfig::findLoadThemeFile(
            this,
            tray_prefs,
            upath("themes").child(themeName));
    }
    YConfig::findLoadConfigFile(this, tray_prefs, "prefoverride");
#endif
    if (taskBarBg)
        delete taskBarBg;
    taskBarBg = new YColor(clrDefaultTaskBar);
#endif
}

SysTrayApp::~SysTrayApp() {
    delete taskBarBg; taskBarBg = 0;
}

bool SysTrayApp::filterEvent(const XEvent &xev) {
#ifdef DEBUG
    extern void logEvent(const XEvent &xev);
    logEvent(xev);
#endif
    if (xev.type == ClientMessage) {
        if (xev.xclient.message_type == _ICEWM_ACTION) {
            MSG(("loadConfig"));
            loadConfig();
            tray->trayChanged();
        } else
            tray->checkMessageEvent(xev.xclient);
        return false;
    } else if (xev.type == MappingNotify) {
            MSG(("tray mapping1"));
        if (xev.xmapping.window == tray->handle()) {
            MSG(("tray mapping"));
        }
    }
    return false;
}

void SysTrayApp::handleSignal(int sig) {
    switch (sig) {
    case SIGHUP:
         // Reload config colors from theme file and notify tray to repaint
         loadConfig();
         tray->trayChanged();
         return;
    case SIGINT:
    case SIGTERM:
        MSG(("exiting."));
        this->exit(0);
        return;
    }
    YXApplication::handleSignal(sig);
}

SysTray::SysTray(): YWindow(0) {
    desktop->setStyle(YWindow::wsDesktopAware);

    char trayatom[64];
    sprintf(trayatom, "_NET_SYSTEM_TRAY_S%d", xapp->screen());
    fTray2 = new YXTray(this, false, trayatom, this);

    char trayatom2[64];
    sprintf(trayatom2, "_ICEWM_INTTRAY_S%d", xapp->screen());
    icewm_internal_tray =
        XInternAtom(xapp->display(), trayatom2, False);
    manager =
        XInternAtom(xapp->display(), "MANAGER", False);

    _NET_SYSTEM_TRAY_OPCODE =
        XInternAtom(xapp->display(),
                    "_NET_SYSTEM_TRAY_OPCODE",
                    False);

    fTray2->relayout();
    setSize(fTray2->width(),
            fTray2->height());
    fTray2->show();
    requestDock();
}

void SysTray::trayChanged() {
    fTray2->backgroundChanged();
    setSize(fTray2->width(),
            fTray2->height());
    if (fTray2->visible())
        show();
    else
        hide();
}

void SysTray::requestDock() {
    Window w = XGetSelectionOwner(xapp->display(), icewm_internal_tray);

    if (w && w != handle()) {
        XClientMessageEvent xev = { ClientMessage };
        xev.window = w;
        xev.message_type = _NET_SYSTEM_TRAY_OPCODE;
        xev.format = 32;
        xev.data.l[0] = CurrentTime;
        xev.data.l[1] = SYSTEM_TRAY_REQUEST_DOCK;
        xev.data.l[2] = handle(); //fTray2->handle();

        XSendEvent(xapp->display(), w, False,
                   StructureNotifyMask, (XEvent *) &xev);
    }
}

bool SysTray::checkMessageEvent(const XClientMessageEvent &message) {
    if (message.message_type == manager &&
            (Atom) message.data.l[1] == icewm_internal_tray) {
        MSG(("requestDock"));
        requestDock();
    }
    return true;
}

static const char* get_help_text() {
    return _(
    "  -n, --notify        Notify parent process by sending signal USR1.\n"
    "  --display=NAME      Use NAME to connect to the X server.\n"
    "  --sync              Synchronize communication with X11 server.\n"
    "\n"
    "  -c, --config=FILE   Load preferences from FILE.\n"
    "  -t, --theme=FILE    Load the theme from FILE.\n"
    );
}

int main(int argc, char **argv) {
    YLocale locale;

    bool notifyParent = false;
    const char* configFile = 0;
    const char* overrideTheme = 0;

    for (char **arg = 1 + argv; arg < argv + argc; ++arg) {
        if (**arg == '-') {
            char* value(0);
            if (is_switch(*arg, "n", "notify")) {
                notifyParent = true;
            }
            else if (GetArgument(value, "c", "config", arg, argv+argc)) {
                configFile = value;
            }
            else if (GetArgument(value, "t", "theme", arg, argv+argc)) {
                overrideTheme = value;
            }
            else if (is_help_switch(*arg)) {
                print_help_exit(get_help_text());
            }
            else if (is_version_switch(*arg)) {
                print_version_exit(VERSION);
            }
#ifdef DEBUG
            else if (is_long_switch(*arg, "debug")) {
                debug = 1;
            }
#endif
        }
    }

    SysTrayApp stapp(&argc, &argv, configFile, overrideTheme);

    if (notifyParent) {
        kill(getppid(), SIGUSR1);
    }

    return stapp.mainLoop();
}
<|endoftext|>


<commit_before>#include "config.h"
#include "ylib.h"
#include "ylocale.h"
#include "yxapp.h"
#include "yxtray.h"
#include "base.h"
#include "debug.h"
#include "sysdep.h"
#include "yprefs.h"

extern void logEvent(const XEvent &xev);

char const *ApplicationName = "icewmtray";

#include "yconfig.h"

#ifdef CONFIG_TASKBAR
YColor *taskBarBg;

XSV(const char *, clrDefaultTaskBar,            "rgb:C0/C0/C0")
XIV(bool, trayDrawBevel,                        false)

cfoption icewmbg_prefs[] = {
    OSV("ColorDefaultTaskBar",                  &clrDefaultTaskBar,             "Background of the taskbar"),
    OBV("TrayDrawBevel",                        &trayDrawBevel,                 "Surround the tray with plastic border"),
    OK0()
};
#endif

class SysTray: public YWindow, public YXTrayNotifier {
public:
    SysTray();
    bool checkMessageEvent(const XClientMessageEvent &message);
    void requestDock();

    void handleUnmap(const XUnmapEvent &) {
        MSG(("hide"));
        if (visible())
            hide();
    }

    void trayChanged();
private:
    Atom icewm_internal_tray;
    Atom _NET_SYSTEM_TRAY_OPCODE;
    YXTray *fTray2;
};

class SysTrayApp: public YXApplication {
public:
    SysTrayApp(int *argc, char ***argv, const char *displayName = 0);
    ~SysTrayApp();

    void loadConfig(); //MCM OFFICIAL
    bool filterEvent(const XEvent &xev);
    void handleSignal(int sig);

private:
    Atom _ICEWM_ACTION;
    SysTray *tray;
};

int handler(Display *display, XErrorEvent *xev) {
    DBG {
        char message[80], req[80], number[80];

        sprintf(number, "%d", xev->request_code);
        XGetErrorDatabaseText(display,
                              "XRequest",
                              number, "",
                              req, sizeof(req));
        if (!req[0])
            sprintf(req, "[request_code=%d]", xev->request_code);

        if (XGetErrorText(display,
                          xev->error_code,
                          message, sizeof(message)) !=
                          Success)
            *message = '\0';

        warn("X error %s(0x%lX): %s", req, xev->resourceid, message);
    }
    return 0;
}
SysTrayApp::SysTrayApp(int *argc, char ***argv, const char *displayName):
    YXApplication(argc, argv, displayName)
{
    desktop->setStyle(YWindow::wsDesktopAware);
    catchSignal(SIGINT);
    catchSignal(SIGTERM);
    catchSignal(SIGHUP);
    loadConfig();

    XSetErrorHandler(handler);
    tray = new SysTray();

    _ICEWM_ACTION = XInternAtom(xapp->display(), "_ICEWM_ACTION", False);
}
void SysTrayApp::loadConfig() {
#ifdef CONFIG_TASKBAR
#ifndef NO_CONFIGURE
    {
        cfoption theme_prefs[] = {
            OSV("Theme", &themeName, "Theme name"),
            OK0()
        };

        YConfig::findLoadConfigFile(this, theme_prefs, "preferences");
        YConfig::findLoadConfigFile(this, theme_prefs, "theme");
    }
    YConfig::findLoadConfigFile(this, icewmbg_prefs, "preferences");
    if (themeName != 0) {
        MSG(("themeName=%s", themeName));

        YConfig::findLoadConfigFile(
            this,
            icewmbg_prefs,
            upath("themes").child(themeName));
    }
    YConfig::findLoadConfigFile(this, icewmbg_prefs, "prefoverride");
#endif
    if (taskBarBg)
           delete taskBarBg;
        taskBarBg = new YColor(clrDefaultTaskBar);
#endif
}

SysTrayApp::~SysTrayApp() {

}

bool SysTrayApp::filterEvent(const XEvent &xev) {
#ifdef DEBUG
    logEvent(xev);
#endif
    if (xev.type == ClientMessage) {
        if (xev.xclient.message_type == _ICEWM_ACTION) {
            MSG(("loadConfig"));
            loadConfig();
            tray->trayChanged();
        } else
            tray->checkMessageEvent(xev.xclient);
        return false;
    } else if (xev.type == MappingNotify) {
            MSG(("tray mapping1"));
        if (xev.xmapping.window == tray->handle()) {
            MSG(("tray mapping"));
        }
    }
    return false;
}

void SysTrayApp::handleSignal(int sig) {
    switch (sig) {
    case SIGHUP:
         // Reload config colors from theme file and notify tray to repaint
         loadConfig();
         tray->trayChanged();
         return;
    case SIGINT:
    case SIGTERM:
        MSG(("exiting."));
        exit(0);
        return;
    }
    YXApplication::handleSignal(sig);
}

SysTray::SysTray(): YWindow(0) {
    desktop->setStyle(YWindow::wsDesktopAware);

    char trayatom[64];
    sprintf(trayatom, "_NET_SYSTEM_TRAY_S%d", xapp->screen());
    fTray2 = new YXTray(this, false, trayatom, this);

    char trayatom2[64];
    sprintf(trayatom2, "_ICEWM_INTTRAY_S%d", xapp->screen());
    icewm_internal_tray =
        XInternAtom(xapp->display(), trayatom2, False);

    _NET_SYSTEM_TRAY_OPCODE =
        XInternAtom(xapp->display(),
                    "_NET_SYSTEM_TRAY_OPCODE",
                    False);

    fTray2->relayout();
    setSize(fTray2->width(),
            fTray2->height());
    fTray2->show();
    requestDock();
}

void SysTray::trayChanged() {
    fTray2->backgroundChanged();
    setSize(fTray2->width(),
            fTray2->height());
    if (fTray2->visible())
        show();
    else
        hide();
}

void SysTray::requestDock() {
    Window w = XGetSelectionOwner(xapp->display(), icewm_internal_tray);

    if (w && w != handle()) {
        XClientMessageEvent xev;
        memset(&xev, 0, sizeof(xev));

        xev.type = ClientMessage;
        xev.window = w;
        xev.message_type = _NET_SYSTEM_TRAY_OPCODE;
        xev.format = 32;
        xev.data.l[0] = CurrentTime;
        xev.data.l[1] = SYSTEM_TRAY_REQUEST_DOCK;
        xev.data.l[2] = handle(); //fTray2->handle();

        XSendEvent(xapp->display(), w, False, StructureNotifyMask, (XEvent *) &xev);
    }
}

bool SysTray::checkMessageEvent(const XClientMessageEvent &message) {
    if (message.message_type == icewm_internal_tray) {
        MSG(("requestDock"));
        requestDock();
    }
    return true;
}

int main(int argc, char **argv) {
    YLocale locale;
    SysTrayApp stapp(&argc, &argv);
    for(int i=1; i<argc; ++i)
    {
       if(argv[i] && 0 == strcmp("--notify", argv[i]))
       {
          kill(getppid(), SIGUSR1);
          break;
       }
    }

    return stapp.mainLoop();
}
<commit_msg>CLI --debug switch for icewmtray<commit_after>#include "config.h"
#include "ylib.h"
#include "ylocale.h"
#include "yxapp.h"
#include "yxtray.h"
#include "base.h"
#include "debug.h"
#include "sysdep.h"
#include "yprefs.h"

extern void logEvent(const XEvent &xev);

char const *ApplicationName = "icewmtray";

#include "yconfig.h"

#ifdef CONFIG_TASKBAR
YColor *taskBarBg;

XSV(const char *, clrDefaultTaskBar,            "rgb:C0/C0/C0")
XIV(bool, trayDrawBevel,                        false)

cfoption icewmbg_prefs[] = {
    OSV("ColorDefaultTaskBar",                  &clrDefaultTaskBar,             "Background of the taskbar"),
    OBV("TrayDrawBevel",                        &trayDrawBevel,                 "Surround the tray with plastic border"),
    OK0()
};
#endif

class SysTray: public YWindow, public YXTrayNotifier {
public:
    SysTray();
    bool checkMessageEvent(const XClientMessageEvent &message);
    void requestDock();

    void handleUnmap(const XUnmapEvent &) {
        MSG(("hide"));
        if (visible())
            hide();
    }

    void trayChanged();
private:
    Atom icewm_internal_tray;
    Atom _NET_SYSTEM_TRAY_OPCODE;
    YXTray *fTray2;
};

class SysTrayApp: public YXApplication {
public:
    SysTrayApp(int *argc, char ***argv, const char *displayName = 0);
    ~SysTrayApp();

    void loadConfig(); //MCM OFFICIAL
    bool filterEvent(const XEvent &xev);
    void handleSignal(int sig);

private:
    Atom _ICEWM_ACTION;
    SysTray *tray;
};

int handler(Display *display, XErrorEvent *xev) {
    DBG {
        char message[80], req[80], number[80];

        sprintf(number, "%d", xev->request_code);
        XGetErrorDatabaseText(display,
                              "XRequest",
                              number, "",
                              req, sizeof(req));
        if (!req[0])
            sprintf(req, "[request_code=%d]", xev->request_code);

        if (XGetErrorText(display,
                          xev->error_code,
                          message, sizeof(message)) !=
                          Success)
            *message = '\0';

        warn("X error %s(0x%lX): %s", req, xev->resourceid, message);
    }
    return 0;
}
SysTrayApp::SysTrayApp(int *argc, char ***argv, const char *displayName):
    YXApplication(argc, argv, displayName)
{
    desktop->setStyle(YWindow::wsDesktopAware);
    catchSignal(SIGINT);
    catchSignal(SIGTERM);
    catchSignal(SIGHUP);
    loadConfig();

    XSetErrorHandler(handler);
    tray = new SysTray();

    _ICEWM_ACTION = XInternAtom(xapp->display(), "_ICEWM_ACTION", False);
}
void SysTrayApp::loadConfig() {
#ifdef CONFIG_TASKBAR
#ifndef NO_CONFIGURE
    {
        cfoption theme_prefs[] = {
            OSV("Theme", &themeName, "Theme name"),
            OK0()
        };

        YConfig::findLoadConfigFile(this, theme_prefs, "preferences");
        YConfig::findLoadConfigFile(this, theme_prefs, "theme");
    }
    YConfig::findLoadConfigFile(this, icewmbg_prefs, "preferences");
    if (themeName != 0) {
        MSG(("themeName=%s", themeName));

        YConfig::findLoadConfigFile(
            this,
            icewmbg_prefs,
            upath("themes").child(themeName));
    }
    YConfig::findLoadConfigFile(this, icewmbg_prefs, "prefoverride");
#endif
    if (taskBarBg)
           delete taskBarBg;
        taskBarBg = new YColor(clrDefaultTaskBar);
#endif
}

SysTrayApp::~SysTrayApp() {

}

bool SysTrayApp::filterEvent(const XEvent &xev) {
#ifdef DEBUG
    logEvent(xev);
#endif
    if (xev.type == ClientMessage) {
        if (xev.xclient.message_type == _ICEWM_ACTION) {
            MSG(("loadConfig"));
            loadConfig();
            tray->trayChanged();
        } else
            tray->checkMessageEvent(xev.xclient);
        return false;
    } else if (xev.type == MappingNotify) {
            MSG(("tray mapping1"));
        if (xev.xmapping.window == tray->handle()) {
            MSG(("tray mapping"));
        }
    }
    return false;
}

void SysTrayApp::handleSignal(int sig) {
    switch (sig) {
    case SIGHUP:
         // Reload config colors from theme file and notify tray to repaint
         loadConfig();
         tray->trayChanged();
         return;
    case SIGINT:
    case SIGTERM:
        MSG(("exiting."));
        exit(0);
        return;
    }
    YXApplication::handleSignal(sig);
}

SysTray::SysTray(): YWindow(0) {
    desktop->setStyle(YWindow::wsDesktopAware);

    char trayatom[64];
    sprintf(trayatom, "_NET_SYSTEM_TRAY_S%d", xapp->screen());
    fTray2 = new YXTray(this, false, trayatom, this);

    char trayatom2[64];
    sprintf(trayatom2, "_ICEWM_INTTRAY_S%d", xapp->screen());
    icewm_internal_tray =
        XInternAtom(xapp->display(), trayatom2, False);

    _NET_SYSTEM_TRAY_OPCODE =
        XInternAtom(xapp->display(),
                    "_NET_SYSTEM_TRAY_OPCODE",
                    False);

    fTray2->relayout();
    setSize(fTray2->width(),
            fTray2->height());
    fTray2->show();
    requestDock();
}

void SysTray::trayChanged() {
    fTray2->backgroundChanged();
    setSize(fTray2->width(),
            fTray2->height());
    if (fTray2->visible())
        show();
    else
        hide();
}

void SysTray::requestDock() {
    Window w = XGetSelectionOwner(xapp->display(), icewm_internal_tray);

    if (w && w != handle()) {
        XClientMessageEvent xev;
        memset(&xev, 0, sizeof(xev));

        xev.type = ClientMessage;
        xev.window = w;
        xev.message_type = _NET_SYSTEM_TRAY_OPCODE;
        xev.format = 32;
        xev.data.l[0] = CurrentTime;
        xev.data.l[1] = SYSTEM_TRAY_REQUEST_DOCK;
        xev.data.l[2] = handle(); //fTray2->handle();

        XSendEvent(xapp->display(), w, False, StructureNotifyMask, (XEvent *) &xev);
    }
}

bool SysTray::checkMessageEvent(const XClientMessageEvent &message) {
    if (message.message_type == icewm_internal_tray) {
        MSG(("requestDock"));
        requestDock();
    }
    return true;
}

int main(int argc, char **argv) {
    YLocale locale;
    SysTrayApp stapp(&argc, &argv);
    int notified = 0;
    for(int i=1; i<argc; ++i)
    {
       if(argv[i] && 0 == strcmp("--notify", argv[i]) && !notified)
       {
          kill(getppid(), SIGUSR1);
          notified = 1;
       }
#ifdef DEBUG
       if(argv[i] && 0 == strcmp("--debug", argv[i]))
          debug = 1;
#endif
    }

    return stapp.mainLoop();
}
<|endoftext|>


<commit_before>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2012 Francois Beaune, Jupiter Jazz Limited
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// Interface header.
#include "inputarray.h"

// appleseed.renderer headers.
#include "renderer/global/globaltypes.h"
#include "renderer/modeling/input/source.h"

// appleseed.foundation headers.
#include "foundation/utility/foreach.h"
#include "foundation/utility/memory.h"

// Standard headers.
#include <cassert>
#include <cstring>
#include <string>
#include <vector>

using namespace foundation;
using namespace std;

namespace renderer
{

//
// InputArray class implementation.
//

struct InputArray::Impl
{
    struct InputDecl
    {
        string          m_name;
        InputFormat     m_format;
        bool            m_has_default_value;
        string          m_default_value;
        Source*         m_source;
    };

    typedef vector<InputDecl> InputDeclVector;

    InputDeclVector m_input_decls;
};

InputArray::InputArray()
  : impl(new Impl())
{
}

InputArray::~InputArray()
{
    for (each<Impl::InputDeclVector> i = impl->m_input_decls; i; ++i)
        delete i->m_source;

    delete impl;
}

void InputArray::declare(
    const char*         name,
    const InputFormat   format,
    const char*         default_value)
{
    assert(name);

    Impl::InputDecl decl;
    decl.m_name = name;
    decl.m_format = format;
    decl.m_has_default_value = default_value != 0;
    if (default_value)
        decl.m_default_value = default_value;
    decl.m_source = 0;

    impl->m_input_decls.push_back(decl);
}

InputArray::iterator InputArray::begin()
{
    return iterator(this, 0);
}

InputArray::iterator InputArray::end()
{
    return iterator(this, impl->m_input_decls.size());
}

InputArray::const_iterator InputArray::begin() const
{
    return const_iterator(this, 0);
}

InputArray::const_iterator InputArray::end() const
{
    return const_iterator(this, impl->m_input_decls.size());
}

InputArray::iterator InputArray::find(const char* name)
{
    assert(name);

    const size_t input_count = impl->m_input_decls.size();

    for (size_t i = 0; i < input_count; ++i)
    {
        if (strcmp(impl->m_input_decls[i].m_name.c_str(), name) == 0)
            return iterator(this, i);
    }

    return end();
}

InputArray::const_iterator InputArray::find(const char* name) const
{
    assert(name);

    const size_t input_count = impl->m_input_decls.size();

    for (size_t i = 0; i < input_count; ++i)
    {
        if (strcmp(impl->m_input_decls[i].m_name.c_str(), name) == 0)
            return const_iterator(this, i);
    }

    return end();
}

Source* InputArray::source(const char* name) const
{
    assert(name);

    for (const_each<Impl::InputDeclVector> i = impl->m_input_decls; i; ++i)
    {
        if (strcmp(i->m_name.c_str(), name) == 0)
            return i->m_source;
    }

    return 0;
}

size_t InputArray::compute_data_size() const
{
    size_t size = 0;

    for (const_each<Impl::InputDeclVector> i = impl->m_input_decls; i; ++i)
    {
        switch (i->m_format)
        {
          case InputFormatScalar:
            size = align(size, 8);
            size += sizeof(double);
            break;

          case InputFormatSpectrum:
            size = align(size, 16);
            size += sizeof(Spectrum);
            size += sizeof(Alpha);
            break;
        }
    }

    size = align(size, 16);

    return size;
}

void InputArray::evaluate(
    TextureCache&       texture_cache,
    const Vector2d&     uv,
    void*               values,
    const size_t        offset) const
{
    assert(values);

    uint8* ptr = static_cast<uint8*>(values) + offset;
    assert(is_aligned(ptr, 16));

    for (const_each<Impl::InputDeclVector> i = impl->m_input_decls; i; ++i)
    {
        switch (i->m_format)
        {
          case InputFormatScalar:
            ptr = align(ptr, 8);
            if (i->m_source)
            {
                i->m_source->evaluate(
                    texture_cache,
                    uv,
                    *reinterpret_cast<double*>(ptr));
            }
            ptr += sizeof(double);
            break;

          case InputFormatSpectrum:
            ptr = align(ptr, 16);
            if (i->m_source)
            {
                i->m_source->evaluate(
                    texture_cache,
                    uv,
                    *reinterpret_cast<Spectrum*>(ptr),
                    *reinterpret_cast<Alpha*>(ptr + sizeof(Spectrum)));
            }
            ptr += sizeof(Spectrum);
            ptr += sizeof(Alpha);
            break;
        }
    }
}

void InputArray::evaluate_uniforms(
    void*               values,
    const size_t        offset) const
{
    assert(values);

    uint8* ptr = static_cast<uint8*>(values) + offset;
    assert(is_aligned(ptr, 16));

    for (const_each<Impl::InputDeclVector> i = impl->m_input_decls; i; ++i)
    {
        switch (i->m_format)
        {
          case InputFormatScalar:
            ptr = align(ptr, 8);
            if (i->m_source && i->m_source->is_uniform())
                i->m_source->evaluate_uniform(*reinterpret_cast<double*>(ptr));
            ptr += sizeof(double);
            break;

          case InputFormatSpectrum:
            ptr = align(ptr, 16);
            if (i->m_source && i->m_source->is_uniform())
            {
                i->m_source->evaluate_uniform(
                    *reinterpret_cast<Spectrum*>(ptr),
                    *reinterpret_cast<Alpha*>(ptr + sizeof(Spectrum)));
            }
            ptr += sizeof(Spectrum);
            ptr += sizeof(Alpha);
            break;
        }
    }
}

//
// InputArray::const_iterator class implementation.
//

InputArray::const_iterator::const_iterator(const InputArray* array, const size_t index)
  : m_input_array(array)
  , m_input_index(index)
{
}

InputArray::const_iterator::const_iterator(const iterator& rhs)
  : m_input_array(rhs.m_input_array)
  , m_input_index(rhs.m_input_index)
{
}

InputArray::const_iterator::const_iterator(const const_iterator& rhs)
  : m_input_array(rhs.m_input_array)
  , m_input_index(rhs.m_input_index)
{
}

InputArray::const_iterator& InputArray::const_iterator::operator=(const const_iterator& rhs)
{
    m_input_array = rhs.m_input_array;
    m_input_index = rhs.m_input_index;
    return *this;
}

bool InputArray::const_iterator::operator==(const const_iterator& rhs) const
{
    return
        m_input_index == rhs.m_input_index &&
        m_input_array == rhs.m_input_array;
}

bool InputArray::const_iterator::operator!=(const const_iterator& rhs) const
{
    return
        m_input_index != rhs.m_input_index ||
        m_input_array != rhs.m_input_array;
}

InputArray::const_iterator& InputArray::const_iterator::operator++()
{
    ++m_input_index;
    return *this;
}

InputArray::const_iterator& InputArray::const_iterator::operator--()
{
    --m_input_index;
    return *this;
}

const InputArray::const_iterator& InputArray::const_iterator::operator*() const
{
    return *this;
}

const char* InputArray::const_iterator::name() const
{
    return m_input_array->impl->m_input_decls[m_input_index].m_name.c_str();
}

InputFormat InputArray::const_iterator::format() const
{
    return m_input_array->impl->m_input_decls[m_input_index].m_format;
}

const char* InputArray::const_iterator::default_value() const
{
    const Impl::InputDecl& decl = m_input_array->impl->m_input_decls[m_input_index];
    return decl.m_has_default_value ? decl.m_default_value.c_str() : 0;
}

Source* InputArray::const_iterator::source() const
{
    return m_input_array->impl->m_input_decls[m_input_index].m_source;
}

//
// InputArray::iterator class implementation.
//

InputArray::iterator::iterator(const InputArray* array, const size_t index)
  : const_iterator(array, index)
{
}

InputArray::iterator::iterator(const iterator& rhs)
  : const_iterator(rhs)
{
}

InputArray::iterator& InputArray::iterator::operator=(const iterator& rhs)
{
    m_input_array = rhs.m_input_array;
    m_input_index = rhs.m_input_index;
    return *this;
}

InputArray::iterator& InputArray::iterator::operator++()
{
    ++m_input_index;
    return *this;
}

InputArray::iterator& InputArray::iterator::operator--()
{
    --m_input_index;
    return *this;
}

InputArray::iterator& InputArray::iterator::operator*()
{
    return *this;
}

void InputArray::iterator::bind(Source* source)
{
    Impl::InputDecl& decl = m_input_array->impl->m_input_decls[m_input_index];
    delete decl.m_source;
    decl.m_source = source;
}

}   // namespace renderer
<commit_msg>made input evaluation more robust with respect to structure members alignment.<commit_after>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2012 Francois Beaune, Jupiter Jazz Limited
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// Interface header.
#include "inputarray.h"

// appleseed.renderer headers.
#include "renderer/global/globaltypes.h"
#include "renderer/modeling/input/source.h"

// appleseed.foundation headers.
#include "foundation/platform/compiler.h"
#include "foundation/utility/foreach.h"
#include "foundation/utility/memory.h"

// Standard headers.
#include <cassert>
#include <cstring>
#include <string>
#include <vector>

using namespace foundation;
using namespace std;

namespace renderer
{

//
// InputArray class implementation.
//

struct InputArray::Impl
{
    struct InputDecl
    {
        string          m_name;
        InputFormat     m_format;
        bool            m_has_default_value;
        string          m_default_value;
        Source*         m_source;
    };

    typedef vector<InputDecl> InputDeclVector;

    InputDeclVector m_input_decls;
};

InputArray::InputArray()
  : impl(new Impl())
{
}

InputArray::~InputArray()
{
    for (each<Impl::InputDeclVector> i = impl->m_input_decls; i; ++i)
        delete i->m_source;

    delete impl;
}

void InputArray::declare(
    const char*         name,
    const InputFormat   format,
    const char*         default_value)
{
    assert(name);

    Impl::InputDecl decl;
    decl.m_name = name;
    decl.m_format = format;
    decl.m_has_default_value = default_value != 0;
    if (default_value)
        decl.m_default_value = default_value;
    decl.m_source = 0;

    impl->m_input_decls.push_back(decl);
}

InputArray::iterator InputArray::begin()
{
    return iterator(this, 0);
}

InputArray::iterator InputArray::end()
{
    return iterator(this, impl->m_input_decls.size());
}

InputArray::const_iterator InputArray::begin() const
{
    return const_iterator(this, 0);
}

InputArray::const_iterator InputArray::end() const
{
    return const_iterator(this, impl->m_input_decls.size());
}

InputArray::iterator InputArray::find(const char* name)
{
    assert(name);

    const size_t input_count = impl->m_input_decls.size();

    for (size_t i = 0; i < input_count; ++i)
    {
        if (strcmp(impl->m_input_decls[i].m_name.c_str(), name) == 0)
            return iterator(this, i);
    }

    return end();
}

InputArray::const_iterator InputArray::find(const char* name) const
{
    assert(name);

    const size_t input_count = impl->m_input_decls.size();

    for (size_t i = 0; i < input_count; ++i)
    {
        if (strcmp(impl->m_input_decls[i].m_name.c_str(), name) == 0)
            return const_iterator(this, i);
    }

    return end();
}

Source* InputArray::source(const char* name) const
{
    assert(name);

    for (const_each<Impl::InputDeclVector> i = impl->m_input_decls; i; ++i)
    {
        if (strcmp(i->m_name.c_str(), name) == 0)
            return i->m_source;
    }

    return 0;
}

namespace
{
    // Not the same as ALIGNOF(), see http://stackoverflow.com/q/11545153/393756.
    template <typename Target>
    size_t offset_of()
    {
        struct S { char c; Target t; };
        return offsetof(S, t);
    }

    // Can't use offsetof() on non-POD types.
    template <>
    size_t offset_of<Spectrum>()
    {
        return ALIGNOF(Spectrum);
    }

    template <typename Target, typename T>
    T align_to(const T x)
    {
        return align(x, offset_of<Target>());
    }
}

size_t InputArray::compute_data_size() const
{
    size_t size = 0;

    for (const_each<Impl::InputDeclVector> i = impl->m_input_decls; i; ++i)
    {
        switch (i->m_format)
        {
          case InputFormatScalar:
            size = align_to<double>(size);
            size += sizeof(double);
            break;

          case InputFormatSpectrum:
            size = align_to<Spectrum>(size);
            size += sizeof(Spectrum);
            size += sizeof(Alpha);
            break;
        }
    }

    size = align(size, 16);

    return size;
}

void InputArray::evaluate(
    TextureCache&       texture_cache,
    const Vector2d&     uv,
    void*               values,
    const size_t        offset) const
{
    assert(values);

    uint8* ptr = static_cast<uint8*>(values) + offset;
    assert(is_aligned(ptr, 16));

    for (const_each<Impl::InputDeclVector> i = impl->m_input_decls; i; ++i)
    {
        switch (i->m_format)
        {
          case InputFormatScalar:
            ptr = align_to<double>(ptr);
            if (i->m_source)
            {
                i->m_source->evaluate(
                    texture_cache,
                    uv,
                    *reinterpret_cast<double*>(ptr));
            }
            ptr += sizeof(double);
            break;

          case InputFormatSpectrum:
            ptr = align_to<Spectrum>(ptr);
            if (i->m_source)
            {
                i->m_source->evaluate(
                    texture_cache,
                    uv,
                    *reinterpret_cast<Spectrum*>(ptr),
                    *reinterpret_cast<Alpha*>(ptr + sizeof(Spectrum)));
            }
            ptr += sizeof(Spectrum);
            ptr += sizeof(Alpha);
            break;
        }
    }
}

void InputArray::evaluate_uniforms(
    void*               values,
    const size_t        offset) const
{
    assert(values);

    uint8* ptr = static_cast<uint8*>(values) + offset;
    assert(is_aligned(ptr, 16));

    for (const_each<Impl::InputDeclVector> i = impl->m_input_decls; i; ++i)
    {
        switch (i->m_format)
        {
          case InputFormatScalar:
            ptr = align_to<double>(ptr);
            if (i->m_source && i->m_source->is_uniform())
                i->m_source->evaluate_uniform(*reinterpret_cast<double*>(ptr));
            ptr += sizeof(double);
            break;

          case InputFormatSpectrum:
            ptr = align_to<Spectrum>(ptr);
            if (i->m_source && i->m_source->is_uniform())
            {
                i->m_source->evaluate_uniform(
                    *reinterpret_cast<Spectrum*>(ptr),
                    *reinterpret_cast<Alpha*>(ptr + sizeof(Spectrum)));
            }
            ptr += sizeof(Spectrum);
            ptr += sizeof(Alpha);
            break;
        }
    }
}

//
// InputArray::const_iterator class implementation.
//

InputArray::const_iterator::const_iterator(const InputArray* array, const size_t index)
  : m_input_array(array)
  , m_input_index(index)
{
}

InputArray::const_iterator::const_iterator(const iterator& rhs)
  : m_input_array(rhs.m_input_array)
  , m_input_index(rhs.m_input_index)
{
}

InputArray::const_iterator::const_iterator(const const_iterator& rhs)
  : m_input_array(rhs.m_input_array)
  , m_input_index(rhs.m_input_index)
{
}

InputArray::const_iterator& InputArray::const_iterator::operator=(const const_iterator& rhs)
{
    m_input_array = rhs.m_input_array;
    m_input_index = rhs.m_input_index;
    return *this;
}

bool InputArray::const_iterator::operator==(const const_iterator& rhs) const
{
    return
        m_input_index == rhs.m_input_index &&
        m_input_array == rhs.m_input_array;
}

bool InputArray::const_iterator::operator!=(const const_iterator& rhs) const
{
    return
        m_input_index != rhs.m_input_index ||
        m_input_array != rhs.m_input_array;
}

InputArray::const_iterator& InputArray::const_iterator::operator++()
{
    ++m_input_index;
    return *this;
}

InputArray::const_iterator& InputArray::const_iterator::operator--()
{
    --m_input_index;
    return *this;
}

const InputArray::const_iterator& InputArray::const_iterator::operator*() const
{
    return *this;
}

const char* InputArray::const_iterator::name() const
{
    return m_input_array->impl->m_input_decls[m_input_index].m_name.c_str();
}

InputFormat InputArray::const_iterator::format() const
{
    return m_input_array->impl->m_input_decls[m_input_index].m_format;
}

const char* InputArray::const_iterator::default_value() const
{
    const Impl::InputDecl& decl = m_input_array->impl->m_input_decls[m_input_index];
    return decl.m_has_default_value ? decl.m_default_value.c_str() : 0;
}

Source* InputArray::const_iterator::source() const
{
    return m_input_array->impl->m_input_decls[m_input_index].m_source;
}

//
// InputArray::iterator class implementation.
//

InputArray::iterator::iterator(const InputArray* array, const size_t index)
  : const_iterator(array, index)
{
}

InputArray::iterator::iterator(const iterator& rhs)
  : const_iterator(rhs)
{
}

InputArray::iterator& InputArray::iterator::operator=(const iterator& rhs)
{
    m_input_array = rhs.m_input_array;
    m_input_index = rhs.m_input_index;
    return *this;
}

InputArray::iterator& InputArray::iterator::operator++()
{
    ++m_input_index;
    return *this;
}

InputArray::iterator& InputArray::iterator::operator--()
{
    --m_input_index;
    return *this;
}

InputArray::iterator& InputArray::iterator::operator*()
{
    return *this;
}

void InputArray::iterator::bind(Source* source)
{
    Impl::InputDecl& decl = m_input_array->impl->m_input_decls[m_input_index];
    delete decl.m_source;
    decl.m_source = source;
}

}   // namespace renderer
<|endoftext|>