<commit_before>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "InputMenu.h"

/* system implementation headers */
#include <string>
#include <vector>

/* common implementation headers */
#include "BzfWindow.h"
#include "StateDatabase.h"

/* local implementation headers */
#include "MainWindow.h"
#include "MainMenu.h"
#include "HUDDialogStack.h"
#include "LocalPlayer.h"

/* FIXME - from playing.h */
MainWindow*    getMainWindow();

InputMenu::InputMenu() : keyboardMapMenu(NULL)
{
  std::string currentJoystickDevice = BZDB.get("joystickname");
  // add controls
  std::vector<HUDuiControl*>& list = getControls();

  HUDuiLabel* label = new HUDuiLabel;
  label->setFont(MainMenu::getFont());
  label->setString("Input Setting");
  list.push_back(label);

  keyMapping = new HUDuiLabel;
  keyMapping->setFont(MainMenu::getFont());
  keyMapping->setLabel("Change Key Mapping");
  list.push_back(keyMapping);

  HUDuiList* option = new HUDuiList;

  option = new HUDuiList;
  std::vector<std::string>* options = &option->getList();
  // set joystick Device
  option->setFont(MainMenu::getFont());
  option->setLabel("Joystick device:");
  option->setCallback(callback, (void*)"J");
  options = &option->getList();
  options->push_back(std::string("off"));
  std::vector<std::string> joystickDevices;
  getMainWindow()->getJoyDevices(joystickDevices);
  int i;
  for (i = 0; i < (int)joystickDevices.size(); i++) {
    options->push_back(joystickDevices[i]);
  }
  joystickDevices.erase(joystickDevices.begin(), joystickDevices.end());
  for (i = 0; i < (int)options->size(); i++) {
    if ((*options)[i].compare(currentJoystickDevice) == 0) {
      option->setIndex(i);
      break;
    }
  }
  option->update();
  list.push_back(option);

  forceInput = new HUDuiList;
  forceInput->setFont(MainMenu::getFont());
  forceInput->setLabel("Force input device:");
  forceInput->setCallback(callback, (void*)"F");
  options = &forceInput->getList();
  options->push_back("Do not force");
  options->push_back(LocalPlayer::getInputMethodName(LocalPlayer::Keyboard));
  options->push_back(LocalPlayer::getInputMethodName(LocalPlayer::Mouse));
  options->push_back(LocalPlayer::getInputMethodName(LocalPlayer::Joystick));
  forceInput->update();
  list.push_back(forceInput);

  initNavigation(list, 1,list.size()-1);
}

InputMenu::~InputMenu()
{
  delete keyboardMapMenu;
}

void			InputMenu::execute()
{
  HUDuiControl* focus = HUDui::getFocus();
  if (focus == keyMapping) {
    if (!keyboardMapMenu) keyboardMapMenu = new KeyboardMapMenu;
    HUDDialogStack::get()->push(keyboardMapMenu);
  }
}

void			InputMenu::callback(HUDuiControl* w, void* data) {
  HUDuiList* list = (HUDuiList*)w;
  std::vector<std::string> *options = &list->getList();
  std::string selectedOption = (*options)[list->getIndex()];
  switch (((const char*)data)[0]) {
    case 'J':
      BZDB.set("joystickname", selectedOption);
      getMainWindow()->initJoystick(selectedOption);
      break;
    case 'F':
      {
	LocalPlayer*   myTank = LocalPlayer::getMyTank();
	// Do we force or not?
	if (selectedOption == "Do not force") {
	  BZDB.set("allowInputChange", "1");
	} else {
	  BZDB.set("allowInputChange", "0");
	  BZDB.set("forceInputDevice", selectedOption);
	}
        // Set the current input device to whatever we're forced to
	if (myTank) {
	  // FIXME - right now setInputMethod(Joystick) has no effect
	  // someone who knows about the joystick code should fix this
	  myTank->setInputMethod(BZDB.get("forceInputDevice"));
	}
      }
      break;
  }
}

void			InputMenu::resize(int width, int height)
{
  HUDDialog::resize(width, height);
  int i;

  // use a big font for title, smaller font for the rest
  const float titleFontWidth = (float)height / 10.0f;
  const float titleFontHeight = (float)height / 10.0f;
  const float fontWidth = (float)height / 30.0f;
  const float fontHeight = (float)height / 30.0f;

  // reposition title
  std::vector<HUDuiControl*>& list = getControls();
  HUDuiLabel* title = (HUDuiLabel*)list[0];
  title->setFontSize(titleFontWidth, titleFontHeight);
  const OpenGLTexFont& titleFont = title->getFont();
  const float titleWidth = titleFont.getWidth(title->getString());
  float x = 0.5f * ((float)width - titleWidth);
  float y = (float)height - titleFont.getHeight();
  title->setPosition(x, y);

  // reposition options
  x = 0.5f * ((float)width + 0.5f * titleWidth);
  y -= 0.6f * titleFont.getHeight();
  const int count = list.size();
  for (i = 1; i < count; i++) {
    list[i]->setFontSize(fontWidth, fontHeight);
    list[i]->setPosition(x, y);
    y -= 1.0f * list[i]->getFont().getHeight();
  }

  // load current settings
  std::vector<std::string> *options = &forceInput->getList();
  for (i = 0; i < options->size(); i++) {
    std::string currentOption = (*options)[i];
    if (BZDB.get("forceInputDevice") == currentOption)
      forceInput->setIndex(i);
  }
  if (BZDB.isTrue("allowInputChange"))
    forceInput->setIndex(0);
}

// Local Variables: ***
// mode: C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>fixed compilation warning<commit_after>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "InputMenu.h"

/* system implementation headers */
#include <string>
#include <vector>

/* common implementation headers */
#include "BzfWindow.h"
#include "StateDatabase.h"

/* local implementation headers */
#include "MainWindow.h"
#include "MainMenu.h"
#include "HUDDialogStack.h"
#include "LocalPlayer.h"

/* FIXME - from playing.h */
MainWindow*    getMainWindow();

InputMenu::InputMenu() : keyboardMapMenu(NULL)
{
  std::string currentJoystickDevice = BZDB.get("joystickname");
  // add controls
  std::vector<HUDuiControl*>& list = getControls();

  HUDuiLabel* label = new HUDuiLabel;
  label->setFont(MainMenu::getFont());
  label->setString("Input Setting");
  list.push_back(label);

  keyMapping = new HUDuiLabel;
  keyMapping->setFont(MainMenu::getFont());
  keyMapping->setLabel("Change Key Mapping");
  list.push_back(keyMapping);

  HUDuiList* option = new HUDuiList;

  option = new HUDuiList;
  std::vector<std::string>* options = &option->getList();
  // set joystick Device
  option->setFont(MainMenu::getFont());
  option->setLabel("Joystick device:");
  option->setCallback(callback, (void*)"J");
  options = &option->getList();
  options->push_back(std::string("off"));
  std::vector<std::string> joystickDevices;
  getMainWindow()->getJoyDevices(joystickDevices);
  int i;
  for (i = 0; i < (int)joystickDevices.size(); i++) {
    options->push_back(joystickDevices[i]);
  }
  joystickDevices.erase(joystickDevices.begin(), joystickDevices.end());
  for (i = 0; i < (int)options->size(); i++) {
    if ((*options)[i].compare(currentJoystickDevice) == 0) {
      option->setIndex(i);
      break;
    }
  }
  option->update();
  list.push_back(option);

  forceInput = new HUDuiList;
  forceInput->setFont(MainMenu::getFont());
  forceInput->setLabel("Force input device:");
  forceInput->setCallback(callback, (void*)"F");
  options = &forceInput->getList();
  options->push_back("Do not force");
  options->push_back(LocalPlayer::getInputMethodName(LocalPlayer::Keyboard));
  options->push_back(LocalPlayer::getInputMethodName(LocalPlayer::Mouse));
  options->push_back(LocalPlayer::getInputMethodName(LocalPlayer::Joystick));
  forceInput->update();
  list.push_back(forceInput);

  initNavigation(list, 1,list.size()-1);
}

InputMenu::~InputMenu()
{
  delete keyboardMapMenu;
}

void			InputMenu::execute()
{
  HUDuiControl* focus = HUDui::getFocus();
  if (focus == keyMapping) {
    if (!keyboardMapMenu) keyboardMapMenu = new KeyboardMapMenu;
    HUDDialogStack::get()->push(keyboardMapMenu);
  }
}

void			InputMenu::callback(HUDuiControl* w, void* data) {
  HUDuiList* list = (HUDuiList*)w;
  std::vector<std::string> *options = &list->getList();
  std::string selectedOption = (*options)[list->getIndex()];
  switch (((const char*)data)[0]) {
    case 'J':
      BZDB.set("joystickname", selectedOption);
      getMainWindow()->initJoystick(selectedOption);
      break;
    case 'F':
      {
	LocalPlayer*   myTank = LocalPlayer::getMyTank();
	// Do we force or not?
	if (selectedOption == "Do not force") {
	  BZDB.set("allowInputChange", "1");
	} else {
	  BZDB.set("allowInputChange", "0");
	  BZDB.set("forceInputDevice", selectedOption);
	}
        // Set the current input device to whatever we're forced to
	if (myTank) {
	  // FIXME - right now setInputMethod(Joystick) has no effect
	  // someone who knows about the joystick code should fix this
	  myTank->setInputMethod(BZDB.get("forceInputDevice"));
	}
      }
      break;
  }
}

