mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	Implemented raw keyboard input
This commit is contained in:
		@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user