2018-07-15 19:52:59 +02:00
|
|
|
/***********************************************************************
|
|
|
|
* fkeyboard.h - Read keyboard events *
|
|
|
|
* *
|
|
|
|
* This file is part of the Final Cut widget toolkit *
|
|
|
|
* *
|
2020-02-02 22:34:27 +01:00
|
|
|
* Copyright 2018-2020 Markus Gans *
|
2018-07-15 19:52:59 +02:00
|
|
|
* *
|
|
|
|
* The Final Cut is free software; you can redistribute it and/or *
|
|
|
|
* modify it under the terms of the GNU Lesser General Public License *
|
|
|
|
* as published by the Free Software Foundation; either version 3 of *
|
|
|
|
* the License, or (at your option) any later version. *
|
|
|
|
* *
|
|
|
|
* The Final Cut 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 Lesser General Public License for more details. *
|
|
|
|
* *
|
|
|
|
* You should have received a copy of the GNU Lesser General Public *
|
|
|
|
* License along with this program. If not, see *
|
|
|
|
* <http://www.gnu.org/licenses/>. *
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
|
|
/* Standalone class
|
|
|
|
* ════════════════
|
|
|
|
*
|
|
|
|
* ▕▔▔▔▔▔▔▔▔▔▔▔▏
|
|
|
|
* ▕ FKeyboard ▏
|
|
|
|
* ▕▁▁▁▁▁▁▁▁▁▁▁▏
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef FKEYBOARD_H
|
|
|
|
#define FKEYBOARD_H
|
|
|
|
|
|
|
|
#if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT)
|
|
|
|
#error "Only <final/final.h> can be included directly."
|
|
|
|
#endif
|
|
|
|
|
2019-08-06 23:45:28 +02:00
|
|
|
#include <sys/time.h>
|
2019-10-05 23:20:07 +02:00
|
|
|
#include <functional>
|
|
|
|
#include "final/fstring.h"
|
2018-07-15 19:52:59 +02:00
|
|
|
#include "final/ftypes.h"
|
|
|
|
|
2018-09-20 23:59:01 +02:00
|
|
|
namespace finalcut
|
|
|
|
{
|
|
|
|
|
2018-07-15 19:52:59 +02:00
|
|
|
// class forward declaration
|
|
|
|
class FApplication;
|
2019-07-21 23:31:21 +02:00
|
|
|
class FString;
|
|
|
|
class FTermLinux;
|
2018-07-15 19:52:59 +02:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// class FKeyboardCommand
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
2019-01-04 02:18:54 +01:00
|
|
|
class FKeyboardCommand final
|
2018-07-15 19:52:59 +02:00
|
|
|
{
|
|
|
|
public:
|
2019-10-05 23:20:07 +02:00
|
|
|
// Constructors
|
|
|
|
FKeyboardCommand () = default;
|
2019-10-14 01:44:24 +02:00
|
|
|
explicit FKeyboardCommand (const std::function<void()>& fn)
|
2019-10-05 23:20:07 +02:00
|
|
|
: handler(fn)
|
|
|
|
{ }
|
2018-07-15 19:52:59 +02:00
|
|
|
|
|
|
|
// Method
|
2019-10-05 23:20:07 +02:00
|
|
|
void execute()
|
|
|
|
{
|
|
|
|
handler();
|
|
|
|
}
|
2018-07-15 19:52:59 +02:00
|
|
|
|
|
|
|
private:
|
2019-09-04 23:57:31 +02:00
|
|
|
// Data members
|
2019-10-05 23:20:07 +02:00
|
|
|
std::function<void()> handler{};
|
2018-07-15 19:52:59 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// class FKeyboard
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
2019-01-04 02:18:54 +01:00
|
|
|
class FKeyboard final
|
2018-07-15 19:52:59 +02:00
|
|
|
{
|
|
|
|
public:
|
2018-10-11 03:46:37 +02:00
|
|
|
// Constants
|
2018-12-26 23:41:49 +01:00
|
|
|
static constexpr std::size_t FIFO_BUF_SIZE{512};
|
2018-10-11 03:46:37 +02:00
|
|
|
|
|
|
|
// Typedef
|
|
|
|
typedef char keybuffer[FIFO_BUF_SIZE];
|
|
|
|
|
2018-07-15 19:52:59 +02:00
|
|
|
// Constructor
|
|
|
|
FKeyboard();
|
2018-12-24 18:11:16 +01:00
|
|
|
|
2018-12-09 22:04:55 +01:00
|
|
|
// Disable copy constructor
|
|
|
|
FKeyboard (const FKeyboard&) = delete;
|
2018-12-24 18:11:16 +01:00
|
|
|
|
2018-07-15 19:52:59 +02:00
|
|
|
// Destructor
|
2020-04-04 20:58:47 +02:00
|
|
|
~FKeyboard();
|
2018-07-15 19:52:59 +02:00
|
|
|
|
2020-04-15 23:44:08 +02:00
|
|
|
// Disable copy assignment operator (=)
|
2018-12-09 22:04:55 +01:00
|
|
|
FKeyboard& operator = (const FKeyboard&) = delete;
|
|
|
|
|
2018-07-15 19:52:59 +02:00
|
|
|
// Accessors
|
2020-04-04 20:58:47 +02:00
|
|
|
const FString getClassName() const;
|
2019-10-05 23:20:07 +02:00
|
|
|
FKey getKey();
|
2020-02-02 22:34:27 +01:00
|
|
|
const FString getKeyName (const FKey);
|
2019-10-05 23:20:07 +02:00
|
|
|
keybuffer& getKeyBuffer();
|
|
|
|
timeval* getKeyPressedTime();
|
2020-03-05 21:30:54 +01:00
|
|
|
static uInt64 getKeypressTimeout();
|
|
|
|
static uInt64 getReadBlockingTime();
|
2018-07-15 19:52:59 +02:00
|
|
|
|
|
|
|
// Mutators
|
2019-10-08 04:37:19 +02:00
|
|
|
void setTermcapMap (fc::FKeyMap*);
|
2020-03-05 21:30:54 +01:00
|
|
|
static void setKeypressTimeout (const uInt64);
|
|
|
|
static void setReadBlockingTime (const uInt64);
|
2019-10-05 23:20:07 +02:00
|
|
|
void enableUTF8();
|
|
|
|
void disableUTF8();
|
|
|
|
void enableMouseSequences();
|
|
|
|
void disableMouseSequences();
|
2020-04-19 20:38:52 +02:00
|
|
|
void setPressCommand (const FKeyboardCommand&);
|
|
|
|
void setReleaseCommand (const FKeyboardCommand&);
|
|
|
|
void setEscPressedCommand (const FKeyboardCommand&);
|
2018-07-15 19:52:59 +02:00
|
|
|
|
|
|
|
// Inquiry
|
2020-05-02 00:07:35 +02:00
|
|
|
bool isInputDataPending() const;
|
2018-07-15 19:52:59 +02:00
|
|
|
|
|
|
|
// Methods
|
2019-10-05 23:20:07 +02:00
|
|
|
static void init();
|
|
|
|
bool& unprocessedInput();
|
2020-05-02 00:07:35 +02:00
|
|
|
bool isKeyPressed() const;
|
2019-10-05 23:20:07 +02:00
|
|
|
void clearKeyBuffer();
|
|
|
|
void clearKeyBufferOnTimeout();
|
|
|
|
void fetchKeyCode();
|
|
|
|
void escapeKeyHandling();
|
2018-07-15 19:52:59 +02:00
|
|
|
|
|
|
|
private:
|
|
|
|
// Constants
|
2018-12-26 23:41:49 +01:00
|
|
|
static constexpr FKey NOT_SET = static_cast<FKey>(-1);
|
2018-07-15 19:52:59 +02:00
|
|
|
|
|
|
|
// Accessors
|
2019-10-05 23:20:07 +02:00
|
|
|
FKey getMouseProtocolKey();
|
|
|
|
FKey getTermcapKey();
|
|
|
|
FKey getMetaKey();
|
|
|
|
FKey getSingleKey();
|
2018-07-15 19:52:59 +02:00
|
|
|
|
|
|
|
// Mutators
|
2019-10-05 23:20:07 +02:00
|
|
|
bool setNonBlockingInput (bool);
|
|
|
|
bool setNonBlockingInput();
|
|
|
|
bool unsetNonBlockingInput();
|
2018-07-15 19:52:59 +02:00
|
|
|
|
|
|
|
// Inquiry
|
2019-10-05 23:20:07 +02:00
|
|
|
static bool isKeypressTimeout();
|
2018-07-15 19:52:59 +02:00
|
|
|
|
|
|
|
// Methods
|
2019-10-05 23:20:07 +02:00
|
|
|
FKey UTF8decode (const char[]);
|
|
|
|
ssize_t readKey();
|
|
|
|
void parseKeyBuffer();
|
|
|
|
FKey parseKeyString();
|
|
|
|
FKey keyCorrection (const FKey&);
|
|
|
|
void substringKeyHandling();
|
|
|
|
void keyPressed();
|
|
|
|
void keyReleased();
|
|
|
|
void escapeKeyPressed();
|
2018-07-15 19:52:59 +02:00
|
|
|
|
2019-09-04 23:57:31 +02:00
|
|
|
// Data members
|
2019-10-05 23:20:07 +02:00
|
|
|
FKeyboardCommand keypressed_cmd{};
|
|
|
|
FKeyboardCommand keyreleased_cmd{};
|
|
|
|
FKeyboardCommand escape_key_cmd{};
|
2019-09-08 02:04:24 +02:00
|
|
|
|
|
|
|
#if defined(__linux__)
|
|
|
|
#undef linux
|
2019-10-05 23:20:07 +02:00
|
|
|
static FTermLinux* linux;
|
2019-09-08 02:04:24 +02:00
|
|
|
#endif
|
|
|
|
|
2019-10-05 23:20:07 +02:00
|
|
|
static timeval time_keypressed;
|
2020-03-05 21:30:54 +01:00
|
|
|
static uInt64 read_blocking_time;
|
2019-10-05 23:20:07 +02:00
|
|
|
static uInt64 key_timeout;
|
2019-10-08 04:37:19 +02:00
|
|
|
fc::FKeyMap* key_map{nullptr};
|
2019-10-05 23:20:07 +02:00
|
|
|
FKey key{0};
|
2020-03-05 21:30:54 +01:00
|
|
|
uChar read_character{};
|
2019-10-05 23:20:07 +02:00
|
|
|
char fifo_buf[FIFO_BUF_SIZE]{'\0'};
|
|
|
|
int fifo_offset{0};
|
|
|
|
int stdin_status_flags{0};
|
|
|
|
bool fifo_in_use{false};
|
|
|
|
bool input_data_pending{false};
|
|
|
|
bool utf8_input{false};
|
|
|
|
bool mouse_support{true};
|
|
|
|
bool non_blocking_stdin{false};
|
2018-07-15 19:52:59 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// FKeyboard inline functions
|
2018-07-22 23:07:49 +02:00
|
|
|
//----------------------------------------------------------------------
|
2019-10-05 23:20:07 +02:00
|
|
|
inline const FString FKeyboard::getClassName() const
|
2018-07-22 23:07:49 +02:00
|
|
|
{ return "FKeyboard"; }
|
|
|
|
|
2018-07-15 19:52:59 +02:00
|
|
|
//----------------------------------------------------------------------
|
2018-11-21 20:07:08 +01:00
|
|
|
inline FKey FKeyboard::getKey()
|
2018-07-15 19:52:59 +02:00
|
|
|
{ return key; }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2018-10-11 03:46:37 +02:00
|
|
|
inline FKeyboard::keybuffer& FKeyboard::getKeyBuffer()
|
|
|
|
{ return fifo_buf; }
|
2018-07-15 19:52:59 +02:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2018-07-22 23:07:49 +02:00
|
|
|
inline timeval* FKeyboard::getKeyPressedTime()
|
2018-07-15 19:52:59 +02:00
|
|
|
{ return &time_keypressed; }
|
|
|
|
|
2020-03-05 21:30:54 +01:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline uInt64 FKeyboard::getKeypressTimeout()
|
|
|
|
{ return key_timeout; }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline uInt64 FKeyboard::getReadBlockingTime()
|
|
|
|
{ return read_blocking_time; }
|
|
|
|
|
2018-07-15 19:52:59 +02:00
|
|
|
//----------------------------------------------------------------------
|
2018-12-28 22:57:43 +01:00
|
|
|
inline void FKeyboard::setKeypressTimeout (const uInt64 timeout)
|
2018-07-15 19:52:59 +02:00
|
|
|
{ key_timeout = timeout; }
|
|
|
|
|
2020-03-05 21:30:54 +01:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline void FKeyboard::setReadBlockingTime (const uInt64 blocking_time)
|
|
|
|
{ read_blocking_time = blocking_time; }
|
|
|
|
|
2018-07-15 19:52:59 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline void FKeyboard::enableUTF8()
|
|
|
|
{ utf8_input = true; }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline void FKeyboard::disableUTF8()
|
|
|
|
{ utf8_input = false; }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline void FKeyboard::enableMouseSequences()
|
|
|
|
{ mouse_support = true; }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline void FKeyboard::disableMouseSequences()
|
|
|
|
{ mouse_support = false; }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2020-04-19 20:38:52 +02:00
|
|
|
inline void FKeyboard::setPressCommand (const FKeyboardCommand& cmd)
|
2018-07-15 19:52:59 +02:00
|
|
|
{ keypressed_cmd = cmd; }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2020-04-19 20:38:52 +02:00
|
|
|
inline void FKeyboard::setReleaseCommand (const FKeyboardCommand& cmd)
|
2018-07-15 19:52:59 +02:00
|
|
|
{ keyreleased_cmd = cmd; }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2020-04-19 20:38:52 +02:00
|
|
|
inline void FKeyboard::setEscPressedCommand (const FKeyboardCommand& cmd)
|
2018-07-15 19:52:59 +02:00
|
|
|
{ escape_key_cmd = cmd; }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2020-05-02 00:07:35 +02:00
|
|
|
inline bool FKeyboard::isInputDataPending() const
|
2018-07-15 19:52:59 +02:00
|
|
|
{ return input_data_pending; }
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline bool FKeyboard::setNonBlockingInput()
|
|
|
|
{ return setNonBlockingInput(true); }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline bool FKeyboard::unsetNonBlockingInput()
|
|
|
|
{ return setNonBlockingInput(false); }
|
|
|
|
|
2018-09-20 23:59:01 +02:00
|
|
|
} // namespace finalcut
|
|
|
|
|
2018-07-15 19:52:59 +02:00
|
|
|
#endif // FKEYBOARD_H
|