void			InputMenu::resize(int width, int height)
{
  HUDDialog::resize(width, height);
  int i;

  // use a big font for title, smaller font for the rest
  const float titleFontWidth = (float)height / 10.0f;
  const float titleFontHeight = (float)height / 10.0f;
  const float fontWidth = (float)height / 30.0f;
  const float fontHeight = (float)height / 30.0f;

  // reposition title
  std::vector<HUDuiControl*>& list = getControls();
  HUDuiLabel* title = (HUDuiLabel*)list[0];
  title->setFontSize(titleFontWidth, titleFontHeight);
  const OpenGLTexFont& titleFont = title->getFont();
  const float titleWidth = titleFont.getWidth(title->getString());
  float x = 0.5f * ((float)width - titleWidth);
  float y = (float)height - titleFont.getHeight();
  title->setPosition(x, y);

  // reposition options
  x = 0.5f * ((float)width + 0.5f * titleWidth);
  y -= 0.6f * titleFont.getHeight();
  const int count = list.size();
  for (i = 1; i < count; i++) {
    list[i]->setFontSize(fontWidth, fontHeight);
    list[i]->setPosition(x, y);
    y -= 1.0f * list[i]->getFont().getHeight();
  }

  // load current settings
  std::vector<std::string> *options = &forceInput->getList();
  for (i = 0; i < (int)options->size(); i++) {
    std::string currentOption = (*options)[i];
    if (BZDB.get("forceInputDevice") == currentOption)
      forceInput->setIndex(i);
  }
  if (BZDB.isTrue("allowInputChange"))
    forceInput->setIndex(0);
}

