VTB: release CVBuffer after it actually has been rendered
[xbmc.git] / xbmc / input / KeyboardStat.cpp
blob38e5f3f0662cc8ddef4d7e8872ac457835ba2c07
1 /*
2 * Copyright (C) 2007-2013 Team XBMC
3 * http://xbmc.org
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
21 // C++ Implementation: CKeyboard
23 // Comment OUT, if not really debugging!!!:
24 //#define DEBUG_KEYBOARD_GETCHAR
26 #include "KeyboardStat.h"
27 #include "windowing/XBMC_events.h"
28 #include "input/XBMC_keytable.h"
29 #include "input/XBMC_vkeys.h"
30 #include "peripherals/Peripherals.h"
31 #include "peripherals/devices/PeripheralHID.h"
32 #include "threads/SystemClock.h"
33 #include "utils/log.h"
35 #define HOLD_THRESHOLD 250
37 using namespace PERIPHERALS;
39 bool operator==(const XBMC_keysym& lhs, const XBMC_keysym& rhs)
41 return lhs.mod == rhs.mod &&
42 lhs.scancode == rhs.scancode &&
43 lhs.sym == rhs.sym &&
44 lhs.unicode == rhs.unicode;
47 CKeyboardStat::CKeyboardStat()
49 memset(&m_lastKeysym, 0, sizeof(m_lastKeysym));
50 m_lastKeyTime = 0;
53 CKeyboardStat::~CKeyboardStat()
57 void CKeyboardStat::Initialize()
61 bool CKeyboardStat::LookupSymAndUnicodePeripherals(XBMC_keysym &keysym, uint8_t *key, char *unicode)
63 std::vector<CPeripheral *> hidDevices;
64 if (g_peripherals.GetPeripheralsWithFeature(hidDevices, FEATURE_HID))
66 for (unsigned int iDevicePtr = 0; iDevicePtr < hidDevices.size(); iDevicePtr++)
68 CPeripheralHID *hidDevice = (CPeripheralHID *) hidDevices.at(iDevicePtr);
69 if (hidDevice && hidDevice->LookupSymAndUnicode(keysym, key, unicode))
70 return true;
73 return false;
76 CKey CKeyboardStat::TranslateKey(XBMC_keysym& keysym) const
78 uint8_t vkey;
79 wchar_t unicode;
80 char ascii;
81 uint32_t modifiers;
82 unsigned int held;
83 XBMCKEYTABLE keytable;
85 modifiers = 0;
86 if (keysym.mod & XBMCKMOD_CTRL)
87 modifiers |= CKey::MODIFIER_CTRL;
88 if (keysym.mod & XBMCKMOD_SHIFT)
89 modifiers |= CKey::MODIFIER_SHIFT;
90 if (keysym.mod & XBMCKMOD_ALT)
91 modifiers |= CKey::MODIFIER_ALT;
92 if (keysym.mod & XBMCKMOD_SUPER)
93 modifiers |= CKey::MODIFIER_SUPER;
94 if (keysym.mod & XBMCKMOD_META)
95 modifiers |= CKey::MODIFIER_META;
97 CLog::Log(LOGDEBUG, "Keyboard: scancode: 0x%02x, sym: 0x%04x, unicode: 0x%04x, modifier: 0x%x", keysym.scancode, keysym.sym, keysym.unicode, keysym.mod);
99 // The keysym.unicode is usually valid, even if it is zero. A zero
100 // unicode just means this is a non-printing keypress. The ascii and
101 // vkey will be set below.
102 unicode = keysym.unicode;
103 ascii = 0;
104 vkey = 0;
105 held = 0;
107 // Start by check whether any of the HID peripherals wants to translate this keypress
108 if (LookupSymAndUnicodePeripherals(keysym, &vkey, &ascii))
110 CLog::Log(LOGDEBUG, "%s - keypress translated by a HID peripheral", __FUNCTION__);
113 // Continue by trying to match both the sym and unicode. This will identify
114 // the majority of keypresses
115 else if (KeyTableLookupSymAndUnicode(keysym.sym, keysym.unicode, &keytable))
117 vkey = keytable.vkey;
118 ascii = keytable.ascii;
121 // If we failed to match the sym and unicode try just the unicode. This
122 // will match keys like \ that are on different keys on regional keyboards.
123 else if (KeyTableLookupUnicode(keysym.unicode, &keytable))
125 vkey = keytable.vkey;
126 ascii = keytable.ascii;
129 // If there is still no match try the sym
130 else if (KeyTableLookupSym(keysym.sym, &keytable))
132 vkey = keytable.vkey;
134 // Occasionally we get non-printing keys that have a non-zero value in
135 // the keysym.unicode. Check for this here and replace any rogue unicode
136 // values.
137 if (keytable.unicode == 0 && unicode != 0)
138 unicode = 0;
139 else if (keysym.unicode > 32 && keysym.unicode < 128)
140 ascii = unicode & 0x7f;
143 // The keysym.sym is unknown ...
144 else
146 if (!vkey && !ascii)
148 if (keysym.mod & XBMCKMOD_LSHIFT) vkey = 0xa0;
149 else if (keysym.mod & XBMCKMOD_RSHIFT) vkey = 0xa1;
150 else if (keysym.mod & XBMCKMOD_LALT) vkey = 0xa4;
151 else if (keysym.mod & XBMCKMOD_RALT) vkey = 0xa5;
152 else if (keysym.mod & XBMCKMOD_LCTRL) vkey = 0xa2;
153 else if (keysym.mod & XBMCKMOD_RCTRL) vkey = 0xa3;
154 else if (keysym.unicode > 32 && keysym.unicode < 128)
155 // only TRUE ASCII! (Otherwise XBMC crashes! No unicode not even latin 1!)
156 ascii = (char)(keysym.unicode & 0xff);
160 if (keysym == m_lastKeysym)
162 held = XbmcThreads::SystemClockMillis() - m_lastKeyTime;
163 if (held > HOLD_THRESHOLD)
164 modifiers |= CKey::MODIFIER_LONG;
167 // For all shift-X keys except shift-A to shift-Z and shift-F1 to shift-F24 the
168 // shift modifier is ignored. This so that, for example, the * keypress (shift-8)
169 // is seen as <asterisk> not <asterisk mod="shift">.
170 // The A-Z keys are exempted because shift-A-Z is used for navigation in lists.
171 // The function keys are exempted because function keys have no shifted value and
172 // the Nyxboard remote uses keys like Shift-F3 for some buttons.
173 if (modifiers == CKey::MODIFIER_SHIFT)
174 if ((unicode < 'A' || unicode > 'Z') && (unicode < 'a' || unicode > 'z') && (vkey < XBMCVK_F1 || vkey > XBMCVK_F24))
175 modifiers = 0;
177 // Create and return a CKey
179 CKey key(vkey, unicode, ascii, modifiers, held);
181 return key;
184 void CKeyboardStat::ProcessKeyDown(XBMC_keysym& keysym)
186 if (!(m_lastKeysym == keysym))
188 m_lastKeysym = keysym;
189 m_lastKeyTime = XbmcThreads::SystemClockMillis();
193 void CKeyboardStat::ProcessKeyUp(void)
195 memset(&m_lastKeysym, 0, sizeof(m_lastKeysym));
196 m_lastKeyTime = 0;
199 // Return the key name given a key ID
200 // Used to make the debug log more intelligable
201 // The KeyID includes the flags for ctrl, alt etc
203 std::string CKeyboardStat::GetKeyName(int KeyID)
204 { int keyid;
205 std::string keyname;
206 XBMCKEYTABLE keytable;
208 keyname.clear();
210 // Get modifiers
212 if (KeyID & CKey::MODIFIER_CTRL)
213 keyname.append("ctrl-");
214 if (KeyID & CKey::MODIFIER_SHIFT)
215 keyname.append("shift-");
216 if (KeyID & CKey::MODIFIER_ALT)
217 keyname.append("alt-");
218 if (KeyID & CKey::MODIFIER_SUPER)
219 keyname.append("win-");
220 if (KeyID & CKey::MODIFIER_META)
221 keyname.append("meta-");
222 if (KeyID & CKey::MODIFIER_LONG)
223 keyname.append("long-");
225 // Now get the key name
227 keyid = KeyID & 0xFF;
228 bool VKeyFound = KeyTableLookupVKeyName(keyid, &keytable);
229 if (VKeyFound)
230 keyname.append(keytable.keyname);
231 else
232 keyname += StringUtils::Format("%i", keyid);
234 // in case this might be an universalremote keyid
235 // we also print the possile corresponding obc code
236 // so users can easily find it in their universalremote
237 // map xml
238 if (VKeyFound || keyid > 255)
239 keyname += StringUtils::Format(" (0x%02x)", KeyID);
240 else// obc keys are 255 -rawid
241 keyname += StringUtils::Format(" (0x%02x, obc%i)", KeyID, 255 - KeyID);
243 return keyname;