<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/automation/ui_controls.h"

#include "app/keyboard_code_conversion_win.h"
#include "app/keyboard_codes.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/win_util.h"
#include "base/ref_counted.h"
#include "base/task.h"
#include "views/view.h"

namespace ui_controls {

namespace {

// InputDispatcher ------------------------------------------------------------

// InputDispatcher is used to listen for a mouse/keyboard event. When the
// appropriate event is received the task is notified.
class InputDispatcher : public base::RefCounted<InputDispatcher> {
 public:
  InputDispatcher(Task* task, WPARAM message_waiting_for);

  // Invoked from the hook. If mouse_message matches message_waiting_for_
  // MatchingMessageFound is invoked.
  void DispatchedMessage(WPARAM mouse_message);

  // Invoked when a matching event is found. Uninstalls the hook and schedules
  // an event that notifies the task.
  void MatchingMessageFound();

 private:
  friend class base::RefCounted<InputDispatcher>;

  ~InputDispatcher();

   // Notifies the task and release this (which should delete it).
  void NotifyTask();

  // The task we notify.
  scoped_ptr<Task> task_;

  // Message we're waiting for. Not used for keyboard events.
  const WPARAM message_waiting_for_;

  DISALLOW_COPY_AND_ASSIGN(InputDispatcher);
};

// Have we installed the hook?
bool installed_hook_ = false;

// Return value from SetWindowsHookEx.
HHOOK next_hook_ = NULL;

// If a hook is installed, this is the dispatcher.
InputDispatcher* current_dispatcher_ = NULL;

// Callback from hook when a mouse message is received.
LRESULT CALLBACK MouseHook(int n_code, WPARAM w_param, LPARAM l_param) {
  HHOOK next_hook = next_hook_;
  if (n_code == HC_ACTION) {
    DCHECK(current_dispatcher_);
    current_dispatcher_->DispatchedMessage(w_param);
  }
  return CallNextHookEx(next_hook, n_code, w_param, l_param);
}

// Callback from hook when a key message is received.
LRESULT CALLBACK KeyHook(int n_code, WPARAM w_param, LPARAM l_param) {
  HHOOK next_hook = next_hook_;
  if (n_code == HC_ACTION) {
    DCHECK(current_dispatcher_);
    if (l_param & (1 << 30))  // Only send on key up.
      current_dispatcher_->MatchingMessageFound();
  }
  return CallNextHookEx(next_hook, n_code, w_param, l_param);
}

// Installs dispatcher as the current hook.
void InstallHook(InputDispatcher* dispatcher, bool key_hook) {
  DCHECK(!installed_hook_);
  current_dispatcher_ = dispatcher;
  installed_hook_ = true;
  if (key_hook) {
    next_hook_ = SetWindowsHookEx(WH_KEYBOARD, &KeyHook, NULL,
                                  GetCurrentThreadId());
  } else {
    // NOTE: I originally tried WH_CALLWNDPROCRET, but for some reason I
    // didn't get a mouse message like I do with MouseHook.
    next_hook_ = SetWindowsHookEx(WH_MOUSE, &MouseHook, NULL,
                                  GetCurrentThreadId());
  }
  DCHECK(next_hook_);
}

// Uninstalls the hook set in InstallHook.
void UninstallHook(InputDispatcher* dispatcher) {
  if (current_dispatcher_ == dispatcher) {
    installed_hook_ = false;
    current_dispatcher_ = NULL;
    UnhookWindowsHookEx(next_hook_);
  }
}

InputDispatcher::InputDispatcher(Task* task, UINT message_waiting_for)
    : task_(task), message_waiting_for_(message_waiting_for) {
  InstallHook(this, message_waiting_for == WM_KEYUP);
}

InputDispatcher::~InputDispatcher() {
  // Make sure the hook isn't installed.
  UninstallHook(this);
}

void InputDispatcher::DispatchedMessage(WPARAM message) {
  if (message == message_waiting_for_)
    MatchingMessageFound();
}

void InputDispatcher::MatchingMessageFound() {
  UninstallHook(this);
  // At the time we're invoked the event has not actually been processed.
  // Use PostTask to make sure the event has been processed before notifying.
  MessageLoop::current()->PostDelayedTask(
      FROM_HERE, NewRunnableMethod(this, &InputDispatcher::NotifyTask), 0);
}

void InputDispatcher::NotifyTask() {
  task_->Run();
  Release();
}

// Private functions ----------------------------------------------------------

// Populate the INPUT structure with the appropriate keyboard event
// parameters required by SendInput
bool FillKeyboardInput(app::KeyboardCode key, INPUT* input, bool key_up) {
  memset(input, 0, sizeof(INPUT));
  input->type = INPUT_KEYBOARD;
  input->ki.wVk = app::WindowsKeyCodeForKeyboardCode(key);
  input->ki.dwFlags = key_up ? KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP :
                               KEYEVENTF_EXTENDEDKEY;

  return true;
}

// Send a key event (up/down)
bool SendKeyEvent(app::KeyboardCode key, bool up) {
  INPUT input = { 0 };

  if (!FillKeyboardInput(key, &input, up))
    return false;

  if (!::SendInput(1, &input, sizeof(INPUT)))
    return false;

  return true;
}

void Checkpoint(const char* message, const base::TimeTicks& start_time) {
  LOG(INFO) << message << " : "
            << (base::TimeTicks::Now() - start_time).InMilliseconds()
            << " ms" << std::flush;
}

bool SendKeyPressImpl(app::KeyboardCode key,
                      bool control, bool shift, bool alt,
                      Task* task) {
  base::TimeTicks start_time = base::TimeTicks::Now();
  Checkpoint("SendKeyPressImpl starts", start_time);

  scoped_refptr<InputDispatcher> dispatcher(
      task ? new InputDispatcher(task, WM_KEYUP) : NULL);

  // If a pop-up menu is open, it won't receive events sent using SendInput.
  // Check for a pop-up menu using its window class (#32768) and if one
  // exists, send the key event directly there.
  Checkpoint("FindWindow", start_time);
  HWND popup_menu = ::FindWindow(L"#32768", 0);
  if (popup_menu != NULL && popup_menu == ::GetTopWindow(NULL)) {
    Checkpoint("Found popup window", start_time);
    WPARAM w_param = app::WindowsKeyCodeForKeyboardCode(key);
    LPARAM l_param = 0;
    Checkpoint("Send WM_KEYDOWN", start_time);
    ::SendMessage(popup_menu, WM_KEYDOWN, w_param, l_param);
    Checkpoint("Send WM_KEYUP", start_time);
    ::SendMessage(popup_menu, WM_KEYUP, w_param, l_param);

    Checkpoint("Send Done", start_time);
    if (dispatcher.get())
      dispatcher->AddRef();
    return true;
  }

  Checkpoint("Found no popup window", start_time);

  INPUT input[8] = { 0 }; // 8, assuming all the modifiers are activated

  UINT i = 0;
  if (control) {
    Checkpoint("FillKeyboardInput Control", start_time);
    if (!FillKeyboardInput(app::VKEY_CONTROL, &input[i], false))
      return false;
    i++;
  }

  if (shift) {
    Checkpoint("FillKeyboardInput Shift", start_time);
    if (!FillKeyboardInput(app::VKEY_SHIFT, &input[i], false))
      return false;
    i++;
  }

  if (alt) {
    Checkpoint("FillKeyboardInput Alt", start_time);
    if (!FillKeyboardInput(app::VKEY_MENU, &input[i], false))
      return false;
    i++;
  }

  Checkpoint("FillKeyboardInput 1", start_time);
  if (!FillKeyboardInput(key, &input[i], false))
    return false;
  i++;

  Checkpoint("FillKeyboardInput 2", start_time);
  if (!FillKeyboardInput(key, &input[i], true))
    return false;
  i++;

  if (alt) {
    Checkpoint("FillKeyboardInput Alt2", start_time);
    if (!FillKeyboardInput(app::VKEY_MENU, &input[i], true))
      return false;
    i++;
  }

  if (shift) {
    Checkpoint("FillKeyboardInput Shift2", start_time);
    if (!FillKeyboardInput(app::VKEY_SHIFT, &input[i], true))
      return false;
    i++;
  }

  if (control) {
    Checkpoint("FillKeyboardInput Ctrl2", start_time);
    if (!FillKeyboardInput(app::VKEY_CONTROL, &input[i], true))
      return false;
    i++;
  }

  Checkpoint("SendInput called", start_time);
  if (::SendInput(i, input, sizeof(INPUT)) != i)
    return false;

  Checkpoint("SendInput done", start_time);

  if (dispatcher.get())
    dispatcher->AddRef();

  Checkpoint("Test done", start_time);
  return true;
}

bool SendMouseMoveImpl(long x, long y, Task* task) {
  // First check if the mouse is already there.
  POINT current_pos;
  ::GetCursorPos(&current_pos);
  if (x == current_pos.x && y == current_pos.y) {
    if (task)
      MessageLoop::current()->PostTask(FROM_HERE, task);
    return true;
  }

  INPUT input = { 0 };

  int screen_width = ::GetSystemMetrics(SM_CXSCREEN) - 1;
  int screen_height  = ::GetSystemMetrics(SM_CYSCREEN) - 1;
  LONG pixel_x  = static_cast<LONG>(x * (65535.0f / screen_width));
  LONG pixel_y = static_cast<LONG>(y * (65535.0f / screen_height));

  input.type = INPUT_MOUSE;
  input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
  input.mi.dx = pixel_x;
  input.mi.dy = pixel_y;

  scoped_refptr<InputDispatcher> dispatcher(
      task ? new InputDispatcher(task, WM_MOUSEMOVE) : NULL);

  if (!::SendInput(1, &input, sizeof(INPUT)))
    return false;

  if (dispatcher.get())
    dispatcher->AddRef();

  return true;
}

bool SendMouseEventsImpl(MouseButton type, int state, Task* task) {
  DWORD down_flags = MOUSEEVENTF_ABSOLUTE;
  DWORD up_flags = MOUSEEVENTF_ABSOLUTE;
  UINT last_event;

  switch (type) {
    case LEFT:
      down_flags |= MOUSEEVENTF_LEFTDOWN;
      up_flags |= MOUSEEVENTF_LEFTUP;
      last_event = (state & UP) ? WM_LBUTTONUP : WM_LBUTTONDOWN;
      break;

    case MIDDLE:
      down_flags |= MOUSEEVENTF_MIDDLEDOWN;
      up_flags |= MOUSEEVENTF_MIDDLEUP;
      last_event = (state & UP) ? WM_MBUTTONUP : WM_MBUTTONDOWN;
      break;

    case RIGHT:
      down_flags |= MOUSEEVENTF_RIGHTDOWN;
      up_flags |= MOUSEEVENTF_RIGHTUP;
      last_event = (state & UP) ? WM_RBUTTONUP : WM_RBUTTONDOWN;
      break;

    default:
      NOTREACHED();
      return false;
  }

  scoped_refptr<InputDispatcher> dispatcher(
      task ? new InputDispatcher(task, last_event) : NULL);

  INPUT input = { 0 };
  input.type = INPUT_MOUSE;
  input.mi.dwFlags = down_flags;
  if ((state & DOWN) && !::SendInput(1, &input, sizeof(INPUT)))
    return false;

  input.mi.dwFlags = up_flags;
  if ((state & UP) && !::SendInput(1, &input, sizeof(INPUT)))
    return false;

  if (dispatcher.get())
    dispatcher->AddRef();

  return true;
}

}  // namespace

// public functions -----------------------------------------------------------

bool SendKeyPress(gfx::NativeWindow window, app::KeyboardCode key,
                  bool control, bool shift, bool alt, bool command) {
  DCHECK(command == false);  // No command key on Windows
  return SendKeyPressImpl(key, control, shift, alt, NULL);
}

bool SendKeyPressNotifyWhenDone(gfx::NativeWindow window,
                                app::KeyboardCode key,
                                bool control, bool shift, bool alt,
                                bool command,
                                Task* task) {
  DCHECK(command == false);  // No command key on Windows
  return SendKeyPressImpl(key, control, shift, alt, task);
}

bool SendMouseMove(long x, long y) {
  return SendMouseMoveImpl(x, y, NULL);
}

bool SendMouseMoveNotifyWhenDone(long x, long y, Task* task) {
  return SendMouseMoveImpl(x, y, task);
}

bool SendMouseEvents(MouseButton type, int state) {
  return SendMouseEventsImpl(type, state, NULL);
}

bool SendMouseEventsNotifyWhenDone(MouseButton type, int state, Task* task) {
  return SendMouseEventsImpl(type, state, task);
}

bool SendMouseClick(MouseButton type) {
  return SendMouseEventsImpl(type, UP | DOWN, NULL);
}

void MoveMouseToCenterAndPress(views::View* view, MouseButton button,
                               int state, Task* task) {
  DCHECK(view);
  DCHECK(view->GetWidget());
  gfx::Point view_center(view->width() / 2, view->height() / 2);
  views::View::ConvertPointToScreen(view, &view_center);
  SendMouseMove(view_center.x(), view_center.y());
  SendMouseEventsNotifyWhenDone(button, state, task);
}

}  // ui_controls
<commit_msg>Add some more temporary traces to narrow down the cause of failure.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/automation/ui_controls.h"