// Local Variables: ***
// mode: C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>#include "BZRobot.h"

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<commit_msg>missing header<commit_after>/* bzflag
 * Copyright (c) 1993 - 2007 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "BZRobot.h"

// Local Variables: ***
// mode: C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<|endoftext|>


<commit_before>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "kernel/register.h"
#include "kernel/celltypes.h"
#include "kernel/rtlil.h"
#include "kernel/log.h"

struct DesignPass : public Pass {
	DesignPass() : Pass("design", "save, restore and reset current design") { }
	std::map<std::string, RTLIL::Design*> saved_designs;
	virtual ~DesignPass() {
		for (auto &it : saved_designs)
			delete it.second;
		saved_designs.clear();
	}
	virtual void help()
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    design -reset\n");
		log("\n");
		log("Clear the current design.\n");
		log("\n");
		log("\n");
		log("    design -save <name>\n");
		log("\n");
		log("Save the current design under the given name.\n");
		log("\n");
		log("\n");
		log("    design -stash <name>\n");
		log("\n");
		log("Save the current design under the given name and then clear the current design.\n");
		log("\n");
		log("\n");
		log("    design -load <name>\n");
		log("\n");
		log("Reset the current design and load the design previously saved under the given\n");
		log("name.\n");
		log("\n");
		log("\n");
		log("    design -copy-from <name> [-as <new_mod_name>] <selection>\n");
		log("\n");
		log("Copy modules from the specified design into the current one. The selection is\n");
		log("evaluated in the other design.\n");
		log("\n");
		log("\n");
		log("    design -copy-to <name> [-as <new_mod_name>] [selection]\n");
		log("\n");
		log("Copy modules from the current design into the soecified one.\n");
		log("\n");
	}
	virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
	{
		bool got_mode = false;
		bool reset_mode = false;
		RTLIL::Design *copy_from_design = NULL, *copy_to_design = NULL;
		std::string save_name, load_name, as_name;
		std::vector<RTLIL::Module*> copy_src_modules;

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++)
		{
			std::string arg = args[argidx];
			if (!got_mode && args[argidx] == "-reset") {
				got_mode = true;
				reset_mode = true;
				continue;
			}
			if (!got_mode && args[argidx] == "-save" && argidx+1 < args.size()) {
				got_mode = true;
				save_name = args[++argidx];
				continue;
			}
			if (!got_mode && args[argidx] == "-stash" && argidx+1 < args.size()) {
				got_mode = true;
				save_name = args[++argidx];
				reset_mode = true;
				continue;
			}
			if (!got_mode && args[argidx] == "-load" && argidx+1 < args.size()) {
				got_mode = true;
				load_name = args[++argidx];
				if (saved_designs.count(load_name) == 0)
					log_cmd_error("No saved design '%s' found!\n", load_name.c_str());
				continue;
			}
			if (!got_mode && args[argidx] == "-copy-from" && argidx+1 < args.size()) {
				got_mode = true;
				if (saved_designs.count(args[++argidx]) == 0)
					log_cmd_error("No saved design '%s' found!\n", args[argidx].c_str());
				copy_from_design = saved_designs.at(args[argidx]);
				copy_to_design = design;
				continue;
			}
			if (!got_mode && args[argidx] == "-copy-to" && argidx+1 < args.size()) {
				got_mode = true;
				if (saved_designs.count(args[++argidx]) == 0)
					saved_designs[args[argidx]] = new RTLIL::Design;
				copy_to_design = saved_designs.at(args[argidx]);
				copy_from_design = design;
				continue;
			}
			if (copy_from_design != NULL && args[argidx] == "-as" && argidx+1 < args.size()) {
				got_mode = true;
				as_name = args[++argidx];
				continue;
			}
			break;
		}

		if (copy_from_design != NULL)
		{
			if (copy_from_design != design && argidx == args.size())
				cmd_error(args, argidx, "Missing selection.\n");

			RTLIL::Selection sel = design->selection_stack.back();
			if (argidx != args.size()) {
				handle_extra_select_args(this, args, argidx, args.size(), copy_from_design);
				sel = copy_from_design->selection_stack.back();
				copy_from_design->selection_stack.pop_back();
				argidx = args.size();
			}

			for (auto &it : copy_from_design->modules) {
				if (sel.selected_whole_module(it.first)) {
					copy_src_modules.push_back(it.second);
					continue;
				}
				if (sel.selected_module(it.first))
					log_cmd_error("Module %s is only partly selected.\n", RTLIL::id2cstr(it.first));
			}
		}

		extra_args(args, argidx, design, false);

		if (!got_mode)
			cmd_error(args, argidx, "Missing mode argument (-reset, -save, -load, -copy-from, or -copy-to).\n");

		if (copy_to_design != NULL)
		{
			if (!as_name.empty() && copy_src_modules.size() > 1)
				log_cmd_error("Only one module can be selected in combination with -as.\n");

			for (auto mod : copy_src_modules)
			{
				std::string trg_name = as_name.empty() ? mod->name : RTLIL::escape_id(as_name);

				if (copy_to_design->modules.count(trg_name))
					delete copy_to_design->modules.at(trg_name);
				copy_to_design->modules[trg_name] = mod->clone();
				copy_to_design->modules[trg_name]->name = trg_name;
			}
		}

		if (!save_name.empty())
		{
			RTLIL::Design *design_copy = new RTLIL::Design;

			for (auto &it : design->modules)
				design_copy->modules[it.first] = it.second->clone();

			design_copy->selection_stack = design->selection_stack;
			design_copy->selection_vars = design->selection_vars;
			design_copy->selected_active_module = design->selected_active_module;

			if (saved_designs.count(save_name))
				delete saved_designs.at(save_name);
			saved_designs[save_name] = design_copy;
		}

		if (reset_mode || !load_name.empty())
		{
			for (auto &it : design->modules)
				delete it.second;
			design->modules.clear();

			design->selection_stack.clear();
			design->selection_vars.clear();
			design->selected_active_module.clear();

			design->selection_stack.push_back(RTLIL::Selection());
		}

		if (!load_name.empty())
		{
			RTLIL::Design *saved_design = saved_designs.at(load_name);

			for (auto &it : saved_design->modules)
				design->modules[it.first] = it.second->clone();

			design->selection_stack = saved_design->selection_stack;
			design->selection_vars = saved_design->selection_vars;
			design->selected_active_module = saved_design->selected_active_module;
		}
	}
} DesignPass;

<commit_msg>Fixed use of "cmd_error" in passes/cmds/design.cc<commit_after>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "kernel/register.h"
#include "kernel/celltypes.h"
#include "kernel/rtlil.h"
#include "kernel/log.h"

struct DesignPass : public Pass {
	DesignPass() : Pass("design", "save, restore and reset current design") { }
	std::map<std::string, RTLIL::Design*> saved_designs;
	virtual ~DesignPass() {
		for (auto &it : saved_designs)
			delete it.second;
		saved_designs.clear();
	}
	virtual void help()
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    design -reset\n");
		log("\n");
		log("Clear the current design.\n");
		log("\n");
		log("\n");
		log("    design -save <name>\n");
		log("\n");
		log("Save the current design under the given name.\n");
		log("\n");
		log("\n");
		log("    design -stash <name>\n");
		log("\n");
		log("Save the current design under the given name and then clear the current design.\n");
		log("\n");
		log("\n");
		log("    design -load <name>\n");
		log("\n");
		log("Reset the current design and load the design previously saved under the given\n");
		log("name.\n");
		log("\n");
		log("\n");
		log("    design -copy-from <name> [-as <new_mod_name>] <selection>\n");
		log("\n");
		log("Copy modules from the specified design into the current one. The selection is\n");
		log("evaluated in the other design.\n");
		log("\n");
		log("\n");
		log("    design -copy-to <name> [-as <new_mod_name>] [selection]\n");
		log("\n");
		log("Copy modules from the current design into the soecified one.\n");
		log("\n");
	}
	virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
	{
		bool got_mode = false;
		bool reset_mode = false;
		RTLIL::Design *copy_from_design = NULL, *copy_to_design = NULL;
		std::string save_name, load_name, as_name;
		std::vector<RTLIL::Module*> copy_src_modules;

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++)
		{
			std::string arg = args[argidx];
			if (!got_mode && args[argidx] == "-reset") {
				got_mode = true;
				reset_mode = true;
				continue;
			}
			if (!got_mode && args[argidx] == "-save" && argidx+1 < args.size()) {
				got_mode = true;
				save_name = args[++argidx];
				continue;
			}
			if (!got_mode && args[argidx] == "-stash" && argidx+1 < args.size()) {
				got_mode = true;
				save_name = args[++argidx];
				reset_mode = true;
				continue;
			}
			if (!got_mode && args[argidx] == "-load" && argidx+1 < args.size()) {
				got_mode = true;
				load_name = args[++argidx];
				if (saved_designs.count(load_name) == 0)
					log_cmd_error("No saved design '%s' found!\n", load_name.c_str());
				continue;
			}
			if (!got_mode && args[argidx] == "-copy-from" && argidx+1 < args.size()) {
				got_mode = true;
				if (saved_designs.count(args[++argidx]) == 0)
					log_cmd_error("No saved design '%s' found!\n", args[argidx].c_str());
				copy_from_design = saved_designs.at(args[argidx]);
				copy_to_design = design;
				continue;
			}
			if (!got_mode && args[argidx] == "-copy-to" && argidx+1 < args.size()) {
				got_mode = true;
				if (saved_designs.count(args[++argidx]) == 0)
					saved_designs[args[argidx]] = new RTLIL::Design;
				copy_to_design = saved_designs.at(args[argidx]);
				copy_from_design = design;
				continue;
			}
			if (copy_from_design != NULL && args[argidx] == "-as" && argidx+1 < args.size()) {
				got_mode = true;
				as_name = args[++argidx];
				continue;
			}
			break;
		}

		if (copy_from_design != NULL)
		{
			if (copy_from_design != design && argidx == args.size())
				cmd_error(args, argidx, "Missing selection.");

			RTLIL::Selection sel = design->selection_stack.back();
			if (argidx != args.size()) {
				handle_extra_select_args(this, args, argidx, args.size(), copy_from_design);
				sel = copy_from_design->selection_stack.back();
				copy_from_design->selection_stack.pop_back();
				argidx = args.size();
			}

			for (auto &it : copy_from_design->modules) {
				if (sel.selected_whole_module(it.first)) {
					copy_src_modules.push_back(it.second);
					continue;
				}
				if (sel.selected_module(it.first))
					log_cmd_error("Module %s is only partly selected.\n", RTLIL::id2cstr(it.first));
			}
		}

		extra_args(args, argidx, design, false);

		if (!got_mode)
			cmd_error(args, argidx, "Missing mode argument (-reset, -save, -load, -copy-from, or -copy-to).");

		if (copy_to_design != NULL)
		{
			if (!as_name.empty() && copy_src_modules.size() > 1)
				log_cmd_error("Only one module can be selected in combination with -as.\n");

			for (auto mod : copy_src_modules)
			{
				std::string trg_name = as_name.empty() ? mod->name : RTLIL::escape_id(as_name);

				if (copy_to_design->modules.count(trg_name))
					delete copy_to_design->modules.at(trg_name);
				copy_to_design->modules[trg_name] = mod->clone();
				copy_to_design->modules[trg_name]->name = trg_name;
			}
		}

		if (!save_name.empty())
		{
			RTLIL::Design *design_copy = new RTLIL::Design;

			for (auto &it : design->modules)
				design_copy->modules[it.first] = it.second->clone();

			design_copy->selection_stack = design->selection_stack;
			design_copy->selection_vars = design->selection_vars;
			design_copy->selected_active_module = design->selected_active_module;

			if (saved_designs.count(save_name))
				delete saved_designs.at(save_name);
			saved_designs[save_name] = design_copy;
		}

		if (reset_mode || !load_name.empty())
		{
			for (auto &it : design->modules)
				delete it.second;
			design->modules.clear();

			design->selection_stack.clear();
			design->selection_vars.clear();
			design->selected_active_module.clear();

			design->selection_stack.push_back(RTLIL::Selection());
		}

		if (!load_name.empty())
		{
			RTLIL::Design *saved_design = saved_designs.at(load_name);

			for (auto &it : saved_design->modules)
				design->modules[it.first] = it.second->clone();

			design->selection_stack = saved_design->selection_stack;
			design->selection_vars = saved_design->selection_vars;
			design->selected_active_module = saved_design->selected_active_module;
		}
	}
} DesignPass;

<|endoftext|>


<commit_before>#include "Config.hpp"
#include "EventOutputQueue.hpp"
#include "ListHookedConsumer.hpp"
#include "ListHookedKeyboard.hpp"
#include "ListHookedPointing.hpp"
#include "PressDownKeys.hpp"
#include "RemapClass.hpp"
#include "VirtualKey.hpp"
#include "VK_IOHIDPOSTEVENT.hpp"

namespace org_pqrs_KeyRemap4MacBook {
  List* EventOutputQueue::queue_ = NULL;
  TimerWrapper EventOutputQueue::fire_timer_;

  void
  EventOutputQueue::initialize(IOWorkLoop& workloop)
  {
    queue_ = new List();
    fire_timer_.initialize(&workloop, NULL, EventOutputQueue::fire_timer_callback);
  }

  void
  EventOutputQueue::terminate(void)
  {
    fire_timer_.terminate();

    if (queue_) {
      delete queue_;
    }
  }

  // ----------------------------------------------------------------------
#define PUSH_TO_OUTPUTQUEUE {           \
    if (! queue_) return;               \
                                        \
    queue_->push_back(new Item(p));     \
    fire_timer_.setTimeoutMS(0, false); \
}
  void EventOutputQueue::push(const Params_KeyboardEventCallBack& p) {
    PUSH_TO_OUTPUTQUEUE;
    if (p.eventType == EventType::DOWN) {
      FlagStatus::globalFlagStatus().sticky_clear();
    }
  }
  void EventOutputQueue::push(const Params_KeyboardSpecialEventCallback& p) {
    PUSH_TO_OUTPUTQUEUE;
    if (p.ex_iskeydown) {
      FlagStatus::globalFlagStatus().sticky_clear();
    }
  }
  void EventOutputQueue::push(const Params_RelativePointerEventCallback& p) {
    PUSH_TO_OUTPUTQUEUE;
    if (p.buttons != Buttons(0)) {
      FlagStatus::globalFlagStatus().sticky_clear();
    }
  }
  void EventOutputQueue::push(const Params_ScrollWheelEventCallback& p) {
    PUSH_TO_OUTPUTQUEUE;
    FlagStatus::globalFlagStatus().sticky_clear();
  }
  void EventOutputQueue::push(const Params_Wait& p) {
    PUSH_TO_OUTPUTQUEUE;
  }
#undef PUSH_TO_OUTPUTQUEUE

  // ----------------------------------------------------------------------
  void
  EventOutputQueue::fire_timer_callback(OSObject* /* owner */, IOTimerEventSource* /* sender */)
  {
    if (! queue_) return;

    // IOLOG_DEVEL("EventOutputQueue::fire queue_->size = %d\n", static_cast<int>(queue_->size()));

    Item* p = static_cast<Item*>(queue_->front());
    if (! p) return;

    int delay = 0;

    // ----------------------------------------
    switch ((p->params).type) {
      case ParamsUnion::KEYBOARD:
      {
        Params_KeyboardEventCallBack* params = (p->params).get_Params_KeyboardEventCallBack();
        if (params) {
          bool handled = VirtualKey::handleAfterEnqueued(*params);
          if (! handled) {
            ListHookedKeyboard::instance().apply(*params);
          }

          if ((p->params).isModifier()) {
            // Delay after modifier
            //
            // We need to wait before and after a modifier event because
            // events will be dropped by window server if
            // we send a mouse click event and a modifier event at the same time.
            //
            delay = Config::get_wait_before_and_after_a_modifier_key_event();
          }
        }
        break;
      }
      case ParamsUnion::KEYBOARD_SPECIAL:
      {
        Params_KeyboardSpecialEventCallback* params = (p->params).get_Params_KeyboardSpecialEventCallback();
        if (params) {
          if (! ListHookedConsumer::instance().apply(*params)) {
            // If there is no consumer device, we send an event as a software key.
            VirtualKey::VK_IOHIDPOSTEVENT::post(*params);
          }
        }
        break;
      }
      case ParamsUnion::RELATIVE_POINTER:
      {
        Params_RelativePointerEventCallback* params = (p->params).get_Params_RelativePointerEventCallback();
        if (params) {
          ListHookedPointing::instance().apply(*params);
        }
        break;
      }
      case ParamsUnion::SCROLL_WHEEL:
      {
        Params_ScrollWheelEventCallback* params = (p->params).get_Params_ScrollWheelEventCallback();
        if (params) {
          ListHookedPointing::instance().apply(*params);
        }
        break;
      }
      case ParamsUnion::WAIT:
      {
        Params_Wait* params = (p->params).get_Params_Wait();
        if (params) {
          delay = params->milliseconds;
        }
        break;
      }
      case ParamsUnion::UPDATE_FLAGS:
        // do nothing
        break;
    }

    queue_->pop_front();

    // ----------------------------------------
    Item* next = static_cast<Item*>(queue_->front());
    if (! next) return;

    if ((next->params).isModifier()) {
      // Delay before modifier
      //
      // See comments of "Delay after modifier".
      //
      delay = Config::get_wait_before_and_after_a_modifier_key_event();
    }

    fire_timer_.setTimeoutMS(delay);
  }

  // ======================================================================
  Flags EventOutputQueue::FireModifiers::lastFlags_(0);

  void
  EventOutputQueue::FireModifiers::fire(Flags toFlags, KeyboardType keyboardType)
  {
    if (lastFlags_ == toFlags) return;

    // ------------------------------------------------------------
    // At first we handle KeyUp events and handle KeyDown events next.
    // We need to end KeyDown at Command+Space to Option_L+Shift_L.
    //
    // When Option_L+Shift_L has a meaning (switch input language at Windows),
    // it does not works well when the last is KeyUp of Command.

    // ------------------------------------------------------------
    // KeyUp
    for (size_t i = 0; i < FlagStatus::globalFlagStatus().itemSize(); ++i) {
      ModifierFlag flag = FlagStatus::globalFlagStatus().getFlag(i);

      // Skipping ModifierFlag::NUMPAD
      if (flag.getKeyCode() == KeyCode::VK_NONE) continue;
      // Skipping virtual modifiers.
      if (flag.getRawBits() == 0) continue;

      // ----------------------------------------
      if (! lastFlags_.isOn(flag)) continue;
      if (toFlags.isOn(flag)) continue;

      lastFlags_.remove(flag);

      Params_KeyboardEventCallBack::auto_ptr ptr(Params_KeyboardEventCallBack::alloc(EventType::MODIFY, lastFlags_, flag.getKeyCode(), keyboardType, false));
      if (! ptr) continue;
      EventOutputQueue::push(*ptr);
    }

    // KeyDown
    for (size_t i = 0; i < FlagStatus::globalFlagStatus().itemSize(); ++i) {
      ModifierFlag flag = FlagStatus::globalFlagStatus().getFlag(i);

      // Skipping ModifierFlag::NUMPAD
      if (flag.getKeyCode() == KeyCode::VK_NONE) continue;
      // Skipping virtual modifiers.
      if (flag.getRawBits() == 0) continue;

      // ----------------------------------------
      if (! toFlags.isOn(flag)) continue;
      if (lastFlags_.isOn(flag)) continue;

      lastFlags_.add(flag);

      Params_KeyboardEventCallBack::auto_ptr ptr(Params_KeyboardEventCallBack::alloc(EventType::MODIFY, lastFlags_, flag.getKeyCode(), keyboardType, false));
      if (! ptr) continue;
      EventOutputQueue::push(*ptr);
    }

    lastFlags_ = toFlags;
  }

  // ======================================================================
  void
  EventOutputQueue::FireKey::fire(const Params_KeyboardEventCallBack& params)
  {
    if (VirtualKey::handle(params)) return;

    // ------------------------------------------------------------
    KeyCode newkeycode = params.key;
    Flags newflags = params.flags;

    KeyCode::reverseNormalizeKey(newkeycode, newflags, params.eventType, params.keyboardType);

    // skip no-outputable keycodes.
    // Note: check before FireModifiers to avoid meaningless modifier event.
    if (newkeycode == KeyCode::VK_NONE ||
        newkeycode == KeyCode::VK_PSEUDO_KEY) {
      return;
    }
    if (newkeycode.isModifier() && newkeycode.getModifierFlag().getRawBits() == 0) {
      // virtual modifiers.
      return;
    }

    FireModifiers::fire(newflags, params.keyboardType);

    if (params.eventType == EventType::DOWN || params.eventType == EventType::UP) {
      Params_KeyboardEventCallBack::auto_ptr ptr(Params_KeyboardEventCallBack::alloc(params.eventType, newflags, newkeycode,
                                                                                params.charCode, params.charSet, params.origCharCode, params.origCharSet,
                                                                                params.keyboardType, params.repeat));
      if (ptr) {
        EventOutputQueue::push(*ptr);
      }

      if (! params.repeat) {
        if (params.eventType == EventType::DOWN) {
          PressDownKeys::add(newkeycode, params.keyboardType);
        } else {
          PressDownKeys::remove(newkeycode, params.keyboardType);
        }
      }
    }
  }

  // ======================================================================
  void
  EventOutputQueue::FireConsumer::fire(const Params_KeyboardSpecialEventCallback& params)
  {
    // skip no-outputable keycodes.
    // Note: check before FireModifiers to avoid meaningless modifier event.
    if (params.key == ConsumerKeyCode::VK_NONE ||
        params.key == ConsumerKeyCode::VK_PSEUDO_KEY) {
      return;
    }

    FireModifiers::fire();

    Params_KeyboardSpecialEventCallback::auto_ptr ptr(Params_KeyboardSpecialEventCallback::alloc(params.eventType, params.flags, params.key, params.repeat));
    if (ptr) {
      EventOutputQueue::push(*ptr);
    }
  }

  // ======================================================================
  Buttons EventOutputQueue::FireRelativePointer::lastButtons_(0);

  void
  EventOutputQueue::FireRelativePointer::fire(Buttons toButtons, int dx, int dy)
  {
    // When changing space to command+left click,
    //   __KeyToKey__ KeyCode::SPACE, PointingButton::LEFT, ModifierFlag::COMMAND_L
    //
    // We need to release command key after left click was released as follows.
    //   (1) KeyDown   Command_L
    //   (2) MouseDown Left
    //   (3) MouseUp   Left
    //   (4) KeyUp     Command_L
    //
    // For mouse drag support, command modifier is increased as normal (not temporary_increase).
    // Therefore, command modifier is decreased when space key is released.
    // If we call FireModifiers::fire() at the begining of this function,
    // input events are fired as follows order.
    //   (1) KeyDown   Command_L
    //   (2) MouseDown Left
    //   (3) KeyUp     Command_L
    //   (4) MouseUp   Left
    //
    // It's not desired order.
    // So, we call FireModifiers::fire() at the end of this function when button is released.

    Buttons releasedButtons = lastButtons_;
    releasedButtons.remove(toButtons);
    bool isButtonReleased = ! releasedButtons.isNONE();

    if (! isButtonReleased) {
      FireModifiers::fire();
    }

    // Sending button event
    if (lastButtons_ != toButtons) {
      lastButtons_ = toButtons;

      Params_RelativePointerEventCallback::auto_ptr ptr(Params_RelativePointerEventCallback::alloc(toButtons, 0, 0, PointingButton::NONE, false));
      if (! ptr) return;
      Params_RelativePointerEventCallback& params = *ptr;

      EventOutputQueue::push(params);
    }

    // Sending cursor
    if (dx != 0 || dy != 0) {
      Params_RelativePointerEventCallback::auto_ptr ptr(Params_RelativePointerEventCallback::alloc(toButtons, dx, dy, PointingButton::NONE, false));
      if (! ptr) return;
      Params_RelativePointerEventCallback& params = *ptr;

      EventOutputQueue::push(params);
    }

    if (isButtonReleased) {
      FireModifiers::fire();
    }
  }

  // ======================================================================
  void
  EventOutputQueue::FireScrollWheel::fire(const Params_ScrollWheelEventCallback& params)
  {
    FireModifiers::fire();
    EventOutputQueue::push(params);
  }

  void
  EventOutputQueue::FireScrollWheel::fire(int delta1, int delta2)
  {
    short deltaAxis1;
    short deltaAxis2;
    IOFixed fixedDelta1;
    IOFixed fixedDelta2;
    SInt32 pointDelta1;
    SInt32 pointDelta2;

    int relative2scroll_rate = Config::get_essential_config(BRIDGE_ESSENTIAL_CONFIG_INDEX_pointing_relative2scroll_rate);

    deltaAxis1 = (delta1 * relative2scroll_rate) / 1024 / DELTA_SCALE;
    deltaAxis2 = (delta2 * relative2scroll_rate) / 1024 / DELTA_SCALE;

    fixedDelta1 = (delta1 * relative2scroll_rate) * (POINTING_FIXED_SCALE / 1024) / DELTA_SCALE;
    fixedDelta2 = (delta2 * relative2scroll_rate) * (POINTING_FIXED_SCALE / 1024) / DELTA_SCALE;

    pointDelta1 = (delta1 * POINTING_POINT_SCALE * relative2scroll_rate) / 1024 / DELTA_SCALE;
    pointDelta2 = (delta2 * POINTING_POINT_SCALE * relative2scroll_rate) / 1024 / DELTA_SCALE;

    // see IOHIDSystem/IOHIDevicePrivateKeys.h about options.
    const int kScrollTypeContinuous_ = 0x0001;
    int options = kScrollTypeContinuous_;

    Params_ScrollWheelEventCallback::auto_ptr ptr(Params_ScrollWheelEventCallback::alloc(deltaAxis1,  deltaAxis2, 0,
                                                                                fixedDelta1, fixedDelta2, 0,
                                                                                pointDelta1, pointDelta2, 0,
                                                                                options));
    if (! ptr) return;
    EventOutputQueue::FireScrollWheel::fire(*ptr);
  }

  // ======================================================================
  void
  EventOutputQueue::FireWait::fire(const Params_Wait& params)
  {
    EventOutputQueue::push(params);
  }
}
<commit_msg>use max to delay<commit_after>#include "Config.hpp"
#include "EventOutputQueue.hpp"
#include "ListHookedConsumer.hpp"
#include "ListHookedKeyboard.hpp"
#include "ListHookedPointing.hpp"
#include "PressDownKeys.hpp"
#include "RemapClass.hpp"
#include "VirtualKey.hpp"
#include "VK_IOHIDPOSTEVENT.hpp"

