// license:BSD-3-Clause // copyright-holders:Aaron Giles /*************************************************************************** natkeyboard.h Natural keyboard input support. ***************************************************************************/ #ifndef MAME_EMU_NATKEYBOARD_H #define MAME_EMU_NATKEYBOARD_H #pragma once #include #include //************************************************************************** // TYPE DEFINITIONS //************************************************************************** // keyboard helper function delegates typedef delegate ioport_queue_chars_delegate; typedef delegate ioport_accept_char_delegate; typedef delegate ioport_charqueue_empty_delegate; // ======================> natural_keyboard // buffer to handle copy/paste/insert of keys class natural_keyboard { DISABLE_COPYING(natural_keyboard); public: // construction/destruction natural_keyboard(running_machine &machine); // getters and queries running_machine &machine() const { return m_machine; } bool empty() const { return (m_bufbegin == m_bufend); } bool full() const { return ((m_bufend + 1) % m_buffer.size()) == m_bufbegin; } bool can_post() const { return (!m_queue_chars.isnull() || !m_keycode_map.empty()); } bool is_posting() const { return (!empty() || (!m_charqueue_empty.isnull() && !m_charqueue_empty())); } bool in_use() const { return m_in_use; } // configuration void configure(ioport_queue_chars_delegate queue_chars, ioport_accept_char_delegate accept_char, ioport_charqueue_empty_delegate charqueue_empty); void set_in_use(bool usage); // posting void post(char32_t ch); void post(const char32_t *text, size_t length = 0, const attotime &rate = attotime::zero); void post_utf8(const char *text, size_t length = 0, const attotime &rate = attotime::zero); void post_utf8(const std::string &text, const attotime &rate = attotime::zero); void post_coded(const char *text, size_t length = 0, const attotime &rate = attotime::zero); void post_coded(const std::string &text, const attotime &rate = attotime::zero); void paste(); // debugging void dump(std::ostream &str) const; std::string dump() const; private: enum { SHIFT_COUNT = UCHAR_SHIFT_END - UCHAR_SHIFT_BEGIN + 1, SHIFT_STATES = 1 << SHIFT_COUNT }; // internal keyboard code information struct keycode_map_entry { std::array field; unsigned shift; }; typedef std::unordered_map keycode_map; // internal helpers void build_codes(ioport_manager &manager); bool can_post_directly(char32_t ch); bool can_post_alternate(char32_t ch); attotime choose_delay(char32_t ch); void internal_post(char32_t ch); void timer(void *ptr, int param); std::string unicode_to_string(char32_t ch) const; const keycode_map_entry *find_code(char32_t ch) const; // internal state running_machine & m_machine; // reference to our machine bool m_in_use; // is natural keyboard in use? u32 m_bufbegin; // index of starting character u32 m_bufend; // index of ending character std::vector m_buffer; // actual buffer unsigned m_fieldnum; // current step in multi-key sequence bool m_status_keydown; // current keydown status bool m_last_cr; // was the last char a CR? emu_timer * m_timer; // timer for posting characters attotime m_current_rate; // current rate for posting ioport_queue_chars_delegate m_queue_chars; // queue characters callback ioport_accept_char_delegate m_accept_char; // accept character callback ioport_charqueue_empty_delegate m_charqueue_empty; // character queue empty callback keycode_map m_keycode_map; // keycode map }; inline std::ostream &operator<<(std::ostream &str, natural_keyboard const &kbd) { kbd.dump(str); return str; } #endif // MAME_EMU_NATKEYBOARD_H