#include "app/keyboard_code_conversion_win.h"
#include "app/keyboard_codes.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/win_util.h"
#include "base/ref_counted.h"
#include "base/task.h"
#include "views/view.h"

namespace ui_controls {

namespace {

void Checkpoint(const char* message, const base::TimeTicks& start_time) {
  LOG(INFO) << message << " : "
            << (base::TimeTicks::Now() - start_time).InMilliseconds()
            << " ms" << std::flush;
}

// InputDispatcher ------------------------------------------------------------

// InputDispatcher is used to listen for a mouse/keyboard event. When the
// appropriate event is received the task is notified.
class InputDispatcher : public base::RefCounted<InputDispatcher> {
 public:
  InputDispatcher(Task* task, WPARAM message_waiting_for);

  // Invoked from the hook. If mouse_message matches message_waiting_for_
  // MatchingMessageFound is invoked.
  void DispatchedMessage(WPARAM mouse_message);

  // Invoked when a matching event is found. Uninstalls the hook and schedules
  // an event that notifies the task.
  void MatchingMessageFound();

 private:
  friend class base::RefCounted<InputDispatcher>;

  ~InputDispatcher();

   // Notifies the task and release this (which should delete it).
  void NotifyTask();

  // The task we notify.
  scoped_ptr<Task> task_;

  // Message we're waiting for. Not used for keyboard events.
  const WPARAM message_waiting_for_;

  DISALLOW_COPY_AND_ASSIGN(InputDispatcher);
};

// Have we installed the hook?
bool installed_hook_ = false;

// Return value from SetWindowsHookEx.
HHOOK next_hook_ = NULL;

// If a hook is installed, this is the dispatcher.
InputDispatcher* current_dispatcher_ = NULL;

// Callback from hook when a mouse message is received.
LRESULT CALLBACK MouseHook(int n_code, WPARAM w_param, LPARAM l_param) {
  HHOOK next_hook = next_hook_;
  if (n_code == HC_ACTION) {
    DCHECK(current_dispatcher_);
    current_dispatcher_->DispatchedMessage(w_param);
  }
  return CallNextHookEx(next_hook, n_code, w_param, l_param);
}

// Callback from hook when a key message is received.
LRESULT CALLBACK KeyHook(int n_code, WPARAM w_param, LPARAM l_param) {
  base::TimeTicks start_time = base::TimeTicks::Now();
  char msg[512];
  base::snprintf(msg, 512, "KeyHook starts: %d", n_code);
  Checkpoint(msg, start_time);

  HHOOK next_hook = next_hook_;
  base::snprintf(msg, 512, "n_code == HC_ACTION: %d, %d",
          l_param, !!(l_param & (1 << 30)));
  Checkpoint(msg, start_time);
  if (n_code == HC_ACTION) {
    DCHECK(current_dispatcher_);
    if (l_param & (1 << 30)) {  // Only send on key up.
      Checkpoint("MatchingMessageFound", start_time);
      current_dispatcher_->MatchingMessageFound();
    } else {
      Checkpoint("Not key up", start_time);
    }
  }
  Checkpoint("KeyHook ends, calling next hook.", start_time);
  return CallNextHookEx(next_hook, n_code, w_param, l_param);
}

// Installs dispatcher as the current hook.
void InstallHook(InputDispatcher* dispatcher, bool key_hook) {
  DCHECK(!installed_hook_);
  current_dispatcher_ = dispatcher;
  installed_hook_ = true;
  if (key_hook) {
    next_hook_ = SetWindowsHookEx(WH_KEYBOARD, &KeyHook, NULL,
                                  GetCurrentThreadId());
  } else {
    // NOTE: I originally tried WH_CALLWNDPROCRET, but for some reason I
    // didn't get a mouse message like I do with MouseHook.
    next_hook_ = SetWindowsHookEx(WH_MOUSE, &MouseHook, NULL,
                                  GetCurrentThreadId());
  }
  DCHECK(next_hook_);
}

// Uninstalls the hook set in InstallHook.
void UninstallHook(InputDispatcher* dispatcher) {
  if (current_dispatcher_ == dispatcher) {
    installed_hook_ = false;
    current_dispatcher_ = NULL;
    UnhookWindowsHookEx(next_hook_);
  }
}

InputDispatcher::InputDispatcher(Task* task, UINT message_waiting_for)
    : task_(task), message_waiting_for_(message_waiting_for) {
  InstallHook(this, message_waiting_for == WM_KEYUP);
}

InputDispatcher::~InputDispatcher() {
  // Make sure the hook isn't installed.
  UninstallHook(this);
}

void InputDispatcher::DispatchedMessage(WPARAM message) {
  if (message == message_waiting_for_)
    MatchingMessageFound();
}

void InputDispatcher::MatchingMessageFound() {
  UninstallHook(this);
  // At the time we're invoked the event has not actually been processed.
  // Use PostTask to make sure the event has been processed before notifying.
  MessageLoop::current()->PostDelayedTask(
      FROM_HERE, NewRunnableMethod(this, &InputDispatcher::NotifyTask), 0);
}

void InputDispatcher::NotifyTask() {
  task_->Run();
  Release();
}

// Private functions ----------------------------------------------------------

// Populate the INPUT structure with the appropriate keyboard event
// parameters required by SendInput
bool FillKeyboardInput(app::KeyboardCode key, INPUT* input, bool key_up) {
  memset(input, 0, sizeof(INPUT));
  input->type = INPUT_KEYBOARD;
  input->ki.wVk = app::WindowsKeyCodeForKeyboardCode(key);
  input->ki.dwFlags = key_up ? KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP :
                               KEYEVENTF_EXTENDEDKEY;

  return true;
}

// Send a key event (up/down)
bool SendKeyEvent(app::KeyboardCode key, bool up) {
  INPUT input = { 0 };

  if (!FillKeyboardInput(key, &input, up))
    return false;

  if (!::SendInput(1, &input, sizeof(INPUT)))
    return false;

  return true;
}

bool SendKeyPressImpl(app::KeyboardCode key,
                      bool control, bool shift, bool alt,
                      Task* task) {
  base::TimeTicks start_time = base::TimeTicks::Now();
  Checkpoint("SendKeyPressImpl starts", start_time);

  scoped_refptr<InputDispatcher> dispatcher(
      task ? new InputDispatcher(task, WM_KEYUP) : NULL);

  // If a pop-up menu is open, it won't receive events sent using SendInput.
  // Check for a pop-up menu using its window class (#32768) and if one
  // exists, send the key event directly there.
  Checkpoint("FindWindow", start_time);
  HWND popup_menu = ::FindWindow(L"#32768", 0);
  if (popup_menu != NULL && popup_menu == ::GetTopWindow(NULL)) {
    Checkpoint("Found popup window", start_time);
    WPARAM w_param = app::WindowsKeyCodeForKeyboardCode(key);
    LPARAM l_param = 0;
    Checkpoint("Send WM_KEYDOWN", start_time);
    ::SendMessage(popup_menu, WM_KEYDOWN, w_param, l_param);
    Checkpoint("Send WM_KEYUP", start_time);
    ::SendMessage(popup_menu, WM_KEYUP, w_param, l_param);

    Checkpoint("Send Done", start_time);
    if (dispatcher.get())
      dispatcher->AddRef();
    return true;
  }

  Checkpoint("Found no popup window", start_time);

  INPUT input[8] = { 0 }; // 8, assuming all the modifiers are activated

  UINT i = 0;
  if (control) {
    Checkpoint("FillKeyboardInput Control", start_time);
    if (!FillKeyboardInput(app::VKEY_CONTROL, &input[i], false))
      return false;
    i++;
  }

  if (shift) {
    Checkpoint("FillKeyboardInput Shift", start_time);
    if (!FillKeyboardInput(app::VKEY_SHIFT, &input[i], false))
      return false;
    i++;
  }

  if (alt) {
    Checkpoint("FillKeyboardInput Alt", start_time);
    if (!FillKeyboardInput(app::VKEY_MENU, &input[i], false))
      return false;
    i++;
  }

  Checkpoint("FillKeyboardInput 1", start_time);
  if (!FillKeyboardInput(key, &input[i], false))
    return false;
  i++;

  Checkpoint("FillKeyboardInput 2", start_time);
  if (!FillKeyboardInput(key, &input[i], true))
    return false;
  i++;

  if (alt) {
    Checkpoint("FillKeyboardInput Alt2", start_time);
    if (!FillKeyboardInput(app::VKEY_MENU, &input[i], true))
      return false;
    i++;
  }

  if (shift) {
    Checkpoint("FillKeyboardInput Shift2", start_time);
    if (!FillKeyboardInput(app::VKEY_SHIFT, &input[i], true))
      return false;
    i++;
  }

  if (control) {
    Checkpoint("FillKeyboardInput Ctrl2", start_time);
    if (!FillKeyboardInput(app::VKEY_CONTROL, &input[i], true))
      return false;
    i++;
  }

  Checkpoint("SendInput called", start_time);
  if (::SendInput(i, input, sizeof(INPUT)) != i)
    return false;

  Checkpoint("SendInput done", start_time);

  if (dispatcher.get())
    dispatcher->AddRef();

  Checkpoint("Test done", start_time);
  return true;
}

bool SendMouseMoveImpl(long x, long y, Task* task) {
  // First check if the mouse is already there.
  POINT current_pos;
  ::GetCursorPos(&current_pos);
  if (x == current_pos.x && y == current_pos.y) {
    if (task)
      MessageLoop::current()->PostTask(FROM_HERE, task);
    return true;
  }

  INPUT input = { 0 };

  int screen_width = ::GetSystemMetrics(SM_CXSCREEN) - 1;
  int screen_height  = ::GetSystemMetrics(SM_CYSCREEN) - 1;
  LONG pixel_x  = static_cast<LONG>(x * (65535.0f / screen_width));
  LONG pixel_y = static_cast<LONG>(y * (65535.0f / screen_height));

  input.type = INPUT_MOUSE;
  input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
  input.mi.dx = pixel_x;
  input.mi.dy = pixel_y;

  scoped_refptr<InputDispatcher> dispatcher(
      task ? new InputDispatcher(task, WM_MOUSEMOVE) : NULL);

  if (!::SendInput(1, &input, sizeof(INPUT)))
    return false;

  if (dispatcher.get())
    dispatcher->AddRef();

  return true;
}

bool SendMouseEventsImpl(MouseButton type, int state, Task* task) {
  DWORD down_flags = MOUSEEVENTF_ABSOLUTE;
  DWORD up_flags = MOUSEEVENTF_ABSOLUTE;
  UINT last_event;

  switch (type) {
    case LEFT:
      down_flags |= MOUSEEVENTF_LEFTDOWN;
      up_flags |= MOUSEEVENTF_LEFTUP;
      last_event = (state & UP) ? WM_LBUTTONUP : WM_LBUTTONDOWN;
      break;

    case MIDDLE:
      down_flags |= MOUSEEVENTF_MIDDLEDOWN;
      up_flags |= MOUSEEVENTF_MIDDLEUP;
      last_event = (state & UP) ? WM_MBUTTONUP : WM_MBUTTONDOWN;
      break;

    case RIGHT:
      down_flags |= MOUSEEVENTF_RIGHTDOWN;
      up_flags |= MOUSEEVENTF_RIGHTUP;
      last_event = (state & UP) ? WM_RBUTTONUP : WM_RBUTTONDOWN;
      break;

    default:
      NOTREACHED();
      return false;
  }

  scoped_refptr<InputDispatcher> dispatcher(
      task ? new InputDispatcher(task, last_event) : NULL);

  INPUT input = { 0 };
  input.type = INPUT_MOUSE;
  input.mi.dwFlags = down_flags;
  if ((state & DOWN) && !::SendInput(1, &input, sizeof(INPUT)))
    return false;

  input.mi.dwFlags = up_flags;
  if ((state & UP) && !::SendInput(1, &input, sizeof(INPUT)))
    return false;

  if (dispatcher.get())
    dispatcher->AddRef();

  return true;
}

}  // namespace

// public functions -----------------------------------------------------------

bool SendKeyPress(gfx::NativeWindow window, app::KeyboardCode key,
                  bool control, bool shift, bool alt, bool command) {
  DCHECK(command == false);  // No command key on Windows
  return SendKeyPressImpl(key, control, shift, alt, NULL);
}

bool SendKeyPressNotifyWhenDone(gfx::NativeWindow window,
                                app::KeyboardCode key,
                                bool control, bool shift, bool alt,
                                bool command,
                                Task* task) {
  DCHECK(command == false);  // No command key on Windows
  return SendKeyPressImpl(key, control, shift, alt, task);
}

bool SendMouseMove(long x, long y) {
  return SendMouseMoveImpl(x, y, NULL);
}

bool SendMouseMoveNotifyWhenDone(long x, long y, Task* task) {
  return SendMouseMoveImpl(x, y, task);
}

bool SendMouseEvents(MouseButton type, int state) {
  return SendMouseEventsImpl(type, state, NULL);
}

bool SendMouseEventsNotifyWhenDone(MouseButton type, int state, Task* task) {
  return SendMouseEventsImpl(type, state, task);
}

bool SendMouseClick(MouseButton type) {
  return SendMouseEventsImpl(type, UP | DOWN, NULL);
}

void MoveMouseToCenterAndPress(views::View* view, MouseButton button,
                               int state, Task* task) {
  DCHECK(view);
  DCHECK(view->GetWidget());
  gfx::Point view_center(view->width() / 2, view->height() / 2);
  views::View::ConvertPointToScreen(view, &view_center);
  SendMouseMove(view_center.x(), view_center.y());
  SendMouseEventsNotifyWhenDone(button, state, task);
}

}  // ui_controls
<|endoftext|>


