From 231c30f740d6d5ab44cec0aa396e6aca9d105f74 Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Tue, 12 Jun 2018 16:37:48 +0200 Subject: [PATCH] Linux functions from FTerm moved into the FTermLinux class --- ChangeLog | 3 + include/final/fapplication.h | 12 - include/final/fterm.h | 145 +---- include/final/ftermfreebsd.h | 5 +- include/final/ftermios.h | 28 +- include/final/ftermlinux.h | 213 ++++++ include/final/ftermopenbsd.h | 12 - src/Makefile.am | 2 + src/Makefile.clang | 2 + src/Makefile.gcc | 2 + src/Makefile.in | 11 +- src/fapplication.cpp | 330 +--------- src/fcolorpalette.cpp | 47 +- src/fscrollbar.cpp | 18 +- src/fterm.cpp | 951 +++++---------------------- src/ftermdetection.cpp | 4 + src/ftermfreebsd.cpp | 6 +- src/ftermlinux.cpp | 1196 ++++++++++++++++++++++++++++++++++ src/ftermopenbsd.cpp | 1 + src/ftermxterminal.cpp | 8 +- 20 files changed, 1719 insertions(+), 1277 deletions(-) create mode 100644 include/final/ftermlinux.h create mode 100644 src/ftermlinux.cpp diff --git a/ChangeLog b/ChangeLog index d31149ed..3de66536 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2017-06-12 Markus Gans + * Linux functions from FTerm moved into the FTermLinux class + 2017-05-27 Markus Gans * Move FreeBSD, NetBSD and OpenBSD functions to separate classes diff --git a/include/final/fapplication.h b/include/final/fapplication.h index f813d185..cdeb8494 100644 --- a/include/final/fapplication.h +++ b/include/final/fapplication.h @@ -151,18 +151,6 @@ class FApplication : public FWidget bool sendKeyUpEvent (FWidget*); void sendKeyboardAccelerator(); void processKeyboardEvent(); - -#if defined(__linux__) - static int linuxShiftKeyCorrection (const int&); - static int linuxCtrlKeyCorrection (const int&); - static int linuxAltKeyCorrection (const int&); - static int linuxShiftCtrlKeyCorrection (const int&); - static int linuxShiftAltKeyCorrection (const int&); - static int linuxCtrlAltKeyCorrection (const int&); - static int linuxShiftCtrlAltKeyCorrection (const int&); - static int linuxModifierKeyCorrection (const int&); -#endif - bool processDialogSwitchAccelerator(); bool processAccelerator (const FWidget*&); bool getMouseEvent(); diff --git a/include/final/fterm.h b/include/final/fterm.h index db745ac7..5f8d4669 100644 --- a/include/final/fterm.h +++ b/include/final/fterm.h @@ -43,6 +43,18 @@ * :- - - -▕ FTermXTerminal ▏ * : ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏ * : + * : 1▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏ + * :- - - -▕ FTermLinux ▏ + * : ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏ + * : + * : 1▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏ + * :- - - -▕ FTermFreeBSD ▏ + * : ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏ + * : + * : 1▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏ + * :- - - -▕ FTermOpenBSD ▏ + * : ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏ + * : * : 1▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏ * :- - - -▕ FColorPalette ▏ * : ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏ @@ -77,16 +89,6 @@ #include "final/fconfig.h" -#if defined(__linux__) - #include // Linux framebuffer console - - #if defined(__x86_64__) || defined(__i386) || defined(__arm__) - #include // is deprecated - #endif - - #include -#endif - #include #include @@ -137,6 +139,10 @@ #include "final/ftermcapquirks.h" #include "final/ftermdetection.h" +#if defined(__linux__) + #include "final/ftermlinux.h" +#endif + #if defined(__FreeBSD__) || defined(__DragonFly__) #include "final/ftermfreebsd.h" #endif @@ -162,17 +168,6 @@ class FTerm // Typedefs typedef FOptiAttr::char_data char_data; -#if defined(__linux__) - static struct modifier_key // bit field - { - uChar shift : 1; // 0..1 - uChar alt_gr : 1; // 0..1 - uChar ctrl : 1; // 0..1 - uChar alt : 1; // 0..1 - uChar : 4; // padding bits - } mod_key; -#endif - // Constructor explicit FTerm (bool = false); @@ -182,24 +177,17 @@ class FTerm // Accessors virtual const char* getClassName() const; static termios getTTY(); + static int getTTYFileDescriptor(); static int getLineNumber(); static int getColumnNumber(); static const FString getKeyName (int); static FMouseControl* getMouseControl(); -#if defined(__linux__) - static modifier_key& getLinuxModifierKey(); -#endif - static char* getTermType(); static char* getTermFileName(); static int getTabstop(); static int getMaxColor(); -#if defined(__linux__) - static fc::linuxConsoleCursorStyle getLinuxConsoleCursorStyle(); -#endif - #if DEBUG static const FString& getAnswerbackString(); static const FString& getSecDAString(); @@ -249,12 +237,6 @@ class FTerm static void unsetInsertCursor(); static bool setCursorOptimisation (bool); static void redefineDefaultColors (bool); - -#if defined(__linux__) - static char* setLinuxConsoleCursorStyle \ - (fc::linuxConsoleCursorStyle, bool); -#endif - static void setKeypressTimeout (const long); static void setDblclickInterval (const long); static void disableAltScreen(); @@ -267,10 +249,13 @@ class FTerm // Methods static int parseKeyString (char[], int, timeval*); + static int keyCorrection (const int&); static bool& unprocessedInput(); static bool setVGAFont(); static bool setNewFont(); static bool setOldFont(); + static int openConsole(); + static int closeConsole(); static char* moveCursor (int, int, int, int); static char* cursorsVisibility (bool); static void printMoveDurations(); @@ -290,6 +275,9 @@ class FTerm static void setEncoding (fc::encoding); static fc::encoding getEncoding(); static std::string getEncodingString(); + static bool charEncodable (uInt); + static uInt charEncode (uInt); + static uInt charEncode (uInt, fc::encoding); static bool scrollTermForward(); static bool scrollTermReverse(); @@ -334,9 +322,6 @@ class FTerm // Methods static void initScreenSettings(); - static bool charEncodable (uInt); - static uInt charEncode (uInt); - static uInt charEncode (uInt, fc::encoding); static char* changeAttribute ( char_data*& , char_data*& ); static void changeTermSizeFinished(); @@ -372,13 +357,6 @@ class FTerm // Typedefs typedef FTermcap::tcap_map termcap_map; - typedef struct - { - uChar red; - uChar green; - uChar blue; - } dacreg; - // Constants static const int NEED_MORE_DATA = -1; // parseKeyString return value @@ -387,36 +365,7 @@ class FTerm // Disable assignment operator (=) FTerm& operator = (const FTerm&); -#if defined(__linux__) - static int isLinuxConsole(); -#endif - // Methods -#if defined(__linux__) -#if defined(__x86_64__) || defined(__i386) || defined(__arm__) - static uInt16 getInputStatusRegisterOne(); - static uChar readAttributeController (uChar); - static void writeAttributeController (uChar, uChar); - static uChar getAttributeMode(); - static void setAttributeMode (uChar); - static int setBlinkAsIntensity (bool); -#endif - static int getFramebuffer_bpp(); -#endif - - static int openConsole(); - static int closeConsole(); - -#if defined(__linux__) - static int getScreenFont(); - static int setScreenFont ( uChar[], uInt, uInt, uInt - , bool = false ); - static int setUnicodeMap (struct unimapdesc*); - static int getUnicodeMap (); - static void initLinuxConsole(); - static void initLinuxConsoleCharMap(); -#endif - static void init_global_values(); static void oscPrefix(); static void oscPostfix(); @@ -519,6 +468,11 @@ class FTerm static FTermDetection* term_detection; static FTermXTerminal* xterm; +#if defined(__linux__) + #undef linux + static FTermLinux* linux; +#endif + #if defined(__FreeBSD__) || defined(__DragonFly__) static FTermFreeBSD* freebsd; #endif @@ -530,45 +484,6 @@ class FTerm static FMouseControl* mouse; static const FString* save_xterm_font; static const FString* save_xterm_title; - - static struct colorEnv - { - void setDefault() - { - string1 = 0; - string2 = 0; - string3 = 0; - string4 = 0; - string5 = 0; - string6 = 0; - } - - char* string1; - char* string2; - char* string3; - char* string4; - char* string5; - char* string6; - } color_env; - - static struct secondaryDA - { - void setDefault() - { - terminal_id_type = -1; - terminal_id_version = -1; - terminal_id_hardware = -1; - } - - int terminal_id_type; - int terminal_id_version; - int terminal_id_hardware; - } secondary_da; - - struct - { - dacreg d[16]; - } color_map; }; #pragma pack(pop) @@ -578,6 +493,10 @@ class FTerm inline const char* FTerm::getClassName() const { return "FTerm"; } +//---------------------------------------------------------------------- +inline int FTerm::getTTYFileDescriptor() +{ return fd_tty; } + //---------------------------------------------------------------------- inline char* FTerm::getTermType() { return termtype; } diff --git a/include/final/ftermfreebsd.h b/include/final/ftermfreebsd.h index 75abbbdc..d3235e6c 100644 --- a/include/final/ftermfreebsd.h +++ b/include/final/ftermfreebsd.h @@ -65,8 +65,6 @@ class FTermFreeBSD // Destructor ~FTermFreeBSD(); - // Overloaded operators - // Accessors static CursorStyle getCursorStyle(); @@ -75,9 +73,10 @@ class FTermFreeBSD // Mutators static void setCursorStyle (CursorStyle, bool); + // Methods static void init(); - static void initCharMap(); + static void initCharMap (uInt[][fc::NUM_OF_ENCODINGS]); static void finish(); static void restoreCursorStyle(); diff --git a/include/final/ftermios.h b/include/final/ftermios.h index 5f0d4b1b..33246af7 100644 --- a/include/final/ftermios.h +++ b/include/final/ftermios.h @@ -64,22 +64,22 @@ class FTermios static int getStdOut(); // Inquiries - static bool isRaw(); + static bool isRaw(); // Methods - static void init(); - static void setTTY (const termios&); - static void storeTTYsettings(); - static void restoreTTYsettings(); - static void setHardwareEcho(); - static void unsetHardwareEcho(); - static void setCaptureSendCharacters(); - static void unsetCaptureSendCharacters(); - static bool setRawMode (bool); - static bool setRawMode(); - static bool unsetRawMode(); - static bool setCookedMode(); - static uInt getBaudRate(); + static void init(); + static void setTTY (const termios&); + static void storeTTYsettings(); + static void restoreTTYsettings(); + static void setHardwareEcho(); + static void unsetHardwareEcho(); + static void setCaptureSendCharacters(); + static void unsetCaptureSendCharacters(); + static bool setRawMode (bool); + static bool setRawMode(); + static bool unsetRawMode(); + static bool setCookedMode(); + static uInt getBaudRate(); private: // Data Members diff --git a/include/final/ftermlinux.h b/include/final/ftermlinux.h new file mode 100644 index 00000000..0bde0971 --- /dev/null +++ b/include/final/ftermlinux.h @@ -0,0 +1,213 @@ +/*********************************************************************** +* ftermlinux.h - Contains the Linux terminal functions * +* * +* This file is part of the Final Cut widget toolkit * +* * +* Copyright 2018 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 * +* . * +***********************************************************************/ + +/* Standalone class + * ════════════════ + * + * ▕▔▔▔▔▔▔▔▔▔▔▔▔▏ + * ▕ FTermLinux ▏ + * ▕▁▁▁▁▁▁▁▁▁▁▁▁▏ + */ + +#ifndef FTERMLINUX_H +#define FTERMLINUX_H + +#if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT) + #error "Only can be included directly." +#endif + +#if defined(__linux__) + #include // Linux framebuffer console + + #if defined(__x86_64__) || defined(__i386) || defined(__arm__) + #include // is deprecated + #endif + + #include +#endif + +#include +#include + +#include // need for sprintf +#include + +#include "final/fc.h" +#include "final/fcharmap.h" +#include "final/ftermdetection.h" +#include "final/ftypes.h" + + +//---------------------------------------------------------------------- +// class FTermLinux +//---------------------------------------------------------------------- + +#pragma pack(push) +#pragma pack(1) + +class FTermLinux +{ + public: + // Constructors + FTermLinux(); + + // Destructor + ~FTermLinux(); + + // Accessors + static fc::linuxConsoleCursorStyle getCursorStyle(); + static int getFramebufferBpp(); + + // Mutators + static void setFTermDetection (FTermDetection*); + static char* setCursorStyle (fc::linuxConsoleCursorStyle, bool); + static bool setPalette (short, int, int, int); + static void setUTF8 (bool); + + // Inquiries + static bool isLinuxConsole(); + static bool hasShadowCharacter(); + static bool hasHalfBlockCharacter(); + static bool isVGAFontUsed(); + static bool isNewFontUsed(); + + // Methods + static void init(); + static void initCharMap (uInt[][fc::NUM_OF_ENCODINGS]); + static void finish(); + static bool loadVGAFont(); + static bool loadNewFont(); + static bool loadOldFont (uInt[][fc::NUM_OF_ENCODINGS]); + static bool saveColorMap(); + static bool resetColorMap(); + static void setBeep (int, int); + static void resetBeep(); + static char* restoreCursorStyle(); + static int modifierKeyCorrection (const int&); + + private: + // Typedef + static struct modifier_key // bit field + { + uChar shift : 1; // 0..1 + uChar alt_gr : 1; // 0..1 + uChar ctrl : 1; // 0..1 + uChar alt : 1; // 0..1 + uChar : 4; // padding bits + } mod_key; + + typedef struct + { + uChar red; + uChar green; + uChar blue; + } rgb; + + typedef struct + { + rgb color[16]; + } ColorMap; + + // Disable copy constructor + FTermLinux (const FTermLinux&); + + // Disable assignment operator (=) + FTermLinux& operator = (const FTermLinux&); + + // Accessors + static int getFramebuffer_bpp(); + static bool getScreenFont(); + static bool getUnicodeMap (); + static modifier_key& getModifierKey(); + + // Mutators + static int setScreenFont ( uChar[], uInt, uInt, uInt + , bool = false ); + static int setUnicodeMap (struct unimapdesc*); + + // Methods +#if defined(__x86_64__) || defined(__i386) || defined(__arm__) + static uInt16 getInputStatusRegisterOne(); + static uChar readAttributeController (uChar); + static void writeAttributeController (uChar, uChar); + static uChar getAttributeMode(); + static void setAttributeMode (uChar); + static int setBlinkAsIntensity (bool); + static bool setVGAPalette (short, int, int, int); + static bool saveVGAPalette(); + static bool resetVGAPalette(); +#endif + static int shiftKeyCorrection (const int&); + static int ctrlKeyCorrection (const int&); + static int altKeyCorrection (const int&); + static int shiftCtrlKeyCorrection (const int&); + static int shiftAltKeyCorrection (const int&); + static int ctrlAltKeyCorrection (const int&); + static int shiftCtrlAltKeyCorrection (const int&); + + // Data Members +#if defined(__linux__) + static bool VGAFont; + static bool NewFont; + static bool shadow_character; + static bool half_block_character; + static bool has_saved_palette; + static FTermDetection* term_detection; + static fc::linuxConsoleCursorStyle + linux_console_cursor_style; + static console_font_op screen_font; + static unimapdesc screen_unicode_map; + static ColorMap saved_color_map; + static ColorMap cmap; +#if DEBUG + static int framebuffer_bpp; +#endif +#endif // defined(__linux__) +}; +#pragma pack(pop) + +// FTermLinux inline functions +//---------------------------------------------------------------------- +inline int FTermLinux::getFramebufferBpp() +{ return framebuffer_bpp; } + +//---------------------------------------------------------------------- +inline void FTermLinux::setFTermDetection (FTermDetection* td) +{ term_detection = td; } + +//---------------------------------------------------------------------- +inline bool FTermLinux::hasShadowCharacter() +{ return shadow_character; } + +//---------------------------------------------------------------------- +inline bool FTermLinux::hasHalfBlockCharacter() +{ return half_block_character; } + +//---------------------------------------------------------------------- +inline bool FTermLinux::isVGAFontUsed() +{ return VGAFont; } + +//---------------------------------------------------------------------- +inline bool FTermLinux::isNewFontUsed() +{ return NewFont; } + +#endif // FTERMLINUX_H diff --git a/include/final/ftermopenbsd.h b/include/final/ftermopenbsd.h index 12d95826..03f43afc 100644 --- a/include/final/ftermopenbsd.h +++ b/include/final/ftermopenbsd.h @@ -58,12 +58,6 @@ class FTermOpenBSD // Destructor ~FTermOpenBSD(); - // Overloaded operators - - // Accessors - - // Mutators - // Inquiries static bool isWSConsConsole(); @@ -91,10 +85,4 @@ class FTermOpenBSD }; #pragma pack(pop) -// FTermOpenBSD inline functions -//---------------------------------------------------------------------- - - #endif // FTERMOPENBSD_H - - diff --git a/src/Makefile.am b/src/Makefile.am index 01740c44..7a5c3960 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -44,6 +44,7 @@ libfinal_la_SOURCES = \ ftermxterminal.cpp \ ftermfreebsd.cpp \ ftermopenbsd.cpp \ + ftermlinux.cpp \ ftermdetection.cpp \ ftermios.cpp \ fterm.cpp \ @@ -110,6 +111,7 @@ finalcutinclude_HEADERS = \ ../include/final/ftermxterminal.h \ ../include/final/ftermfreebsd.h \ ../include/final/ftermopenbsd.h \ + ../include/final/ftermlinux.h \ ../include/final/ftermdetection.h \ ../include/final/ftermios.h \ ../include/final/fterm.h \ diff --git a/src/Makefile.clang b/src/Makefile.clang index a1ec792c..bb1548f2 100644 --- a/src/Makefile.clang +++ b/src/Makefile.clang @@ -50,6 +50,7 @@ INCLUDE_HEADERS = \ ftermxterminal.h \ ftermfreebsd.h \ ftermopenbsd.h \ + ftermlinux.h \ fvterm.h \ ftextview.h \ ftogglebutton.h \ @@ -107,6 +108,7 @@ OBJS = \ ftermxterminal.o \ ftermfreebsd.o \ ftermopenbsd.o \ + ftermlinux.o \ fvterm.o \ fevent.o \ foptiattr.o \ diff --git a/src/Makefile.gcc b/src/Makefile.gcc index 7e305db1..a425ae32 100644 --- a/src/Makefile.gcc +++ b/src/Makefile.gcc @@ -50,6 +50,7 @@ INCLUDE_HEADERS = \ ftermxterminal.h \ ftermfreebsd.h \ ftermopenbsd.h \ + ftermlinux.h \ fvterm.h \ ftextview.h \ ftogglebutton.h \ @@ -107,6 +108,7 @@ OBJS = \ ftermxterminal.o \ ftermfreebsd.o \ ftermopenbsd.o \ + ftermlinux.o \ fvterm.o \ fevent.o \ foptiattr.o \ diff --git a/src/Makefile.in b/src/Makefile.in index 2f7f6d76..8512b101 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -137,10 +137,10 @@ am_libfinal_la_OBJECTS = fstring.lo fpoint.lo frect.lo fscrollbar.lo \ fcheckmenuitem.lo fmenulist.lo fdialog.lo fscrollview.lo \ fwindow.lo fmessagebox.lo ftooltip.lo ffiledialog.lo \ ftextview.lo fstatusbar.lo ftermcapquirks.lo ftermxterminal.lo \ - ftermfreebsd.lo ftermopenbsd.lo ftermdetection.lo ftermios.lo \ - fterm.lo fvterm.lo fevent.lo foptiattr.lo foptimove.lo \ - ftermbuffer.lo fapplication.lo fcolorpalette.lo \ - fwidgetcolors.lo fwidget.lo fobject.lo + ftermfreebsd.lo ftermopenbsd.lo ftermlinux.lo \ + ftermdetection.lo ftermios.lo fterm.lo fvterm.lo fevent.lo \ + foptiattr.lo foptimove.lo ftermbuffer.lo fapplication.lo \ + fcolorpalette.lo fwidgetcolors.lo fwidget.lo fobject.lo libfinal_la_OBJECTS = $(am_libfinal_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -418,6 +418,7 @@ libfinal_la_SOURCES = \ ftermxterminal.cpp \ ftermfreebsd.cpp \ ftermopenbsd.cpp \ + ftermlinux.cpp \ ftermdetection.cpp \ ftermios.cpp \ fterm.cpp \ @@ -482,6 +483,7 @@ finalcutinclude_HEADERS = \ ../include/final/ftermxterminal.h \ ../include/final/ftermfreebsd.h \ ../include/final/ftermopenbsd.h \ + ../include/final/ftermlinux.h \ ../include/final/ftermdetection.h \ ../include/final/ftermios.h \ ../include/final/fterm.h \ @@ -611,6 +613,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftermdetection.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftermfreebsd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftermios.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftermlinux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftermopenbsd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftermxterminal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftextview.Plo@am__quote@ diff --git a/src/fapplication.cpp b/src/fapplication.cpp index 7e4825e1..8f35da9b 100644 --- a/src/fapplication.cpp +++ b/src/fapplication.cpp @@ -562,6 +562,7 @@ inline void FApplication::parseKeyPuffer (FWidget* widget) && key != NEED_MORE_DATA ) { key = FTerm::parseKeyString(fifo_buf, fifo_buf_size, &time_keypressed); + key = keyCorrection(key); if ( key != NEED_MORE_DATA ) performKeyboardAction (widget); @@ -580,10 +581,6 @@ inline void FApplication::parseKeyPuffer (FWidget* widget) //---------------------------------------------------------------------- inline void FApplication::performKeyboardAction (FWidget* widget) { -#if defined(__linux__) - key = linuxModifierKeyCorrection (key); -#endif - switch ( key ) { case fc::Fckey_l: // Ctrl-L (redraw the screen) @@ -716,331 +713,6 @@ void FApplication::processKeyboardEvent() sendEscapeKeyPressEvent (widget); } -#if defined(__linux__) -//---------------------------------------------------------------------- -int FApplication::linuxShiftKeyCorrection (const int& key_id) -{ - switch ( key_id ) - { - case fc::Fkey_up: - return fc::Fkey_sr; // Shift+Up - - case fc::Fkey_down: - return fc::Fkey_sf; // Shift+Down - - case fc::Fkey_left: - return fc::Fkey_sleft; // Shift+Left - - case fc::Fkey_right: - return fc::Fkey_sright; // Shift+Right - - case fc::Fkey_ic: - return fc::Fkey_sic; // Shift+Ins - - case fc::Fkey_dc: - return fc::Fkey_sdc; // Shift+Del - - case fc::Fkey_home: - return fc::Fkey_shome; // Shift+Home - - case fc::Fkey_end: - return fc::Fkey_send; // Shift+End - - case fc::Fkey_ppage: - return fc::Fkey_sprevious; // Shift+PgUp - - case fc::Fkey_npage: - return fc::Fkey_snext; // Shift+PgDn - - default: - return key_id; - } -} - -//---------------------------------------------------------------------- -int FApplication::linuxCtrlKeyCorrection (const int& key_id) -{ - switch ( key_id ) - { - case fc::Fkey_up: - return fc::Fckey_up; // Ctrl+Up - - case fc::Fkey_down: - return fc::Fckey_down; // Ctrl+Down - - case fc::Fkey_left: - return fc::Fckey_left; // Ctrl+Left - - case fc::Fkey_right: - return fc::Fckey_right; // Ctrl+Right - - case fc::Fkey_ic: - return fc::Fckey_ic; // Ctrl+Ins - - case fc::Fkey_dc: - return fc::Fckey_dc; // Ctrl+Del - - case fc::Fkey_home: - return fc::Fckey_home; // Ctrl+Home - - case fc::Fkey_end: - return fc::Fckey_end; // Ctrl+End - - case fc::Fkey_ppage: - return fc::Fckey_ppage; // Ctrl+PgUp - - case fc::Fkey_npage: - return fc::Fckey_npage; // Ctrl+PgDn - - default: - return key_id; - } -} - -//---------------------------------------------------------------------- -int FApplication::linuxAltKeyCorrection (const int& key_id) -{ - switch ( key_id ) - { - case fc::Fkey_up: - return fc::Fmkey_up; // Meta+Up - - case fc::Fkey_down: - return fc::Fmkey_down; // Meta+Down - - case fc::Fkey_left: - return fc::Fmkey_left; // Meta+Left - - case fc::Fkey_right: - return fc::Fmkey_right; // Meta+Right - - case fc::Fkey_ic: - return fc::Fmkey_ic; // Meta+Ins - - case fc::Fkey_dc: - return fc::Fmkey_dc; // Meta+Del - - case fc::Fkey_home: - return fc::Fmkey_home; // Meta+Home - - case fc::Fkey_end: - return fc::Fmkey_end; // Meta+End - - case fc::Fkey_ppage: - return fc::Fmkey_ppage; // Meta+PgUp - - case fc::Fkey_npage: - return fc::Fmkey_npage; // Meta+PgDn - - default: - return key_id; - } -} - -//---------------------------------------------------------------------- -int FApplication::linuxShiftCtrlKeyCorrection (const int& key_id) -{ - switch ( key_id ) - { - case fc::Fkey_up: - return fc::Fckey_sup; // Shift+Ctrl+Up - - case fc::Fkey_down: - return fc::Fckey_sdown; // Shift+Ctrl+Down - - case fc::Fkey_left: - return fc::Fckey_sleft; // Shift+Ctrl+Left - - case fc::Fkey_right: - return fc::Fckey_sright; // Shift+Ctrl+Right - - case fc::Fkey_ic: - return fc::Fckey_sic; // Shift+Ctrl+Ins - - case fc::Fkey_dc: - return fc::Fckey_sdc; // Shift+Ctrl+Del - - case fc::Fkey_home: - return fc::Fckey_shome; // Shift+Ctrl+Home - - case fc::Fkey_end: - return fc::Fckey_send; // Shift+Ctrl+End - - case fc::Fkey_ppage: - return fc::Fckey_sppage; // Shift+Ctrl+PgUp - - case fc::Fkey_npage: - return fc::Fckey_snpage; // Shift+Ctrl+PgDn - - default: - return key_id; - } -} - -//---------------------------------------------------------------------- -int FApplication::linuxShiftAltKeyCorrection (const int& key_id) -{ - switch ( key_id ) - { - case fc::Fkey_up: - return fc::Fmkey_sup; // Shift+Meta+Up - - case fc::Fkey_down: - return fc::Fmkey_sdown; // Shift+Meta+Down - - case fc::Fkey_left: - return fc::Fmkey_sright; // Shift+Meta+Left - - case fc::Fkey_right: - return fc::Fmkey_sleft; // Shift+Meta+Right - - case fc::Fkey_ic: - return fc::Fmkey_sic; // Shift+Meta+Ins - - case fc::Fkey_dc: - return fc::Fmkey_sdc; // Shift+Meta+Del - - case fc::Fkey_home: - return fc::Fmkey_shome; // Shift+Meta+Home - - case fc::Fkey_end: - return fc::Fmkey_send; // Shift+Meta+End - - case fc::Fkey_ppage: - return fc::Fmkey_sppage; // Shift+Meta+PgUp - - case fc::Fkey_npage: - return fc::Fmkey_snpage; // Shift+Meta+PgDn - - default: - return key_id; - } -} - -//---------------------------------------------------------------------- -int FApplication::linuxCtrlAltKeyCorrection (const int& key_id) -{ - switch ( key_id ) - { - case fc::Fkey_up: - return fc::Fcmkey_up; // Ctrl+Meta+Up - - case fc::Fkey_down: - return fc::Fcmkey_down; // Ctrl+Meta+Down - - case fc::Fkey_left: - return fc::Fcmkey_left; // Ctrl+Meta+Left - - case fc::Fkey_right: - return fc::Fcmkey_right; // Ctrl+Meta+Right - - case fc::Fkey_ic: - return fc::Fcmkey_ic; // Ctrl+Meta+Ins - - case fc::Fkey_dc: - return fc::Fcmkey_dc; // Ctrl+Meta+Del - - case fc::Fkey_home: - return fc::Fcmkey_home; // Ctrl+Meta+Home - - case fc::Fkey_end: - return fc::Fcmkey_end; // Ctrl+Meta+End - - case fc::Fkey_ppage: - return fc::Fcmkey_ppage; // Ctrl+Meta+PgUp - - case fc::Fkey_npage: - return fc::Fcmkey_npage; // Ctrl+Meta+PgDn - - default: - return key_id; - } -} - -//---------------------------------------------------------------------- -int FApplication::linuxShiftCtrlAltKeyCorrection (const int& key_id) -{ - switch ( key_id ) - { - case fc::Fkey_up: - return fc::Fcmkey_sup; // Shift+Ctrl+Meta+Up - - case fc::Fkey_down: - return fc::Fcmkey_sdown; // Shift+Ctrl+Meta+Down - - case fc::Fkey_left: - return fc::Fcmkey_sleft; // Shift+Ctrl+Meta+Left - - case fc::Fkey_right: - return fc::Fcmkey_sright; // Shift+Ctrl+Meta+Right - - case fc::Fkey_ic: - return fc::Fcmkey_sic; // Shift+Ctrl+Meta+Ins - - case fc::Fkey_dc: - return fc::Fcmkey_sdc; // Shift+Ctrl+Meta+Del - - case fc::Fkey_home: - return fc::Fcmkey_shome; // Shift+Ctrl+Meta+Home - - case fc::Fkey_end: - return fc::Fcmkey_send; // Shift+Ctrl+Meta+End - - case fc::Fkey_ppage: - return fc::Fcmkey_sppage; // Shift+Ctrl+Meta+PgUp - - case fc::Fkey_npage: - return fc::Fcmkey_snpage; // Shift+Ctrl+Meta+PgDn - - default: - return key_id; - } -} - -//---------------------------------------------------------------------- -int FApplication::linuxModifierKeyCorrection (const int& key_id) -{ - // Get the current modifier key state - - FTerm::modifier_key& m = getLinuxModifierKey(); - - if ( ! (m.shift || m.ctrl || m.alt) ) - { - return key_id; - } - else if ( m.shift && ! m.ctrl && ! m.alt ) - { - return linuxShiftKeyCorrection(key_id); - } - else if ( ! m.shift && m.ctrl && ! m.alt ) - { - return linuxCtrlKeyCorrection(key_id); - } - else if ( ! m.shift && ! m.ctrl && m.alt ) - { - return linuxAltKeyCorrection(key_id); - } - else if ( m.shift && m.ctrl && ! m.alt ) - { - return linuxShiftCtrlKeyCorrection(key_id); - } - else if ( m.shift && ! m.ctrl && m.alt ) - { - return linuxShiftAltKeyCorrection(key_id); - } - else if ( ! m.shift && m.ctrl && m.alt ) - { - return linuxCtrlAltKeyCorrection(key_id); - } - else if ( m.shift && m.ctrl && m.alt ) - { - return linuxShiftCtrlAltKeyCorrection(key_id); - } - - return key_id; -} -#endif - //---------------------------------------------------------------------- bool FApplication::processDialogSwitchAccelerator() { diff --git a/src/fcolorpalette.cpp b/src/fcolorpalette.cpp index d13f86bb..9e564f44 100644 --- a/src/fcolorpalette.cpp +++ b/src/fcolorpalette.cpp @@ -39,6 +39,15 @@ void FColorPalette::set8ColorPalette (funcp setPalette) setPalette (fc::Magenta, 0xb2, 0x18, 0xb2); setPalette (fc::Brown, 0xe8, 0x87, 0x1f); setPalette (fc::LightGray, 0xe0, 0xe0, 0xe0); + // The same colors again... + setPalette (fc::DarkGray, 0x00, 0x00, 0x00); + setPalette (fc::LightBlue, 0x22, 0x22, 0xb2); + setPalette (fc::LightGreen, 0x18, 0x78, 0x18); + setPalette (fc::LightCyan, 0x66, 0x66, 0xff); + setPalette (fc::LightRed, 0xb2, 0x18, 0x18); + setPalette (fc::LightMagenta, 0xb2, 0x18, 0xb2); + setPalette (fc::Yellow, 0xe8, 0x87, 0x1f); + setPalette (fc::White, 0xe0, 0xe0, 0xe0); } //---------------------------------------------------------------------- @@ -65,15 +74,41 @@ void FColorPalette::set16ColorPalette (funcp setPalette) //---------------------------------------------------------------------- void FColorPalette::reset8ColorPalette (funcp setPalette) { - setPalette (fc::Cyan, 0x18, 0xb2, 0xb2); + setPalette (fc::Black, 0x00, 0x00, 0x00); + setPalette (fc::Blue, 0x00, 0x00, 0xaa); + setPalette (fc::Green, 0x00, 0xaa, 0x00); + setPalette (fc::Cyan, 0x00, 0x55, 0xaa); + setPalette (fc::Red, 0xaa, 0x00, 0x00); + setPalette (fc::Magenta, 0xaa, 0x00, 0xaa); + setPalette (fc::Brown, 0xaa, 0xaa, 0x00); + setPalette (fc::LightGray, 0xaa, 0xaa, 0xaa); + setPalette (fc::DarkGray, 0x55, 0x55, 0x55); + setPalette (fc::LightBlue, 0x55, 0x55, 0xff); + setPalette (fc::LightGreen, 0x55, 0xff, 0x55); + setPalette (fc::LightCyan, 0x55, 0xff, 0xff); + setPalette (fc::LightRed, 0xff, 0x55, 0x55); + setPalette (fc::LightMagenta, 0xff, 0x55, 0xff); + setPalette (fc::Yellow, 0xff, 0xff, 0x55); + setPalette (fc::White, 0xff, 0xff, 0xff); } //---------------------------------------------------------------------- void FColorPalette::reset16ColorPalette (funcp setPalette) { - setPalette (fc::Cyan, 0x18, 0xb2, 0xb2); - setPalette (fc::LightGray, 0xb2, 0xb2, 0xb2); - setPalette (fc::DarkGray, 0x68, 0x68, 0x68); - setPalette (fc::LightBlue, 0x54, 0x54, 0xff); - setPalette (fc::LightGreen, 0x54, 0xff, 0x54); + setPalette (fc::Black, 0x00, 0x00, 0x00); + setPalette (fc::Blue, 0x00, 0x00, 0xaa); + setPalette (fc::Green, 0x00, 0xaa, 0x00); + setPalette (fc::Cyan, 0x00, 0x55, 0xaa); + setPalette (fc::Red, 0xaa, 0x00, 0x00); + setPalette (fc::Magenta, 0xaa, 0x00, 0xaa); + setPalette (fc::Brown, 0xaa, 0xaa, 0x00); + setPalette (fc::LightGray, 0xaa, 0xaa, 0xaa); + setPalette (fc::DarkGray, 0x55, 0x55, 0x55); + setPalette (fc::LightBlue, 0x55, 0x55, 0xff); + setPalette (fc::LightGreen, 0x55, 0xff, 0x55); + setPalette (fc::LightCyan, 0x55, 0xff, 0xff); + setPalette (fc::LightRed, 0xff, 0x55, 0x55); + setPalette (fc::LightMagenta, 0xff, 0x55, 0xff); + setPalette (fc::Yellow, 0xff, 0xff, 0x55); + setPalette (fc::White, 0xff, 0xff, 0xff); } diff --git a/src/fscrollbar.cpp b/src/fscrollbar.cpp index 3e7aac76..bf8b0955 100644 --- a/src/fscrollbar.cpp +++ b/src/fscrollbar.cpp @@ -260,7 +260,12 @@ void FScrollbar::drawVerticalBar() setPrintPos (1, 1 + z); if ( isNewFont() ) - print (fc::NF_border_line_left); // ⎸ + { + if ( isMonochron() || max_color < 16 ) + print (fc::MediumShade); // ▒ + else + print (fc::NF_border_line_left); // ⎸ + } if ( isMonochron() || max_color < 16 ) print (fc::MediumShade); // ▒ @@ -293,7 +298,12 @@ void FScrollbar::drawVerticalBar() setPrintPos (1, 1 + z); if ( isNewFont() ) - print (fc::NF_border_line_left); // ⎸ + { + if ( isMonochron() || max_color < 16 ) + print (fc::MediumShade); // ▒ + else + print (fc::NF_border_line_left); // ⎸ + } if ( isMonochron() || max_color < 16 ) print (fc::MediumShade); @@ -318,7 +328,7 @@ void FScrollbar::drawHorizontalBar() for (z = 0; z < slider_pos; z++) { - if ( isNewFont() ) + if ( isNewFont() && max_color > 8 ) print (fc::NF_border_line_upper); // ¯ else if ( isMonochron() || max_color < 16 ) print (fc::MediumShade); // ▒ @@ -342,7 +352,7 @@ void FScrollbar::drawHorizontalBar() for (; z <= bar_length; z++) { - if ( isNewFont() ) + if ( isNewFont() && max_color > 8 ) print (fc::NF_border_line_upper); // ¯ else if ( isMonochron() || max_color < 16 ) print (fc::MediumShade); // ▒ diff --git a/src/fterm.cpp b/src/fterm.cpp index 41eb20d0..2bc8ba0b 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -30,12 +30,6 @@ #include "final/fkey_map.h" #include "final/ftcap_map.h" -#if defined(__linux__) - #include "../fonts/newfont.h" - #include "../fonts/unicodemap.h" - #include "../fonts/vgafont.h" -#endif - // global FTerm object static FTerm* init_term_object = 0; @@ -106,23 +100,19 @@ bool FTermcap::no_utf8_acs_chars = false; int FTermcap::max_color = 1; int FTermcap::tabstop = 8; int FTermcap::attr_without_color = 0; -FTerm::colorEnv FTerm::color_env; -FTerm::secondaryDA FTerm::secondary_da; FTerm::initializationValues FTerm::init_values; fc::linuxConsoleCursorStyle FTerm::linux_console_cursor_style; #if defined(__linux__) - FTerm::modifier_key FTerm::mod_key; - console_font_op FTerm::screen_font; - unimapdesc FTerm::screen_unicode_map; + FTermLinux* FTerm::linux = 0; #endif #if defined(__FreeBSD__) || defined(__DragonFly__) - FTermFreeBSD* FTerm::freebsd = 0; + FTermFreeBSD* FTerm::freebsd = 0; #endif #if defined(__NetBSD__) || defined(__OpenBSD__) - FTermOpenBSD* FTerm::openbsd = 0; + FTermOpenBSD* FTerm::openbsd = 0; #endif @@ -133,7 +123,6 @@ fc::linuxConsoleCursorStyle FTerm::linux_console_cursor_style; // constructors and destructor //---------------------------------------------------------------------- FTerm::FTerm (bool disable_alt_screen) - : color_map() { resize_term = false; @@ -193,43 +182,6 @@ FMouseControl* FTerm::getMouseControl() return 0; } -#if defined(__linux__) -//---------------------------------------------------------------------- -FTerm::modifier_key& FTerm::getLinuxModifierKey() -{ - // Get Linux console shift state - - char subcode = 6; // Shift state command + return value - - // fill bit field with 0 - std::memset (&mod_key, 0x00, sizeof(mod_key)); - - // TIOCLINUX, subcode = 6 - if ( ioctl(0, TIOCLINUX, &subcode) >= 0 ) - { - if ( subcode & (1 << KG_SHIFT) ) - mod_key.shift = true; - - if ( subcode & (1 << KG_ALTGR) ) - mod_key.alt_gr = true; - - if ( subcode & (1 << KG_CTRL) ) - mod_key.ctrl = true; - - if ( subcode & (1 << KG_ALT) ) - mod_key.alt = true; - } - - return mod_key; -} - -//---------------------------------------------------------------------- -fc::linuxConsoleCursorStyle FTerm::getLinuxConsoleCursorStyle() -{ - return linux_console_cursor_style; -} -#endif - //---------------------------------------------------------------------- bool FTerm::isNormal (char_data*& ch) { @@ -262,28 +214,6 @@ void FTerm::redefineDefaultColors (bool on) xterm->redefineDefaultColors (on); } -#if defined(__linux__) -//---------------------------------------------------------------------- -char* FTerm::setLinuxConsoleCursorStyle ( fc::linuxConsoleCursorStyle style - , bool hidden ) -{ - // Set cursor style in linux console - - static char buf[16] = { }; - - if ( ! isLinuxTerm() ) - return buf; - - linux_console_cursor_style = style; - - if ( hidden ) - return buf; - - std::sprintf (buf, CSI "?%dc", style); - return buf; -} -#endif - //---------------------------------------------------------------------- void FTerm::setDblclickInterval (const long timeout) { @@ -301,15 +231,10 @@ bool FTerm::setUTF8 (bool on) // UTF-8 (Unicode) else utf8_state = false; - if ( isLinuxTerm() ) - { - if ( on ) - putstring (ESC "%G"); - else - putstring (ESC "%@"); - } +#if defined(__linux__) + linux->setUTF8 (on); +#endif - std::fflush(stdout); return utf8_state; } @@ -342,11 +267,12 @@ int FTerm::parseKeyString ( char buffer[] , int buf_size , timeval* time_keypressed ) { + int key; uChar firstchar = uChar(buffer[0]); if ( firstchar == ESC[0] ) { - int key = getMouseProtocolKey(buffer); + key = getMouseProtocolKey(buffer); if ( key > 0 ) return key; @@ -368,6 +294,18 @@ int FTerm::parseKeyString ( char buffer[] return getSingleKey(buffer, buf_size); } +//---------------------------------------------------------------------- +int FTerm::keyCorrection (const int& key) +{ + int key_correction; + +#if defined(__linux__) + key_correction = linux->modifierKeyCorrection(key); +#endif + + return key_correction; +} + //---------------------------------------------------------------------- bool& FTerm::unprocessedInput() { @@ -388,10 +326,11 @@ bool FTerm::setVGAFont() || isMinttyTerm() ) return false; - VGAFont = true; - if ( isXTerminal() || isScreenTerm() || FTermcap::osc_support ) + if ( isXTerminal() || isScreenTerm() + || isUrxvtTerminal() || FTermcap::osc_support ) { + VGAFont = true; // Set font in xterm to vga xterm->setFont("vga"); NewFont = false; @@ -406,32 +345,7 @@ bool FTerm::setVGAFont() #if defined(__linux__) else if ( isLinuxTerm() ) { - if ( openConsole() == 0 ) - { - if ( isLinuxConsole() ) - { - // standard vga font 8x16 - int ret = setScreenFont(fc::__8x16std, 256, 8, 16); - - if ( ret != 0 ) - VGAFont = false; - - // unicode character mapping - struct unimapdesc unimap; - unimap.entry_ct = uChar ( sizeof(fc::unicode_cp437_pairs) - / sizeof(unipair) ); - unimap.entries = &fc::unicode_cp437_pairs[0]; - setUnicodeMap(&unimap); - } - else - VGAFont = false; - - detectTermSize(); - closeConsole(); - } - else - VGAFont = false; - + VGAFont = linux->loadVGAFont(); pc_charset_console = true; term_encoding = fc::PC; Fputchar = &FTerm::putchar_ASCII; @@ -440,6 +354,9 @@ bool FTerm::setVGAFont() else VGAFont = false; + if ( VGAFont ) + shadow_character = half_block_character = true; + return VGAFont; } @@ -474,32 +391,7 @@ bool FTerm::setNewFont() #if defined(__linux__) else if ( isLinuxTerm() ) { - NewFont = true; - - if ( openConsole() == 0 ) - { - if ( isLinuxConsole() ) - { - struct unimapdesc unimap; - int ret; - - // Set the graphical font 8x16 - ret = setScreenFont(fc::__8x16graph, 256, 8, 16); - - if ( ret != 0 ) - NewFont = false; - - // unicode character mapping - unimap.entry_ct = uInt16 ( sizeof(fc::unicode_cp437_pairs) - / sizeof(unipair) ); - unimap.entries = &fc::unicode_cp437_pairs[0]; - setUnicodeMap(&unimap); - } - - detectTermSize(); - closeConsole(); - } - + NewFont = linux->loadNewFont(); pc_charset_console = true; term_encoding = fc::PC; Fputchar = &FTerm::putchar_ASCII; // function pointer @@ -508,13 +400,16 @@ bool FTerm::setNewFont() else NewFont = false; + if ( NewFont ) + shadow_character = half_block_character = true; + return NewFont; } //---------------------------------------------------------------------- bool FTerm::setOldFont() { - bool retval; + bool retval = false; if ( ! (NewFont || VGAFont) ) return false; @@ -542,39 +437,62 @@ bool FTerm::setOldFont() #if defined(__linux__) else if ( isLinuxTerm() ) { - if ( openConsole() == 0 ) - { - if ( isLinuxConsole() ) - { - if ( screen_font.data ) - { - int ret = setScreenFont ( screen_font.data - , screen_font.charcount - , screen_font.width - , screen_font.height - , true ); - delete[] screen_font.data; - - if ( ret == 0 ) - retval = true; - } - - if ( screen_unicode_map.entries ) - { - setUnicodeMap (&screen_unicode_map); - delete[] screen_unicode_map.entries; - } - } - - detectTermSize(); - closeConsole(); - } + retval = linux->loadOldFont(fc::character); } #endif + if ( retval ) + { + VGAFont = NewFont = false; + shadow_character = linux->hasShadowCharacter(); + half_block_character = linux->hasHalfBlockCharacter(); + } + return retval; } +//---------------------------------------------------------------------- +int FTerm::openConsole() +{ + static const char* terminal_devices[] = + { + "/proc/self/fd/0", + "/dev/tty", + "/dev/tty0", + "/dev/vc/0", + "/dev/systty", + "/dev/console", + 0 + }; + + if ( fd_tty >= 0 ) // console is already opened + return 0; + + if ( ! *termfilename ) + return 0; + + for (int i = 0; terminal_devices[i] != 0; i++) + if ( (fd_tty = open(terminal_devices[i], O_RDWR, 0)) >= 0 ) + return 0; + + return -1; // No file descriptor referring to the console +} + +//---------------------------------------------------------------------- +int FTerm::closeConsole() +{ + if ( fd_tty < 0 ) // console is already closed + return 0; + + int ret = ::close (fd_tty); // use 'close' from the global namespace + fd_tty = -1; + + if ( ret == 0 ) + return 0; + else + return -1; +} + //---------------------------------------------------------------------- char* FTerm::moveCursor (int xold, int yold, int xnew, int ynew) { @@ -639,15 +557,18 @@ char* FTerm::enableCursor() if ( isLinuxTerm() ) { // Restore the last used Linux console cursor style - char* lcur; - lcur = setLinuxConsoleCursorStyle (getLinuxConsoleCursorStyle(), false); - std::strncat (enable_str, lcur, SIZE - std::strlen(enable_str) - 1); + char* cstyle; + cstyle = linux->restoreCursorStyle(); + std::strncat (enable_str, cstyle, SIZE - std::strlen(enable_str) - 1); } #endif #if defined(__FreeBSD__) || defined(__DragonFly__) - // Restore the last used FreeBSD console cursor style - freebsd->restoreCursorStyle(); + if ( isFreeBSDTerm() ) + { + // Restore the last used FreeBSD console cursor style + freebsd->restoreCursorStyle(); + } #endif return enable_str; @@ -742,7 +663,9 @@ void FTerm::setKDECursor (fc::kdeKonsoleCursorShape style) //---------------------------------------------------------------------- void FTerm::saveColorMap() { - //ioctl (0, GIO_CMAP, &color_map); +#if defined(__linux__) + linux->saveColorMap(); +#endif } //---------------------------------------------------------------------- @@ -753,27 +676,14 @@ void FTerm::resetColorMap() if ( oc ) putstring (oc); -/*else + +#if defined(__linux__) + else { - dacreg CurrentColors[16] = - { - {0x00, 0x00, 0x00}, {0xAA, 0x00, 0x00}, - {0x00, 0xAA, 0x00}, {0xAA, 0x55, 0x00}, - {0x00, 0x00, 0xAA}, {0xAA, 0x00, 0xAA}, - {0x00, 0xAA, 0xAA}, {0xAA, 0xAA, 0xAA}, - {0x55, 0x55, 0x55}, {0xFF, 0x55, 0x55}, - {0x55, 0xFF, 0x55}, {0xFF, 0xFF, 0x55}, - {0x55, 0x55, 0xFF}, {0xFF, 0x55, 0xFF}, - {0x55, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF} - }; - for (int x = 0; x < 16; x++) - { - color_map.d[x].red = CurrentColors[x].red; - color_map.d[x].green = CurrentColors[x].green; - color_map.d[x].blue = CurrentColors[x].blue; - } - ioctl (0, PIO_CMAP, &color_map); - }*/ + linux->resetColorMap(); + + } +#endif if ( op ) putstring (op); @@ -806,19 +716,12 @@ void FTerm::setPalette (short index, int r, int g, int b) putstring (color_str); } - else if ( isLinuxTerm() ) +#if defined(__linux__) + else { -/* // direct vga-register set - if ( r>=0 && r<256 - && g>=0 && g<256 - && b>=0 && b<256 ) - { - map.d[index].red = r; - map.d[index].green = g; - map.d[index].blue = b; - } - ioctl (0, PIO_CMAP, &map); */ + linux->setPalette(index, r, g, b); } +#endif std::fflush(stdout); } @@ -826,34 +729,17 @@ void FTerm::setPalette (short index, int r, int g, int b) //---------------------------------------------------------------------- void FTerm::setBeep (int Hz, int ms) { - if ( ! isLinuxTerm() ) - return; - - // range for frequency: 21-32766 - if ( Hz < 21 || Hz > 32766 ) - return; - - // range for duration: 0-1999 - if ( ms < 0 || ms > 1999 ) - return; - - putstringf ( CSI "10;%d]" - CSI "11;%d]" - , Hz, ms ); - std::fflush(stdout); +#if defined(__linux__) + linux->setBeep (Hz, ms); +#endif } //---------------------------------------------------------------------- void FTerm::resetBeep() { - if ( ! isLinuxTerm() ) - return; - - // default frequency: 750 Hz - // default duration: 125 ms - putstring ( CSI "10;750]" - CSI "11;125]" ); - std::fflush(stdout); +#if defined(__linux__) + linux->resetBeep(); +#endif } //---------------------------------------------------------------------- @@ -928,6 +814,34 @@ std::string FTerm::getEncodingString() return ""; } +//---------------------------------------------------------------------- +bool FTerm::charEncodable (uInt c) +{ + uInt ch = charEncode(c); + return bool(ch > 0 && ch != c); +} + +//---------------------------------------------------------------------- +uInt FTerm::charEncode (uInt c) +{ + return charEncode (c, term_encoding); +} + +//---------------------------------------------------------------------- +uInt FTerm::charEncode (uInt c, fc::encoding enc) +{ + for (uInt i = 0; i <= uInt(fc::lastCharItem); i++) + { + if ( fc::character[i][fc::UTF8] == c ) + { + c = fc::character[i][enc]; + break; + } + } + + return c; +} + //---------------------------------------------------------------------- bool FTerm::scrollTermForward() { @@ -1089,7 +1003,9 @@ void FTerm::initScreenSettings() #if defined(__linux__) // Important: Do not use setNewFont() or setVGAFont() after // the console character mapping has been initialized - initLinuxConsoleCharMap(); + linux->initCharMap (fc::character); + shadow_character = linux->hasShadowCharacter(); + half_block_character = linux->hasHalfBlockCharacter(); #endif #if defined(__FreeBSD__) || defined(__DragonFly__) @@ -1103,34 +1019,6 @@ void FTerm::initScreenSettings() xterm->setDefaults(); } -//---------------------------------------------------------------------- -bool FTerm::charEncodable (uInt c) -{ - uInt ch = charEncode(c); - return bool(ch > 0 && ch != c); -} - -//---------------------------------------------------------------------- -uInt FTerm::charEncode (uInt c) -{ - return charEncode (c, term_encoding); -} - -//---------------------------------------------------------------------- -uInt FTerm::charEncode (uInt c, fc::encoding enc) -{ - for (uInt i = 0; i <= uInt(fc::lastCharItem); i++) - { - if ( fc::character[i][0] == c ) - { - c = fc::character[i][enc]; - break; - } - } - - return c; -} - //---------------------------------------------------------------------- char* FTerm::changeAttribute ( char_data*& term_attr , char_data*& next_attr ) @@ -1162,495 +1050,6 @@ void FTerm::exitWithMessage (std::string message) // private methods of FTerm -//---------------------------------------------------------------------- -#if defined(__linux__) -int FTerm::isLinuxConsole() -{ - // Check if it's a Linux console - - char arg = 0; - // get keyboard type an compare - return ( isatty (fd_tty) - && ioctl(fd_tty, KDGKBTYPE, &arg) == 0 - && ((arg == KB_101) || (arg == KB_84)) ); -} -#endif - -#if defined(__linux__) -#if defined(__x86_64__) || defined(__i386) || defined(__arm__) -//---------------------------------------------------------------------- -inline uInt16 FTerm::getInputStatusRegisterOne() -{ - // Gets the VGA input-status-register-1 - - // Miscellaneous output (read port) - static const uInt16 misc_read = 0x3cc; - const uInt16 io_base = ( inb(misc_read) & 0x01 ) ? 0x3d0 : 0x3b0; - // 0x3ba : Input status 1 MDA (read port) - // 0x3da : Input status 1 CGA (read port) - return io_base + 0x0a; -} - -//---------------------------------------------------------------------- -uChar FTerm::readAttributeController (uChar index) -{ - // Reads a byte from the attribute controller from a given index - - uChar res; - // Attribute controller (write port) - static const uInt16 attrib_cntlr_write = 0x3c0; - // Attribute controller (read port) - static const uInt16 attrib_cntlr_read = 0x3c1; - const uInt16 input_status_1 = getInputStatusRegisterOne(); - - inb (input_status_1); // switch to index mode - outb (index & 0x1f, attrib_cntlr_write); - res = inb (attrib_cntlr_read); - - inb (input_status_1); // switch to data mode - index = (index & 0x1f) | 0x20; // set bit 5 (enable display) - outb (index, attrib_cntlr_write); - inb (attrib_cntlr_read); - return res; -} - -//---------------------------------------------------------------------- -void FTerm::writeAttributeController (uChar index, uChar data) -{ - // Writes a byte from the attribute controller from a given index - - // Attribute controller (write port) - static const uInt16 attrib_cntlr_write = 0x3c0; - const uInt16 input_status_1 = getInputStatusRegisterOne(); - - inb (input_status_1); // switch to index mode - outb (index & 0x1f, attrib_cntlr_write); - outb (data, attrib_cntlr_write); - - inb (input_status_1); // switch to data mode - index = (index & 0x1f) | 0x20; // set bit 5 (enable display) - outb (index, attrib_cntlr_write); - outb (data, attrib_cntlr_write); -} - -//---------------------------------------------------------------------- -inline uChar FTerm::getAttributeMode() -{ - // Gets the attribute mode value from the vga attribute controller - static const uChar attrib_mode = 0x10; - return readAttributeController(attrib_mode); -} - -//---------------------------------------------------------------------- -inline void FTerm::setAttributeMode (uChar data) -{ - // Sets the attribute mode value from the vga attribute controller - static const uChar attrib_mode = 0x10; - writeAttributeController (attrib_mode, data); -} - -//---------------------------------------------------------------------- -int FTerm::setBlinkAsIntensity (bool on) -{ - // Uses blink-bit as background intensity. - // That permits 16 colors for background - - // Test if the blink-bit is used by the screen font (512 characters) - if ( screen_font.charcount > 256 ) - return -1; - - if ( getuid() != 0 ) // Direct hardware access requires root privileges - return -2; - - if ( fd_tty < 0 ) - return -1; - - // Enable access to VGA I/O ports (from 0x3B4 with num = 0x2C) - if ( ioctl(fd_tty, KDENABIO, 0) < 0 ) - return -1; // error on KDENABIO - - if ( on ) - setAttributeMode (getAttributeMode() & 0xF7); // clear bit 3 - else - setAttributeMode (getAttributeMode() | 0x08); // set bit 3 - - // Disable access to VGA I/O ports - if ( ioctl(fd_tty, KDDISABIO, 0) < 0 ) - return -1; // error on KDDISABIO - - return 0; -} -#endif - -//---------------------------------------------------------------------- -int FTerm::getFramebuffer_bpp() -{ - int fd = -1; - struct fb_var_screeninfo fb_var; - struct fb_fix_screeninfo fb_fix; - - const char* fb = C_STR("/dev/fb/0"); - - if ( (fd = open(fb, O_RDWR)) < 0 ) - { - if ( errno != ENOENT && errno != ENOTDIR ) - return -1; - - fb = C_STR("/dev/fb0"); - - if ( (fd = open(fb, O_RDWR)) < 0 ) - return -1; - } - - if ( ! ioctl(fd, FBIOGET_VSCREENINFO, &fb_var) - && ! ioctl(fd, FBIOGET_FSCREENINFO, &fb_fix) ) - { - ::close(fd); - return int(fb_var.bits_per_pixel); - } - else - { - ::close(fd); - } - - return -1; -} -#endif - -//---------------------------------------------------------------------- -int FTerm::openConsole() -{ - static const char* terminal_devices[] = - { - "/proc/self/fd/0", - "/dev/tty", - "/dev/tty0", - "/dev/vc/0", - "/dev/systty", - "/dev/console", - 0 - }; - - if ( fd_tty >= 0 ) // console is already opened - return 0; - - if ( ! *termfilename ) - return 0; - - for (int i = 0; terminal_devices[i] != 0; i++) - if ( (fd_tty = open(terminal_devices[i], O_RDWR, 0)) >= 0 ) - return 0; - - return -1; // No file descriptor referring to the console -} - -//---------------------------------------------------------------------- -int FTerm::closeConsole() -{ - if ( fd_tty < 0 ) // console is already closed - return 0; - - int ret = ::close (fd_tty); // use 'close' from the global namespace - fd_tty = -1; - - if ( ret == 0 ) - return 0; - else - return -1; -} - -#if defined(__linux__) -//---------------------------------------------------------------------- -int FTerm::getScreenFont() -{ - static const std::size_t data_size = 4 * 32 * 512; - struct console_font_op font; - - int ret; - - if ( fd_tty < 0 ) - return -1; - - // initialize unused padding bytes in struct - std::memset (&font, 0, sizeof(console_font_op)); - - font.op = KD_FONT_OP_GET; - font.flags = 0; - font.width = 32; - font.height = 32; - font.charcount = 512; - - // initialize with 0 - try - { - font.data = new uChar[data_size](); - } - catch (const std::bad_alloc& ex) - { - std::cerr << "not enough memory to alloc " << ex.what() << std::endl; - return -1; - } - - // font operation - ret = ioctl (fd_tty, KDFONTOP, &font); - - if ( ret == 0 ) - { - screen_font.width = font.width; - screen_font.height = font.height; - screen_font.charcount = font.charcount; - screen_font.data = font.data; - return 0; - } - else - return -1; -} - -//---------------------------------------------------------------------- -int FTerm::setScreenFont ( uChar fontdata[], uInt count - , uInt fontwidth, uInt fontheight - , bool direct) -{ - struct console_font_op font; - int ret; - - if ( fd_tty < 0 ) - return -1; - - // initialize unused padding bytes in struct - std::memset (&font, 0x00, sizeof(console_font_op)); - - font.op = KD_FONT_OP_SET; - font.flags = 0; - font.width = fontwidth; - font.height = fontheight; - font.charcount = count; - - if ( direct ) - font.data = fontdata; - else - { - const uInt bytes_per_line = font.width / 8; - const std::size_t data_size = bytes_per_line * 32 * font.charcount; - - try - { - font.data = new uChar[data_size](); // initialize with 0 - } - catch (const std::bad_alloc& ex) - { - std::cerr << "not enough memory to alloc " << ex.what() << std::endl; - return -1; - } - - for (uInt i = 0; i < count; i++) - std::memcpy ( const_cast(font.data + bytes_per_line * 32 * i) - , &fontdata[i * font.height] - , font.height); - } - // font operation - ret = ioctl (fd_tty, KDFONTOP, &font); - - if ( ret != 0 && errno != ENOSYS && errno != EINVAL ) - { - if ( ! direct ) - delete[] font.data; - - return -1; - } - - if ( ! direct ) - delete[] font.data; - - if ( ret == 0 ) - return 0; - else - return -1; -} - -//---------------------------------------------------------------------- -int FTerm::getUnicodeMap() -{ - struct unimapdesc unimap; - int ret; - - if ( fd_tty < 0 ) - return -1; - - unimap.entry_ct = 0; - unimap.entries = 0; - - // get count - ret = ioctl (fd_tty, GIO_UNIMAP, &unimap); - - if ( ret != 0 ) - { - int count; - - if ( errno != ENOMEM || unimap.entry_ct == 0 ) - return -1; - - count = unimap.entry_ct; - - try - { - unimap.entries = new struct unipair[count](); - } - catch (const std::bad_alloc& ex) - { - std::cerr << "not enough memory to alloc " << ex.what() << std::endl; - return -1; - } - - // get unicode-to-font mapping from kernel - ret = ioctl(fd_tty, GIO_UNIMAP, &unimap); - - if ( ret == 0 ) - { - screen_unicode_map.entry_ct = unimap.entry_ct; - screen_unicode_map.entries = unimap.entries; - } - else - return -1; - } - - return 0; -} - -//---------------------------------------------------------------------- -int FTerm::setUnicodeMap (struct unimapdesc* unimap) -{ - struct unimapinit advice; - int ret; - - if ( fd_tty < 0 ) - return -1; - - advice.advised_hashsize = 0; - advice.advised_hashstep = 0; - advice.advised_hashlevel = 0; - - do - { - // clear the unicode-to-font table - ret = ioctl(fd_tty, PIO_UNIMAPCLR, &advice); - - if ( ret != 0 ) - return -1; - - // put the new unicode-to-font mapping in kernel - ret = ioctl(fd_tty, PIO_UNIMAP, unimap); - - if ( ret != 0 ) - advice.advised_hashlevel++; - } - while ( ret != 0 && errno == ENOMEM && advice.advised_hashlevel < 100); - - if ( ret == 0 ) - return 0; - else - return -1; -} - -//---------------------------------------------------------------------- -void FTerm::initLinuxConsole() -{ - // initialize Linux console - - screen_unicode_map.entries = 0; - screen_font.data = 0; - - if ( openConsole() == 0 ) - { - term_detection->setLinuxTerm (isLinuxConsole()); - - if ( isLinuxTerm() ) - { - getUnicodeMap(); - getScreenFont(); - -#if defined(__x86_64__) || defined(__i386) || defined(__arm__) - // Enable 16 background colors - if ( setBlinkAsIntensity(true) == 0 ) - FTermcap::max_color = 16; - else - FTermcap::max_color = 8; -#endif - // Underline cursor - setLinuxConsoleCursorStyle (fc::underscore_cursor, true); - - // Framebuffer color depth in bits per pixel - int bpp = getFramebuffer_bpp(); - - // More than 4 bits per pixel and the font uses the blink-bit - if ( bpp >= 4 && screen_font.charcount <= 256 ) - FTermcap::max_color = 16; - -#if DEBUG - framebuffer_bpp = bpp; -#endif - } - - detectTermSize(); - closeConsole(); - } - else - { - std::cerr << "can not open the console.\n"; - std::abort(); - } -} - -//---------------------------------------------------------------------- -void FTerm::initLinuxConsoleCharMap() -{ - uInt c1, c2, c3, c4, c5; - - if ( NewFont || VGAFont ) - return; - - if ( screen_unicode_map.entry_ct != 0 ) - { - for (int i = 0; i <= fc::lastCharItem; i++ ) - { - bool found = false; - - for (uInt n = 0; n < screen_unicode_map.entry_ct; n++) - { - if ( fc::character[i][fc::UTF8] == screen_unicode_map.entries[n].unicode ) - { - found = true; - break; - } - } - - if ( ! found ) - fc::character[i][fc::PC] = fc::character[i][fc::ASCII]; - } - } - - c1 = fc::UpperHalfBlock; - c2 = fc::LowerHalfBlock; - c3 = fc::FullBlock; - - if ( charEncode(c1, fc::PC) == charEncode(c1, fc::ASCII) - || charEncode(c2, fc::PC) == charEncode(c2, fc::ASCII) - || charEncode(c3, fc::PC) == charEncode(c3, fc::ASCII) ) - { - shadow_character = false; - } - - c4 = fc::RightHalfBlock; - c5 = fc::LeftHalfBlock; - - if ( charEncode(c4, fc::PC) == charEncode(c4, fc::ASCII) - || charEncode(c5, fc::PC) == charEncode(c5, fc::ASCII) ) - { - half_block_character = false; - } -} -#endif - //---------------------------------------------------------------------- void FTerm::init_global_values() { @@ -1691,10 +1090,6 @@ void FTerm::init_global_values() xterm->setTermcapMap(tcap); xterm->setFTermDetection(term_detection); - // Initialize the structs - color_env.setDefault(); - secondary_da.setDefault(); - if ( ! init_values.terminal_detection ) term_detection->setTerminalDetection (false); } @@ -2462,7 +1857,10 @@ void FTerm::setInsertCursorStyle() setKDECursor(fc::UnderlineCursor); #if defined(__linux__) - setLinuxConsoleCursorStyle (fc::underscore_cursor, isCursorHidden()); + char* cstyle; + cstyle = linux->setCursorStyle (fc::underscore_cursor, isCursorHidden()); + putstring (cstyle); + std::fflush(stdout); #endif #if defined(__FreeBSD__) || defined(__DragonFly__) @@ -2480,7 +1878,10 @@ void FTerm::setOverwriteCursorStyle() setKDECursor(fc::BlockCursor); #if defined(__linux__) - setLinuxConsoleCursorStyle (fc::full_block_cursor, isCursorHidden()); + char* cstyle; + cstyle = linux->setCursorStyle (fc::full_block_cursor, isCursorHidden()); + putstring (cstyle); + std::fflush(stdout); #endif #if defined(__FreeBSD__) || defined(__DragonFly__) @@ -2500,7 +1901,7 @@ void FTerm::enableMouse() #if defined(__linux__) if ( isLinuxTerm() && openConsole() == 0 ) { - if ( isLinuxConsole() ) + if ( linux->isLinuxConsole() ) gpm_mouse = true; closeConsole(); @@ -2577,10 +1978,18 @@ inline void FTerm::allocationValues() term_detection = new FTermDetection(); xterm = new FTermXTerminal(); +#if defined(__linux__) + linux = new FTermLinux(); +#endif + #if defined(__FreeBSD__) || defined(__DragonFly__) freebsd = new FTermFreeBSD(); #endif +#if defined(__NetBSD__) || defined(__OpenBSD__) + openbsd = new FTermOpenBSD(); +#endif + mouse = new FMouseControl(); term = new FRect(0, 0, 0, 0); vt100_alt_char = new std::map; @@ -2614,11 +2023,21 @@ inline void FTerm::deallocationValues() if ( mouse ) delete mouse; +#if defined(__NetBSD__) || defined(__OpenBSD__) + if ( openbsd ) + delete openbsd; +#endif + #if defined(__FreeBSD__) || defined(__DragonFly__) if ( freebsd ) delete freebsd; #endif +#if defined(__linux__) + if ( linux ) + delete linux; +#endif + if ( xterm ) delete xterm; @@ -2755,18 +2174,17 @@ void FTerm::init() void FTerm::initOSspecifics() { #if defined(__linux__) - // initialize Linux console - initLinuxConsole(); + linux->setFTermDetection(term_detection); + linux->init(); // Initialize Linux console + framebuffer_bpp = linux->getFramebufferBpp(); #endif #if defined(__FreeBSD__) || defined(__DragonFly__) - // Initialize BSD console - freebsd->init(); + freebsd->init(); // Initialize BSD console #endif #if defined(__NetBSD__) || defined(__OpenBSD__) - // Initialize wscons console - openbsd->init(); + openbsd->init(); // Initialize wscons console #endif } @@ -2837,6 +2255,10 @@ void FTerm::finish() } finishOSspecifics2(); + + if ( NewFont || VGAFont ) + setOldFont(); + deallocationValues(); } @@ -2844,13 +2266,7 @@ void FTerm::finish() void FTerm::finishOSspecifics1() { #if defined(__linux__) - if ( isLinuxTerm() ) - { -#if defined(__x86_64__) || defined(__i386) || defined(__arm__) - setBlinkAsIntensity (false); -#endif - setLinuxConsoleCursorStyle (fc::default_cursor, false); - } + linux->finish(); #endif #if defined(__FreeBSD__) || defined(__DragonFly__) @@ -2868,17 +2284,6 @@ void FTerm::finishOSspecifics2() #if defined(__linux__) if ( isLinuxTerm() && utf8_console ) setUTF8(true); - - if ( NewFont || VGAFont ) - setOldFont(); - else - { - if ( screen_font.data != 0 ) - delete[] screen_font.data; - - if ( screen_unicode_map.entries != 0 ) - delete[] screen_unicode_map.entries; - } #endif } diff --git a/src/ftermdetection.cpp b/src/ftermdetection.cpp index 9c0c39eb..ab2d270e 100644 --- a/src/ftermdetection.cpp +++ b/src/ftermdetection.cpp @@ -62,6 +62,10 @@ FTermDetection::FTermDetection() // Example: vte version 0.40.0 = 0 * 100 + 40 * 100 + 0 = 4000 // a.b.c = a * 100 + b * 100 + c gnome_terminal_id = 0; + + // Initialize the structs + color_env.setDefault(); + secondary_da.setDefault(); } //---------------------------------------------------------------------- diff --git a/src/ftermfreebsd.cpp b/src/ftermfreebsd.cpp index 5b9a0019..d2b8e6ed 100644 --- a/src/ftermfreebsd.cpp +++ b/src/ftermfreebsd.cpp @@ -99,7 +99,7 @@ void FTermFreeBSD::init() } //---------------------------------------------------------------------- -void FTermFreeBSD::initCharMap() +void FTermFreeBSD::initCharMap (uInt char_map[][fc::NUM_OF_ENCODINGS]) { // A FreeBSD console can't show ASCII codes from 0x00 to 0x1b @@ -107,8 +107,8 @@ void FTermFreeBSD::initCharMap() return; for (int i = 0; i <= fc::lastCharItem; i++) - if ( fc::character[i][fc::PC] < 0x1c ) - fc::character[i][fc::PC] = fc::character[i][fc::ASCII]; + if ( char_map[i][fc::PC] < 0x1c ) + char_map[i][fc::PC] = char_map[i][fc::ASCII]; } //---------------------------------------------------------------------- diff --git a/src/ftermlinux.cpp b/src/ftermlinux.cpp new file mode 100644 index 00000000..a15595bc --- /dev/null +++ b/src/ftermlinux.cpp @@ -0,0 +1,1196 @@ +/*********************************************************************** +* ftermlinux.cpp - Contains the Linux terminal functions * +* * +* This file is part of the Final Cut widget toolkit * +* * +* Copyright 2018 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 * +* . * +***********************************************************************/ + +#include "final/fterm.h" +#include "final/ftermlinux.h" + +#if defined(__linux__) + #include "../fonts/newfont.h" + #include "../fonts/unicodemap.h" + #include "../fonts/vgafont.h" +#endif + +// static class attributes +#if defined(__linux__) + FTermLinux::modifier_key FTermLinux::mod_key; + console_font_op FTermLinux::screen_font; + unimapdesc FTermLinux::screen_unicode_map; + + bool FTermLinux::NewFont; + bool FTermLinux::VGAFont; + bool FTermLinux::shadow_character = true; + bool FTermLinux::half_block_character = true; + bool FTermLinux::has_saved_palette = false; + + FTermDetection* FTermLinux::term_detection = 0; + fc::linuxConsoleCursorStyle FTermLinux::linux_console_cursor_style; + FTermLinux::ColorMap FTermLinux::saved_color_map; + FTermLinux::ColorMap FTermLinux::cmap; +#if DEBUG + int FTermLinux::framebuffer_bpp = -1; +#endif + +#endif // defined(__linux__) + + +//---------------------------------------------------------------------- +// class FTermLinux +//---------------------------------------------------------------------- + +// constructors and destructor +//---------------------------------------------------------------------- +FTermLinux::FTermLinux() +{ } + +//---------------------------------------------------------------------- +FTermLinux::~FTermLinux() // destructor +{ + if ( screen_font.data ) + delete[] screen_font.data; + + if ( screen_unicode_map.entries ) + delete[] screen_unicode_map.entries; +} + +// public methods of FTermLinux +//---------------------------------------------------------------------- +#if defined(__linux__) +fc::linuxConsoleCursorStyle FTermLinux::getCursorStyle() +{ + // Get the current set cursor style + + return linux_console_cursor_style; +} + +//---------------------------------------------------------------------- +char* FTermLinux::setCursorStyle ( fc::linuxConsoleCursorStyle style + , bool hidden ) +{ + // Set cursor style in linux console + + static char buf[16] = { }; + + if ( ! FTerm::isLinuxTerm() ) + return buf; + + linux_console_cursor_style = style; + + if ( hidden ) + return buf; + + std::sprintf (buf, CSI "?%dc", style); + return buf; +} + +//---------------------------------------------------------------------- +void FTermLinux::setUTF8 (bool on) +{ + if ( ! FTerm::isLinuxTerm() ) + return; + + if ( on ) + FTerm::putstring (ESC "%G"); + else + FTerm::putstring (ESC "%@"); + + std::fflush(stdout); +} + +//---------------------------------------------------------------------- +bool FTermLinux::setPalette (short index, int r, int g, int b) +{ + if ( ! FTerm::isLinuxTerm() ) + return false; + +#if defined(__x86_64__) || defined(__i386) || defined(__arm__) + return setVGAPalette (index, r, g, b); +#else + return false; +#endif +} + +//---------------------------------------------------------------------- +bool FTermLinux::isLinuxConsole() +{ + // Check if it's a Linux console + + char arg = 0; + int fd_tty = FTerm::getTTYFileDescriptor(); + + // get keyboard type an compare + return ( isatty (fd_tty) + && ioctl(fd_tty, KDGKBTYPE, &arg) == 0 + && ((arg == KB_101) || (arg == KB_84)) ); +} + +//---------------------------------------------------------------------- +void FTermLinux::init() +{ + // initialize Linux console + + screen_unicode_map.entries = 0; + screen_font.data = 0; + + if ( FTerm::openConsole() == 0 ) + { + term_detection->setLinuxTerm (isLinuxConsole()); + + if ( FTerm::isLinuxTerm() ) + { + getUnicodeMap(); + getScreenFont(); + +#if defined(__x86_64__) || defined(__i386) || defined(__arm__) + // Enable 16 background colors + if ( setBlinkAsIntensity(true) == 0 ) + FTermcap::max_color = 16; + else + FTermcap::max_color = 8; +#endif + // Underline cursor + setCursorStyle (fc::underscore_cursor, true); + + // Framebuffer color depth in bits per pixel + int bpp = getFramebuffer_bpp(); + + // More than 4 bits per pixel and the font uses the blink-bit + if ( bpp >= 4 && screen_font.charcount <= 256 ) + FTermcap::max_color = 16; + +#if DEBUG + framebuffer_bpp = bpp; +#endif + } + + FTerm::detectTermSize(); + FTerm::closeConsole(); + } + else + { + std::cerr << "can not open the console.\n"; + std::abort(); + } +} + +//---------------------------------------------------------------------- +void FTermLinux::initCharMap (uInt char_map[][fc::NUM_OF_ENCODINGS]) +{ + uInt c1, c2, c3, c4, c5; + + if ( NewFont || VGAFont ) + return; + + if ( screen_unicode_map.entry_ct != 0 ) + { + for (int i = 0; i <= fc::lastCharItem; i++ ) + { + bool known_unicode = false; + + for (uInt n = 0; n < screen_unicode_map.entry_ct; n++) + { + if ( char_map[i][fc::UTF8] == screen_unicode_map.entries[n].unicode ) + { + if ( screen_unicode_map.entries[n].fontpos < 256 ) + known_unicode = true; + + break; + } + } + + if ( ! known_unicode ) + char_map[i][fc::PC] = char_map[i][fc::ASCII]; + } + } + + c1 = fc::UpperHalfBlock; + c2 = fc::LowerHalfBlock; + c3 = fc::FullBlock; + + if ( FTerm::charEncode(c1, fc::PC) == FTerm::charEncode(c1, fc::ASCII) + || FTerm::charEncode(c2, fc::PC) == FTerm::charEncode(c2, fc::ASCII) + || FTerm::charEncode(c3, fc::PC) == FTerm::charEncode(c3, fc::ASCII) ) + { + shadow_character = false; + } + + c4 = fc::RightHalfBlock; + c5 = fc::LeftHalfBlock; + + if ( FTerm::charEncode(c4, fc::PC) == FTerm::charEncode(c4, fc::ASCII) + || FTerm::charEncode(c5, fc::PC) == FTerm::charEncode(c5, fc::ASCII) ) + { + half_block_character = false; + } +} + +//---------------------------------------------------------------------- +void FTermLinux::finish() +{ + if ( FTerm::isLinuxTerm() ) + { +#if defined(__x86_64__) || defined(__i386) || defined(__arm__) + setBlinkAsIntensity (false); +#endif + setCursorStyle (fc::default_cursor, false); + } +} + +//---------------------------------------------------------------------- +bool FTermLinux::loadVGAFont() +{ + VGAFont = true; + + if ( FTerm::openConsole() == 0 ) + { + if ( isLinuxConsole() ) + { + // Set the standard vga font 8x16 + int ret = setScreenFont(fc::__8x16std, 256, 8, 16); + + if ( ret != 0 ) + VGAFont = false; + + // unicode character mapping + struct unimapdesc unimap; + unimap.entry_ct = uInt16 ( sizeof(fc::unicode_cp437_pairs) + / sizeof(unipair) ); + unimap.entries = &fc::unicode_cp437_pairs[0]; + setUnicodeMap(&unimap); + } + else + VGAFont = false; + + FTerm::detectTermSize(); + FTerm::closeConsole(); + } + else + VGAFont = false; + + if ( VGAFont ) + shadow_character = half_block_character = true; + + return VGAFont; +} + +//---------------------------------------------------------------------- +bool FTermLinux::loadNewFont() +{ + NewFont = true; + + if ( FTerm::openConsole() == 0 ) + { + if ( isLinuxConsole() ) + { + // Set the graphical font 8x16 + int ret = setScreenFont(fc::__8x16graph, 256, 8, 16); + + if ( ret != 0 ) + NewFont = false; + + // unicode character mapping + struct unimapdesc unimap; + unimap.entry_ct = uInt16 ( sizeof(fc::unicode_cp437_pairs) + / sizeof(unipair) ); + unimap.entries = &fc::unicode_cp437_pairs[0]; + setUnicodeMap(&unimap); + } + else + NewFont = false; + + FTerm::detectTermSize(); + FTerm::closeConsole(); + } + else + NewFont = false; + + if ( VGAFont ) + shadow_character = half_block_character = true; + + return NewFont; +} + +//---------------------------------------------------------------------- +bool FTermLinux::loadOldFont (uInt char_map[][fc::NUM_OF_ENCODINGS]) +{ + bool retval = false; + + if ( FTerm::openConsole() == 0 ) + { + if ( isLinuxConsole() ) + { + if ( screen_font.data ) + { + int ret = setScreenFont ( screen_font.data + , screen_font.charcount + , screen_font.width + , screen_font.height + , true ); + delete[] screen_font.data; + screen_font.data = 0; + + if ( ret == 0 ) + retval = true; + } + + if ( screen_unicode_map.entries ) + { + setUnicodeMap (&screen_unicode_map); + initCharMap(char_map); + delete[] screen_unicode_map.entries; + screen_unicode_map.entries = 0; + } + } + + FTerm::detectTermSize(); + FTerm::closeConsole(); + } + + if ( retval ) + VGAFont = NewFont = false; + + return retval; +} + +//---------------------------------------------------------------------- +bool FTermLinux::saveColorMap() +{ + if ( ! FTerm::isLinuxTerm() ) + return false; + +#if defined(__x86_64__) || defined(__i386) || defined(__arm__) + return saveVGAPalette(); +#else + return false; +#endif +} + +//---------------------------------------------------------------------- +bool FTermLinux::resetColorMap() +{ + if ( ! FTerm::isLinuxTerm() ) + return false; + +#if defined(__x86_64__) || defined(__i386) || defined(__arm__) + return resetVGAPalette(); +#else + return false; +#endif +} + +//---------------------------------------------------------------------- +void FTermLinux::setBeep (int Hz, int ms) +{ + if ( ! FTerm::isLinuxTerm() ) + return; + + // range for frequency: 21-32766 + if ( Hz < 21 || Hz > 32766 ) + return; + + // range for duration: 0-1999 + if ( ms < 0 || ms > 1999 ) + return; + + FTerm::putstringf ( CSI "10;%d]" + CSI "11;%d]" + , Hz, ms ); + std::fflush(stdout); +} + +//---------------------------------------------------------------------- +void FTermLinux::resetBeep() +{ + if ( ! FTerm::isLinuxTerm() ) + return; + + // default frequency: 750 Hz + // default duration: 125 ms + FTerm::putstring ( CSI "10;750]" + CSI "11;125]" ); + std::fflush(stdout); +} + +//---------------------------------------------------------------------- +char* FTermLinux::restoreCursorStyle() +{ + // Reset to the last used Linux console cursor style + + return setCursorStyle (getCursorStyle(), false); +} + +//---------------------------------------------------------------------- +int FTermLinux::modifierKeyCorrection (const int& key_id) +{ + // Get the current modifier key state + modifier_key& m = getModifierKey(); + + if ( ! (m.shift || m.ctrl || m.alt) ) + { + return key_id; + } + else if ( m.shift && ! m.ctrl && ! m.alt ) + { + return shiftKeyCorrection(key_id); + } + else if ( ! m.shift && m.ctrl && ! m.alt ) + { + return ctrlKeyCorrection(key_id); + } + else if ( ! m.shift && ! m.ctrl && m.alt ) + { + return altKeyCorrection(key_id); + } + else if ( m.shift && m.ctrl && ! m.alt ) + { + return shiftCtrlKeyCorrection(key_id); + } + else if ( m.shift && ! m.ctrl && m.alt ) + { + return shiftAltKeyCorrection(key_id); + } + else if ( ! m.shift && m.ctrl && m.alt ) + { + return ctrlAltKeyCorrection(key_id); + } + else if ( m.shift && m.ctrl && m.alt ) + { + return shiftCtrlAltKeyCorrection(key_id); + } + + return key_id; +} + + +// private methods of FTermLinux +//---------------------------------------------------------------------- +int FTermLinux::getFramebuffer_bpp() +{ + int fd = -1; + struct fb_var_screeninfo fb_var; + struct fb_fix_screeninfo fb_fix; + + const char* fb = C_STR("/dev/fb/0"); + + if ( (fd = open(fb, O_RDWR)) < 0 ) + { + if ( errno != ENOENT && errno != ENOTDIR ) + return -1; + + fb = C_STR("/dev/fb0"); + + if ( (fd = open(fb, O_RDWR)) < 0 ) + return -1; + } + + if ( ! ioctl(fd, FBIOGET_VSCREENINFO, &fb_var) + && ! ioctl(fd, FBIOGET_FSCREENINFO, &fb_fix) ) + { + ::close(fd); + return int(fb_var.bits_per_pixel); + } + else + { + ::close(fd); + } + + return -1; +} + +//---------------------------------------------------------------------- +bool FTermLinux::getScreenFont() +{ + static const std::size_t data_size = 4 * 32 * 512; + struct console_font_op font; + int fd_tty = FTerm::getTTYFileDescriptor(); + + int ret; + + if ( fd_tty < 0 ) + return false; + + // initialize unused padding bytes in struct + std::memset (&font, 0, sizeof(console_font_op)); + + font.op = KD_FONT_OP_GET; + font.flags = 0; + font.width = 32; + font.height = 32; + font.charcount = 512; + + // initialize with 0 + try + { + font.data = new uChar[data_size](); + } + catch (const std::bad_alloc& ex) + { + std::cerr << "not enough memory to alloc " << ex.what() << std::endl; + return false; + } + + // font operation + ret = ioctl (fd_tty, KDFONTOP, &font); + + if ( ret == 0 ) + { + screen_font.width = font.width; + screen_font.height = font.height; + screen_font.charcount = font.charcount; + screen_font.data = font.data; + return true; + } + else + return false; +} + +//---------------------------------------------------------------------- +bool FTermLinux::getUnicodeMap() +{ + int ret; + int fd_tty = FTerm::getTTYFileDescriptor(); + + if ( fd_tty < 0 ) + return false; + + screen_unicode_map.entry_ct = 0; + screen_unicode_map.entries = 0; + + // get count + ret = ioctl (fd_tty, GIO_UNIMAP, &screen_unicode_map); + + if ( ret != 0 ) + { + int count; + + if ( errno != ENOMEM || screen_unicode_map.entry_ct == 0 ) + return false; + + count = screen_unicode_map.entry_ct; + + try + { + screen_unicode_map.entries = new struct unipair[count](); + } + catch (const std::bad_alloc& ex) + { + std::cerr << "not enough memory to alloc " << ex.what() << std::endl; + return false; + } + + // get unicode-to-font mapping from kernel + ret = ioctl(fd_tty, GIO_UNIMAP, &screen_unicode_map); + + if ( ret != 0 ) + return false; + } + + return true; +} + +//---------------------------------------------------------------------- +FTermLinux::modifier_key& FTermLinux::getModifierKey() +{ + // Get Linux console shift state + + char subcode = 6; // Shift state command + return value + + // fill bit field with 0 + std::memset (&mod_key, 0x00, sizeof(mod_key)); + + // TIOCLINUX, subcode = 6 + if ( ioctl(0, TIOCLINUX, &subcode) >= 0 ) + { + if ( subcode & (1 << KG_SHIFT) ) + mod_key.shift = true; + + if ( subcode & (1 << KG_ALTGR) ) + mod_key.alt_gr = true; + + if ( subcode & (1 << KG_CTRL) ) + mod_key.ctrl = true; + + if ( subcode & (1 << KG_ALT) ) + mod_key.alt = true; + } + + return mod_key; +} + +//---------------------------------------------------------------------- +int FTermLinux::setScreenFont ( uChar fontdata[], uInt count + , uInt fontwidth, uInt fontheight + , bool direct) +{ + struct console_font_op font; + int ret; + int fd_tty = FTerm::getTTYFileDescriptor(); + + if ( fd_tty < 0 ) + return -1; + + // initialize unused padding bytes in struct + std::memset (&font, 0x00, sizeof(console_font_op)); + + font.op = KD_FONT_OP_SET; + font.flags = 0; + font.width = fontwidth; + font.height = fontheight; + font.charcount = count; + + if ( direct ) + font.data = fontdata; + else + { + const uInt bytes_per_line = font.width / 8; + const std::size_t data_size = bytes_per_line * 32 * font.charcount; + + try + { + font.data = new uChar[data_size](); // initialize with 0 + } + catch (const std::bad_alloc& ex) + { + std::cerr << "not enough memory to alloc " << ex.what() << std::endl; + return -1; + } + + for (uInt i = 0; i < count; i++) + std::memcpy ( const_cast(font.data + bytes_per_line * 32 * i) + , &fontdata[i * font.height] + , font.height); + } + + // font operation + ret = ioctl (fd_tty, KDFONTOP, &font); + + if ( ret != 0 && errno != ENOSYS && errno != EINVAL ) + { + if ( ! direct ) + delete[] font.data; + + return -1; + } + + if ( ! direct ) + delete[] font.data; + + if ( ret == 0 ) + return 0; + else + return -1; +} + +//---------------------------------------------------------------------- +int FTermLinux::setUnicodeMap (struct unimapdesc* unimap) +{ + struct unimapinit advice; + int ret; + int fd_tty = FTerm::getTTYFileDescriptor(); + + if ( fd_tty < 0 ) + return -1; + + advice.advised_hashsize = 0; + advice.advised_hashstep = 0; + advice.advised_hashlevel = 0; + + do + { + // clear the unicode-to-font table + ret = ioctl(fd_tty, PIO_UNIMAPCLR, &advice); + + if ( ret != 0 ) + return -1; + + // put the new unicode-to-font mapping in kernel + ret = ioctl(fd_tty, PIO_UNIMAP, unimap); + + if ( ret != 0 ) + advice.advised_hashlevel++; + } + while ( ret != 0 && errno == ENOMEM && advice.advised_hashlevel < 100); + + if ( ret == 0 ) + return 0; + else + return -1; +} + +#if defined(__x86_64__) || defined(__i386) || defined(__arm__) +//---------------------------------------------------------------------- +inline uInt16 FTermLinux::getInputStatusRegisterOne() +{ + // Gets the VGA input-status-register-1 + + // Miscellaneous output (read port) + static const uInt16 misc_read = 0x3cc; + const uInt16 io_base = ( inb(misc_read) & 0x01 ) ? 0x3d0 : 0x3b0; + // 0x3ba : Input status 1 MDA (read port) + // 0x3da : Input status 1 CGA (read port) + return io_base + 0x0a; +} + +//---------------------------------------------------------------------- +uChar FTermLinux::readAttributeController (uChar index) +{ + // Reads a byte from the attribute controller from a given index + + uChar res; + // Attribute controller (write port) + static const uInt16 attrib_cntlr_write = 0x3c0; + // Attribute controller (read port) + static const uInt16 attrib_cntlr_read = 0x3c1; + const uInt16 input_status_1 = getInputStatusRegisterOne(); + + inb (input_status_1); // switch to index mode + outb (index & 0x1f, attrib_cntlr_write); + res = inb (attrib_cntlr_read); + + inb (input_status_1); // switch to data mode + index = (index & 0x1f) | 0x20; // set bit 5 (enable display) + outb (index, attrib_cntlr_write); + inb (attrib_cntlr_read); + return res; +} + +//---------------------------------------------------------------------- +void FTermLinux::writeAttributeController (uChar index, uChar data) +{ + // Writes a byte from the attribute controller from a given index + + // Attribute controller (write port) + static const uInt16 attrib_cntlr_write = 0x3c0; + const uInt16 input_status_1 = getInputStatusRegisterOne(); + + inb (input_status_1); // switch to index mode + outb (index & 0x1f, attrib_cntlr_write); + outb (data, attrib_cntlr_write); + + inb (input_status_1); // switch to data mode + index = (index & 0x1f) | 0x20; // set bit 5 (enable display) + outb (index, attrib_cntlr_write); + outb (data, attrib_cntlr_write); +} + +//---------------------------------------------------------------------- +inline uChar FTermLinux::getAttributeMode() +{ + // Gets the attribute mode value from the vga attribute controller + static const uChar attrib_mode = 0x10; + return readAttributeController(attrib_mode); +} + +//---------------------------------------------------------------------- +inline void FTermLinux::setAttributeMode (uChar data) +{ + // Sets the attribute mode value from the vga attribute controller + static const uChar attrib_mode = 0x10; + writeAttributeController (attrib_mode, data); +} + +//---------------------------------------------------------------------- +int FTermLinux::setBlinkAsIntensity (bool on) +{ + // Uses blink-bit as background intensity. + // That permits 16 colors for background + + int fd_tty = FTerm::getTTYFileDescriptor(); + + // Test if the blink-bit is used by the screen font (512 characters) + if ( screen_font.charcount > 256 ) + return -1; + + if ( getuid() != 0 ) // Direct hardware access requires root privileges + return -2; + + if ( fd_tty < 0 ) + return -1; + + // Enable access to VGA I/O ports (from 0x3B4 with num = 0x2C) + if ( ioctl(fd_tty, KDENABIO, 0) < 0 ) + return -1; // error on KDENABIO + + if ( on ) + setAttributeMode (getAttributeMode() & 0xF7); // clear bit 3 + else + setAttributeMode (getAttributeMode() | 0x08); // set bit 3 + + // Disable access to VGA I/O ports + if ( ioctl(fd_tty, KDDISABIO, 0) < 0 ) + return -1; // error on KDDISABIO + + return 0; +} + +//---------------------------------------------------------------------- +bool FTermLinux::setVGAPalette (short index, int r, int g, int b) +{ + // Set the vga color map + + if ( r >= 0 && r < 256 + && g >= 0 && g < 256 + && b >= 0 && b < 256 ) + { + cmap.color[index].red = uChar(r); + cmap.color[index].green = uChar(g); + cmap.color[index].blue = uChar(b); + } + + if ( ioctl (0, PIO_CMAP, &cmap) ) + return false; + else + return true; +} + +//---------------------------------------------------------------------- +bool FTermLinux::saveVGAPalette() +{ + // Save the current vga color map + + if ( ioctl (0, GIO_CMAP, &saved_color_map) ) + has_saved_palette = false; + else + has_saved_palette = true; + + return has_saved_palette; +} + +//---------------------------------------------------------------------- +bool FTermLinux::resetVGAPalette() +{ + // Reset the vga color map + + if ( has_saved_palette ) + { + if ( ioctl (0, PIO_CMAP, &saved_color_map) ) + return false; + } + else + { + rgb defaultColor[16] = + { + {0x00, 0x00, 0x00}, {0xAA, 0x00, 0x00}, + {0x00, 0xAA, 0x00}, {0xAA, 0x55, 0x00}, + {0x00, 0x00, 0xAA}, {0xAA, 0x00, 0xAA}, + {0x00, 0xAA, 0xAA}, {0xAA, 0xAA, 0xAA}, + {0x55, 0x55, 0x55}, {0xFF, 0x55, 0x55}, + {0x55, 0xFF, 0x55}, {0xFF, 0xFF, 0x55}, + {0x55, 0x55, 0xFF}, {0xFF, 0x55, 0xFF}, + {0x55, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF} + }; + + for (int index = 0; index < 16; index++) + { + cmap.color[index].red = defaultColor[index].red; + cmap.color[index].green = defaultColor[index].green; + cmap.color[index].blue = defaultColor[index].blue; + } + + if ( ioctl (0, PIO_CMAP, &cmap) ) + return false; + } + + return true; +} +#endif // defined(__x86_64__) || defined(__i386) || defined(__arm__) + +//---------------------------------------------------------------------- +int FTermLinux::shiftKeyCorrection (const int& key_id) +{ + switch ( key_id ) + { + case fc::Fkey_up: + return fc::Fkey_sr; // Shift+Up + + case fc::Fkey_down: + return fc::Fkey_sf; // Shift+Down + + case fc::Fkey_left: + return fc::Fkey_sleft; // Shift+Left + + case fc::Fkey_right: + return fc::Fkey_sright; // Shift+Right + + case fc::Fkey_ic: + return fc::Fkey_sic; // Shift+Ins + + case fc::Fkey_dc: + return fc::Fkey_sdc; // Shift+Del + + case fc::Fkey_home: + return fc::Fkey_shome; // Shift+Home + + case fc::Fkey_end: + return fc::Fkey_send; // Shift+End + + case fc::Fkey_ppage: + return fc::Fkey_sprevious; // Shift+PgUp + + case fc::Fkey_npage: + return fc::Fkey_snext; // Shift+PgDn + + default: + return key_id; + } +} + +//---------------------------------------------------------------------- +int FTermLinux::ctrlKeyCorrection (const int& key_id) +{ + switch ( key_id ) + { + case fc::Fkey_up: + return fc::Fckey_up; // Ctrl+Up + + case fc::Fkey_down: + return fc::Fckey_down; // Ctrl+Down + + case fc::Fkey_left: + return fc::Fckey_left; // Ctrl+Left + + case fc::Fkey_right: + return fc::Fckey_right; // Ctrl+Right + + case fc::Fkey_ic: + return fc::Fckey_ic; // Ctrl+Ins + + case fc::Fkey_dc: + return fc::Fckey_dc; // Ctrl+Del + + case fc::Fkey_home: + return fc::Fckey_home; // Ctrl+Home + + case fc::Fkey_end: + return fc::Fckey_end; // Ctrl+End + + case fc::Fkey_ppage: + return fc::Fckey_ppage; // Ctrl+PgUp + + case fc::Fkey_npage: + return fc::Fckey_npage; // Ctrl+PgDn + + default: + return key_id; + } +} + +//---------------------------------------------------------------------- +int FTermLinux::altKeyCorrection (const int& key_id) +{ + switch ( key_id ) + { + case fc::Fkey_up: + return fc::Fmkey_up; // Meta+Up + + case fc::Fkey_down: + return fc::Fmkey_down; // Meta+Down + + case fc::Fkey_left: + return fc::Fmkey_left; // Meta+Left + + case fc::Fkey_right: + return fc::Fmkey_right; // Meta+Right + + case fc::Fkey_ic: + return fc::Fmkey_ic; // Meta+Ins + + case fc::Fkey_dc: + return fc::Fmkey_dc; // Meta+Del + + case fc::Fkey_home: + return fc::Fmkey_home; // Meta+Home + + case fc::Fkey_end: + return fc::Fmkey_end; // Meta+End + + case fc::Fkey_ppage: + return fc::Fmkey_ppage; // Meta+PgUp + + case fc::Fkey_npage: + return fc::Fmkey_npage; // Meta+PgDn + + default: + return key_id; + } +} + +//---------------------------------------------------------------------- +int FTermLinux::shiftCtrlKeyCorrection (const int& key_id) +{ + switch ( key_id ) + { + case fc::Fkey_up: + return fc::Fckey_sup; // Shift+Ctrl+Up + + case fc::Fkey_down: + return fc::Fckey_sdown; // Shift+Ctrl+Down + + case fc::Fkey_left: + return fc::Fckey_sleft; // Shift+Ctrl+Left + + case fc::Fkey_right: + return fc::Fckey_sright; // Shift+Ctrl+Right + + case fc::Fkey_ic: + return fc::Fckey_sic; // Shift+Ctrl+Ins + + case fc::Fkey_dc: + return fc::Fckey_sdc; // Shift+Ctrl+Del + + case fc::Fkey_home: + return fc::Fckey_shome; // Shift+Ctrl+Home + + case fc::Fkey_end: + return fc::Fckey_send; // Shift+Ctrl+End + + case fc::Fkey_ppage: + return fc::Fckey_sppage; // Shift+Ctrl+PgUp + + case fc::Fkey_npage: + return fc::Fckey_snpage; // Shift+Ctrl+PgDn + + default: + return key_id; + } +} + +//---------------------------------------------------------------------- +int FTermLinux::shiftAltKeyCorrection (const int& key_id) +{ + switch ( key_id ) + { + case fc::Fkey_up: + return fc::Fmkey_sup; // Shift+Meta+Up + + case fc::Fkey_down: + return fc::Fmkey_sdown; // Shift+Meta+Down + + case fc::Fkey_left: + return fc::Fmkey_sright; // Shift+Meta+Left + + case fc::Fkey_right: + return fc::Fmkey_sleft; // Shift+Meta+Right + + case fc::Fkey_ic: + return fc::Fmkey_sic; // Shift+Meta+Ins + + case fc::Fkey_dc: + return fc::Fmkey_sdc; // Shift+Meta+Del + + case fc::Fkey_home: + return fc::Fmkey_shome; // Shift+Meta+Home + + case fc::Fkey_end: + return fc::Fmkey_send; // Shift+Meta+End + + case fc::Fkey_ppage: + return fc::Fmkey_sppage; // Shift+Meta+PgUp + + case fc::Fkey_npage: + return fc::Fmkey_snpage; // Shift+Meta+PgDn + + default: + return key_id; + } +} + +//---------------------------------------------------------------------- +int FTermLinux::ctrlAltKeyCorrection (const int& key_id) +{ + switch ( key_id ) + { + case fc::Fkey_up: + return fc::Fcmkey_up; // Ctrl+Meta+Up + + case fc::Fkey_down: + return fc::Fcmkey_down; // Ctrl+Meta+Down + + case fc::Fkey_left: + return fc::Fcmkey_left; // Ctrl+Meta+Left + + case fc::Fkey_right: + return fc::Fcmkey_right; // Ctrl+Meta+Right + + case fc::Fkey_ic: + return fc::Fcmkey_ic; // Ctrl+Meta+Ins + + case fc::Fkey_dc: + return fc::Fcmkey_dc; // Ctrl+Meta+Del + + case fc::Fkey_home: + return fc::Fcmkey_home; // Ctrl+Meta+Home + + case fc::Fkey_end: + return fc::Fcmkey_end; // Ctrl+Meta+End + + case fc::Fkey_ppage: + return fc::Fcmkey_ppage; // Ctrl+Meta+PgUp + + case fc::Fkey_npage: + return fc::Fcmkey_npage; // Ctrl+Meta+PgDn + + default: + return key_id; + } +} + +//---------------------------------------------------------------------- +int FTermLinux::shiftCtrlAltKeyCorrection (const int& key_id) +{ + switch ( key_id ) + { + case fc::Fkey_up: + return fc::Fcmkey_sup; // Shift+Ctrl+Meta+Up + + case fc::Fkey_down: + return fc::Fcmkey_sdown; // Shift+Ctrl+Meta+Down + + case fc::Fkey_left: + return fc::Fcmkey_sleft; // Shift+Ctrl+Meta+Left + + case fc::Fkey_right: + return fc::Fcmkey_sright; // Shift+Ctrl+Meta+Right + + case fc::Fkey_ic: + return fc::Fcmkey_sic; // Shift+Ctrl+Meta+Ins + + case fc::Fkey_dc: + return fc::Fcmkey_sdc; // Shift+Ctrl+Meta+Del + + case fc::Fkey_home: + return fc::Fcmkey_shome; // Shift+Ctrl+Meta+Home + + case fc::Fkey_end: + return fc::Fcmkey_send; // Shift+Ctrl+Meta+End + + case fc::Fkey_ppage: + return fc::Fcmkey_sppage; // Shift+Ctrl+Meta+PgUp + + case fc::Fkey_npage: + return fc::Fcmkey_snpage; // Shift+Ctrl+Meta+PgDn + + default: + return key_id; + } +} + +#endif // defined(__linux__) diff --git a/src/ftermopenbsd.cpp b/src/ftermopenbsd.cpp index 468cde27..d070153c 100644 --- a/src/ftermopenbsd.cpp +++ b/src/ftermopenbsd.cpp @@ -27,6 +27,7 @@ kbd_t FTermOpenBSD::wscons_keyboard_encoding = 0; #endif + //---------------------------------------------------------------------- // class FTermOpenBSD //---------------------------------------------------------------------- diff --git a/src/ftermxterminal.cpp b/src/ftermxterminal.cpp index 0656cb03..ece11d9d 100644 --- a/src/ftermxterminal.cpp +++ b/src/ftermxterminal.cpp @@ -868,7 +868,7 @@ const FString* FTermXTerminal::captureXTermTitle() //---------------------------------------------------------------------- void FTermXTerminal::enableXTermMouse() { - // activate the xterm mouse support + // Activate the xterm mouse support if ( mouse_support ) return; @@ -885,7 +885,7 @@ void FTermXTerminal::enableXTermMouse() //---------------------------------------------------------------------- void FTermXTerminal::disableXTermMouse() { - // deactivate the xterm mouse support + // Deactivate the xterm mouse support if ( ! mouse_support ) return; @@ -902,7 +902,7 @@ void FTermXTerminal::disableXTermMouse() //---------------------------------------------------------------------- void FTermXTerminal::enableXTermMetaSendsESC() { - // activate the xterm meta key sends escape prefix + // Activate the xterm meta key sends escape prefix if ( meta_sends_esc ) return; @@ -916,7 +916,7 @@ void FTermXTerminal::enableXTermMetaSendsESC() //---------------------------------------------------------------------- void FTermXTerminal::disableXTermMetaSendsESC() { - // deactivate the xterm meta key sends escape prefix + // Deactivate the xterm meta key sends escape prefix if ( ! meta_sends_esc ) return;