namespace org_pqrs_KeyRemap4MacBook {
  List* EventOutputQueue::queue_ = NULL;
  TimerWrapper EventOutputQueue::fire_timer_;

  void
  EventOutputQueue::initialize(IOWorkLoop& workloop)
  {
    queue_ = new List();
    fire_timer_.initialize(&workloop, NULL, EventOutputQueue::fire_timer_callback);
  }

  void
  EventOutputQueue::terminate(void)
  {
    fire_timer_.terminate();

    if (queue_) {
      delete queue_;
    }
  }

  // ----------------------------------------------------------------------
#define PUSH_TO_OUTPUTQUEUE {           \
    if (! queue_) return;               \
                                        \
    queue_->push_back(new Item(p));     \
    fire_timer_.setTimeoutMS(0, false); \
}
  void EventOutputQueue::push(const Params_KeyboardEventCallBack& p) {
    PUSH_TO_OUTPUTQUEUE;
    if (p.eventType == EventType::DOWN) {
      FlagStatus::globalFlagStatus().sticky_clear();
    }
  }
  void EventOutputQueue::push(const Params_KeyboardSpecialEventCallback& p) {
    PUSH_TO_OUTPUTQUEUE;
    if (p.ex_iskeydown) {
      FlagStatus::globalFlagStatus().sticky_clear();
    }
  }
  void EventOutputQueue::push(const Params_RelativePointerEventCallback& p) {
    PUSH_TO_OUTPUTQUEUE;
    if (p.buttons != Buttons(0)) {
      FlagStatus::globalFlagStatus().sticky_clear();
    }
  }
  void EventOutputQueue::push(const Params_ScrollWheelEventCallback& p) {
    PUSH_TO_OUTPUTQUEUE;
    FlagStatus::globalFlagStatus().sticky_clear();
  }
  void EventOutputQueue::push(const Params_Wait& p) {
    PUSH_TO_OUTPUTQUEUE;
  }