<commit_before>#include "APICamera.hpp"

// Messages
#include "camera_application/InitializeCameraService.h"
#include "camera_application/PictureSendingActivation.h"
#include "camera_application/CalibrateCamera.h"

#include <string>
#include <stdexcept>

using namespace kitrokopter;

/**
 * Constructs an APICamera.
 *
 * @param newId the cameras id
 */
APICamera::APICamera(uint32_t newId) :
    calibrated(false),
    calibration(NULL),
    position(Vector()),
    hardwareId(0)
{
    this->id = newId;
}

/**
 * Destructs an APICamera.
 */
APICamera::~APICamera()
{
    if (calibration)
	delete calibration;
}

uint32_t APICamera::getId()
{
    return this->id;
}

void APICamera::listen()
{
    ros::NodeHandle nh;
    pictureSubscriber = nh.subscribe("Picture", 1, &APICamera::handlePicture, this);
    pictureSendingActivationPublisher = nh.advertise<camera_application::PictureSendingActivation>("PictureSendingActivation", 1);
}

/**
 * Sets the camera's position.
 */
void APICamera::setPosition(double x, double y, double z)
{
    position = Vector(x, y, z);
}

/**
 * Sets calibration data.
 *
 * @param data The calibration data to set.
 */
void APICamera::setCalibrationData(APICalibrationData data)
{
    if (calibration)
	*calibration = data;
    else
	calibration = new APICalibrationData(data);
    /**
     * TODO: Can we do this now? Is there a hardware id?
     */
}

/**
 * @return The calibration data.
 */
APICalibrationData* const APICamera::getCalibrationData()
{
    return calibration;
}

/**
 * Add an calibration image. This will not send this image to the control_application.
 *
 * @param image the image to add
 */
void APICamera::addCalibrationImage(cv::Mat image) {
    this->calibrationImages.push_back(image);
}

/**
 * Get all calibration images
 *
 * @return all images which were used for calibration
 */
std::vector<cv::Mat> APICamera::getAllCalibrationImages() {
    return this->calibrationImages;
}

/**
 * @return Whether the camera is calibrated.
 */
bool APICamera::isCalibrated()
{
    return calibrated;
}

/**
 * Deletes this camera's calibration.
 */
void APICamera::deleteCalibration()
{
    calibrated = false;

    /**
     * TODO: Is there something to send to the camera?
     */
}

/**
 * Adds an image listener.
 *
 * The image listener will receive images this camera takes.
 *
 * @param listener A pointer to the listener.
 */
void APICamera::addImageListener(APIImageListener *listener)
{
    imageListeners.push_back(listener);
}

/**
 * Adds an camera listener.
 *
 * @param listener A pointer to the listener.
 */
void APICamera::addCameraListener(APICameraListener *listener)
{
    cameraListeners.push_back(listener);
}

template <typename T>
void removeListener(std::vector<T*> from, T *listener)
{
    for (typename std::vector<T*>::iterator it = from.begin(); it != from.end(); ++it) {
	if (*it == listener) {
	    from.erase(it);
	    return;
	}
    }
}

/**
 * Removes an image listener.
 *
 * Remember to free it!
 *
 * @param listener A pointer to the listener.
 */
void APICamera::removeImageListener(APIImageListener *listener)
{
    removeListener(imageListeners, listener);
}

/**
 * Removes an camera listener.
 *
 * Remember to free it!
 *
 * @param listener A pointer to the listener.
 */
void APICamera::removeCameraListener(APICameraListener *listener)
{
    removeListener(cameraListeners, listener);
}

/**
 * Sends a message requesting pictures to be or not to be sent.
 *
 * @param active `true` will enable image sending, `false` will disable.
 */
void APICamera::sendPictureSendingActivation(bool active)
{
    camera_application::PictureSendingActivation msg;
    msg.ID = this->id;
    msg.active = active;
    msg.all = false;
    pictureSendingActivationPublisher.publish(msg);
}

cv::Mat* msgToMat(camera_application::Picture::_image_type data)
{
    /*
     * TODO: Is there a possibility to make the size of the image variable?
     * this hardcoded thing is pretty ugly...
     */
    cv::Mat *mat = new cv::Mat(cv::Size(640, 480), CV_8UC3);
    //640 * 480 * 3 = 921600
    for (size_t i = 0; i < (921600); i++) {
	mat->data[i] = data[i];
    }
    return mat;
}

/**
 * Handles incoming pictures.
 */
void APICamera::handlePicture(const camera_application::Picture::Ptr &msg)
{
    if (msg->ID != this->id) return;
    cv::Mat* image = msgToMat(msg->image);
    this->lastImage = *image;
    //call the listeners
    for (std::vector<APIImageListener*>::iterator it = imageListeners.begin(); it != imageListeners.end(); ++it) {
       (*it)->imageReceived(*image);
    }
    delete image;
}

Vector APICamera::getPosition()
{
	return position;
}
<commit_msg>Fix camera image listener removal not working<commit_after>#include "APICamera.hpp"

// Messages
#include "camera_application/InitializeCameraService.h"
#include "camera_application/PictureSendingActivation.h"
#include "camera_application/CalibrateCamera.h"

#include <string>
#include <stdexcept>

using namespace kitrokopter;

/**
 * Constructs an APICamera.
 *
 * @param newId the cameras id
 */
APICamera::APICamera(uint32_t newId) :
    calibrated(false),
    calibration(NULL),
    position(Vector()),
    hardwareId(0)
{
    this->id = newId;
}

/**
 * Destructs an APICamera.
 */
APICamera::~APICamera()
{
    if (calibration)
	delete calibration;
}

uint32_t APICamera::getId()
{
    return this->id;
}

void APICamera::listen()
{
    ros::NodeHandle nh;
    pictureSubscriber = nh.subscribe("Picture", 1, &APICamera::handlePicture, this);
    pictureSendingActivationPublisher = nh.advertise<camera_application::PictureSendingActivation>("PictureSendingActivation", 1);
}

/**
 * Sets the camera's position.
 */
void APICamera::setPosition(double x, double y, double z)
{
    position = Vector(x, y, z);
}

/**
 * Sets calibration data.
 *
 * @param data The calibration data to set.
 */
void APICamera::setCalibrationData(APICalibrationData data)
{
    if (calibration)
	*calibration = data;
    else
	calibration = new APICalibrationData(data);
    /**
     * TODO: Can we do this now? Is there a hardware id?
     */
}

