/*********************************************************************** * fmouse.h - Read mouse events * * * * This file is part of the Final Cut widget toolkit * * * * Copyright 2018-2019 Markus Gans * * * * 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 * * . * ***********************************************************************/ /* Inheritance diagram * ═══════════════════ * * ▕▔▔▔▔▔▔▔▔▔▔▏ * ▕ FMouse ▏ * ▕▁▁▁▁▁▁▁▁▁▁▏ * ▲ * │ * ┌─────────────┬──────┴───────┬─────────────┐ * │ │ │ │ * ▕▔▔▔▔▔▔▔▔▔▔▔▏ ▕▔▔▔▔▔▔▔▔▔▔▔▏ ▕▔▔▔▔▔▔▔▔▔▔▔▏ ▕▔▔▔▔▔▔▔▔▔▔▔▔▔▏ * ▕ FMouseGPM ▏ ▕ FMouseX11 ▏ ▕ FMouseSGR ▏ ▕ FMouseUrxvt ▏ * ▕▁▁▁▁▁▁▁▁▁▁▁▏ ▕▁▁▁▁▁▁▁▁▁▁▁▏ ▕▁▁▁▁▁▁▁▁▁▁▁▏ ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▏ * * * * ▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏1 1▕▔▔▔▔▔▔▔▔▔▔▔▏ * ▕ FMouseControl ▏- -┬- - -▕ FMouseGPM ▏ * ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏ : ▕▁▁▁▁▁▁▁▁▁▁▁▏ * : * : 1▕▔▔▔▔▔▔▔▔▔▔▔▏ * :- - -▕ FMouseX11 ▏ * : ▕▁▁▁▁▁▁▁▁▁▁▁▏ * : * : 1▕▔▔▔▔▔▔▔▔▔▔▔▏ * └- - -▕ FMouseSGR ▏ * : ▕▁▁▁▁▁▁▁▁▁▁▁▏ * : * : 1▕▔▔▔▔▔▔▔▔▔▔▔▔▔▏ * └- - -▕ FMouseUrxvt ▏ * ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▏ */ #ifndef FMOUSE_H #define FMOUSE_H #if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT) #error "Only can be included directly." #endif #include #include #include "final/fconfig.h" #include "final/fkeyboard.h" #include "final/fpoint.h" #include "final/ftypes.h" #if defined(__linux__) #include // need for gpm keyboard modifiers #endif #ifdef F_HAVE_LIBGPM #include #endif namespace finalcut { //---------------------------------------------------------------------- // class FMouse //---------------------------------------------------------------------- #pragma pack(push) #pragma pack(1) class FMouse { public: // Enumeration enum mouse_type { none = 0, gpm = 1, x11 = 2, sgr = 3, urxvt = 4 }; // Constructor FMouse(); // Destructor virtual ~FMouse() { } // Accessors virtual const char* getClassName() const; FPoint& getPos(); void clearEvent(); // Mutators void setMaxWidth (uInt16); void setMaxHeight (uInt16); void setDblclickInterval (const uInt64); // Inquiries virtual bool hasData() = 0; bool hasEvent(); bool isLeftButtonPressed(); bool isLeftButtonReleased(); bool isLeftButtonDoubleClick(); bool isRightButtonPressed(); bool isRightButtonReleased(); bool isMiddleButtonPressed(); bool isMiddleButtonReleased(); bool isShiftKeyPressed(); bool isControlKeyPressed(); bool isMetaKeyPressed(); bool isWheelUp(); bool isWheelDown(); bool isMoved(); bool isInputDataPending(); // Methods static FMouse* createMouseObject (mouse_type); virtual void setRawData (FKeyboard::keybuffer&) = 0; virtual void processEvent (struct timeval*) = 0; protected: // Typedef and Enumerations typedef struct { uChar left_button : 2; // 0..3 uChar right_button : 2; // 0..3 uChar middle_button : 2; // 0..3 uChar shift_button : 1; // 0..1 uChar control_button : 1; // 0..1 uChar meta_button : 1; // 0..1 uChar wheel_up : 1; // 0..1 uChar wheel_down : 1; // 0..1 uChar mouse_moved : 1; // 0..1 uChar : 4; // padding bits } button; // bit field enum states { Undefined = 0, Pressed = 1, Released = 2, DoubleClick = 3 }; // Mutator void setPos (const FPoint&); // Method bool isDblclickTimeout (timeval*); // Data Members button b_state{}; bool mouse_event_occurred{false}; bool input_data_pending{false}; uInt64 dblclick_interval{500000}; // 500 ms uInt16 max_width{80}; uInt16 max_height{25}; struct timeval time_mousepressed{}; FPoint zero_point{0, 0}; // zero point (x=0, y=0) FPoint mouse{0, 0}; // mouse click position FPoint new_mouse_position{}; }; #pragma pack(pop) #ifdef F_HAVE_LIBGPM //---------------------------------------------------------------------- // class FMouseGPM //---------------------------------------------------------------------- #pragma pack(push) #pragma pack(1) class FMouseGPM : public FMouse { public: // Constructor FMouseGPM(); // Destructor virtual ~FMouseGPM(); // Accessors virtual const char* getClassName() const override; // Mutators void setStdinNo(int); // Inquiry virtual bool hasData() override; bool isGpmMouseEnabled(); // Methods virtual void setRawData (FKeyboard::keybuffer&) override; virtual void processEvent (struct timeval*) override; bool gpmMouse (bool); bool enableGpmMouse(); bool disableGpmMouse(); bool hasSignificantEvents(); void interpretKeyDown(); void interpretKeyUp(); bool getGpmKeyPressed(bool); void drawGpmPointer(); private: // Enumeration enum gpmEventType { no_event = 0, keyboard_event = 1, mouse_event = 2 }; // Method int gpmEvent (bool = true); // Data Member Gpm_Event gpm_ev{}; bool has_gpm_mouse_data{false}; bool gpm_mouse_enabled{false}; int stdin_no{0}; }; #pragma pack(pop) //---------------------------------------------------------------------- inline bool FMouseGPM::enableGpmMouse() { return gpmMouse(true); } //---------------------------------------------------------------------- inline bool FMouseGPM::disableGpmMouse() { return gpmMouse(false); } //---------------------------------------------------------------------- inline bool FMouseGPM::isGpmMouseEnabled() { return gpm_mouse_enabled; } #endif // F_HAVE_LIBGPM //---------------------------------------------------------------------- // class FMouseX11 //---------------------------------------------------------------------- #pragma pack(push) #pragma pack(1) class FMouseX11 : public FMouse { public: // Constructor FMouseX11() = default; // Destructor virtual ~FMouseX11() = default; // Accessors virtual const char* getClassName() const override; // Inquiry virtual bool hasData() override; // Methods virtual void setRawData (FKeyboard::keybuffer&) override; virtual void processEvent (struct timeval*) override; private: // Enumeration enum btn_states { key_shift = 0x04, key_meta = 0x08, key_ctrl = 0x10, key_button_mask = 0x1c, button1_pressed = 0x20, button2_pressed = 0x21, button3_pressed = 0x22, all_buttons_released = 0x23, button1_pressed_move = 0x40, button2_pressed_move = 0x41, button3_pressed_move = 0x42, button_mask = 0x63, button_up = 0x60, button_down = 0x61, button_up_move = 0x60, button_down_move = 0x61 }; // Constant static constexpr std::size_t MOUSE_BUF_SIZE = 4; // Method void setKeyState (int); void setMoveState (const FPoint&, int); void setButtonState (int, struct timeval*); // Data Member char x11_mouse[MOUSE_BUF_SIZE]{'\0'}; uChar x11_button_state{all_buttons_released}; }; #pragma pack(pop) //---------------------------------------------------------------------- // class FMouseSGR //---------------------------------------------------------------------- #pragma pack(push) #pragma pack(1) class FMouseSGR : public FMouse { public: // Constructor FMouseSGR() = default; // Destructor virtual ~FMouseSGR() = default; // Accessors virtual const char* getClassName() const override; // Inquiry virtual bool hasData() override; // Methods virtual void setRawData (FKeyboard::keybuffer&) override; virtual void processEvent (struct timeval*) override; private: // Enumeration enum x11_ext_btn_states { key_shift = 0x04, key_meta = 0x08, key_ctrl = 0x10, key_button_mask = 0x1c, button1 = 0x00, button2 = 0x01, button3 = 0x02, button1_move = 0x20, button2_move = 0x21, button3_move = 0x22, button_mask = 0x63, button_up = 0x40, button_down = 0x41, pressed = 'M', released = 'm' }; // Constant static constexpr std::size_t MOUSE_BUF_SIZE = 13; // Methods void setKeyState (int); void setMoveState (const FPoint&, int); void setPressedButtonState (int, struct timeval*); void setReleasedButtonState (int); // Data Members char sgr_mouse[MOUSE_BUF_SIZE]{'\0'}; uChar sgr_button_state{0x23}; }; #pragma pack(pop) //---------------------------------------------------------------------- // class FMouseUrxvt //---------------------------------------------------------------------- #pragma pack(push) #pragma pack(1) class FMouseUrxvt : public FMouse { public: // Constructor FMouseUrxvt() = default; // Destructor virtual ~FMouseUrxvt() = default; // Accessors virtual const char* getClassName() const override; // Inquiry virtual bool hasData() override; // Methods virtual void setRawData (FKeyboard::keybuffer&) override; virtual void processEvent (struct timeval*) override; private: // Enumeration enum urxvt_btn_states { key_shift = 0x04, key_meta = 0x08, key_ctrl = 0x10, key_button_mask = 0x1c, button1_pressed = 0x20, button2_pressed = 0x21, button3_pressed = 0x22, all_buttons_released = 0x23, button1_pressed_move = 0x40, button2_pressed_move = 0x41, button3_pressed_move = 0x42, button_mask = 0x63, button_up = 0x60, button_down = 0x61, button_up_move = 0x60, button_down_move = 0x61 }; // Constant static constexpr std::size_t MOUSE_BUF_SIZE = 13; // Methods void setKeyState (int); void setMoveState (const FPoint&, int); void setButtonState (int, struct timeval*); // Data Members char urxvt_mouse[MOUSE_BUF_SIZE]{'\0'}; uChar urxvt_button_state{all_buttons_released}; }; #pragma pack(pop) //---------------------------------------------------------------------- // class FMouseControl //---------------------------------------------------------------------- #pragma pack(push) #pragma pack(1) class FMouseControl { public: // Constructor FMouseControl(); // Destructor virtual ~FMouseControl(); // Accessors virtual const char* getClassName() const; FPoint& getPos(); void clearEvent(); // Mutators void setStdinNo (int); void setMaxWidth (uInt16); void setMaxHeight (uInt16); void setDblclickInterval (const uInt64); void useGpmMouse (bool = true); void useXtermMouse (bool = true); // Inquiries bool hasData(); bool hasEvent(); bool isLeftButtonPressed(); bool isLeftButtonReleased(); bool isLeftButtonDoubleClick(); bool isRightButtonPressed(); bool isRightButtonReleased(); bool isMiddleButtonPressed(); bool isMiddleButtonReleased(); bool isShiftKeyPressed(); bool isControlKeyPressed(); bool isMetaKeyPressed(); bool isWheelUp(); bool isWheelDown(); bool isMoved(); bool isInputDataPending(); bool isGpmMouseEnabled(); // Methods void enable(); void disable(); virtual void setRawData ( FMouse::mouse_type , FKeyboard::keybuffer& ); virtual void processEvent (struct timeval* time); bool getGpmKeyPressed (bool); void drawGpmPointer(); private: // Accessor FMouse* getMouseWithData(); FMouse* getMouseWithEvent(); void xtermMouse (bool); void enableXTermMouse(); void disableXTermMouse(); // Data Member std::map mouse_protocol{}; std::map::iterator iter{}; FPoint zero_point{0, 0}; bool use_gpm_mouse{false}; bool use_xterm_mouse{false}; }; #pragma pack(pop) // FMouseControl inline functions //---------------------------------------------------------------------- inline const char* FMouseControl::getClassName() const { return "FMouseControl"; } //---------------------------------------------------------------------- inline void FMouseControl::enableXTermMouse() { xtermMouse(true); } //---------------------------------------------------------------------- inline void FMouseControl::disableXTermMouse() { xtermMouse(false); } } // namespace finalcut #endif // FMOUSE_H