#undef PUSH_TO_OUTPUTQUEUE

  // ----------------------------------------------------------------------
  void
  EventOutputQueue::fire_timer_callback(OSObject* /* owner */, IOTimerEventSource* /* sender */)
  {
    if (! queue_) return;

    // IOLOG_DEVEL("EventOutputQueue::fire queue_->size = %d\n", static_cast<int>(queue_->size()));

    Item* p = static_cast<Item*>(queue_->front());
    if (! p) return;

    unsigned int delay = 0;

    // ----------------------------------------
    switch ((p->params).type) {
      case ParamsUnion::KEYBOARD:
      {
        Params_KeyboardEventCallBack* params = (p->params).get_Params_KeyboardEventCallBack();
        if (params) {
          bool handled = VirtualKey::handleAfterEnqueued(*params);
          if (! handled) {
            ListHookedKeyboard::instance().apply(*params);
          }

          if ((p->params).isModifier()) {
            // Delay after modifier
            //
            // We need to wait before and after a modifier event because
            // events will be dropped by window server if
            // we send a mouse click event and a modifier event at the same time.
            //
            delay = max(delay, Config::get_wait_before_and_after_a_modifier_key_event());
          }
        }
        break;
      }
      case ParamsUnion::KEYBOARD_SPECIAL:
      {
        Params_KeyboardSpecialEventCallback* params = (p->params).get_Params_KeyboardSpecialEventCallback();
        if (params) {
          if (! ListHookedConsumer::instance().apply(*params)) {
            // If there is no consumer device, we send an event as a software key.
            VirtualKey::VK_IOHIDPOSTEVENT::post(*params);
          }
        }
        break;
      }
      case ParamsUnion::RELATIVE_POINTER:
      {
        Params_RelativePointerEventCallback* params = (p->params).get_Params_RelativePointerEventCallback();
        if (params) {
          ListHookedPointing::instance().apply(*params);
        }
        break;
      }
      case ParamsUnion::SCROLL_WHEEL:
      {
        Params_ScrollWheelEventCallback* params = (p->params).get_Params_ScrollWheelEventCallback();
        if (params) {
          ListHookedPointing::instance().apply(*params);
        }
        break;
      }
      case ParamsUnion::WAIT:
      {
        Params_Wait* params = (p->params).get_Params_Wait();
        if (params) {
          delay = max(delay, static_cast<unsigned int>(params->milliseconds));
        }
        break;
      }
      case ParamsUnion::UPDATE_FLAGS:
        // do nothing
        break;
    }

    queue_->pop_front();

    // ----------------------------------------
    Item* next = static_cast<Item*>(queue_->front());
    if (! next) return;

    if ((next->params).isModifier()) {
      // Delay before modifier
      //
      // See comments of "Delay after modifier".
      //
      delay = max(delay, Config::get_wait_before_and_after_a_modifier_key_event());
    }

    fire_timer_.setTimeoutMS(delay);
  }

  // ======================================================================
  Flags EventOutputQueue::FireModifiers::lastFlags_(0);

  void
  EventOutputQueue::FireModifiers::fire(Flags toFlags, KeyboardType keyboardType)
  {
    if (lastFlags_ == toFlags) return;

    // ------------------------------------------------------------
    // At first we handle KeyUp events and handle KeyDown events next.
    // We need to end KeyDown at Command+Space to Option_L+Shift_L.
    //
    // When Option_L+Shift_L has a meaning (switch input language at Windows),
    // it does not works well when the last is KeyUp of Command.

    // ------------------------------------------------------------
    // KeyUp
    for (size_t i = 0; i < FlagStatus::globalFlagStatus().itemSize(); ++i) {
      ModifierFlag flag = FlagStatus::globalFlagStatus().getFlag(i);

      // Skipping ModifierFlag::NUMPAD
      if (flag.getKeyCode() == KeyCode::VK_NONE) continue;
      // Skipping virtual modifiers.
      if (flag.getRawBits() == 0) continue;

      // ----------------------------------------
      if (! lastFlags_.isOn(flag)) continue;
      if (toFlags.isOn(flag)) continue;

      lastFlags_.remove(flag);

      Params_KeyboardEventCallBack::auto_ptr ptr(Params_KeyboardEventCallBack::alloc(EventType::MODIFY, lastFlags_, flag.getKeyCode(), keyboardType, false));
      if (! ptr) continue;
      EventOutputQueue::push(*ptr);
    }

    // KeyDown
    for (size_t i = 0; i < FlagStatus::globalFlagStatus().itemSize(); ++i) {
      ModifierFlag flag = FlagStatus::globalFlagStatus().getFlag(i);

      // Skipping ModifierFlag::NUMPAD
      if (flag.getKeyCode() == KeyCode::VK_NONE) continue;
      // Skipping virtual modifiers.
      if (flag.getRawBits() == 0) continue;

      // ----------------------------------------
      if (! toFlags.isOn(flag)) continue;
      if (lastFlags_.isOn(flag)) continue;

      lastFlags_.add(flag);

      Params_KeyboardEventCallBack::auto_ptr ptr(Params_KeyboardEventCallBack::alloc(EventType::MODIFY, lastFlags_, flag.getKeyCode(), keyboardType, false));
      if (! ptr) continue;
      EventOutputQueue::push(*ptr);
    }

    lastFlags_ = toFlags;
  }

  // ======================================================================
  void
  EventOutputQueue::FireKey::fire(const Params_KeyboardEventCallBack& params)
  {
    if (VirtualKey::handle(params)) return;

    // ------------------------------------------------------------
    KeyCode newkeycode = params.key;
    Flags newflags = params.flags;

    KeyCode::reverseNormalizeKey(newkeycode, newflags, params.eventType, params.keyboardType);

    // skip no-outputable keycodes.
    // Note: check before FireModifiers to avoid meaningless modifier event.
    if (newkeycode == KeyCode::VK_NONE ||
        newkeycode == KeyCode::VK_PSEUDO_KEY) {
      return;
    }
    if (newkeycode.isModifier() && newkeycode.getModifierFlag().getRawBits() == 0) {
      // virtual modifiers.
      return;
    }

    FireModifiers::fire(newflags, params.keyboardType);

    if (params.eventType == EventType::DOWN || params.eventType == EventType::UP) {
      Params_KeyboardEventCallBack::auto_ptr ptr(Params_KeyboardEventCallBack::alloc(params.eventType, newflags, newkeycode,
                                                                                params.charCode, params.charSet, params.origCharCode, params.origCharSet,
                                                                                params.keyboardType, params.repeat));
      if (ptr) {
        EventOutputQueue::push(*ptr);
      }

      if (! params.repeat) {
        if (params.eventType == EventType::DOWN) {
          PressDownKeys::add(newkeycode, params.keyboardType);
        } else {
          PressDownKeys::remove(newkeycode, params.keyboardType);
        }
      }
    }
  }

  // ======================================================================
  void
  EventOutputQueue::FireConsumer::fire(const Params_KeyboardSpecialEventCallback& params)
  {
    // skip no-outputable keycodes.
    // Note: check before FireModifiers to avoid meaningless modifier event.
    if (params.key == ConsumerKeyCode::VK_NONE ||
        params.key == ConsumerKeyCode::VK_PSEUDO_KEY) {
      return;
    }

    FireModifiers::fire();

    Params_KeyboardSpecialEventCallback::auto_ptr ptr(Params_KeyboardSpecialEventCallback::alloc(params.eventType, params.flags, params.key, params.repeat));
    if (ptr) {
      EventOutputQueue::push(*ptr);
    }
  }

  // ======================================================================
  Buttons EventOutputQueue::FireRelativePointer::lastButtons_(0);

  void
  EventOutputQueue::FireRelativePointer::fire(Buttons toButtons, int dx, int dy)
  {
    // When changing space to command+left click,
    //   __KeyToKey__ KeyCode::SPACE, PointingButton::LEFT, ModifierFlag::COMMAND_L
    //
    // We need to release command key after left click was released as follows.
    //   (1) KeyDown   Command_L
    //   (2) MouseDown Left
    //   (3) MouseUp   Left
    //   (4) KeyUp     Command_L
    //
    // For mouse drag support, command modifier is increased as normal (not temporary_increase).
    // Therefore, command modifier is decreased when space key is released.
    // If we call FireModifiers::fire() at the begining of this function,
    // input events are fired as follows order.
    //   (1) KeyDown   Command_L
    //   (2) MouseDown Left
    //   (3) KeyUp     Command_L
    //   (4) MouseUp   Left
    //
    // It's not desired order.
    // So, we call FireModifiers::fire() at the end of this function when button is released.

    Buttons releasedButtons = lastButtons_;
    releasedButtons.remove(toButtons);
    bool isButtonReleased = ! releasedButtons.isNONE();

    if (! isButtonReleased) {
      FireModifiers::fire();
    }

    // Sending button event
    if (lastButtons_ != toButtons) {
      lastButtons_ = toButtons;

      Params_RelativePointerEventCallback::auto_ptr ptr(Params_RelativePointerEventCallback::alloc(toButtons, 0, 0, PointingButton::NONE, false));
      if (! ptr) return;
      Params_RelativePointerEventCallback& params = *ptr;

      EventOutputQueue::push(params);
    }

    // Sending cursor
    if (dx != 0 || dy != 0) {
      Params_RelativePointerEventCallback::auto_ptr ptr(Params_RelativePointerEventCallback::alloc(toButtons, dx, dy, PointingButton::NONE, false));
      if (! ptr) return;
      Params_RelativePointerEventCallback& params = *ptr;

      EventOutputQueue::push(params);
    }

    if (isButtonReleased) {
      FireModifiers::fire();
    }
  }

  // ======================================================================
  void
  EventOutputQueue::FireScrollWheel::fire(const Params_ScrollWheelEventCallback& params)
  {
    FireModifiers::fire();
    EventOutputQueue::push(params);
  }

  void
  EventOutputQueue::FireScrollWheel::fire(int delta1, int delta2)
  {
    short deltaAxis1;
    short deltaAxis2;
    IOFixed fixedDelta1;
    IOFixed fixedDelta2;
    SInt32 pointDelta1;
    SInt32 pointDelta2;

    int relative2scroll_rate = Config::get_essential_config(BRIDGE_ESSENTIAL_CONFIG_INDEX_pointing_relative2scroll_rate);

    deltaAxis1 = (delta1 * relative2scroll_rate) / 1024 / DELTA_SCALE;
    deltaAxis2 = (delta2 * relative2scroll_rate) / 1024 / DELTA_SCALE;

    fixedDelta1 = (delta1 * relative2scroll_rate) * (POINTING_FIXED_SCALE / 1024) / DELTA_SCALE;
    fixedDelta2 = (delta2 * relative2scroll_rate) * (POINTING_FIXED_SCALE / 1024) / DELTA_SCALE;

    pointDelta1 = (delta1 * POINTING_POINT_SCALE * relative2scroll_rate) / 1024 / DELTA_SCALE;
    pointDelta2 = (delta2 * POINTING_POINT_SCALE * relative2scroll_rate) / 1024 / DELTA_SCALE;

    // see IOHIDSystem/IOHIDevicePrivateKeys.h about options.
    const int kScrollTypeContinuous_ = 0x0001;
    int options = kScrollTypeContinuous_;

    Params_ScrollWheelEventCallback::auto_ptr ptr(Params_ScrollWheelEventCallback::alloc(deltaAxis1,  deltaAxis2, 0,
                                                                                fixedDelta1, fixedDelta2, 0,
                                                                                pointDelta1, pointDelta2, 0,
                                                                                options));
    if (! ptr) return;
    EventOutputQueue::FireScrollWheel::fire(*ptr);
  }

  // ======================================================================
  void
  EventOutputQueue::FireWait::fire(const Params_Wait& params)
  {
    EventOutputQueue::push(params);
  }
}
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	spring damper class
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "utils/vmath.hpp"