/**
 * @return The calibration data.
 */
APICalibrationData* const APICamera::getCalibrationData()
{
    return calibration;
}

/**
 * Add an calibration image. This will not send this image to the control_application.
 *
 * @param image the image to add
 */
void APICamera::addCalibrationImage(cv::Mat image) {
    this->calibrationImages.push_back(image);
}

/**
 * Get all calibration images
 *
 * @return all images which were used for calibration
 */
std::vector<cv::Mat> APICamera::getAllCalibrationImages() {
    return this->calibrationImages;
}

/**
 * @return Whether the camera is calibrated.
 */
bool APICamera::isCalibrated()
{
    return calibrated;
}

/**
 * Deletes this camera's calibration.
 */
void APICamera::deleteCalibration()
{
    calibrated = false;

    /**
     * TODO: Is there something to send to the camera?
     */
}

/**
 * Adds an image listener.
 *
 * The image listener will receive images this camera takes.
 *
 * @param listener A pointer to the listener.
 */
void APICamera::addImageListener(APIImageListener *listener)
{
    imageListeners.push_back(listener);
}

/**
 * Adds an camera listener.
 *
 * @param listener A pointer to the listener.
 */
void APICamera::addCameraListener(APICameraListener *listener)
{
    cameraListeners.push_back(listener);
}

template <typename T>
void removeListener(std::vector<T*> &from, T *listener)
{
    for (typename std::vector<T*>::iterator it = from.begin(); it != from.end(); ++it) {
	if (*it == listener) {
	    from.erase(it);
	    return;
	}
    }
}

/**
 * Removes an image listener.
 *
 * Remember to free it!
 *
 * @param listener A pointer to the listener.
 */
void APICamera::removeImageListener(APIImageListener *listener)
{
    removeListener(imageListeners, listener);
}

/**
 * Removes an camera listener.
 *
 * Remember to free it!
 *
 * @param listener A pointer to the listener.
 */
void APICamera::removeCameraListener(APICameraListener *listener)
{
    removeListener(cameraListeners, listener);
}

/**
 * Sends a message requesting pictures to be or not to be sent.
 *
 * @param active `true` will enable image sending, `false` will disable.
 */
void APICamera::sendPictureSendingActivation(bool active)
{
    camera_application::PictureSendingActivation msg;
    msg.ID = this->id;
    msg.active = active;
    msg.all = false;
    pictureSendingActivationPublisher.publish(msg);
}

cv::Mat* msgToMat(camera_application::Picture::_image_type data)
{
    /*
     * TODO: Is there a possibility to make the size of the image variable?
     * this hardcoded thing is pretty ugly...
     */
    cv::Mat *mat = new cv::Mat(cv::Size(640, 480), CV_8UC3);
    //640 * 480 * 3 = 921600
    for (size_t i = 0; i < (921600); i++) {
	mat->data[i] = data[i];
    }
    return mat;
}

/**
 * Handles incoming pictures.
 */
void APICamera::handlePicture(const camera_application::Picture::Ptr &msg)
{
    if (msg->ID != this->id) return;
    cv::Mat* image = msgToMat(msg->image);
    this->lastImage = *image;
    //call the listeners
    for (std::vector<APIImageListener*>::iterator it = imageListeners.begin(); it != imageListeners.end(); ++it) {
       (*it)->imageReceived(*image);
    }
    delete image;
}

Vector APICamera::getPosition()
{
	return position;
}
<|endoftext|>


<commit_before>/**************************************************************************

 The MIT License (MIT)

 Copyright (c) 2015 Dmitry Sovetov

 https://github.com/dmsovetov

 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.

 **************************************************************************/

#include "ServerHandler.h"
#include "Connection.h"

DC_BEGIN_DREEMCHEST

namespace net {

// --------------------------------------- ServerHandler -------------------------------------- //

// ** ServerHandler::ServerHandler
ServerHandler::ServerHandler( const TCPSocketListenerPtr& socketListener ) : m_socketListener( socketListener )
{
}

// ** ServerHandler::create
ServerHandlerPtr ServerHandler::create( u16 port )
{
	ServerSocketDelegate* serverDelegate = DC_NEW ServerSocketDelegate;
	TCPSocketListenerPtr  socketListener = TCPSocketListener::bindTo( port, serverDelegate );

	if( socketListener == NULL ) {
		return ServerHandlerPtr();
	}

	ServerHandler* serverHandler    = DC_NEW ServerHandler( socketListener );
	serverDelegate->m_serverHandler = serverHandler;

	return ServerHandlerPtr( serverHandler );
}

// ** ServerHandler::update
void ServerHandler::update( void )
{
	NetworkHandler::update();
	m_socketListener->update();
}

// ** ServerHandler::handleDetectServersPacket
bool ServerHandler::handleDetectServersPacket( ConnectionPtr& connection, packets::DetectServers& packet )
{
	return true;
}

// ** ServerHandler::processClientConnection
void ServerHandler::processClientConnection( TCPSocket* socket )
{
	log::verbose( "Client %s connected to server\n", socket->address().toString() );

	ConnectionPtr connection = createConnection( socket );
	connection->send<packets::Time>( UnixTime::current().value() );
}

// ** ServerHandler::processClientDisconnection
void ServerHandler::processClientDisconnection( TCPSocket* socket )
{
	log::verbose( "Client %s dicconnected from server\n", socket->address().toString() );
	removeConnection( socket );
}

// ** ServerHandler::eventListeners
ConnectionList ServerHandler::eventListeners( void ) const
{
    const TCPSocketList& sockets = m_socketListener->connections();

    ConnectionList connections;
    for( TCPSocketList::const_iterator i = sockets.begin(), end = sockets.end(); i != end; ++i ) {
		ConnectionPtr connection = findConnectionBySocket( const_cast<TCPSocket*>( i->get() ) );
		if( connection == ConnectionPtr() ) {
			log::msg( "ServerHandler::eventListeners : null\n" );
			continue;
		}

        connections.push_back( connection );
    }

	return connections;
}

// ** ServerHandler::handleTimePacket
bool ServerHandler::handleTimePacket( ConnectionPtr& connection, packets::Time& packet )
{
	s32 roundTripTime = UnixTime::current() - packet.timestamp;

	if( abs( packet.roundTripTime - roundTripTime ) > 1 ) {
		packet.roundTripTime = roundTripTime;
		return NetworkHandler::handleTimePacket( connection, packet );
	}

	return true;
}

// ---------------------------------------- ServerSocketDelegate ------------------------------------//

// ** ServerSocketDelegate::handleReceivedData
void ServerSocketDelegate::handleReceivedData( TCPSocketListener* sender, TCPSocket* socket, TCPStream* stream )
{
	m_serverHandler->processReceivedData( socket, stream );
}

// ** ServerSocketDelegate::handleConnectionAccepted
void ServerSocketDelegate::handleConnectionAccepted( TCPSocketListener* sender, TCPSocket* socket )
{
	m_serverHandler->processClientConnection( socket );
}

// ** ServerSocketDelegate::handleConnectionClosed
void ServerSocketDelegate::handleConnectionClosed( TCPSocketListener* sender, TCPSocket* socket )
{
	m_serverHandler->processClientDisconnection( socket );
}

/*
// ** NetworkServerHandler::NetworkServerHandler
NetworkServerHandler::NetworkServerHandler( void ) : m_time( 0 )
{

}

NetworkServerHandler::~NetworkServerHandler( void )
{

}

// ** NetworkServerHandler::Start
bool NetworkServerHandler::Start( u16 port )
{
    if( IsConnected() ) {
        DC_BREAK
        return false;
    }

    // ** Connect sockets
    bool tcpConnected = m_netTCP->Connect( NULL, port );

    // ** Check connection
    if( !tcpConnected ) {
        ProcessFailure();
        return false;
    }

    // ** Attach listeners
    m_netTCP->AttachListener( TCPSocketEvent::ConnectionAccepted,   dcThisMethod( NetworkServerHandler::OnConnectionAccepted  ) );
    m_netTCP->AttachListener( TCPSocketEvent::ConnectionClosed,     dcThisMethod( NetworkServerHandler::OnConnectionClosed    ) );

    // ** Process successfull connection
    ProcessConnection( NetworkAddress::Localhost );

    return true;
}

// ** NetworkServerHandler::Update
bool NetworkServerHandler::Update( int dt )
{
    if( !NetworkHandler::Update( dt ) ) {
        return false;
    }

    m_time += dt;
    return true;
}

// ** NetworkServerHandler::ProcessAcceptedConnection
void NetworkServerHandler::ProcessAcceptedConnection( const NetworkAddress& address, int connection )
{
	DC_BREAK
//    DispatchEvent( NetworkHandlerEvent::ConnectionAccepted, NetworkHandlerEvent::OnConnectionAccepted( connection, address ) );
}

// ** NetworkServerHandler::ProcessClosedConnection
void NetworkServerHandler::ProcessClosedConnection( int connection )
{
	DC_BREAK
//    DispatchEvent( NetworkHandlerEvent::ConnectionClosed, NetworkHandlerEvent::OnConnectionClosed( connection ) );
}

// ** NetworkServerHandler::ProcessReceivedPacket
void NetworkServerHandler::ProcessReceivedPacket( int packetId, const INetworkPacket *packet, const NetworkAddress& address, int connection )
{
    switch( packetId ) {
    case sTimeSyncPacket::PacketId: {
                                        DC_ENSURE_TYPE( packet, sTimeSyncPacket );
                                        sTimeSyncPacket sync = *( sTimeSyncPacket* )packet;

                                        // ** Send pong packet
                                        sync.localTime = m_time;
                                        SendPacket( sTimeSyncPacket::PacketId, &sync, connection );
                                    }
                                    break;

    default:    NetworkHandler::ProcessReceivedPacket( packetId, packet, address, connection );
                break;
    }
}

// ** NetworkServerHandler::OnConnectionAccepted
void NetworkServerHandler::OnConnectionAccepted( const dcEvent e )
{
    dcTCPSocketEvent se = ( dcTCPSocketEvent )e;

    ProcessAcceptedConnection( se->m_address, se->m_connection );
}

// ** NetworkServerHandler::OnConnectionClosed
void NetworkServerHandler::OnConnectionClosed( const dcEvent e )
{
    ProcessClosedConnection( static_cast<dcTCPSocketEvent>( e )->m_connection );
}*/

} // namespace net

DC_END_DREEMCHEST
<commit_msg>Fixed time syncronization<commit_after>/**************************************************************************

 The MIT License (MIT)

 Copyright (c) 2015 Dmitry Sovetov

 https://github.com/dmsovetov

 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.

 **************************************************************************/

#include "ServerHandler.h"
#include "Connection.h"

DC_BEGIN_DREEMCHEST

