mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Implemented raw keyboard input
This commit is contained in:
parent
0f01d92106
commit
b90e708733
@ -514,3 +514,6 @@ Thomas Sailer <sailer@scs.ch>
|
|||||||
|
|
||||||
Sven Goethel <sgoethel@jausoft.com>
|
Sven Goethel <sgoethel@jausoft.com>
|
||||||
for making switching audio channels work without stopping/restarting the DMX
|
for making switching audio channels work without stopping/restarting the DMX
|
||||||
|
|
||||||
|
Jan Rieger <jan@ricomp.de>
|
||||||
|
for suggestions and testing raw keyboard input
|
||||||
|
6
HISTORY
6
HISTORY
@ -1887,3 +1887,9 @@ Video Disk Recorder Revision History
|
|||||||
- No longer stopping/restarting the DMX when switching audio channels (thanks to
|
- No longer stopping/restarting the DMX when switching audio channels (thanks to
|
||||||
Sven Goethel).
|
Sven Goethel).
|
||||||
- Fixed high CPU load in 'Transfer Mode' (thanks to Oliver Endriss).
|
- Fixed high CPU load in 'Transfer Mode' (thanks to Oliver Endriss).
|
||||||
|
- If a PC keyboard is used as remote control, the string entry fields in the
|
||||||
|
menus now accept character input directly (however, this works only for keys that
|
||||||
|
are not otherwise defined as remote control keys). Also, plugins can switch the
|
||||||
|
cKbdRemote class into "raw mode", where all keyboard input will be made available
|
||||||
|
through the new 'kKbd' key code and none of it will be processed as normal remote
|
||||||
|
control functions (thanks to Jan Rieger for suggestions and testing).
|
||||||
|
7
keys.h
7
keys.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: keys.h 1.4 2002/12/01 10:43:26 kls Exp $
|
* $Id: keys.h 1.5 2002/12/14 15:49:42 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __KEYS_H
|
#ifndef __KEYS_H
|
||||||
@ -46,6 +46,7 @@ enum eKeys { // "Up" and "Down" must be the first two keys!
|
|||||||
kCommands,
|
kCommands,
|
||||||
kUser1, kUser2, kUser3, kUser4, kUser5, kUser6, kUser7, kUser8, kUser9,
|
kUser1, kUser2, kUser3, kUser4, kUser5, kUser6, kUser7, kUser8, kUser9,
|
||||||
kNone,
|
kNone,
|
||||||
|
kKbd,
|
||||||
// The following codes are used internally:
|
// The following codes are used internally:
|
||||||
k_Plugin,
|
k_Plugin,
|
||||||
k_Setup,
|
k_Setup,
|
||||||
@ -69,6 +70,10 @@ enum eKeys { // "Up" and "Down" must be the first two keys!
|
|||||||
#define NORMALKEY(k) (eKeys((k) & ~k_Repeat))
|
#define NORMALKEY(k) (eKeys((k) & ~k_Repeat))
|
||||||
#define ISMODELESSKEY(k) (RAWKEY(k) > k9)
|
#define ISMODELESSKEY(k) (RAWKEY(k) > k9)
|
||||||
|
|
||||||
|
#define BASICKEY(k) (eKeys((k) & 0xFFFF))
|
||||||
|
#define KBDKEY(k) (eKeys(((k) << 16) | kKbd))
|
||||||
|
#define KEYKBD(k) (((k) >> 16) & 0xFFFF)
|
||||||
|
|
||||||
struct tKey {
|
struct tKey {
|
||||||
eKeys type;
|
eKeys type;
|
||||||
char *name;
|
char *name;
|
||||||
|
45
menuitems.c
45
menuitems.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: menuitems.c 1.9 2002/09/08 14:51:28 kls Exp $
|
* $Id: menuitems.c 1.10 2002/12/15 10:58:00 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "menuitems.h"
|
#include "menuitems.h"
|
||||||
@ -284,7 +284,7 @@ eOSState cMenuEditStrItem::ProcessKey(eKeys Key)
|
|||||||
uppercase = isupper(value[pos]);
|
uppercase = isupper(value[pos]);
|
||||||
break;
|
break;
|
||||||
case kRight|k_Repeat:
|
case kRight|k_Repeat:
|
||||||
case kRight: if (pos < length && pos < int(strlen(value)) ) {
|
case kRight: if (pos < length - 2 && pos < int(strlen(value)) ) {
|
||||||
if (++pos >= int(strlen(value))) {
|
if (++pos >= int(strlen(value))) {
|
||||||
if (pos >= 2 && value[pos - 1] == ' ' && value[pos - 2] == ' ')
|
if (pos >= 2 && value[pos - 1] == ' ' && value[pos - 2] == ' ')
|
||||||
pos--; // allow only two blanks at the end
|
pos--; // allow only two blanks at the end
|
||||||
@ -306,7 +306,7 @@ eOSState cMenuEditStrItem::ProcessKey(eKeys Key)
|
|||||||
case kDown: if (pos >= 0) {
|
case kDown: if (pos >= 0) {
|
||||||
if (insert && newchar) {
|
if (insert && newchar) {
|
||||||
// create a new character in insert mode
|
// create a new character in insert mode
|
||||||
if (int(strlen(value)) < length) {
|
if (int(strlen(value)) < length - 1) {
|
||||||
memmove(value + pos + 1, value + pos, strlen(value) - pos + 1);
|
memmove(value + pos + 1, value + pos, strlen(value) - pos + 1);
|
||||||
value[pos] = ' ';
|
value[pos] = ' ';
|
||||||
}
|
}
|
||||||
@ -328,7 +328,44 @@ eOSState cMenuEditStrItem::ProcessKey(eKeys Key)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// run into default
|
// run into default
|
||||||
default: return cMenuEditItem::ProcessKey(Key);
|
default: if (pos >= 0 && BASICKEY(Key) == kKbd) {
|
||||||
|
int c = KEYKBD(Key);
|
||||||
|
if (c <= 0xFF) {
|
||||||
|
const char *p = strchr(allowed, tolower(c));
|
||||||
|
if (p) {
|
||||||
|
int l = strlen(value);
|
||||||
|
if (insert && l < length - 1)
|
||||||
|
memmove(value + pos + 1, value + pos, l - pos + 1);
|
||||||
|
value[pos] = c;
|
||||||
|
if (pos < length - 2)
|
||||||
|
pos++;
|
||||||
|
if (pos >= l) {
|
||||||
|
value[pos] = ' ';
|
||||||
|
value[pos + 1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch (c) {
|
||||||
|
case 0x7F: // backspace
|
||||||
|
if (pos > 0) {
|
||||||
|
pos--;
|
||||||
|
return ProcessKey(kYellow);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch (c) {
|
||||||
|
case kfHome: pos = 0; break;
|
||||||
|
case kfEnd: pos = strlen(value) - 1; break;
|
||||||
|
case kfIns: return ProcessKey(kGreen);
|
||||||
|
case kfDel: return ProcessKey(kYellow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return cMenuEditItem::ProcessKey(Key);
|
||||||
}
|
}
|
||||||
Set();
|
Set();
|
||||||
return osContinue;
|
return osContinue;
|
||||||
|
67
remote.c
67
remote.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: remote.c 1.34 2002/12/08 13:37:13 kls Exp $
|
* $Id: remote.c 1.35 2002/12/15 10:09:27 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
@ -149,6 +149,39 @@ cRemotes Remotes;
|
|||||||
|
|
||||||
// --- cKbdRemote ------------------------------------------------------------
|
// --- cKbdRemote ------------------------------------------------------------
|
||||||
|
|
||||||
|
struct tKbdMap {
|
||||||
|
eKbdFunc func;
|
||||||
|
uint64 code;
|
||||||
|
};
|
||||||
|
|
||||||
|
static tKbdMap KbdMap[] = {
|
||||||
|
{ kfF1, 0x0000001B5B31317EULL },
|
||||||
|
{ kfF2, 0x0000001B5B31327EULL },
|
||||||
|
{ kfF3, 0x0000001B5B31337EULL },
|
||||||
|
{ kfF4, 0x0000001B5B31347EULL },
|
||||||
|
{ kfF5, 0x0000001B5B31357EULL },
|
||||||
|
{ kfF6, 0x0000001B5B31377EULL },
|
||||||
|
{ kfF7, 0x0000001B5B31387EULL },
|
||||||
|
{ kfF8, 0x0000001B5B31397EULL },
|
||||||
|
{ kfF9, 0x0000001B5B32307EULL },
|
||||||
|
{ kfF10, 0x0000001B5B32317EULL },
|
||||||
|
{ kfF11, 0x0000001B5B32327EULL },
|
||||||
|
{ kfF12, 0x0000001B5B32337EULL },
|
||||||
|
{ kfUp, 0x00000000001B5B41ULL },
|
||||||
|
{ kfDown, 0x00000000001B5B42ULL },
|
||||||
|
{ kfLeft, 0x00000000001B5B44ULL },
|
||||||
|
{ kfRight, 0x00000000001B5B43ULL },
|
||||||
|
{ kfHome, 0x00000000001B5B48ULL },
|
||||||
|
{ kfEnd, 0x00000000001B5B46ULL },
|
||||||
|
{ kfPgUp, 0x000000001B5B357EULL },
|
||||||
|
{ kfPgDown, 0x000000001B5B367EULL },
|
||||||
|
{ kfIns, 0x000000001B5B327EULL },
|
||||||
|
{ kfDel, 0x000000001B5B337EULL },
|
||||||
|
{ kfNone, 0x0000000000000000ULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
bool cKbdRemote::rawMode = false;
|
||||||
|
|
||||||
cKbdRemote::cKbdRemote(void)
|
cKbdRemote::cKbdRemote(void)
|
||||||
:cRemote("KBD")
|
:cRemote("KBD")
|
||||||
{
|
{
|
||||||
@ -172,6 +205,29 @@ cKbdRemote::~cKbdRemote()
|
|||||||
tcsetattr(STDIN_FILENO, TCSANOW, &savedTm);
|
tcsetattr(STDIN_FILENO, TCSANOW, &savedTm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cKbdRemote::SetRawMode(bool RawMode)
|
||||||
|
{
|
||||||
|
rawMode = RawMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64 cKbdRemote::MapFuncToCode(int Func)
|
||||||
|
{
|
||||||
|
for (tKbdMap *p = KbdMap; p->func != kfNone; p++) {
|
||||||
|
if (p->func == Func)
|
||||||
|
return p->code;
|
||||||
|
}
|
||||||
|
return (Func <= 0xFF) ? Func : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cKbdRemote::MapCodeToFunc(uint64 Code)
|
||||||
|
{
|
||||||
|
for (tKbdMap *p = KbdMap; p->func != kfNone; p++) {
|
||||||
|
if (p->code == Code)
|
||||||
|
return p->func;
|
||||||
|
}
|
||||||
|
return (Code <= 0xFF) ? Code : kfNone;
|
||||||
|
}
|
||||||
|
|
||||||
void cKbdRemote::Action(void)
|
void cKbdRemote::Action(void)
|
||||||
{
|
{
|
||||||
dsyslog("KBD remote control thread started (pid=%d)", getpid());
|
dsyslog("KBD remote control thread started (pid=%d)", getpid());
|
||||||
@ -198,8 +254,13 @@ void cKbdRemote::Action(void)
|
|||||||
// key (if somebody knows how to clean this up, please let me know):
|
// key (if somebody knows how to clean this up, please let me know):
|
||||||
if (Command == 0x1B && time_ms() - t0 < 100)
|
if (Command == 0x1B && time_ms() - t0 < 100)
|
||||||
continue;
|
continue;
|
||||||
if (Command)
|
if (Command) {
|
||||||
Put(Command);
|
if (rawMode || !Put(Command)) {
|
||||||
|
int func = MapCodeToFunc(Command);
|
||||||
|
if (func)
|
||||||
|
Put(KBDKEY(func));
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
32
remote.h
32
remote.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: remote.h 1.22 2002/12/08 13:37:02 kls Exp $
|
* $Id: remote.h 1.23 2002/12/15 09:58:32 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __REMOTE_H
|
#ifndef __REMOTE_H
|
||||||
@ -51,14 +51,44 @@ class cRemotes : public cList<cRemote> {};
|
|||||||
|
|
||||||
extern cRemotes Remotes;
|
extern cRemotes Remotes;
|
||||||
|
|
||||||
|
enum eKbdFunc {
|
||||||
|
kfNone,
|
||||||
|
kfF1 = 0x100,
|
||||||
|
kfF2,
|
||||||
|
kfF3,
|
||||||
|
kfF4,
|
||||||
|
kfF5,
|
||||||
|
kfF6,
|
||||||
|
kfF7,
|
||||||
|
kfF8,
|
||||||
|
kfF9,
|
||||||
|
kfF10,
|
||||||
|
kfF11,
|
||||||
|
kfF12,
|
||||||
|
kfUp,
|
||||||
|
kfDown,
|
||||||
|
kfLeft,
|
||||||
|
kfRight,
|
||||||
|
kfHome,
|
||||||
|
kfEnd,
|
||||||
|
kfPgUp,
|
||||||
|
kfPgDown,
|
||||||
|
kfIns,
|
||||||
|
kfDel,
|
||||||
|
};
|
||||||
|
|
||||||
class cKbdRemote : public cRemote, private cThread {
|
class cKbdRemote : public cRemote, private cThread {
|
||||||
private:
|
private:
|
||||||
bool active;
|
bool active;
|
||||||
|
static bool rawMode;
|
||||||
struct termios savedTm;
|
struct termios savedTm;
|
||||||
virtual void Action(void);
|
virtual void Action(void);
|
||||||
|
int MapCodeToFunc(uint64 Code);
|
||||||
public:
|
public:
|
||||||
cKbdRemote(void);
|
cKbdRemote(void);
|
||||||
virtual ~cKbdRemote();
|
virtual ~cKbdRemote();
|
||||||
|
uint64 MapFuncToCode(int Func);
|
||||||
|
static void SetRawMode(bool RawMode);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //__REMOTE_H
|
#endif //__REMOTE_H
|
||||||
|
Loading…
Reference in New Issue
Block a user