namespace gui {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	スプリング・ダンパー・クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class spring_damper {

		float	position_;
		float	offset_;
		float	speed_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
		*/
		//-----------------------------------------------------------------//
		spring_damper() : position_(0.0f), offset_(0.0f), speed_(0.0f) { }

		//-----------------------------------------------------------------//
		/*!
			@brief	アップデート
			@param[in]	select_in	選択開始 (get_select_in)
			@param[in]	select		選択 (get_select)
			@param[in]	pos			現在位置
			@param[in]	scr			スクロール制御量
			@param[in]	limit		リミット
			@param[in]	drag		ドラッグ長
			@return 更新位置
		*/
		//-----------------------------------------------------------------//
		int32_t update(bool select_in, bool select, int32_t pos, int32_t scr, int32_t limit, int32_t drag)
		{
			if(select_in) {
				speed_ = 0.0f;
				offset_ = static_cast<float>(pos);
			}
			float damping = 0.85f;
			float slip_gain = 0.5f;
			float d = static_cast<float>(limit - pos);
			if(select) {
				position_ = offset_ + static_cast<float>(drag);
				if(d < 0.0f) {
					if(position_ < d) {
						position_ -= d;
						position_ *= slip_gain;
						position_ += d;
					} else if(position_ > 0.0f) {
						position_ *= slip_gain;
					}
				} else {
					position_ *= slip_gain;
				}
			} else {
				if(d < 0.0f) {
					if(position_ < d) {
						position_ -= d;
						position_ *= damping;
						position_ += d;
						speed_ = 0.0f;
///						if(position_ >= limit) {
							position_ = limit;
///						}
					} else if(position_ >= 0.0f) {
						position_ *= damping;
						speed_ = 0.0f;
						if(position_ < 0.5f) {
							position_ = 0.0f;
						}
					} else {
						if(scr != 0) {
							position_ += static_cast<float>(scr);
							if(position_ < d) {
								position_ = d;
							} else if(position_ > 0.0f) {
								position_ = 0.0f;
							}
						}
					}
				} else {
///					position_ *= damping;
///					if(-0.5f < position_ && position_ < 0.5f) {
///						position_ = 0.0f;
///						speed_ = 0.0f;
///					}
				}
			}
			return static_cast<int32_t>(position_);
		}
	};
}
<commit_msg>update speed, clip<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	spring damper class
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "utils/vmath.hpp"

namespace gui {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	スプリング・ダンパー・クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class spring_damper {

		static constexpr float slip_gain_  = 0.5f;
		static constexpr float damping_    = 0.85f;
		static constexpr float speed_gain_ = 0.95f;	 ///< 速度の減衰
		static constexpr float acc_gain_   = 0.15f;  ///< ドラッグを離した時の加速度ゲイン

		float	position_;
		float	offset_;
		float	speed_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
		*/
		//-----------------------------------------------------------------//
		spring_damper() : position_(0.0f), offset_(0.0f), speed_(0.0f) { }

		//-----------------------------------------------------------------//
		/*!
			@brief	アップデート
			@param[in]	select_in	選択開始 (get_select_in)
			@param[in]	select		選択 (get_select)
			@param[in]	pos			現在位置
			@param[in]	scr			スクロール制御量
			@param[in]	limit		リミット
			@param[in]	drag		ドラッグ長
			@return 更新位置
		*/
		//-----------------------------------------------------------------//
		int32_t update(bool select_in, bool select, int32_t pos, int32_t scr, int32_t limit, int32_t drag)
		{
			if(select_in) {  // 選択開始時
				speed_ = 0.0f;
				offset_ = static_cast<float>(pos);
			}
			float lim = static_cast<float>(limit);
			if(select) {  // 選択中の挙動
				speed_ = static_cast<float>(drag);
				position_ = offset_ + speed_;
				speed_ *= acc_gain_;  // 加速度の調整
				if(position_ > 0.0f) {
					position_ *= slip_gain_;
				} else if(position_ < lim) {
					position_ -= lim;
					position_ *= slip_gain_;
					position_ += lim;
				}
			} else {
				position_ += speed_;
				speed_ *= speed_gain_;
				if(-0.5f < speed_ && speed_ < 0.5f) speed_ = 0.0f;

				if(position_ > 0.0f) {
					speed_ = 0.0f;
					position_ *= damping_;
					if(position_ < 1.0f) {
						position_ = 0.0f;
					}
				} else if(position_ < lim) {
					speed_ = 0.0f;
					position_ -= lim;
					position_ *= damping_;
					position_ += lim;
					if(position_ > (lim - 1.0f)) {
						position_ = lim;
					}
				}
			}
			return static_cast<int32_t>(position_);
		}
	};
}
<|endoftext|>