namespace net {

// --------------------------------------- ServerHandler -------------------------------------- //

// ** ServerHandler::ServerHandler
ServerHandler::ServerHandler( const TCPSocketListenerPtr& socketListener ) : m_socketListener( socketListener )
{
}

// ** ServerHandler::create
ServerHandlerPtr ServerHandler::create( u16 port )
{
	ServerSocketDelegate* serverDelegate = DC_NEW ServerSocketDelegate;
	TCPSocketListenerPtr  socketListener = TCPSocketListener::bindTo( port, serverDelegate );

	if( socketListener == NULL ) {
		return ServerHandlerPtr();
	}

	ServerHandler* serverHandler    = DC_NEW ServerHandler( socketListener );
	serverDelegate->m_serverHandler = serverHandler;

	return ServerHandlerPtr( serverHandler );
}

// ** ServerHandler::update
void ServerHandler::update( void )
{
	NetworkHandler::update();
	m_socketListener->update();
}

// ** ServerHandler::handleDetectServersPacket
bool ServerHandler::handleDetectServersPacket( ConnectionPtr& connection, packets::DetectServers& packet )
{
	return true;
}

// ** ServerHandler::processClientConnection
void ServerHandler::processClientConnection( TCPSocket* socket )
{
	log::verbose( "Client %s connected to server\n", socket->address().toString() );

	ConnectionPtr connection = createConnection( socket );
	connection->send<packets::Time>( UnixTime::current().value() );
}

// ** ServerHandler::processClientDisconnection
void ServerHandler::processClientDisconnection( TCPSocket* socket )
{
	log::verbose( "Client %s dicconnected from server\n", socket->address().toString() );
	removeConnection( socket );
}

// ** ServerHandler::eventListeners
ConnectionList ServerHandler::eventListeners( void ) const
{
    const TCPSocketList& sockets = m_socketListener->connections();

    ConnectionList connections;
    for( TCPSocketList::const_iterator i = sockets.begin(), end = sockets.end(); i != end; ++i ) {
		ConnectionPtr connection = findConnectionBySocket( const_cast<TCPSocket*>( i->get() ) );
		if( connection == ConnectionPtr() ) {
			log::msg( "ServerHandler::eventListeners : null\n" );
			continue;
		}

        connections.push_back( connection );
    }

	return connections;
}

// ** ServerHandler::handleTimePacket
bool ServerHandler::handleTimePacket( ConnectionPtr& connection, packets::Time& packet )
{
	s32 roundTripTime = UnixTime::current() - packet.timestamp;

	if( abs( packet.roundTripTime - roundTripTime ) > 1 ) {
		packet.timestamp	 = UnixTime::current().value();
		packet.roundTripTime = roundTripTime;
		return NetworkHandler::handleTimePacket( connection, packet );
	}

	return true;
}

// ---------------------------------------- ServerSocketDelegate ------------------------------------//

// ** ServerSocketDelegate::handleReceivedData
void ServerSocketDelegate::handleReceivedData( TCPSocketListener* sender, TCPSocket* socket, TCPStream* stream )
{
	m_serverHandler->processReceivedData( socket, stream );
}

// ** ServerSocketDelegate::handleConnectionAccepted
void ServerSocketDelegate::handleConnectionAccepted( TCPSocketListener* sender, TCPSocket* socket )
{
	m_serverHandler->processClientConnection( socket );
}

// ** ServerSocketDelegate::handleConnectionClosed
void ServerSocketDelegate::handleConnectionClosed( TCPSocketListener* sender, TCPSocket* socket )
{
	m_serverHandler->processClientDisconnection( socket );
}

/*
// ** NetworkServerHandler::NetworkServerHandler
NetworkServerHandler::NetworkServerHandler( void ) : m_time( 0 )
{

}

NetworkServerHandler::~NetworkServerHandler( void )
{

}

// ** NetworkServerHandler::Start
bool NetworkServerHandler::Start( u16 port )
{
    if( IsConnected() ) {
        DC_BREAK
        return false;
    }

    // ** Connect sockets
    bool tcpConnected = m_netTCP->Connect( NULL, port );

    // ** Check connection
    if( !tcpConnected ) {
        ProcessFailure();
        return false;
    }

    // ** Attach listeners
    m_netTCP->AttachListener( TCPSocketEvent::ConnectionAccepted,   dcThisMethod( NetworkServerHandler::OnConnectionAccepted  ) );
    m_netTCP->AttachListener( TCPSocketEvent::ConnectionClosed,     dcThisMethod( NetworkServerHandler::OnConnectionClosed    ) );

    // ** Process successfull connection
    ProcessConnection( NetworkAddress::Localhost );

    return true;
}

// ** NetworkServerHandler::Update
bool NetworkServerHandler::Update( int dt )
{
    if( !NetworkHandler::Update( dt ) ) {
        return false;
    }

    m_time += dt;
    return true;
}

// ** NetworkServerHandler::ProcessAcceptedConnection
void NetworkServerHandler::ProcessAcceptedConnection( const NetworkAddress& address, int connection )
{
	DC_BREAK
//    DispatchEvent( NetworkHandlerEvent::ConnectionAccepted, NetworkHandlerEvent::OnConnectionAccepted( connection, address ) );
}

// ** NetworkServerHandler::ProcessClosedConnection
void NetworkServerHandler::ProcessClosedConnection( int connection )
{
	DC_BREAK
//    DispatchEvent( NetworkHandlerEvent::ConnectionClosed, NetworkHandlerEvent::OnConnectionClosed( connection ) );
}

// ** NetworkServerHandler::ProcessReceivedPacket
void NetworkServerHandler::ProcessReceivedPacket( int packetId, const INetworkPacket *packet, const NetworkAddress& address, int connection )
{
    switch( packetId ) {
    case sTimeSyncPacket::PacketId: {
                                        DC_ENSURE_TYPE( packet, sTimeSyncPacket );
                                        sTimeSyncPacket sync = *( sTimeSyncPacket* )packet;

                                        // ** Send pong packet
                                        sync.localTime = m_time;
                                        SendPacket( sTimeSyncPacket::PacketId, &sync, connection );
                                    }
                                    break;

    default:    NetworkHandler::ProcessReceivedPacket( packetId, packet, address, connection );
                break;
    }
}

// ** NetworkServerHandler::OnConnectionAccepted
void NetworkServerHandler::OnConnectionAccepted( const dcEvent e )
{
    dcTCPSocketEvent se = ( dcTCPSocketEvent )e;

    ProcessAcceptedConnection( se->m_address, se->m_connection );
}

// ** NetworkServerHandler::OnConnectionClosed
void NetworkServerHandler::OnConnectionClosed( const dcEvent e )
{
    ProcessClosedConnection( static_cast<dcTCPSocketEvent>( e )->m_connection );
}*/

} // namespace net

DC_END_DREEMCHEST
<|endoftext|>


<commit_before>/**
 * 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 3 of the License, or
 * 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, see <http://www.gnu.org/licenses/>.
 */

/**
 * Contact: philipp.rescheneder@univie.ac.at
 */

#include "ArgParser.h"

#include <string.h>
#include <tclap/CmdLine.h>
#include <sstream>

#include "ArgParseOutput.h"
#include "Version.h"
#include "Log.h"
#include "PlatformSpecifics.h"

#undef module_name
#define module_name "ARGPARSER"

ArgParser::ArgParser(int argc, char * * argv) {

	outDefault = "stdout";
	noneDefault = "none";

	ParseArguments(argc, (char const * *) argv);
}

ArgParser::~ArgParser() {

}

char * ArgParser::fromString(std::string str) {
	char * cstr = 0;
	if(str.size() > 0 && str != outDefault && str != noneDefault) {
		cstr = new char[str.size() + 1];
		strcpy(cstr, str.c_str());
	}
	return cstr;
}

template<typename T>
void printParameter(std::stringstream & usage, TCLAP::ValueArg<T> & arg) {

	usage << "    " <<  arg.longID() << std::endl;
	usage << "        " << arg.getDescription();
	if(!arg.isRequired()) {
		usage << " [" << arg.getValue() << "]";
	}
	usage << std::endl;
}

void printParameter(std::stringstream & usage, TCLAP::SwitchArg & arg) {

	usage << "    " <<  arg.longID() << std::endl;
	usage << "        " << arg.getDescription();
	if(!arg.isRequired()) {
		usage << " [" << (arg.getValue() ? "true" : "false") << "]";
	}
	usage << std::endl;
}

