IKeyState.cpp

00001 /*
00002  * synergy -- mouse and keyboard sharing utility
00003  * Copyright (C) 2004 Chris Schoeneman
00004  * 
00005  * This package is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * found in the file COPYING that should have accompanied this file.
00008  * 
00009  * This package is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  */
00014 
00015 #include "IKeyState.h"
00016 #include <cstring>
00017 #include <cstdlib>
00018 
00019 //
00020 // IKeyState
00021 //
00022 
00023 CEvent::Type        IKeyState::s_keyDownEvent   = CEvent::kUnknown;
00024 CEvent::Type        IKeyState::s_keyUpEvent     = CEvent::kUnknown;
00025 CEvent::Type        IKeyState::s_keyRepeatEvent = CEvent::kUnknown;
00026 
00027 CEvent::Type
00028 IKeyState::getKeyDownEvent()
00029 {
00030     return CEvent::registerTypeOnce(s_keyDownEvent,
00031                             "IKeyState::keyDown");
00032 }
00033 
00034 CEvent::Type
00035 IKeyState::getKeyUpEvent()
00036 {
00037     return CEvent::registerTypeOnce(s_keyUpEvent,
00038                             "IKeyState::keyUp");
00039 }
00040 
00041 CEvent::Type
00042 IKeyState::getKeyRepeatEvent()
00043 {
00044     return CEvent::registerTypeOnce(s_keyRepeatEvent,
00045                             "IKeyState::keyRepeat");
00046 }
00047 
00048 
00049 //
00050 // IKeyState::CKeyInfo
00051 //
00052 
00053 IKeyState::CKeyInfo*
00054 IKeyState::CKeyInfo::alloc(KeyID id,
00055                 KeyModifierMask mask, KeyButton button, SInt32 count)
00056 {
00057     CKeyInfo* info           = (CKeyInfo*)malloc(sizeof(CKeyInfo));
00058     info->m_key              = id;
00059     info->m_mask             = mask;
00060     info->m_button           = button;
00061     info->m_count            = count;
00062     info->m_screens          = NULL;
00063     info->m_screensBuffer[0] = '\0';
00064     return info;
00065 }
00066 
00067 IKeyState::CKeyInfo*
00068 IKeyState::CKeyInfo::alloc(KeyID id,
00069                 KeyModifierMask mask, KeyButton button, SInt32 count,
00070                 const std::set<CString>& destinations)
00071 {
00072     CString screens = join(destinations);
00073 
00074     // build structure
00075     CKeyInfo* info  = (CKeyInfo*)malloc(sizeof(CKeyInfo) + screens.size());
00076     info->m_key     = id;
00077     info->m_mask    = mask;
00078     info->m_button  = button;
00079     info->m_count   = count;
00080     info->m_screens = info->m_screensBuffer;
00081     strcpy(info->m_screensBuffer, screens.c_str());
00082     return info;
00083 }
00084 
00085 IKeyState::CKeyInfo*
00086 IKeyState::CKeyInfo::alloc(const CKeyInfo& x)
00087 {
00088     CKeyInfo* info  = (CKeyInfo*)malloc(sizeof(CKeyInfo) +
00089                                         strlen(x.m_screensBuffer));
00090     info->m_key     = x.m_key;
00091     info->m_mask    = x.m_mask;
00092     info->m_button  = x.m_button;
00093     info->m_count   = x.m_count;
00094     info->m_screens = x.m_screens ? info->m_screensBuffer : NULL;
00095     strcpy(info->m_screensBuffer, x.m_screensBuffer);
00096     return info;
00097 }
00098 
00099 bool
00100 IKeyState::CKeyInfo::isDefault(const char* screens)
00101 {
00102     return (screens == NULL || screens[0] == '\0');
00103 }
00104 
00105 bool
00106 IKeyState::CKeyInfo::contains(const char* screens, const CString& name)
00107 {
00108     // special cases
00109     if (isDefault(screens)) {
00110         return false;
00111     }
00112     if (screens[0] == '*') {
00113         return true;
00114     }
00115 
00116     // search
00117     CString match;
00118     match.reserve(name.size() + 2);
00119     match += ":";
00120     match += name;
00121     match += ":";
00122     return (strstr(screens, match.c_str()) != NULL);
00123 }
00124 
00125 bool
00126 IKeyState::CKeyInfo::equal(const CKeyInfo* a, const CKeyInfo* b)
00127 {
00128     return (a->m_key    == b->m_key &&
00129             a->m_mask   == b->m_mask &&
00130             a->m_button == b->m_button &&
00131             a->m_count  == b->m_count &&
00132             strcmp(a->m_screensBuffer, b->m_screensBuffer) == 0);
00133 }
00134 
00135 CString
00136 IKeyState::CKeyInfo::join(const std::set<CString>& destinations)
00137 {
00138     // collect destinations into a string.  names are surrounded by ':'
00139     // which makes searching easy.  the string is empty if there are no
00140     // destinations and "*" means all destinations.
00141     CString screens;
00142     for (std::set<CString>::const_iterator i = destinations.begin();
00143                                 i != destinations.end(); ++i) {
00144         if (*i == "*") {
00145             screens = "*";
00146             break;
00147         }
00148         else {
00149             if (screens.empty()) {
00150                 screens = ":";
00151             }
00152             screens += *i;
00153             screens += ":";
00154         }
00155     }
00156     return screens;
00157 }
00158 
00159 void
00160 IKeyState::CKeyInfo::split(const char* screens, std::set<CString>& dst)
00161 {
00162     dst.clear();
00163     if (isDefault(screens)) {
00164         return;
00165     }
00166     if (screens[0] == '*') {
00167         dst.insert("*");
00168         return;
00169     }
00170 
00171     const char* i = screens + 1;
00172     while (*i != '\0') {
00173         const char* j = strchr(i, ':');
00174         dst.insert(CString(i, j - i));
00175         i = j + 1;
00176     }
00177 }

Generated on Fri Nov 6 00:18:46 2009 for synergy-plus by  doxygen 1.4.7