<commit_before>#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
#include <cxxopts.hpp>
#pragma clang diagnostic pop

#include "constants.hpp"
#include "dispatcher_utility.hpp"
#include "logger.hpp"
#include "monitor/configuration_monitor.hpp"
#include <iostream>
#include <pqrs/thread_wait.hpp>
#include <spdlog/sinks/stdout_color_sinks.h>

namespace {
void select_profile(const std::string& name) {
  auto wait = pqrs::make_thread_wait();
  krbn::configuration_monitor monitor(krbn::constants::get_user_core_configuration_file_path());

  monitor.core_configuration_updated.connect([name, wait](auto&& weak_core_configuration) {
    if (auto core_configuration = weak_core_configuration.lock()) {
      auto& profiles = core_configuration->get_profiles();
      for (size_t i = 0; i < profiles.size(); ++i) {
        if (profiles[i].get_name() == name) {
          core_configuration->select_profile(i);
          core_configuration->sync_save_to_file();
          goto finish;
        }
      }
      krbn::logger::get_logger()->error("`{0}` is not found.", name);
    }

  finish:
    wait->notify();
  });

  monitor.async_start();

  wait->wait_notice();
}

int copy_current_profile_to_system_default_profile(void) {
  pqrs::filesystem::create_directory_with_intermediate_directories(krbn::constants::get_system_configuration_directory(), 0755);
  pqrs::filesystem::copy(krbn::constants::get_user_core_configuration_file_path(),
                         krbn::constants::get_system_core_configuration_file_path());
  return 0;
}

int remove_system_default_profile(void) {
  if (!pqrs::filesystem::exists(krbn::constants::get_system_core_configuration_file_path())) {
    krbn::logger::get_logger()->error("{0} is not found.", krbn::constants::get_system_core_configuration_file_path());
    return 1;
  }
  if (unlink(krbn::constants::get_system_core_configuration_file_path()) != 0) {
    krbn::logger::get_logger()->error("Failed to unlink {0}.");
    return 1;
  }
  return 0;
}
} // namespace

int main(int argc, char** argv) {
  int exit_code = 0;

  krbn::dispatcher_utility::initialize_dispatchers();

  {
    auto l = spdlog::stdout_color_mt("karabiner_cli");
    l->set_pattern("[%l] %v");
    l->set_level(spdlog::level::err);
    krbn::logger::set_logger(l);
  }

  cxxopts::Options options("karabiner_cli", "A command line utility of Karabiner-Elements.");

  options.add_options()("select-profile", "Select a profile by name.", cxxopts::value<std::string>());
  options.add_options()("copy-current-profile-to-system-default-profile", "Copy the current profile to system default profile.");
  options.add_options()("remove-system-default-profile", "Remove the system default profile.");
  options.add_options()("help", "Print help.");

  try {
    auto parse_result = options.parse(argc, argv);

    {
      std::string key = "select-profile";
      if (parse_result.count(key)) {
        select_profile(parse_result[key].as<std::string>());
        goto finish;
      }
    }

    {
      std::string key = "copy-current-profile-to-system-default-profile";
      if (parse_result.count(key)) {
        if (getuid() != 0) {
          krbn::logger::get_logger()->error("--{0} requires root privilege.", key);
          exit_code = 1;
          goto finish;
        }
        exit_code = copy_current_profile_to_system_default_profile();
        goto finish;
      }
    }

    {
      std::string key = "remove-system-default-profile";
      if (parse_result.count(key)) {
        if (getuid() != 0) {
          krbn::logger::get_logger()->error("--{0} requires root privilege.", key);
          exit_code = 1;
          goto finish;
        }
        exit_code = remove_system_default_profile();
        goto finish;
      }
    }

  } catch (const cxxopts::OptionException& e) {
    std::cout << "error parsing options: " << e.what() << std::endl;
    exit_code = 2;
    goto finish;
  }

  std::cout << options.help() << std::endl;
  std::cout << "Examples:" << std::endl;
  std::cout << "  karabiner_cli --select-profile 'Default profile'" << std::endl;
  std::cout << std::endl;

  exit_code = 1;

finish:
  krbn::dispatcher_utility::terminate_dispatchers();

  return exit_code;
}
<commit_msg>add --version,--version-number to cli<commit_after>#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
#include <cxxopts.hpp>
#pragma clang diagnostic pop

#include "constants.hpp"
#include "dispatcher_utility.hpp"
#include "karabiner_version.h"
#include "logger.hpp"
#include "monitor/configuration_monitor.hpp"
#include <iostream>
#include <pqrs/thread_wait.hpp>
#include <spdlog/sinks/stdout_color_sinks.h>

namespace {
void select_profile(const std::string& name) {
  auto wait = pqrs::make_thread_wait();
  krbn::configuration_monitor monitor(krbn::constants::get_user_core_configuration_file_path());

  monitor.core_configuration_updated.connect([name, wait](auto&& weak_core_configuration) {
    if (auto core_configuration = weak_core_configuration.lock()) {
      auto& profiles = core_configuration->get_profiles();
      for (size_t i = 0; i < profiles.size(); ++i) {
        if (profiles[i].get_name() == name) {
          core_configuration->select_profile(i);
          core_configuration->sync_save_to_file();
          goto finish;
        }
      }
      krbn::logger::get_logger()->error("`{0}` is not found.", name);
    }

  finish:
    wait->notify();
  });

  monitor.async_start();

  wait->wait_notice();
}

int copy_current_profile_to_system_default_profile(void) {
  pqrs::filesystem::create_directory_with_intermediate_directories(krbn::constants::get_system_configuration_directory(), 0755);
  pqrs::filesystem::copy(krbn::constants::get_user_core_configuration_file_path(),
                         krbn::constants::get_system_core_configuration_file_path());
  return 0;
}

int remove_system_default_profile(void) {
  if (!pqrs::filesystem::exists(krbn::constants::get_system_core_configuration_file_path())) {
    krbn::logger::get_logger()->error("{0} is not found.", krbn::constants::get_system_core_configuration_file_path());
    return 1;
  }
  if (unlink(krbn::constants::get_system_core_configuration_file_path()) != 0) {
    krbn::logger::get_logger()->error("Failed to unlink {0}.");
    return 1;
  }
  return 0;
}
} // namespace

int main(int argc, char** argv) {
  int exit_code = 0;

  krbn::dispatcher_utility::initialize_dispatchers();

  {
    auto l = spdlog::stdout_color_mt("karabiner_cli");
    l->set_pattern("[%l] %v");
    l->set_level(spdlog::level::err);
    krbn::logger::set_logger(l);
  }

  cxxopts::Options options("karabiner_cli", "A command line utility of Karabiner-Elements.");

  options.add_options()("select-profile", "Select a profile by name.", cxxopts::value<std::string>());
  options.add_options()("copy-current-profile-to-system-default-profile", "Copy the current profile to system default profile.");
  options.add_options()("remove-system-default-profile", "Remove the system default profile.");
  options.add_options()("version", "Displays version.");
  options.add_options()("version-number", "Displays version_number.");
  options.add_options()("help", "Print help.");

  try {
    auto parse_result = options.parse(argc, argv);

    {
      std::string key = "select-profile";
      if (parse_result.count(key)) {
        select_profile(parse_result[key].as<std::string>());
        goto finish;
      }
    }

    {
      std::string key = "copy-current-profile-to-system-default-profile";
      if (parse_result.count(key)) {
        if (getuid() != 0) {
          krbn::logger::get_logger()->error("--{0} requires root privilege.", key);
          exit_code = 1;
          goto finish;
        }
        exit_code = copy_current_profile_to_system_default_profile();
        goto finish;
      }
    }

    {
      std::string key = "remove-system-default-profile";
      if (parse_result.count(key)) {
        if (getuid() != 0) {
          krbn::logger::get_logger()->error("--{0} requires root privilege.", key);
          exit_code = 1;
          goto finish;
        }
        exit_code = remove_system_default_profile();
        goto finish;
      }
    }

    {
      std::string key = "version";
      if (parse_result.count(key)) {
        std::cout << karabiner_version << std::endl;
        goto finish;
      }
    }

    {
      std::string key = "version-number";
      if (parse_result.count(key)) {
        int n = 0;
        std::string number;

        for (const auto& c : std::string_view(karabiner_version)) {
          if (c == '.') {
            if (!number.empty()) {
              n += stoi(number);
              number.clear();
            }
            n *= 100;

          } else {
            number += c;
          }
        }

        if (!number.empty()) {
          n += stoi(number);
          number.clear();
        }

        std::cout << n << std::endl;
        goto finish;
      }
    }

  } catch (const cxxopts::OptionException& e) {
    std::cout << "error parsing options: " << e.what() << std::endl;
    exit_code = 2;
    goto finish;
  }

  std::cout << options.help() << std::endl;
  std::cout << "Examples:" << std::endl;
  std::cout << "  karabiner_cli --select-profile 'Default profile'" << std::endl;
  std::cout << std::endl;

  exit_code = 1;

finish:
  krbn::dispatcher_utility::terminate_dispatchers();

  return exit_code;
}
<|endoftext|>


<commit_before>// C++ source file - (C) 2003 Robert Osfield, released under the OSGPL.

#include <osgViewer/Viewer>
#include <osgViewer/StatsHandler>
#include <osgGA/TrackballManipulator>
#include <osgDB/ReadFile>