void ArgParser::ParseArguments(int argc, char const * argv[]) {

	argv[0] = "ngmlr";

	TCLAP::CmdLine cmd("", ' ', "", true);

	TCLAP::ValueArg<std::string> queryArg("q", "query", "Path to the read file (FASTA/Q)", true, noneDefault, "file", cmd);
	TCLAP::ValueArg<std::string> refArg("r", "reference", "Path to the reference genome (FASTA/Q, can be gzipped)", true, noneDefault, "file", cmd);
	TCLAP::ValueArg<std::string> outArg("o", "output", "Path to output file", false, outDefault, "file", cmd);
	TCLAP::ValueArg<std::string> vcfArg("", "vcf", "SNPs will be taken into account when building reference index", false, noneDefault, "file", cmd);
	TCLAP::ValueArg<std::string> bedfilterArg("", "bed-filter", "Only reads in the regions specified by the BED file are read from the input file (requires BAM input)", false, noneDefault, "file", cmd);

	TCLAP::ValueArg<std::string> presetArgs("x", "presets", "Parameter presets for different sequencing technologies", false, "pacbio", "pacbio, ont", cmd);

	TCLAP::ValueArg<float> minIdentityArg("i", "min-identity", "Alignments with an identity lower than this threshold will be discarded", false, minIdentity, "0-1", cmd);
	TCLAP::ValueArg<float> minResiduesArg("R", "min-residues", "Alignments containing less than <int> or (<float> * read length) residues will be discarded", false, minResidues, "int/float", cmd);
	TCLAP::ValueArg<float> sensitivityArg("s", "sensitivity", "", false, sensitivity, "0-1", cmd);

	TCLAP::ValueArg<int> threadsArg("t", "threads", "Number of threads", false, 1, "int", cmd);

	TCLAP::ValueArg<int> binSizeArg("", "bin-size", "Sets the size of the grid used during candidate search", false, binSize, "int", cmd);
	TCLAP::ValueArg<int> kmerLengthArg("k", "kmer-length", "K-mer length in bases", false, kmerLength, "10-15", cmd);
	TCLAP::ValueArg<int> kmerSkipArg("", "kmer-skip", "Number of k-mers to skip when building the lookup table from the reference", false, kmerSkip, "int", cmd);
	TCLAP::ValueArg<int> maxInitialSegmentsArg("", "max-segments", "Max number of segments allowed for a read", false, maxInitialSegments, "int", cmd);
	TCLAP::ValueArg<float> scoreMatchArg("", "match", "Match score", false, scoreMatch, "float", cmd);
	TCLAP::ValueArg<float> scoreMismatchArg("", "mismatch", "Mismatch score", false, scoreMismatch, "float", cmd);
	TCLAP::ValueArg<float> scoreGapOpenArg("", "gap-open", "Gap open score", false, scoreGapOpen, "float", cmd);
	TCLAP::ValueArg<float> scoreGapExtendMaxArg("", "gap-extend-max", "Gap open extend max", false, scoreGapExtendMax, "float", cmd);
	TCLAP::ValueArg<float> scoreGapExtendMinArg("", "gap-extend-min", "Gap open extend min", false, scoreGapExtendMin, "float", cmd);
	TCLAP::ValueArg<float> scoreGapDecayArg("", "gap-decay", "Gap extend decay", false, scoreGapDecay, "float", cmd);
	TCLAP::ValueArg<int> stdoutArg("", "stdout", "Debug mode", false, stdoutMode, "0-7", cmd);
	TCLAP::ValueArg<int> subreadAligner("", "subread-aligner", "Choose subread aligning method", false, subreadaligner, "0-3", cmd);
	TCLAP::ValueArg<int> readpartLengthArg("", "subread-length", "Length of fragments reads are split into", false, readPartLength, "int", cmd);
	TCLAP::ValueArg<int> readpartCorridorArg("", "subread-corridor", "Length of corridor sub-reads are aligned with", false, readPartCorridor, "int", cmd);
	//csSearchTableLength = 0;
	//logLevel = 0; //16383, 255
	//minKmerHits = 0;
	//maxCMRs = INT_MAX;

	TCLAP::SwitchArg noprogressArg("", "no-progress", "Don't print progress info while mapping", cmd, false);
	TCLAP::SwitchArg verboseArg("", "verbose", "Debug output", cmd, false);
	//bam = false;
	TCLAP::SwitchArg colorArg("", "color", "Colored command line output", cmd, false);
	//hardClip = false;
	//log = false;
	TCLAP::SwitchArg lowqualitysplitArg("", "lowqualitysplit", "Split alignments with poor quality", cmd, false);
	TCLAP::SwitchArg nosmallInversionArg("", "no-smallinv", "Don't detect small inversions", cmd, false);
	TCLAP::SwitchArg printAllAlignmentsArg("", "print-all", "Print all alignments. Disable filtering. (debug)", cmd, false);
	//skipSave = false;
	//updateCheck = false;
	//writeUnmapped = true;
	TCLAP::SwitchArg noSSEArg("", "nosse", "Debug switch (don't use if you don't know what you are doing)", cmd, false);

	std::stringstream usage;
	usage << "" << std::endl;
	usage << "Usage: ngmlr [options] -r <reference> -q <reads> [-o <output>]" << std::endl;
	usage << "" << std::endl;
	usage << "Input/Output:" << std::endl;
	printParameter<std::string>(usage, refArg);
	printParameter<std::string>(usage, queryArg);
	printParameter<std::string>(usage, outArg);
	usage << "" << std::endl;
	usage << "General:" << std::endl;
	printParameter<int>(usage, threadsArg);
	printParameter<std::string>(usage, presetArgs);
	printParameter<float>(usage, minIdentityArg);
	printParameter<float>(usage, minResiduesArg);
	printParameter(usage, nosmallInversionArg);
	printParameter(usage, lowqualitysplitArg);
	printParameter(usage, verboseArg);
	printParameter(usage, noprogressArg);
	usage << "" << std::endl;
	usage << "Advanced:" << std::endl;
	printParameter<float>(usage, scoreMatchArg);
	printParameter<float>(usage, scoreMismatchArg);
	printParameter<float>(usage, scoreGapOpenArg);
	printParameter<float>(usage, scoreGapExtendMaxArg);
	printParameter<float>(usage, scoreGapExtendMinArg);
	printParameter<float>(usage, scoreGapDecayArg);
	printParameter<int>(usage, kmerLengthArg);
	printParameter<int>(usage, kmerSkipArg);
	printParameter<int>(usage, binSizeArg);
	printParameter<int>(usage, maxInitialSegmentsArg);
	printParameter<int>(usage, readpartLengthArg);
	printParameter<int>(usage, readpartCorridorArg);
	//printParameter<std::string>(usage, vcfArg);
	//printParameter<std::string>(usage, bedfilterArg);

	cmd.setOutput(new ArgParseOutput(usage.str(), ""));

	cmd.parse(argc, argv);

	queryFile = fromString(queryArg.getValue());
	referenceFile = fromString(refArg.getValue());
	outputFile = fromString(outArg.getValue());
	vcfFile = fromString(vcfArg.getValue());
	bedFile = fromString(bedfilterArg.getValue());

	minIdentity = minIdentityArg.getValue();
	minResidues = minResiduesArg.getValue();

	binSize = binSizeArg.getValue();
	kmerLength = kmerLengthArg.getValue();
	threads = threadsArg.getValue();
	kmerSkip = kmerSkipArg.getValue();
	maxInitialSegments = maxInitialSegmentsArg.getValue();
	scoreMatch = scoreMatchArg.getValue();
	if(scoreMatch < 0.0f) {
		Log.Message("--match must not be smaller than zero. changing from %f to %f", scoreMatch, scoreMatch * -1.0f);
		scoreMatch = scoreMatch * -1.0f;
	}
	scoreMismatch = scoreMismatchArg.getValue();
	if (scoreMismatch > 0.0f) {
		Log.Message("--mismatch must not be greater than zero. changing from %f to %f", scoreMismatch, scoreMismatch * -1.0f);
		scoreMismatch = scoreMismatch * -1.0f;
	}
	scoreGapOpen = scoreGapOpenArg.getValue();
	if (scoreGapOpen > 0.0f) {
		Log.Message("--gap-open must not be greater than zero. changing from %f to %f", scoreGapOpen, scoreGapOpen * -1.0f);
		scoreGapOpen = scoreGapOpen * -1.0f;
	}
	scoreGapExtendMax = scoreGapExtendMaxArg.getValue();
	if (scoreGapExtendMax > 0.0f) {
		Log.Message("--gap-extend-max must not be greater than zero. changing from %f to %f", scoreGapExtendMax, scoreGapExtendMax * -1.0f);
		scoreGapExtendMax = scoreGapExtendMax * -1.0f;
	}
	scoreGapExtendMin = scoreGapExtendMinArg.getValue();
	if (scoreGapExtendMin > 0.0f) {
		Log.Message("--gap-extend-min must not be greater than zero. changing from %f to %f", scoreGapExtendMin, scoreGapExtendMin * -1.0f);
		scoreGapExtendMin = scoreGapExtendMin * -1.0f;
	}
	scoreGapDecay = scoreGapDecayArg.getValue();
	if (scoreGapDecay < 0.0f) {
		Log.Message("--gap-decay must not be smaller than zero. changing from %f to %f", scoreGapDecay, scoreGapDecay * -1.0f);
		scoreGapDecay = scoreGapDecay * -1.0f;
	}
	subreadaligner = subreadAligner.getValue();
	stdoutMode = stdoutArg.getValue();
	readPartCorridor = readpartCorridorArg.getValue();
	readPartLength = readpartLengthArg.getValue();

	progress = !noprogressArg.getValue();
	color = colorArg.getValue();
	verbose = verboseArg.getValue();
	lowQualitySplit = lowqualitysplitArg.getValue();
	smallInversionDetection = !nosmallInversionArg.getValue();
	printAllAlignments = printAllAlignmentsArg.getValue();
	nosse = noSSEArg.getValue();

	if (presetArgs.getValue() == "pacbio") {
		//Do nothing. Defaults are for Pacbio
	} else if (presetArgs.getValue() == "ont") {
		lowQualitySplit = (lowqualitysplitArg.isSet()) ? lowQualitySplit : false;
		smallInversionDetection = (nosmallInversionArg.isSet()) ? smallInversionDetection : false;
		scoreMatch = (scoreMatchArg.isSet()) ? scoreMatch : 3;
		scoreMismatch = (scoreMatchArg.isSet()) ? scoreMismatch : -7;
		//scoreGapOpen = (scoreGapOpenArg.isSet()) ? scoreGapOpen : -1;
		//scoreGapExtendMax = (scoreGapExtendMaxArg.isSet()) ? scoreGapExtendMax : -1;
		//scoreGapExtendMax = (scoreGapExtendMinArg.isSet()) ? scoreGapExtendMin : -0.5;
		scoreGapDecay = (scoreGapDecayArg.isSet()) ? scoreGapDecay : 0.10;
	} else {
		std::cerr << "Preset " << presetArgs.getValue() << " not found" << std::endl;
	}

	std::stringstream fullCmd;
	fullCmd << std::string(argv[0]);
	for(int i = 1; i < argc; ++i) {
		fullCmd << " " << std::string(argv[i]);
	}
	fullCommandLineCall = fromString(fullCmd.str());

	if(!FileExists(queryFile)) {
		Log.Error("Query file (%s) does not exist.", queryFile);
	}
	if(!FileExists(referenceFile)) {
		Log.Error("Reference file (%s) does not exist.", referenceFile);
	}
	if(bedFile != 0 && !FileExists(bedFile)) {
		Log.Error("BED filter file (%s) does not exist.", bedFile);
	}
	if(vcfFile != 0 && !FileExists(vcfFile)) {
		Log.Error("SNP file (%s) does not exist.", vcfFile);
	}
}

<commit_msg>lowqualitysplit default on<commit_after>/**
 * 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 3 of the License, or
 * 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, see <http://www.gnu.org/licenses/>.
 */

/**
 * Contact: philipp.rescheneder@univie.ac.at
 */

#include "ArgParser.h"

#include <string.h>
#include <tclap/CmdLine.h>
#include <sstream>

#include "ArgParseOutput.h"
#include "Version.h"
#include "Log.h"
#include "PlatformSpecifics.h"

#undef module_name
#define module_name "ARGPARSER"

ArgParser::ArgParser(int argc, char * * argv) {

	outDefault = "stdout";
	noneDefault = "none";

	ParseArguments(argc, (char const * *) argv);
}

ArgParser::~ArgParser() {

}

char * ArgParser::fromString(std::string str) {
	char * cstr = 0;
	if(str.size() > 0 && str != outDefault && str != noneDefault) {
		cstr = new char[str.size() + 1];
		strcpy(cstr, str.c_str());
	}
	return cstr;
}

template<typename T>
void printParameter(std::stringstream & usage, TCLAP::ValueArg<T> & arg) {

	usage << "    " <<  arg.longID() << std::endl;
	usage << "        " << arg.getDescription();
	if(!arg.isRequired()) {
		usage << " [" << arg.getValue() << "]";
	}
	usage << std::endl;
}

void printParameter(std::stringstream & usage, TCLAP::SwitchArg & arg) {

	usage << "    " <<  arg.longID() << std::endl;
	usage << "        " << arg.getDescription();
	if(!arg.isRequired()) {
		usage << " [" << (arg.getValue() ? "true" : "false") << "]";
	}
	usage << std::endl;
}

