Example #1
0
//--------------------------------------------------------------------------
//  Read all keyboard definitions
//--------------------------------------------------------------------------
int CKeyMap::Read (SStream *stream, Tag tag)
{
  int rc = TAG_IGNORED;

  switch (tag) {
  case 'vers':
    // Version
    ReadInt (&vers, stream);
    rc = TAG_READ;
    break;

  case 'kset':
    // KeySet sub-object
    {
      Tag ksetTag;
      ReadTag (&ksetTag, stream);
      CheckSet(ksetTag);
      CKeySet *ks = new CKeySet (ksetTag);
      ReadFrom (ks, stream);
      kset[ks->GetTag()] = ks;
      oset.push_back(ks);
    }
    rc = TAG_READ;
    break;
  }

  if (rc == TAG_IGNORED) {
    globals->logWarning->Write ("CKeyMap::Read : Unknown tag %s", TagToString(tag));
  }

  return rc;
}
Example #2
0
//--------------------------------------------------------------------------
//  Print all keys
//--------------------------------------------------------------------------
void CKeyMap::Print (FILE* f)
{
  // Iterate over keysets
  std::map<Tag,CKeySet*>::iterator i;
  for (i=kset.begin(); i!=kset.end(); i++) {
    CKeySet *pKeySet = i->second;

    // Format key set unique ID
    char s[8];
    TagToString (s, pKeySet->GetTag());
    fprintf (f, "KeySet '%s' %s\n", s, pKeySet->GetName());

    // Iterate over key definitions within the keyset
    std::map<Tag,CKeyDefinition*>::iterator j;
    for (j=pKeySet->dkey.begin(); j!=pKeySet->dkey.end(); j++) {
      CKeyDefinition *pKeyDef = j->second;

      // Format key definition unique ID
      char sId[8];
      TagToString (sId, pKeyDef->GetTag());

      // Format key code
      char sCode[32];
      formatKeyCode (sCode, pKeyDef->GetCode());

      fprintf (f, "  '%s' %-40s  %s\n", sId, pKeyDef->GetName(), sCode);
    }
  }
}
Example #3
0
//------------------------------------------------------------------------------
//  Bind keyset with group key to global function f
//------------------------------------------------------------------------------
void CKeyMap::BindGroup(Tag gp,KeyGroupCB f)
{ CKeySet *set = FindKeySetById(gp);
  if (0 == set)   return;
  lgrp  = gp;                     // Remember the group
  set->BindTo(f);
  return;
}
int LuaUnsyncedRead::GetKeyBindings(lua_State* L)
{
	const int args = lua_gettop(L); // number of arguments
	if ((args != 1) || !lua_isstring(L, 1)) {
		luaL_error(L, "Incorrect arguments to GetKeyBindings(\"keyset\")");
	}
	const string keysetStr = lua_tostring(L, 1);
	CKeySet ks;
	if (!ks.Parse(keysetStr)) {
		return 0;
	}
	const CKeyBindings::ActionList&	actions = keyBindings->GetActionList(ks);
	lua_newtable(L);
	for (int i = 0; i < (int)actions.size(); i++) {
		const Action& action = actions[i];
		lua_pushnumber(L, i + 1);
		lua_newtable(L);
		lua_pushstring(L, action.command.c_str());
		lua_pushstring(L, action.extra.c_str());
		lua_rawset(L, -3);
		lua_rawset(L, -3);
	}
	lua_pushstring(L, "n");
	lua_pushnumber(L, actions.size());
	lua_rawset(L, -3);
	return 1;
}
Example #5
0
const CKeyBindings::ActionList&
	CKeyBindings::GetActionList(const CKeySet& ks) const
{
	static const ActionList empty;
	const ActionList* alPtr = NULL;

	if (ks.AnyMod()) {
		KeyMap::const_iterator it = bindings.find(ks);
		if (it == bindings.end()) {
			alPtr = &empty;
		} else {
			alPtr = &(it->second);
		}
	}
	else {
		// have to check for an AnyMod keyset as well as the normal one
		CKeySet anyMod = ks;
		anyMod.SetAnyBit();
		KeyMap::const_iterator nit = bindings.find(ks);
		KeyMap::const_iterator ait = bindings.find(anyMod);
		const bool haveNormal = (nit != bindings.end());
		const bool haveAnyMod = (ait != bindings.end());
		if (!haveNormal && !haveAnyMod) {
			alPtr = &empty;
		}
		else if (haveNormal && !haveAnyMod) {
			alPtr = &(nit->second);
		}
		else if (!haveNormal && haveAnyMod) {
			alPtr = &(ait->second);
		}
		else {
			// combine the two lists (normal first)
			static ActionList merged;
			merged = nit->second;
			const ActionList& aal = ait->second;
			for (int i = 0; i < (int)aal.size(); ++i) {
				merged.push_back(aal[i]);
			}
			alPtr = &merged;
		}
	}

	if (LOG_IS_ENABLED(L_DEBUG)) {
		const bool isEmpty = (alPtr == &empty);
		LOG_L(L_DEBUG, "GetAction: %s (0x%03X)%s",
				ks.GetString(false).c_str(), ks.Key(),
				(isEmpty ? "  EMPTY" : ""));
		if (!isEmpty) {
			const ActionList& al = *alPtr;
			for (size_t i = 0; i < al.size(); ++i) {
				LOG_L(L_DEBUG, "  %s  \"%s\"",
						al[i].command.c_str(), al[i].rawline.c_str());
			}
		}
	}

	return *alPtr;
}
Example #6
0
//------------------------------------------------------------------------------
//  Reset all keys to default values
//------------------------------------------------------------------------------
void CKeyMap::SetDefaultValues(CKeyFile *def)
{ std::map<Tag,CKeySet*>::iterator i;
  for (i=kset.begin(); i!=kset.end(); i++) {
      CKeySet *ks = i->second;
      ks->SetDefaultValues(def);
    }
 return; 
}
Example #7
0
//------------------------------------------------------------------------------
//  Assign code to key definition
//------------------------------------------------------------------------------
void  CKeyMap::Assign(int cde,CKeyDefinition *kdf)
{ Tag ks = kdf->GetSet();
  kdf->SetCode(cde);
  std::map<Tag,CKeySet*>::iterator it = kset.find(ks);
  if (it == kset.end())   return;
  CKeySet *set = (*it).second;
  set->StoreKeyDef(kdf);
  return;
}
Example #8
0
//------------------------------------------------------------------------------
//  Unassign code from any key definition existing in the set
//	NOTE: The key is unassigned from the current set only
//------------------------------------------------------------------------------
CKeyDefinition *CKeyMap::UnAssign(int cde,CKeyDefinition *kdf)
{ CKeySet					*set = FindKeySetById(kdf->GetSet());
  CKeyDefinition	*kpv = set->GetKeyByCode(cde);
  if (0   == kpv)         return 0;
  kdf->SetCode(0);			// remove code from actual
	kpv->SetCode(0);			// remove code from previous
	set->ClearCode(cde);
  return kpv;
}
Example #9
0
//------------------------------------------------------------------------------
//  Locate a key definition by  key identifier only
//  NOTE:  Group are searched from upper group(menus,..) to lower group (aircraft)
//------------------------------------------------------------------------------
CKeyDefinition* CKeyMap::FindKeyDefinitionById (Tag id)
{ CKeyDefinition *rc = NULL;
  for (U_INT k=0; k< oset.size();k++)
  { CKeySet *ks         = oset[k];
    CKeyDefinition* kdf = ks->GetKeyByTag(id);
    if (0 == kdf) continue;
    return kdf;
  }
  return 0;
}
Example #10
0
//-------------------------------------------------------------------------
//  Change group callback if key is redirected
//-------------------------------------------------------------------------
//  Activate key in group (simulate a key stroke)
//  The group is taken from the Keydef in case of redirection
//-------------------------------------------------------------------------
bool CKeyMap::Stroke(Tag grp,Tag kid)
{ //--- find the Key set ---------------------------
  CKeySet *ks = FindKeySetById (grp);
  if (0 == ks)    return false;
  CKeyDefinition *kdf = ks->GetKeyByTag(kid);
  if (0 == kdf)   return false;
  //--- Group Redirection --------------------------
  Tag        ngp = kdf->GetSet();
  ks             =   FindKeySetById (ngp);
  KeyGroupCB  cb = ks->GetCB();
  return (cb)(kdf,kdf->GetCode()) ;
}
Example #11
0
//------------------------------------------------------------------------------
//  Locate a key definition by  keyboard code only
//------------------------------------------------------------------------------
CKeyDefinition* CKeyMap::FindKeyDefinitionByCode (int iCode, Tag &setTagOut)
{ setTagOut = 0;
  std::map<Tag,CKeySet*>::iterator i;
  for (i=kset.begin(); i!=kset.end(); i++)
  { CKeySet *set = i->second;
    CKeyDefinition *kdf = set->GetKeyByCode(iCode);
    if (0 == kdf)     continue;
    setTagOut = set->GetTag();
    return kdf;
  }
 return 0;
}
bool CKeyBindings::AddKeySymbol(const string& keysym, const string& code)
{
	CKeySet ks;
	if (!ks.Parse(code)) {
		logOutput.Print("AddKeySymbol: could not parse key: %s\n", code.c_str());
		return false;
	}
	if (!keyCodes->AddKeySymbol(keysym, ks.Key())) {
		logOutput.Print("AddKeySymbol: could not add: %s\n", keysym.c_str());
		return false;
	}
	return true;
}
bool CKeyBindings::AddNamedKeySet(const string& name, const string& keystr)
{
	CKeySet ks;
	if (!ks.Parse(keystr)) {
		printf("AddNamedKeySet: could not parse keyset: %s\n", keystr.c_str());
		return false;
	}
	if ((ks.Key() < 0) || !CKeyCodes::IsValidLabel(name)) {
		printf("AddNamedKeySet: bad custom keyset name: %s\n", name.c_str());
		return false;
	}
	namedKeySets[name] = ks;
}
Example #14
0
bool CKeyBindings::AddKeySymbol(const string& keysym, const string& code)
{
	CKeySet ks;
	if (!ks.Parse(code)) {
		LOG_L(L_WARNING, "AddKeySymbol: could not parse key: %s", code.c_str());
		return false;
	}
	if (!keyCodes->AddKeySymbol(keysym, ks.Key())) {
		LOG_L(L_WARNING, "AddKeySymbol: could not add: %s", keysym.c_str());
		return false;
	}
	return true;
}
Example #15
0
//------------------------------------------------------------------------------
//  Swap key code
//------------------------------------------------------------------------------
void CKeyMap::SwapCode(CKeyDefinition *kdf,int nc)
{ Tag ks = kdf->GetSet();
  int cd = kdf->GetCode();
  kdf->SetCode(0);
  std::map<Tag,CKeySet*>::iterator it = kset.find(ks);
  if (it != kset.end())      return;   // No set
  CKeySet *set = (*it).second;
  set->ClearCode(cd);
  //---Set the new code ----------------------------
  kdf->SetCode(nc);
  set->StoreKeyDef(kdf);
  return;
}
bool CKeyBindings::SetFakeMetaKey(const string& keystr)
{
	CKeySet ks;
	if (StringToLower(keystr) == "none") {
		fakeMetaKey = -1;
		return true;
	}
	if (!ks.Parse(keystr)) {
		logOutput.Print("SetFakeMetaKey: could not parse key: %s\n", keystr.c_str());
		return false;
	}
	fakeMetaKey = ks.Key();
	return true;
}
Example #17
0
bool CKeyBindings::SetFakeMetaKey(const string& keystr)
{
	CKeySet ks;
	if (StringToLower(keystr) == "none") {
		fakeMetaKey = -1;
		return true;
	}
	if (!ks.Parse(keystr)) {
		LOG_L(L_WARNING, "SetFakeMetaKey: could not parse key: %s", keystr.c_str());
		return false;
	}
	fakeMetaKey = ks.Key();
	return true;
}
Example #18
0
const CKeyBindings::ActionList& CKeyBindings::GetActionList(const CKeySet& ks) const
{
    static const ActionList empty;
    const ActionList* alPtr = &empty;

    if (ks.AnyMod()) {
        KeyMap::const_iterator it = bindings.find(ks);
        if (it != bindings.end()) {
            alPtr = &(it->second);
        }
    }
    else {
        // have to check for an AnyMod keyset as well as the normal one
        CKeySet anyMod = ks;
        anyMod.SetAnyBit();
        KeyMap::const_iterator nit = bindings.find(ks);
        KeyMap::const_iterator ait = bindings.find(anyMod);
        const bool haveNormal = (nit != bindings.end());
        const bool haveAnyMod = (ait != bindings.end());
        if (haveNormal && !haveAnyMod) {
            alPtr = &(nit->second);
        }
        else if (!haveNormal && haveAnyMod) {
            alPtr = &(ait->second);
        }
        else if (haveNormal && haveAnyMod) {
            // combine the two lists (normal first)
            static ActionList merged; //FIXME switch to thread_local when all buildbots are using >=gcc4.7
            merged = nit->second;
            merged.insert(merged.end(), ait->second.begin(), ait->second.end());
            alPtr = &merged;
        }
    }

    if (debugEnabled) {
        LOG("GetActions: hex=0x%02X acii=\"%s\":", ks.Key(), ks.GetString(false).c_str());
        if (alPtr != &empty) {
            int i = 1;
            for (const auto& a: *alPtr) {
                LOG("   %i. action=\"%s\"  rawline=\"%s\"  shortcut=\"%s\"", i++, a.command.c_str(), a.rawline.c_str(), a.boundWith.c_str());
            }
        } else {
            LOG("   EMPTY");
        }
    }

    return *alPtr;
}
Example #19
0
bool CKeyBindings::Bind(const string& keystr, const string& line)
{
	CKeySet ks;
	if (!ParseKeySet(keystr, ks)) {
		LOG_L(L_WARNING, "Bind: could not parse key: %s", keystr.c_str());
		return false;
	}
	Action action(line);
	action.boundWith = keystr;
	if (action.command.empty()) {
		LOG_L(L_WARNING, "Bind: empty action: %s", line.c_str());
		return false;
	}

	// Try to be safe, force AnyMod mode for stateful commands
	if (statefulCommands.find(action.command) != statefulCommands.end()) {
		ks.SetAnyBit();
	}

	KeyMap::iterator it = bindings.find(ks);
	if (it == bindings.end()) {
		// new entry, push it
		ActionList& al = bindings[ks];
		al.push_back(action);
	} else {
		if (it->first != ks) {
			// not a match, push it
			ActionList& al = it->second;
			al.push_back(action);
		}
		else {
			// an exact keyset match, check the command
			ActionList& al = it->second;
			int i;
			for (i = 0; i < (int)al.size(); i++) {
				if (action.command == al[i].command) {
					break;
				}
			}
			if (i == (int)al.size()) {
				// not a match, push it
				al.push_back(action);
			}
		}
	}

	return true;
}
Example #20
0
bool CKeyBindings::UnBindKeyset(const std::string& keystr)
{
    CKeySet ks;
    if (!ks.Parse(keystr)) {
        LOG_L(L_WARNING, "UnBindKeyset: could not parse key: %s", keystr.c_str());
        return false;
    }
    bool success = false;

    KeyMap::iterator it = bindings.find(ks);
    if (it != bindings.end()) {
        bindings.erase(it);
        success = true;
    }

    return success;
}
Example #21
0
bool CKeyBindings::UnBind(const std::string& keystr, const std::string& command)
{
    CKeySet ks;
    if (!ks.Parse(keystr)) {
        LOG_L(L_WARNING, "UnBind: could not parse key: %s", keystr.c_str());
        return false;
    }
    bool success = false;

    KeyMap::iterator it = bindings.find(ks);
    if (it != bindings.end()) {
        ActionList& al = it->second;
        success = RemoveCommandFromList(al, command);
        if (al.empty()) {
            bindings.erase(it);
        }
    }
    return success;
}
Example #22
0
static bool ParseSingleChain(const std::string& keystr, CKeyChain* kc)
{
    kc->clear();
    CKeySet ks;

    // note: this will fail if keystr contains spaces
    std::stringstream ss(keystr);

    while (ss.good()) {
        char kcstr[256];
        ss.getline(kcstr, 256, ',');
        std::string kstr(kcstr);

        if (!ks.Parse(kstr, false))
            return false;

        kc->emplace_back(ks);
    }

    return true;
}
Example #23
0
void CKeyBindings::BuildHotkeyMap()
{
	hotkeys.clear();

	KeyMap::const_iterator kit;
	for (kit = bindings.begin(); kit != bindings.end(); ++kit) {
		const CKeySet ks = kit->first;
		const string keystr = ks.GetString(true);
		const ActionList& al = kit->second;
		for (int i = 0; i < (int)al.size(); ++i) {
			HotkeyList& hl = hotkeys[al[i].command + ((al[i].extra == "") ? "" : " " + al[i].extra)];
			int j;
			for (j = 0; j < (int)hl.size(); ++j) {
				if (hl[j] == keystr) {
					break;
				}
			}
			if (j == (int)hl.size()) {
				hl.push_back(keystr);
			}
		}
	}
}
Example #24
0
//------------------------------------------------------------------------------
//  Keyboard Key pressed
//------------------------------------------------------------------------------
void CKeyMap::KeyPress (U_INT key, EKeyboardModifiers mod)
{ // Translate key and modifier into keycode
  int  code = (mod << 16) + key;
  bool handled = false;
  //--- special detection mode ------------------------------
  if(m_bKeyDetect && m_fKeyCallback)
  {
    /// \todo unbind if this key code is already asigned
    if (m_fKeyCallback(m_winID, code)) return;
  }
  //---Standard key -----------------------------------------
  for (U_INT k=0; (k<oset.size()); k++)
  {   CKeySet *ks = oset[k];
      CKeyDefinition *kdf = ks->GetKeyByCode(code);
      if (0 == kdf)       continue;
      //---Call the redirected group key callback -----------
      Tag        ngp = kdf->GetSet();
      ks             =   FindKeySetById (ngp);
      KeyGroupCB  cb = ks->GetCB();
      handled = (cb)(kdf,code);
			if (handled) return;
  }
  return;
}
Example #25
0
bool CKeyBindings::ParseKeySet(const string& keystr, CKeySet& ks) const
{
	if (keystr[0] != NamedKeySetChar) {
		return ks.Parse(keystr);
	}
	else {
		const string keysetName = keystr.substr(1);
		NamedKeySetMap::const_iterator it = namedKeySets.find(keysetName);
		if (it !=  namedKeySets.end()) {
			ks = it->second;
		} else {
			return false;
		}
	}
	return true;
}
Example #26
0
//------------------------------------------------------------------------------
//  Unbind keyset with group key to global function f
//------------------------------------------------------------------------------
void CKeyMap::UnbindGroup(Tag gp)
{ CKeySet *set = FindKeySetById(gp);
  if (0 == set)   return;
  set->BindTo(GroupUnbind);
  return;
}
Example #27
0
//--------------------------------------------------------------------------
//  Save keyboard mapping to file
//--------------------------------------------------------------------------
void CKeyMap::SaveCurrentConfig()
{ char codk[128];
  char stag[8];
  int i;
  CStreamFile sf;
  std::map<Tag,CKeySet*>::const_iterator it;
  std::map<Tag,CKeyDefinition*>::const_iterator kit;
  CKeySet        * pset;
  CKeyDefinition * pkey;
  sf.OpenWrite("System/Keymap.txt");
  //
  // file header and version
  //
  sf.WriteString("//=================================================");
  sf.WriteString("// Please note that Keyset are ordered by name     ");
  sf.WriteString("// Menus should come first as they intercept keys  ");
  sf.WriteString("// that may be dispatched to lower entity such as  ");
  sf.WriteString("// Aircraft or ground vehicles                     ");
  sf.WriteString("//=================================================");
  sf.DebObject();
  sf.WriteTag('vers', "---- configuration version ----");
  sf.WriteInt(vers);
  for(it = kset.begin(); it != kset.end(); it++)
  {	pset = it->second;
    sf.WriteTag('kset', "=== KeySet Definition File ===");
    TagToString(stag, it->first);
    sf.WriteString(stag);
    sf.WriteTag('bgno', "========== BEGIN OBJECT ==========");
    sf.WriteTag('name', "---- key set name ----");
    sf.WriteString(pset->GetName());
    sf.WriteTag('user', "---- user can modify ----");
    sf.WriteInt(pset->GetUserModifiableState());
    sf.WriteTag('enab', "---- enabled ----");
    sf.WriteInt(pset->GetEnabledState());
    for(kit = pset->dkey.begin(); kit != pset->dkey.end(); kit++)
      { pkey = kit->second;
        sf.WriteTag('kkey', "---- key definition ----");
        sf.DebObject();
        sf.WriteTag('kyid', "---- key ID ----");
        TagToString(stag, kit->first);
        sf.WriteString(stag);
        sf.WriteTag('name', "---- key name ----");
        sf.WriteString(pkey->GetName());
        sf.WriteTag('code', "---- key code & modifier ----");
				i = pkey->GetCode();
				formatKeyCode(codk,i,0);
				sf.WriteString(codk);
        sf.WriteTag('user', "---- user definable ----");
        sf.WriteInt(pkey->IsUserMod());
        sf.WriteTag('enab', "---- enabled ----");
        sf.WriteInt(pkey->IsEnabled());
        sf.EndObject();
      }
      sf.EndObject();
    }
  // File end
  //
  sf.EndObject();
  sf.Close();
	return;
}
const CKeyBindings::ActionList&
	CKeyBindings::GetActionList(const CKeySet& ks) const
{
	static const ActionList empty;
	const ActionList* alPtr = NULL;

	if (ks.AnyMod()) {
		KeyMap::const_iterator it = bindings.find(ks);
		if (it == bindings.end()) {
			alPtr = &empty;
		} else {
			alPtr = &(it->second);
		}
	}
	else {
		// have to check for an AnyMod keyset as well as the normal one
		CKeySet anyMod = ks;
		anyMod.SetAnyBit();
		KeyMap::const_iterator nit = bindings.find(ks);
		KeyMap::const_iterator ait = bindings.find(anyMod);
		const bool haveNormal = (nit != bindings.end());
		const bool haveAnyMod = (ait != bindings.end());
		if (!haveNormal && !haveAnyMod) {
			alPtr = &empty;
		}
		else if (haveNormal && !haveAnyMod) {
			alPtr = &(nit->second);
		}
		else if (!haveNormal && haveAnyMod) {
			alPtr = &(ait->second);
		}
		else {
			// combine the two lists (normal first)
			static ActionList merged;
			merged = nit->second;
			const ActionList& aal = ait->second;
			for (int i = 0; i < (int)aal.size(); ++i) {
				merged.push_back(aal[i]);
			}
			alPtr = &merged;
		}
	}

	if (debug > 0) {
		char buf[256];
		SNPRINTF(buf, sizeof(buf), "GetAction: %s (0x%03X)",
		         ks.GetString(false).c_str(), ks.Key());
		if (alPtr == &empty) {
			strncat(buf, "  EMPTY", sizeof(buf));
			logOutput.Print("%s", buf);
		}
		else {
			logOutput.Print("%s", buf);
			const ActionList& al = *alPtr;
			for (int i = 0; i < (int)al.size(); ++i) {
				SNPRINTF(buf, sizeof(buf), "  %s  \"%s\"",
				         al[i].command.c_str(), al[i].rawline.c_str());
				logOutput.Print("%s", buf);
			}
		}
	}

	return *alPtr;
}