#if USE_QT4

    #include <QtCore/QTimer>
    #include <QtGui/QKeyEvent>
    #include <QtGui/QApplication>
    #include <QtOpenGL/QGLWidget>

    using Qt::WFlags;

#else

    class QWidget;
    #include <qtimer.h>
    #include <qgl.h>
    #include <qapplication.h>

#endif

#include <iostream>

class AdapterWidget : public QGLWidget
{
    public:

        AdapterWidget( QWidget * parent = 0, const char * name = 0, const QGLWidget * shareWidget = 0, WFlags f = 0 );

        virtual ~AdapterWidget() {}

        osgViewer::GraphicsWindow* getGraphicsWindow() { return _gw.get(); }
        const osgViewer::GraphicsWindow* getGraphicsWindow() const { return _gw.get(); }

    protected:

        void init();

        virtual void resizeGL( int width, int height );
        virtual void keyPressEvent( QKeyEvent* event );
        virtual void keyReleaseEvent( QKeyEvent* event );
        virtual void mousePressEvent( QMouseEvent* event );
        virtual void mouseReleaseEvent( QMouseEvent* event );
        virtual void mouseMoveEvent( QMouseEvent* event );

        osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> _gw;
};

AdapterWidget::AdapterWidget( QWidget * parent, const char * name, const QGLWidget * shareWidget, WFlags f):
    QGLWidget(parent, name, shareWidget, f)
{
    _gw = new osgViewer::GraphicsWindowEmbedded(0,0,width(),height());
}

void AdapterWidget::resizeGL( int width, int height )
{
    _gw->getEventQueue()->windowResize(0, 0, width, height );
    _gw->resized(0,0,width,height);
}

void AdapterWidget::keyPressEvent( QKeyEvent* event )
{
    _gw->getEventQueue()->keyPress( (osgGA::GUIEventAdapter::KeySymbol) event->ascii() );
}

void AdapterWidget::keyReleaseEvent( QKeyEvent* event )
{
    _gw->getEventQueue()->keyRelease( (osgGA::GUIEventAdapter::KeySymbol) event->ascii() );
}

void AdapterWidget::mousePressEvent( QMouseEvent* event )
{
    int button = 0;
    switch(event->button())
    {
        case(Qt::LeftButton): button = 1; break;
        case(Qt::MidButton): button = 2; break;
        case(Qt::RightButton): button = 3; break;
        case(Qt::NoButton): button = 0; break;
        default: button = 0; break;
    }
    _gw->getEventQueue()->mouseButtonPress(event->x(), event->y(), button);
}

void AdapterWidget::mouseReleaseEvent( QMouseEvent* event )
{
    int button = 0;
    switch(event->button())
    {
        case(Qt::LeftButton): button = 1; break;
        case(Qt::MidButton): button = 2; break;
        case(Qt::RightButton): button = 3; break;
        case(Qt::NoButton): button = 0; break;
        default: button = 0; break;
    }
    _gw->getEventQueue()->mouseButtonRelease(event->x(), event->y(), button);
}

void AdapterWidget::mouseMoveEvent( QMouseEvent* event )
{
    _gw->getEventQueue()->mouseMotion(event->x(), event->y());
}

class ViewerQT : public osgViewer::Viewer, public AdapterWidget
{
    public:

        ViewerQT(QWidget * parent = 0, const char * name = 0, const QGLWidget * shareWidget = 0, WFlags f = 0):
            AdapterWidget( parent, name, shareWidget, f )
        {
            getCamera()->setViewport(new osg::Viewport(0,0,width(),height()));
            getCamera()->setGraphicsContext(getGraphicsWindow());
            setThreadingModel(osgViewer::Viewer::SingleThreaded);

            connect(&_timer, SIGNAL(timeout()), this, SLOT(updateGL()));
            _timer.start(10);
        }

        virtual void paintGL()
        {
            frame();
        }

    protected:

        QTimer _timer;

};

int main( int argc, char **argv )
{
    QApplication a( argc, argv );

    if (argc<2)
    {
        std::cout << argv[0] <<": requires filename argument." << std::endl;
        return 1;
    }

    // load the scene.
    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(argv[1]);
    if (!loadedModel)
    {
        std::cout << argv[0] <<": No data loaded." << std::endl;
        return 1;
    }

    ViewerQT* viewerWindow = new ViewerQT;

    viewerWindow->setSceneData(loadedModel.get());
    viewerWindow->setCameraManipulator(new osgGA::TrackballManipulator);
    viewerWindow->addEventHandler(new osgViewer::StatsHandler);

    viewerWindow->show();
    a.connect( &a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()) );

    return a.exec();
}

/*EOF*/
<commit_msg>Fixed stray control character<commit_after>// C++ source file - (C) 2003 Robert Osfield, released under the OSGPL.

#include <osgViewer/Viewer>
#include <osgViewer/StatsHandler>
#include <osgGA/TrackballManipulator>
#include <osgDB/ReadFile>

#if USE_QT4

    #include <QtCore/QTimer>
    #include <QtGui/QKeyEvent>
    #include <QtGui/QApplication>
    #include <QtOpenGL/QGLWidget>

    using Qt::WFlags;

#else

    class QWidget;
    #include <qtimer.h>
    #include <qgl.h>
    #include <qapplication.h>

#endif

#include <iostream>

class AdapterWidget : public QGLWidget
{
    public:

        AdapterWidget( QWidget * parent = 0, const char * name = 0, const QGLWidget * shareWidget = 0, WFlags f = 0 );

        virtual ~AdapterWidget() {}

        osgViewer::GraphicsWindow* getGraphicsWindow() { return _gw.get(); }
        const osgViewer::GraphicsWindow* getGraphicsWindow() const { return _gw.get(); }

    protected:

        void init();

        virtual void resizeGL( int width, int height );
        virtual void keyPressEvent( QKeyEvent* event );
        virtual void keyReleaseEvent( QKeyEvent* event );
        virtual void mousePressEvent( QMouseEvent* event );
        virtual void mouseReleaseEvent( QMouseEvent* event );
        virtual void mouseMoveEvent( QMouseEvent* event );

        osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> _gw;
};

AdapterWidget::AdapterWidget( QWidget * parent, const char * name, const QGLWidget * shareWidget, WFlags f):
    QGLWidget(parent, name, shareWidget, f)
{
    _gw = new osgViewer::GraphicsWindowEmbedded(0,0,width(),height());
}

void AdapterWidget::resizeGL( int width, int height )
{
    _gw->getEventQueue()->windowResize(0, 0, width, height );
    _gw->resized(0,0,width,height);
}

void AdapterWidget::keyPressEvent( QKeyEvent* event )
{
    _gw->getEventQueue()->keyPress( (osgGA::GUIEventAdapter::KeySymbol) event->ascii() );
}

void AdapterWidget::keyReleaseEvent( QKeyEvent* event )
{
    _gw->getEventQueue()->keyRelease( (osgGA::GUIEventAdapter::KeySymbol) event->ascii() );
}

void AdapterWidget::mousePressEvent( QMouseEvent* event )
{
    int button = 0;
    switch(event->button())
    {
        case(Qt::LeftButton): button = 1; break;
        case(Qt::MidButton): button = 2; break;
        case(Qt::RightButton): button = 3; break;
        case(Qt::NoButton): button = 0; break;
        default: button = 0; break;
    }
    _gw->getEventQueue()->mouseButtonPress(event->x(), event->y(), button);
}

void AdapterWidget::mouseReleaseEvent( QMouseEvent* event )
{
    int button = 0;
    switch(event->button())
    {
        case(Qt::LeftButton): button = 1; break;
        case(Qt::MidButton): button = 2; break;
        case(Qt::RightButton): button = 3; break;
        case(Qt::NoButton): button = 0; break;
        default: button = 0; break;
    }
    _gw->getEventQueue()->mouseButtonRelease(event->x(), event->y(), button);
}

void AdapterWidget::mouseMoveEvent( QMouseEvent* event )
{
    _gw->getEventQueue()->mouseMotion(event->x(), event->y());
}

class ViewerQT : public osgViewer::Viewer, public AdapterWidget
{
    public:

        ViewerQT(QWidget * parent = 0, const char * name = 0, const QGLWidget * shareWidget = 0, WFlags f = 0):
            AdapterWidget( parent, name, shareWidget, f )
        {
            getCamera()->setViewport(new osg::Viewport(0,0,width(),height()));
            getCamera()->setGraphicsContext(getGraphicsWindow());
            setThreadingModel(osgViewer::Viewer::SingleThreaded);

            connect(&_timer, SIGNAL(timeout()), this, SLOT(updateGL()));
            _timer.start(10);
        }

        virtual void paintGL()
        {
            frame();
        }

    protected:

        QTimer _timer;

};

int main( int argc, char **argv )
{
    QApplication a( argc, argv );

    if (argc<2)
    {
        std::cout << argv[0] <<": requires filename argument." << std::endl;
        return 1;
    }

    // load the scene.
    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(argv[1]);
    if (!loadedModel)
    {
        std::cout << argv[0] <<": No data loaded." << std::endl;
        return 1;
    }

    ViewerQT* viewerWindow = new ViewerQT;

    viewerWindow->setSceneData(loadedModel.get());
    viewerWindow->setCameraManipulator(new osgGA::TrackballManipulator);
    viewerWindow->addEventHandler(new osgViewer::StatsHandler);

    viewerWindow->show();
    a.connect( &a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()) );

    return a.exec();
}

/*EOF*/
<|endoftext|>