void ArgParser::ParseArguments(int argc, char const * argv[]) {

	argv[0] = "ngmlr";

	TCLAP::CmdLine cmd("", ' ', "", true);

	TCLAP::ValueArg<std::string> queryArg("q", "query", "Path to the read file (FASTA/Q)", true, noneDefault, "file", cmd);
	TCLAP::ValueArg<std::string> refArg("r", "reference", "Path to the reference genome (FASTA/Q, can be gzipped)", true, noneDefault, "file", cmd);
	TCLAP::ValueArg<std::string> outArg("o", "output", "Path to output file", false, outDefault, "file", cmd);
	TCLAP::ValueArg<std::string> vcfArg("", "vcf", "SNPs will be taken into account when building reference index", false, noneDefault, "file", cmd);
	TCLAP::ValueArg<std::string> bedfilterArg("", "bed-filter", "Only reads in the regions specified by the BED file are read from the input file (requires BAM input)", false, noneDefault, "file", cmd);

	TCLAP::ValueArg<std::string> presetArgs("x", "presets", "Parameter presets for different sequencing technologies", false, "pacbio", "pacbio, ont", cmd);

	TCLAP::ValueArg<float> minIdentityArg("i", "min-identity", "Alignments with an identity lower than this threshold will be discarded", false, minIdentity, "0-1", cmd);
	TCLAP::ValueArg<float> minResiduesArg("R", "min-residues", "Alignments containing less than <int> or (<float> * read length) residues will be discarded", false, minResidues, "int/float", cmd);
	TCLAP::ValueArg<float> sensitivityArg("s", "sensitivity", "", false, sensitivity, "0-1", cmd);

	TCLAP::ValueArg<int> threadsArg("t", "threads", "Number of threads", false, 1, "int", cmd);

	TCLAP::ValueArg<int> binSizeArg("", "bin-size", "Sets the size of the grid used during candidate search", false, binSize, "int", cmd);
	TCLAP::ValueArg<int> kmerLengthArg("k", "kmer-length", "K-mer length in bases", false, kmerLength, "10-15", cmd);
	TCLAP::ValueArg<int> kmerSkipArg("", "kmer-skip", "Number of k-mers to skip when building the lookup table from the reference", false, kmerSkip, "int", cmd);
	TCLAP::ValueArg<int> maxInitialSegmentsArg("", "max-segments", "Max number of segments allowed for a read", false, maxInitialSegments, "int", cmd);
	TCLAP::ValueArg<float> scoreMatchArg("", "match", "Match score", false, scoreMatch, "float", cmd);
	TCLAP::ValueArg<float> scoreMismatchArg("", "mismatch", "Mismatch score", false, scoreMismatch, "float", cmd);
	TCLAP::ValueArg<float> scoreGapOpenArg("", "gap-open", "Gap open score", false, scoreGapOpen, "float", cmd);
	TCLAP::ValueArg<float> scoreGapExtendMaxArg("", "gap-extend-max", "Gap open extend max", false, scoreGapExtendMax, "float", cmd);
	TCLAP::ValueArg<float> scoreGapExtendMinArg("", "gap-extend-min", "Gap open extend min", false, scoreGapExtendMin, "float", cmd);
	TCLAP::ValueArg<float> scoreGapDecayArg("", "gap-decay", "Gap extend decay", false, scoreGapDecay, "float", cmd);
	TCLAP::ValueArg<int> stdoutArg("", "stdout", "Debug mode", false, stdoutMode, "0-7", cmd);
	TCLAP::ValueArg<int> subreadAligner("", "subread-aligner", "Choose subread aligning method", false, subreadaligner, "0-3", cmd);
	TCLAP::ValueArg<int> readpartLengthArg("", "subread-length", "Length of fragments reads are split into", false, readPartLength, "int", cmd);
	TCLAP::ValueArg<int> readpartCorridorArg("", "subread-corridor", "Length of corridor sub-reads are aligned with", false, readPartCorridor, "int", cmd);
	//csSearchTableLength = 0;
	//logLevel = 0; //16383, 255
	//minKmerHits = 0;
	//maxCMRs = INT_MAX;

	TCLAP::SwitchArg noprogressArg("", "no-progress", "Don't print progress info while mapping", cmd, false);
	TCLAP::SwitchArg verboseArg("", "verbose", "Debug output", cmd, false);
	//bam = false;
	TCLAP::SwitchArg colorArg("", "color", "Colored command line output", cmd, false);
	//hardClip = false;
	//log = false;
	TCLAP::SwitchArg lowqualitysplitArg("", "no-lowqualitysplit", "Split alignments with poor quality", cmd, false);
	TCLAP::SwitchArg nosmallInversionArg("", "no-smallinv", "Don't detect small inversions", cmd, false);
	TCLAP::SwitchArg printAllAlignmentsArg("", "print-all", "Print all alignments. Disable filtering. (debug)", cmd, false);
	//skipSave = false;
	//updateCheck = false;
	//writeUnmapped = true;
	TCLAP::SwitchArg noSSEArg("", "nosse", "Debug switch (don't use if you don't know what you are doing)", cmd, false);

	std::stringstream usage;
	usage << "" << std::endl;
	usage << "Usage: ngmlr [options] -r <reference> -q <reads> [-o <output>]" << std::endl;
	usage << "" << std::endl;
	usage << "Input/Output:" << std::endl;
	printParameter<std::string>(usage, refArg);
	printParameter<std::string>(usage, queryArg);
	printParameter<std::string>(usage, outArg);
	usage << "" << std::endl;
	usage << "General:" << std::endl;
	printParameter<int>(usage, threadsArg);
	printParameter<std::string>(usage, presetArgs);
	printParameter<float>(usage, minIdentityArg);
	printParameter<float>(usage, minResiduesArg);
	printParameter(usage, nosmallInversionArg);
	printParameter(usage, lowqualitysplitArg);
	printParameter(usage, verboseArg);
	printParameter(usage, noprogressArg);
	usage << "" << std::endl;
	usage << "Advanced:" << std::endl;
	printParameter<float>(usage, scoreMatchArg);
	printParameter<float>(usage, scoreMismatchArg);
	printParameter<float>(usage, scoreGapOpenArg);
	printParameter<float>(usage, scoreGapExtendMaxArg);
	printParameter<float>(usage, scoreGapExtendMinArg);
	printParameter<float>(usage, scoreGapDecayArg);
	printParameter<int>(usage, kmerLengthArg);
	printParameter<int>(usage, kmerSkipArg);
	printParameter<int>(usage, binSizeArg);
	printParameter<int>(usage, maxInitialSegmentsArg);
	printParameter<int>(usage, readpartLengthArg);
	printParameter<int>(usage, readpartCorridorArg);
	//printParameter<std::string>(usage, vcfArg);
	//printParameter<std::string>(usage, bedfilterArg);

	cmd.setOutput(new ArgParseOutput(usage.str(), ""));

	cmd.parse(argc, argv);

	queryFile = fromString(queryArg.getValue());
	referenceFile = fromString(refArg.getValue());
	outputFile = fromString(outArg.getValue());
	vcfFile = fromString(vcfArg.getValue());
	bedFile = fromString(bedfilterArg.getValue());

	minIdentity = minIdentityArg.getValue();
	minResidues = minResiduesArg.getValue();

	binSize = binSizeArg.getValue();
	kmerLength = kmerLengthArg.getValue();
	threads = threadsArg.getValue();
	kmerSkip = kmerSkipArg.getValue();
	maxInitialSegments = maxInitialSegmentsArg.getValue();
	scoreMatch = scoreMatchArg.getValue();
	if(scoreMatch < 0.0f) {
		Log.Message("--match must not be smaller than zero. changing from %f to %f", scoreMatch, scoreMatch * -1.0f);
		scoreMatch = scoreMatch * -1.0f;
	}
	scoreMismatch = scoreMismatchArg.getValue();
	if (scoreMismatch > 0.0f) {
		Log.Message("--mismatch must not be greater than zero. changing from %f to %f", scoreMismatch, scoreMismatch * -1.0f);
		scoreMismatch = scoreMismatch * -1.0f;
	}
	scoreGapOpen = scoreGapOpenArg.getValue();
	if (scoreGapOpen > 0.0f) {
		Log.Message("--gap-open must not be greater than zero. changing from %f to %f", scoreGapOpen, scoreGapOpen * -1.0f);
		scoreGapOpen = scoreGapOpen * -1.0f;
	}
	scoreGapExtendMax = scoreGapExtendMaxArg.getValue();
	if (scoreGapExtendMax > 0.0f) {
		Log.Message("--gap-extend-max must not be greater than zero. changing from %f to %f", scoreGapExtendMax, scoreGapExtendMax * -1.0f);
		scoreGapExtendMax = scoreGapExtendMax * -1.0f;
	}
	scoreGapExtendMin = scoreGapExtendMinArg.getValue();
	if (scoreGapExtendMin > 0.0f) {
		Log.Message("--gap-extend-min must not be greater than zero. changing from %f to %f", scoreGapExtendMin, scoreGapExtendMin * -1.0f);
		scoreGapExtendMin = scoreGapExtendMin * -1.0f;
	}
	scoreGapDecay = scoreGapDecayArg.getValue();
	if (scoreGapDecay < 0.0f) {
		Log.Message("--gap-decay must not be smaller than zero. changing from %f to %f", scoreGapDecay, scoreGapDecay * -1.0f);
		scoreGapDecay = scoreGapDecay * -1.0f;
	}
	subreadaligner = subreadAligner.getValue();
	stdoutMode = stdoutArg.getValue();
	readPartCorridor = readpartCorridorArg.getValue();
	readPartLength = readpartLengthArg.getValue();

	progress = !noprogressArg.getValue();
	color = colorArg.getValue();
	verbose = verboseArg.getValue();
	lowQualitySplit = !lowqualitysplitArg.getValue();
	smallInversionDetection = !nosmallInversionArg.getValue();
	printAllAlignments = printAllAlignmentsArg.getValue();
	nosse = noSSEArg.getValue();

	if (presetArgs.getValue() == "pacbio") {
		//Do nothing. Defaults are for Pacbio
	} else if (presetArgs.getValue() == "ont") {
		lowQualitySplit = (lowqualitysplitArg.isSet()) ? lowQualitySplit : false;
		smallInversionDetection = (nosmallInversionArg.isSet()) ? smallInversionDetection : false;
		scoreMatch = (scoreMatchArg.isSet()) ? scoreMatch : 3;
		scoreMismatch = (scoreMatchArg.isSet()) ? scoreMismatch : -7;
		//scoreGapOpen = (scoreGapOpenArg.isSet()) ? scoreGapOpen : -1;
		//scoreGapExtendMax = (scoreGapExtendMaxArg.isSet()) ? scoreGapExtendMax : -1;
		//scoreGapExtendMax = (scoreGapExtendMinArg.isSet()) ? scoreGapExtendMin : -0.5;
		scoreGapDecay = (scoreGapDecayArg.isSet()) ? scoreGapDecay : 0.10;
	} else {
		std::cerr << "Preset " << presetArgs.getValue() << " not found" << std::endl;
	}

	std::stringstream fullCmd;
	fullCmd << std::string(argv[0]);
	for(int i = 1; i < argc; ++i) {
		fullCmd << " " << std::string(argv[i]);
	}
	fullCommandLineCall = fromString(fullCmd.str());

	if(!FileExists(queryFile)) {
		Log.Error("Query file (%s) does not exist.", queryFile);
	}
	if(!FileExists(referenceFile)) {
		Log.Error("Reference file (%s) does not exist.", referenceFile);
	}
	if(bedFile != 0 && !FileExists(bedFile)) {
		Log.Error("BED filter file (%s) does not exist.", bedFile);
	}
	if(vcfFile != 0 && !FileExists(vcfFile)) {
		Log.Error("SNP file (%s) does not exist.", vcfFile);
	}
}

