2002-01-08 21:45:49 +00:00
|
|
|
// Keys.cc for Fluxbox - an X11 Window manager
|
2006-02-16 06:53:05 +00:00
|
|
|
// Copyright (c) 2001 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org)
|
2001-12-11 20:47:02 +00:00
|
|
|
//
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
// copy of this software and associated documentation files (the "Software"),
|
|
|
|
// to deal in the Software without restriction, including without limitation
|
|
|
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
// and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
// Software is furnished to do so, subject to the following conditions:
|
|
|
|
//
|
|
|
|
// The above copyright notice and this permission notice shall be included in
|
|
|
|
// all copies or substantial portions of the Software.
|
|
|
|
//
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
// DEALINGS IN THE SOFTWARE.
|
|
|
|
|
2004-11-19 11:37:27 +00:00
|
|
|
//$Id$
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
|
2001-12-29 10:32:04 +00:00
|
|
|
#include "Keys.hh"
|
2002-08-11 21:21:06 +00:00
|
|
|
|
2003-09-06 13:58:06 +00:00
|
|
|
#include "FbTk/StringUtil.hh"
|
|
|
|
#include "FbTk/App.hh"
|
|
|
|
#include "FbTk/Command.hh"
|
|
|
|
|
2003-06-30 14:57:14 +00:00
|
|
|
#include "CommandParser.hh"
|
2004-06-07 11:46:05 +00:00
|
|
|
#include "FbTk/I18n.hh"
|
2001-12-29 10:32:04 +00:00
|
|
|
|
2002-08-11 21:21:06 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
2003-04-26 18:27:56 +00:00
|
|
|
#include "config.h"
|
2002-08-11 21:21:06 +00:00
|
|
|
#endif // HAVE_CONFIG_H
|
|
|
|
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-05-02 07:10:03 +00:00
|
|
|
#ifdef HAVE_CTYPE_H
|
|
|
|
#include <ctype.h>
|
2002-02-21 00:39:08 +00:00
|
|
|
#endif // HAVE_CTYPE_H
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2004-08-31 15:26:40 +00:00
|
|
|
#ifdef HAVE_CSTDIO
|
|
|
|
#include <cstdio>
|
|
|
|
#else
|
|
|
|
#include <stdio.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_CSTDLIB
|
|
|
|
#include <cstdlib>
|
|
|
|
#else
|
|
|
|
#include <stdlib.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_CERRNO
|
|
|
|
#include <cerrno>
|
|
|
|
#else
|
|
|
|
#include <errno.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_CSTRING
|
|
|
|
#include <cstring>
|
|
|
|
#else
|
|
|
|
#include <string.h>
|
|
|
|
#endif
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-05-02 07:10:03 +00:00
|
|
|
#ifdef HAVE_SYS_TYPES_H
|
|
|
|
#include <sys/types.h>
|
2002-02-21 00:39:08 +00:00
|
|
|
#endif // HAVE_SYS_TYPES_H
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-05-02 07:10:03 +00:00
|
|
|
#ifdef HAVE_SYS_WAIT_H
|
|
|
|
#include <sys/wait.h>
|
2002-02-21 00:39:08 +00:00
|
|
|
#endif // HAVE_SYS_WAIT_H
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-05-02 07:10:03 +00:00
|
|
|
#ifdef HAVE_UNISTD_H
|
|
|
|
#include <unistd.h>
|
2002-02-21 00:39:08 +00:00
|
|
|
#endif // HAVE_UNISTD_H
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-05-02 07:10:03 +00:00
|
|
|
#ifdef HAVE_SYS_STAT_H
|
|
|
|
#include <sys/stat.h>
|
2002-02-21 00:39:08 +00:00
|
|
|
#endif // HAVE_SYS_STAT_H
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
#include <X11/Xlib.h>
|
|
|
|
#include <X11/Xproto.h>
|
|
|
|
#include <X11/keysym.h>
|
2005-05-06 09:22:53 +00:00
|
|
|
#include <X11/Xutil.h>
|
|
|
|
#include <X11/XKBlib.h>
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
#include <fstream>
|
2002-01-07 23:44:09 +00:00
|
|
|
#include <vector>
|
2004-08-31 15:26:40 +00:00
|
|
|
#ifdef HAVE_CASSERT
|
|
|
|
#include <cassert>
|
|
|
|
#else
|
|
|
|
#include <assert.h>
|
|
|
|
#endif
|
2002-01-08 12:13:25 +00:00
|
|
|
#include <memory>
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
2003-02-28 23:55:37 +00:00
|
|
|
Keys::Keys(const char *filename):
|
2003-10-05 07:20:47 +00:00
|
|
|
m_display(FbTk::App::instance()->display())
|
|
|
|
{
|
2003-08-19 16:19:28 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
if (filename != 0)
|
|
|
|
load(filename);
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2005-05-06 09:22:53 +00:00
|
|
|
Keys::~Keys() {
|
2003-09-06 13:58:06 +00:00
|
|
|
|
2003-10-05 07:20:47 +00:00
|
|
|
FbTk::KeyUtil::ungrabKeys();
|
2002-12-01 13:42:15 +00:00
|
|
|
deleteTree();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
2001-12-29 10:32:04 +00:00
|
|
|
|
2003-08-19 16:19:28 +00:00
|
|
|
/// Destroys the keytree
|
2001-12-11 20:47:02 +00:00
|
|
|
void Keys::deleteTree() {
|
2002-12-01 13:42:15 +00:00
|
|
|
while (!m_keylist.empty()) {
|
2003-08-19 16:19:28 +00:00
|
|
|
if (m_keylist.back())
|
2005-05-06 09:22:53 +00:00
|
|
|
delete m_keylist.back();
|
2002-12-01 13:42:15 +00:00
|
|
|
m_keylist.pop_back();
|
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
2001-12-29 10:32:04 +00:00
|
|
|
|
2005-05-06 09:22:53 +00:00
|
|
|
/**
|
2003-02-28 23:55:37 +00:00
|
|
|
Load and grab keys
|
|
|
|
TODO: error checking
|
|
|
|
@return true on success else false
|
|
|
|
*/
|
2002-07-27 18:03:39 +00:00
|
|
|
bool Keys::load(const char *filename) {
|
2002-12-01 13:42:15 +00:00
|
|
|
if (!filename)
|
|
|
|
return false;
|
2005-05-06 09:22:53 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
//ungrab all keys
|
2003-10-05 07:20:47 +00:00
|
|
|
FbTk::KeyUtil::ungrabKeys();
|
2002-08-11 21:21:06 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
//free memory of previous grabs
|
|
|
|
deleteTree();
|
2002-08-11 21:21:06 +00:00
|
|
|
|
2003-12-04 21:31:02 +00:00
|
|
|
FbTk::App::instance()->sync(false);
|
2005-05-06 09:22:53 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
//open the file
|
|
|
|
ifstream infile(filename);
|
|
|
|
if (!infile)
|
|
|
|
return false; // faild to open file
|
2002-08-11 21:21:06 +00:00
|
|
|
|
2003-12-20 17:37:57 +00:00
|
|
|
m_current_line = 0;//current line, so we can tell the user where the fault is
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
while (!infile.eof()) {
|
|
|
|
string linebuffer;
|
2002-08-11 21:21:06 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
getline(infile, linebuffer);
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-12-20 17:37:57 +00:00
|
|
|
m_current_line++;
|
2002-08-11 21:21:06 +00:00
|
|
|
|
2003-12-20 17:37:57 +00:00
|
|
|
addBinding(linebuffer);
|
|
|
|
} // end while eof
|
|
|
|
|
|
|
|
m_current_line = 0;
|
|
|
|
m_filename = filename;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Keys::save(const char *filename) const {
|
|
|
|
//!!
|
2005-05-06 09:22:53 +00:00
|
|
|
//!! TODO: fix keybinding saving
|
|
|
|
//!! (we probably need to save key actions
|
2003-12-20 17:37:57 +00:00
|
|
|
//!! as strings instead of creating new Commands)
|
|
|
|
|
|
|
|
// open file for writing
|
|
|
|
// ofstream outfile(filename);
|
|
|
|
// if (!outfile)
|
|
|
|
return false;
|
|
|
|
// return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Keys::addBinding(const std::string &linebuffer) {
|
|
|
|
|
|
|
|
vector<string> val;
|
|
|
|
// Parse arguments
|
|
|
|
FbTk::StringUtil::stringtok(val, linebuffer.c_str());
|
|
|
|
|
|
|
|
// must have at least 1 argument
|
|
|
|
if (val.size() <= 0)
|
|
|
|
return true; // empty lines are valid.
|
2005-05-06 09:22:53 +00:00
|
|
|
|
2004-02-20 09:29:07 +00:00
|
|
|
if (val[0][0] == '#' || val[0][0] == '!' ) //the line is commented
|
2003-12-20 17:37:57 +00:00
|
|
|
return true; // still a valid line.
|
2005-05-06 09:22:53 +00:00
|
|
|
|
2003-12-20 17:37:57 +00:00
|
|
|
unsigned int key = 0, mod = 0;
|
|
|
|
char keyarg = 0;
|
|
|
|
t_key *current_key=0, *last_key=0;
|
|
|
|
|
2004-06-07 11:46:05 +00:00
|
|
|
_FB_USES_NLS;
|
2005-05-06 09:22:53 +00:00
|
|
|
// for each argument
|
2006-04-02 21:37:44 +00:00
|
|
|
for (size_t argc = 0; argc < val.size(); argc++) {
|
2003-12-20 17:37:57 +00:00
|
|
|
|
|
|
|
if (val[argc][0] != ':') { // parse key(s)
|
|
|
|
keyarg++;
|
|
|
|
if (keyarg==1) //first arg is modifier
|
|
|
|
mod = FbTk::KeyUtil::getModifier(val[argc].c_str());
|
|
|
|
else if (keyarg > 1) {
|
|
|
|
|
|
|
|
int tmpmod = FbTk::KeyUtil::getModifier(val[argc].c_str());
|
|
|
|
if(tmpmod)
|
|
|
|
mod |= tmpmod; //If it's a modifier
|
2005-05-06 09:22:53 +00:00
|
|
|
else {
|
2005-05-20 22:25:22 +00:00
|
|
|
// keycode covers the following three two-byte cases:
|
|
|
|
// 0x - hex
|
|
|
|
// +[1-9] - number between +1 and +9
|
|
|
|
// numbers 10 and above
|
|
|
|
//
|
|
|
|
if (val[argc].size() > 1 && (isdigit(val[argc][0]) &&
|
|
|
|
(isdigit(val[argc][1]) || val[argc][1] == 'x') ||
|
|
|
|
val[argc][0] == '+' && isdigit(val[argc][1])) ) {
|
|
|
|
|
|
|
|
key = strtoul(val[argc].c_str(), NULL, 0);
|
|
|
|
|
|
|
|
if (errno == EINVAL || errno == ERANGE)
|
|
|
|
key = 0;
|
|
|
|
|
|
|
|
} else // convert from string symbol
|
|
|
|
key = FbTk::KeyUtil::getKey(val[argc].c_str());
|
|
|
|
|
2003-12-20 17:37:57 +00:00
|
|
|
if (key == 0) {
|
2005-05-20 22:25:22 +00:00
|
|
|
cerr<<_FBTEXT(Keys, InvalidKeyMod,
|
|
|
|
"Keys: Invalid key/modifier on line",
|
|
|
|
"A bad key/modifier string was found on line (number following)")<<" "<<
|
2003-12-20 17:37:57 +00:00
|
|
|
m_current_line<<"): "<<linebuffer<<endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (!current_key) {
|
|
|
|
current_key = new t_key(key, mod);
|
|
|
|
last_key = current_key;
|
2005-05-06 09:22:53 +00:00
|
|
|
} else {
|
2003-12-20 17:37:57 +00:00
|
|
|
t_key *temp_key = new t_key(key, mod);
|
|
|
|
last_key->keylist.push_back(temp_key);
|
|
|
|
last_key = temp_key;
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2003-07-02 05:42:21 +00:00
|
|
|
}
|
2005-05-06 09:22:53 +00:00
|
|
|
}
|
2003-06-30 19:42:20 +00:00
|
|
|
|
2003-12-20 17:37:57 +00:00
|
|
|
} else { // parse command line
|
|
|
|
if (last_key == 0) {
|
2004-06-07 11:46:05 +00:00
|
|
|
cerr<<_FBTEXT(Keys, BadLine, "Keys: Error on line", "Error on line (number following)")<<": "<<m_current_line<<endl;
|
2003-12-20 17:37:57 +00:00
|
|
|
cerr<<"> "<<linebuffer<<endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
bool ret_val = true;
|
2005-05-06 09:22:53 +00:00
|
|
|
const char *str =
|
2003-12-20 17:37:57 +00:00
|
|
|
FbTk::StringUtil::strcasestr(linebuffer.c_str(),
|
|
|
|
val[argc].c_str() + 1); // +1 to skip ':'
|
|
|
|
if (str == 0) {
|
2004-06-07 11:46:05 +00:00
|
|
|
cerr<<_FBTEXT(Keys, BadLine, "Keys: Error on line", "Error on line (number following)")<<": "<<m_current_line<<endl;
|
2003-12-20 17:37:57 +00:00
|
|
|
cerr<<"> "<<linebuffer<<endl;
|
|
|
|
ret_val = false;
|
|
|
|
} else {
|
|
|
|
|
|
|
|
last_key->m_command = CommandParser::instance().parseLine(str);
|
|
|
|
|
|
|
|
if (*last_key->m_command == 0) {
|
2004-06-07 11:46:05 +00:00
|
|
|
cerr<<_FBTEXT(Keys, BadLine, "Keys: Error on line", "Error on line (number following)")<<": "<<m_current_line<<endl;
|
2003-06-30 14:57:14 +00:00
|
|
|
cerr<<"> "<<linebuffer<<endl;
|
|
|
|
} else {
|
2003-12-20 17:37:57 +00:00
|
|
|
// Add the keychain to list
|
|
|
|
if (!mergeTree(current_key)) {
|
2004-06-07 11:46:05 +00:00
|
|
|
cerr<<_FBTEXT(Keys, BadMerge, "Keys: Failed to merge keytree!", "relatively technical error message. Key bindings are stored in a tree structure")<<endl;
|
2003-12-20 17:37:57 +00:00
|
|
|
ret_val = false;
|
2003-06-30 20:59:28 +00:00
|
|
|
}
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2003-12-20 17:37:57 +00:00
|
|
|
}
|
|
|
|
delete current_key;
|
|
|
|
current_key = 0;
|
|
|
|
last_key = 0;
|
2003-06-30 14:57:14 +00:00
|
|
|
|
2003-12-20 17:37:57 +00:00
|
|
|
return ret_val;
|
2002-01-21 01:48:47 +00:00
|
|
|
|
2003-12-20 17:37:57 +00:00
|
|
|
} // end if
|
|
|
|
} // end for
|
|
|
|
|
|
|
|
return false;
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2003-12-20 17:37:57 +00:00
|
|
|
|
2003-02-28 23:55:37 +00:00
|
|
|
/**
|
|
|
|
@return the KeyAction of the XKeyEvent
|
|
|
|
*/
|
2003-06-30 14:57:14 +00:00
|
|
|
void Keys::doAction(XKeyEvent &ke) {
|
2005-05-06 09:22:53 +00:00
|
|
|
|
2003-12-30 18:14:33 +00:00
|
|
|
ke.state = FbTk::KeyUtil::instance().cleanMods(ke.state);
|
2005-05-06 09:22:53 +00:00
|
|
|
|
|
|
|
static struct t_key* next_key = 0;
|
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
if (!next_key) {
|
2005-05-06 09:22:53 +00:00
|
|
|
|
2006-04-02 21:37:44 +00:00
|
|
|
for (size_t i = 0; i < m_keylist.size(); i++) {
|
2002-12-01 13:42:15 +00:00
|
|
|
if (*m_keylist[i] == ke) {
|
|
|
|
if (m_keylist[i]->keylist.size()) {
|
|
|
|
next_key = m_keylist[i];
|
2005-05-06 09:22:53 +00:00
|
|
|
break; //end for-loop
|
2002-12-01 13:42:15 +00:00
|
|
|
} else {
|
2003-06-30 14:57:14 +00:00
|
|
|
if (*m_keylist[i]->m_command != 0)
|
|
|
|
m_keylist[i]->m_command->execute();
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-05-06 09:22:53 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
} else { //check the nextkey
|
2005-05-06 09:22:53 +00:00
|
|
|
t_key *temp_key = next_key->find(ke);
|
2002-12-01 13:42:15 +00:00
|
|
|
if (temp_key) {
|
|
|
|
if (temp_key->keylist.size()) {
|
2005-05-06 09:22:53 +00:00
|
|
|
next_key = temp_key;
|
2002-12-01 13:42:15 +00:00
|
|
|
} else {
|
|
|
|
next_key = 0;
|
2003-06-30 14:57:14 +00:00
|
|
|
if (*temp_key->m_command != 0)
|
|
|
|
temp_key->m_command->execute();
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
} else {
|
2005-05-06 09:22:53 +00:00
|
|
|
temp_key = next_key;
|
2002-12-01 13:42:15 +00:00
|
|
|
next_key = 0;
|
2003-06-30 14:57:14 +00:00
|
|
|
if (*temp_key->m_command != 0)
|
|
|
|
temp_key->m_command->execute();
|
2005-05-06 09:22:53 +00:00
|
|
|
|
|
|
|
}
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2003-02-28 23:55:37 +00:00
|
|
|
/**
|
|
|
|
deletes the tree and load configuration
|
|
|
|
returns true on success else false
|
|
|
|
*/
|
2002-07-27 18:03:39 +00:00
|
|
|
bool Keys::reconfigure(const char *filename) {
|
2002-12-01 13:42:15 +00:00
|
|
|
deleteTree();
|
|
|
|
return load(filename);
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2003-02-28 23:55:37 +00:00
|
|
|
/**
|
|
|
|
Merges two chains and binds new keys
|
|
|
|
@return true on success else false.
|
|
|
|
*/
|
2001-12-11 20:47:02 +00:00
|
|
|
bool Keys::mergeTree(t_key *newtree, t_key *basetree) {
|
2006-04-02 21:37:44 +00:00
|
|
|
size_t baselit_i = 0;
|
2002-12-01 13:42:15 +00:00
|
|
|
if (basetree==0) {
|
|
|
|
for (; baselist_i<m_keylist.size(); baselist_i++) {
|
2005-05-06 09:22:53 +00:00
|
|
|
if (m_keylist[baselist_i]->mod == newtree->mod &&
|
2002-12-01 13:42:15 +00:00
|
|
|
m_keylist[baselist_i]->key == newtree->key) {
|
2003-06-30 14:57:14 +00:00
|
|
|
if (newtree->keylist.size() && *m_keylist[baselist_i]->m_command == 0) {
|
2002-12-01 13:42:15 +00:00
|
|
|
//assumes the newtree only have one branch
|
|
|
|
return mergeTree(newtree->keylist[0], m_keylist[baselist_i]);
|
|
|
|
} else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (baselist_i == m_keylist.size()) {
|
2003-10-05 07:20:47 +00:00
|
|
|
FbTk::KeyUtil::grabKey(newtree->key, newtree->mod);
|
2005-05-06 09:22:53 +00:00
|
|
|
m_keylist.push_back(new t_key(newtree));
|
2002-12-01 13:42:15 +00:00
|
|
|
if (newtree->keylist.size())
|
|
|
|
return mergeTree(newtree->keylist[0], m_keylist.back());
|
|
|
|
return true;
|
|
|
|
}
|
2005-05-06 09:22:53 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
} else {
|
|
|
|
for (; baselist_i<basetree->keylist.size(); baselist_i++) {
|
|
|
|
if (basetree->keylist[baselist_i]->mod == newtree->mod &&
|
|
|
|
basetree->keylist[baselist_i]->key == newtree->key) {
|
|
|
|
if (newtree->keylist.size()) {
|
|
|
|
//assumes the newtree only have on branch
|
|
|
|
return mergeTree(newtree->keylist[0], basetree->keylist[baselist_i]);
|
|
|
|
} else
|
|
|
|
return false;
|
2005-05-06 09:22:53 +00:00
|
|
|
}
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
//if it wasn't in the list grab the key and add it to the list
|
2005-05-06 09:22:53 +00:00
|
|
|
if (baselist_i==basetree->keylist.size()) {
|
2003-10-05 07:20:47 +00:00
|
|
|
FbTk::KeyUtil::grabKey(newtree->key, newtree->mod);
|
2002-12-01 13:42:15 +00:00
|
|
|
basetree->keylist.push_back(new t_key(newtree));
|
|
|
|
if (newtree->keylist.size())
|
|
|
|
return mergeTree(newtree->keylist[0], basetree->keylist.back());
|
2005-05-06 09:22:53 +00:00
|
|
|
return true;
|
|
|
|
}
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2005-05-06 09:22:53 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
return false;
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2003-06-30 14:57:14 +00:00
|
|
|
Keys::t_key::t_key(unsigned int key_, unsigned int mod_, FbTk::RefCount<FbTk::Command> command) {
|
2002-12-01 13:42:15 +00:00
|
|
|
key = key_;
|
2005-05-06 09:22:53 +00:00
|
|
|
mod = mod_;
|
2003-06-30 14:57:14 +00:00
|
|
|
m_command = command;
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Keys::t_key::t_key(t_key *k) {
|
2002-12-01 13:42:15 +00:00
|
|
|
key = k->key;
|
|
|
|
mod = k->mod;
|
2003-06-30 14:57:14 +00:00
|
|
|
m_command = k->m_command;
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2005-05-06 09:22:53 +00:00
|
|
|
Keys::t_key::~t_key() {
|
|
|
|
while (!keylist.empty()) {
|
2002-12-01 13:42:15 +00:00
|
|
|
t_key *k = keylist.back();
|
|
|
|
if (k != 0) { // make sure we don't have a bad key pointer
|
|
|
|
delete k;
|
|
|
|
keylist.pop_back();
|
|
|
|
}
|
|
|
|
}
|
2003-06-30 14:57:14 +00:00
|
|
|
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|