mirror of
https://github.com/debauchee/barrier.git
synced 2026-05-05 21:02:39 +08:00
to style guidelines. Also enhanced it to allow binding hot keys to not only toggling broadcasting but also turning it on or off, resized the hot key dialog to accommodate the keyboard broadcasting option, changed the configuration string for the keyboard broadcasting option, and added documentation. This change does not include the VS8 fix included in the patch.
177 lines
4.0 KiB
C++
177 lines
4.0 KiB
C++
/*
|
|
* synergy -- mouse and keyboard sharing utility
|
|
* Copyright (C) 2004 Chris Schoeneman
|
|
*
|
|
* This package is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* found in the file COPYING that should have accompanied this file.
|
|
*
|
|
* This package is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#include "IKeyState.h"
|
|
#include <string.h>
|
|
|
|
//
|
|
// IKeyState
|
|
//
|
|
|
|
CEvent::Type IKeyState::s_keyDownEvent = CEvent::kUnknown;
|
|
CEvent::Type IKeyState::s_keyUpEvent = CEvent::kUnknown;
|
|
CEvent::Type IKeyState::s_keyRepeatEvent = CEvent::kUnknown;
|
|
|
|
CEvent::Type
|
|
IKeyState::getKeyDownEvent()
|
|
{
|
|
return CEvent::registerTypeOnce(s_keyDownEvent,
|
|
"IKeyState::keyDown");
|
|
}
|
|
|
|
CEvent::Type
|
|
IKeyState::getKeyUpEvent()
|
|
{
|
|
return CEvent::registerTypeOnce(s_keyUpEvent,
|
|
"IKeyState::keyUp");
|
|
}
|
|
|
|
CEvent::Type
|
|
IKeyState::getKeyRepeatEvent()
|
|
{
|
|
return CEvent::registerTypeOnce(s_keyRepeatEvent,
|
|
"IKeyState::keyRepeat");
|
|
}
|
|
|
|
|
|
//
|
|
// IKeyState::CKeyInfo
|
|
//
|
|
|
|
IKeyState::CKeyInfo*
|
|
IKeyState::CKeyInfo::alloc(KeyID id,
|
|
KeyModifierMask mask, KeyButton button, SInt32 count)
|
|
{
|
|
CKeyInfo* info = (CKeyInfo*)malloc(sizeof(CKeyInfo));
|
|
info->m_key = id;
|
|
info->m_mask = mask;
|
|
info->m_button = button;
|
|
info->m_count = count;
|
|
info->m_screens = NULL;
|
|
info->m_screensBuffer[0] = '\0';
|
|
return info;
|
|
}
|
|
|
|
IKeyState::CKeyInfo*
|
|
IKeyState::CKeyInfo::alloc(KeyID id,
|
|
KeyModifierMask mask, KeyButton button, SInt32 count,
|
|
const std::set<CString>& destinations)
|
|
{
|
|
CString screens = join(destinations);
|
|
|
|
// build structure
|
|
CKeyInfo* info = (CKeyInfo*)malloc(sizeof(CKeyInfo) + screens.size());
|
|
info->m_key = id;
|
|
info->m_mask = mask;
|
|
info->m_button = button;
|
|
info->m_count = count;
|
|
info->m_screens = info->m_screensBuffer;
|
|
strcpy(info->m_screensBuffer, screens.c_str());
|
|
return info;
|
|
}
|
|
|
|
IKeyState::CKeyInfo*
|
|
IKeyState::CKeyInfo::alloc(const CKeyInfo& x)
|
|
{
|
|
CKeyInfo* info = (CKeyInfo*)malloc(sizeof(CKeyInfo) +
|
|
strlen(x.m_screensBuffer));
|
|
info->m_key = x.m_key;
|
|
info->m_mask = x.m_mask;
|
|
info->m_button = x.m_button;
|
|
info->m_count = x.m_count;
|
|
info->m_screens = x.m_screens ? info->m_screensBuffer : NULL;
|
|
strcpy(info->m_screensBuffer, x.m_screensBuffer);
|
|
return info;
|
|
}
|
|
|
|
bool
|
|
IKeyState::CKeyInfo::isDefault(const char* screens)
|
|
{
|
|
return (screens == NULL || screens[0] == '\0');
|
|
}
|
|
|
|
bool
|
|
IKeyState::CKeyInfo::contains(const char* screens, const CString& name)
|
|
{
|
|
// special cases
|
|
if (isDefault(screens)) {
|
|
return false;
|
|
}
|
|
if (screens[0] == '*') {
|
|
return true;
|
|
}
|
|
|
|
// search
|
|
CString match;
|
|
match.reserve(name.size() + 2);
|
|
match += ":";
|
|
match += name;
|
|
match += ":";
|
|
return (strstr(screens, match.c_str()) != NULL);
|
|
}
|
|
|
|
bool
|
|
IKeyState::CKeyInfo::equal(const CKeyInfo* a, const CKeyInfo* b)
|
|
{
|
|
return (a->m_key == b->m_key &&
|
|
a->m_mask == b->m_mask &&
|
|
a->m_button == b->m_button &&
|
|
a->m_count == b->m_count &&
|
|
strcmp(a->m_screensBuffer, b->m_screensBuffer) == 0);
|
|
}
|
|
|
|
CString
|
|
IKeyState::CKeyInfo::join(const std::set<CString>& destinations)
|
|
{
|
|
// collect destinations into a string. names are surrounded by ':'
|
|
// which makes searching easy. the string is empty if there are no
|
|
// destinations and "*" means all destinations.
|
|
CString screens;
|
|
for (std::set<CString>::const_iterator i = destinations.begin();
|
|
i != destinations.end(); ++i) {
|
|
if (*i == "*") {
|
|
screens = "*";
|
|
break;
|
|
}
|
|
else {
|
|
if (screens.empty()) {
|
|
screens = ":";
|
|
}
|
|
screens += *i;
|
|
screens += ":";
|
|
}
|
|
}
|
|
return screens;
|
|
}
|
|
|
|
void
|
|
IKeyState::CKeyInfo::split(const char* screens, std::set<CString>& dst)
|
|
{
|
|
dst.clear();
|
|
if (isDefault(screens)) {
|
|
return;
|
|
}
|
|
if (screens[0] == '*') {
|
|
dst.insert("*");
|
|
return;
|
|
}
|
|
|
|
const char* i = screens + 1;
|
|
while (*i != '\0') {
|
|
const char* j = strchr(i, ':');
|
|
dst.insert(CString(i, j - i));
|
|
i = j + 1;
|
|
}
|
|
}
|