<|endoftext|>


<commit_before>/***************************************************************************
 *   (c) Jrgen Riegel (juergen.riegel@web.de) 2008                        *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 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 Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
# include <QUuid>
#endif

/// Here the FreeCAD includes sorted by Base,App,Gui......
#include "Uuid.h"
#include "Exception.h"
#include "Interpreter.h"
#include <stdexcept>
#include <CXX/Objects.hxx>

using namespace Base;

//**************************************************************************
// Construction/Destruction

/**
 * A constructor.
 * A more elaborate description of the constructor.
 */
Uuid::Uuid()
{
    _uuid = createUuid();
}

/**
 * A destructor.
 * A more elaborate description of the destructor.
 */
Uuid::~Uuid()
{
}

//**************************************************************************
//**************************************************************************
// Get the UUID
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
std::string Uuid::createUuid(void)
{
    std::string Uuid;
    QString uuid = QUuid::createUuid().toString();
    uuid = uuid.mid(1);
    uuid.chop(1);
    Uuid = (const char*)uuid.toAscii();
    return Uuid;
}

void Uuid::setValue(const char* sString)
{
    if (sString) {
        QUuid uuid(QString::fromAscii(sString));
        if (uuid.isNull())
            throw std::runtime_error("invalid uuid");
        // remove curly braces
        QString id = uuid.toString();
        id = id.mid(1);
        id.chop(1);
        _uuid = (const char*)id.toAscii();
    }
}

void Uuid::setValue(const std::string &sString)
{
	setValue(sString.c_str());
}

const std::string& Uuid::getValue(void) const
{
    return _uuid;
}
<commit_msg>Fix whitespace<commit_after>/***************************************************************************
 *   (c) Jrgen Riegel (juergen.riegel@web.de) 2008                        *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 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 Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
# include <QUuid>
#endif

/// Here the FreeCAD includes sorted by Base,App,Gui......
#include "Uuid.h"
#include "Exception.h"
#include "Interpreter.h"
#include <stdexcept>
#include <CXX/Objects.hxx>

using namespace Base;

//**************************************************************************
// Construction/Destruction

/**
 * A constructor.
 * A more elaborate description of the constructor.
 */
Uuid::Uuid()
{
    _uuid = createUuid();
}

/**
 * A destructor.
 * A more elaborate description of the destructor.
 */
Uuid::~Uuid()
{
}

//**************************************************************************
//**************************************************************************
// Get the UUID
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
std::string Uuid::createUuid(void)
{
    std::string Uuid;
    QString uuid = QUuid::createUuid().toString();
    uuid = uuid.mid(1);
    uuid.chop(1);
    Uuid = (const char*)uuid.toAscii();
    return Uuid;
}

void Uuid::setValue(const char* sString)
{
    if (sString) {
        QUuid uuid(QString::fromAscii(sString));
        if (uuid.isNull())
            throw std::runtime_error("invalid uuid");
        // remove curly braces
        QString id = uuid.toString();
        id = id.mid(1);
        id.chop(1);
        _uuid = (const char*)id.toAscii();
    }
}

void Uuid::setValue(const std::string &sString)
{
    setValue(sString.c_str());
}

const std::string& Uuid::getValue(void) const
{
    return _uuid;
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <iostream>

#include "log4cpp/Category.hh"
#include "log4cpp/OstreamAppender.hh"
#include "log4cpp/FileAppender.hh"
#include "log4cpp/BasicLayout.hh"

#include "Clock.hh"

// -----------------------------------------------------------------------------
int main(int argc, char* argv[])
{
    int    count  = argc > 1 ? atoi(argv[1]) : 100;
    size_t size   = argc > 2 ? atoi(argv[2]) : 128;

    std::cout << "  count: " << count << std::endl
	      << "   size: " << size  << " bytes" << std::endl
	      << std::endl;

    log4cpp::Category&	root	 = log4cpp::Category::getRoot();
    log4cpp::Appender*	appender =
        new log4cpp::OstreamAppender("cerr", &std::cerr);
    log4cpp::Appender*	fileAppender =
        new log4cpp::FileAppender("stderr", fileno(stderr));
    appender->setLayout(new log4cpp::BasicLayout());
    fileAppender->setLayout(new log4cpp::BasicLayout());
    root.setAppender(appender);
    root.setPriority(log4cpp::Priority::ERROR);

    Clock  clock;
    char*  buffer = new char[size];

    memset(buffer, 'X', size);
    buffer[size - 1] = '\0';

    {
	clock.start();
	for (int i = 0; i < count; i++) root.error("%s", buffer);
	clock.stop();
	std::cout << "buffer ostream: " << ((float)clock.elapsed()) / count << " us" << std::endl;
    }

    {
	std::string str(size, 'X');

	clock.start();
	for (int i = 0; i < count; i++) root.error(str);
	clock.stop();
	std::cout << "string ostream: " << ((float)clock.elapsed()) / count << " us" << std::endl;
    }

    {
	std::string str(size, 'X');
        root.setAppender(fileAppender);

	clock.start();
	for (int i = 0; i < count; i++) root.error(str);
	clock.stop();
	std::cout << "string file:    " << ((float)clock.elapsed()) / count << " us" << std::endl;
    }

    {
	clock.start();
	for (int i = 0; i < count; i++) fprintf(stderr, "%d ERROR  : %s\n", ::time(NULL), buffer);
	clock.stop();
	std::cout << "fprintf:        " << ((float)clock.elapsed()) / count << " us" << std::endl;
    }

    log4cpp::Category::shutdown();

    return 0;
}
<commit_msg>use TimeStamp instead of ::time().<commit_after>#include <stdio.h>
#include <iostream>

#include "log4cpp/Category.hh"
#include "log4cpp/OstreamAppender.hh"
#include "log4cpp/FileAppender.hh"
#include "log4cpp/BasicLayout.hh"
#include "log4cpp/TimeStamp.hh"

#include "Clock.hh"

// -----------------------------------------------------------------------------
int main(int argc, char* argv[])
{
    int    count  = argc > 1 ? atoi(argv[1]) : 100;
    size_t size   = argc > 2 ? atoi(argv[2]) : 128;

    std::cout << "  count: " << count << std::endl
	      << "   size: " << size  << " bytes" << std::endl
	      << std::endl;

    log4cpp::Category&	root	 = log4cpp::Category::getRoot();
    log4cpp::Appender*	appender =
        new log4cpp::OstreamAppender("cerr", &std::cerr);
    log4cpp::Appender*	fileAppender =
        new log4cpp::FileAppender("stderr", fileno(stderr));
    appender->setLayout(new log4cpp::BasicLayout());
    fileAppender->setLayout(new log4cpp::BasicLayout());
    root.setAppender(appender);
    root.setPriority(log4cpp::Priority::ERROR);

    Clock  clock;
    char*  buffer = new char[size];

    memset(buffer, 'X', size);
    buffer[size - 1] = '\0';

    {
	clock.start();
	for (int i = 0; i < count; i++) root.error("%s", buffer);
	clock.stop();
	std::cout << "buffer ostream: " << ((float)clock.elapsed()) / count << " us" << std::endl;
    }

    {
	std::string str(size, 'X');

	clock.start();
	for (int i = 0; i < count; i++) root.error(str);
	clock.stop();
	std::cout << "string ostream: " << ((float)clock.elapsed()) / count << " us" << std::endl;
    }

    {
	std::string str(size, 'X');
        root.setAppender(fileAppender);

	clock.start();
	for (int i = 0; i < count; i++) root.error(str);
	clock.stop();
	std::cout << "string file:    " << ((float)clock.elapsed()) / count << " us" << std::endl;
    }

    {
	clock.start();
	for (int i = 0; i < count; i++) fprintf(stderr, "%d ERROR  : %s\n", log4cpp::TimeStamp().getSeconds(), buffer);
	clock.stop();
	std::cout << "fprintf:        " << ((float)clock.elapsed()) / count << " us" << std::endl;
    }

    log4cpp::Category::shutdown();

    return 0;
}
<|endoftext|>


<commit_before>void fitcont()
{
   // Example illustrating how to draw the n-sigma contour of a Minuit fit.
   // To get the n-sigma contour the ERRDEF parameter in Minuit has to set
   // to n^2. The fcn function has to be set before the routine is called.
   //
   // The TGraph object is created via the interpreter. The user must cast it
   // to a TGraph*
   // Author;  Rene Brun

   TCanvas *c1 = new TCanvas("c1");
   TH1F *h = new TH1F("h","My histogram",100,-3,3);
   h->FillRandom("gaus",6000);
   h->Fit("gaus");
   c1->Update();

   TCanvas *c2 = new TCanvas("c2","contours",10,10,600,800);
   c2->Divide(1,2);
   c2->cd(1);
   //get first contour for parameter 1 versus parameter 2
   TGraph *gr12 = (TGraph*)gMinuit->Contour(40,1,2);
   gr12->Draw("alp");
   c2->cd(2);
   //Get contour for parameter 0 versus parameter 2  for ERRDEF=2
   gMinuit->SetErrorDef(2);
   TGraph *gr2 = (TGraph*)gMinuit->Contour(80,0,2);
   gr2->SetFillColor(42);
   gr2->Draw("alf");
   //Get contour for parameter 0 versus parameter 2 for ERRDEF=1
   gMinuit->SetErrorDef(1);
   TGraph *gr1 = (TGraph*)gMinuit->Contour(80,0,2);
   gr1->SetFillColor(38);
   gr1->Draw("lf");
}
<commit_msg>Add a Warning to indicate that this tutorial can only run with Minuit.<commit_after>void fitcont()
{
   // Example illustrating how to draw the n-sigma contour of a Minuit fit.
   // To get the n-sigma contour the ERRDEF parameter in Minuit has to set
   // to n^2. The fcn function has to be set before the routine is called.
   //
   // WARNING!!! This test works only with TMinuit
   //
   // The TGraph object is created via the interpreter. The user must cast it
   // to a TGraph*
   // Author;  Rene Brun

   TCanvas *c1 = new TCanvas("c1");
   TH1F *h = new TH1F("h","My histogram",100,-3,3);
   h->FillRandom("gaus",6000);
   h->Fit("gaus");
   c1->Update();

   TCanvas *c2 = new TCanvas("c2","contours",10,10,600,800);
   c2->Divide(1,2);
   c2->cd(1);
   //get first contour for parameter 1 versus parameter 2
   TGraph *gr12 = (TGraph*)gMinuit->Contour(40,1,2);
   gr12->Draw("alp");
   c2->cd(2);
   //Get contour for parameter 0 versus parameter 2  for ERRDEF=2
   gMinuit->SetErrorDef(2);
   TGraph *gr2 = (TGraph*)gMinuit->Contour(80,0,2);
   gr2->SetFillColor(42);
   gr2->Draw("alf");
   //Get contour for parameter 0 versus parameter 2 for ERRDEF=1
   gMinuit->SetErrorDef(1);
   TGraph *gr1 = (TGraph*)gMinuit->Contour(80,0,2);
   gr1->SetFillColor(38);
   gr1->Draw("lf");
}
<|endoftext|>