finalcut/src/ftermfreebsd.cpp
2019-07-29 02:34:58 +02:00

244 lines
6.8 KiB
C++

/***********************************************************************
* ftermfreebsd.cpp - Contains the FreeBSD terminal functions *
* *
* This file is part of the Final Cut widget toolkit *
* *
* Copyright 2018-2019 Markus Gans *
* *
* The Final Cut is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public License *
* as published by the Free Software Foundation; either version 3 of *
* the License, or (at your option) any later version. *
* *
* The Final Cut is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this program. If not, see *
* <http://www.gnu.org/licenses/>. *
***********************************************************************/
#include "final/fcharmap.h"
#include "final/fsystem.h"
#include "final/fterm.h"
#include "final/ftermfreebsd.h"
#include "final/ftypes.h"
namespace finalcut
{
// static class attributes
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(UNIT_TEST)
uInt FTermFreeBSD::bsd_alt_keymap = 0;
FTermFreeBSD::CursorStyle FTermFreeBSD::cursor_style = fc::normal_cursor;
bool FTermFreeBSD::change_cursorstyle = true;
bool FTermFreeBSD::meta_sends_escape = true;
FSystem* FTermFreeBSD::fsystem = nullptr;
#endif
//----------------------------------------------------------------------
// class FTermFreeBSD
//----------------------------------------------------------------------
// public methods of FTermFreeBSD
//----------------------------------------------------------------------
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(UNIT_TEST)
FTermFreeBSD::CursorStyle FTermFreeBSD::getCursorStyle()
{
return cursor_style;
}
//----------------------------------------------------------------------
bool FTermFreeBSD::setCursorStyle (CursorStyle style, bool hidden)
{
// Set cursor style in a BSD console
if ( ! fsystem || ! isFreeBSDConsole() || ! change_cursorstyle )
return false;
cursor_style = style;
if ( hidden )
return false;
if ( fsystem->ioctl(0, CONS_CURSORTYPE, &style) == 0 )
return true;
else
return false;
}
//----------------------------------------------------------------------
bool FTermFreeBSD::isFreeBSDConsole()
{
// Check if it's a FreeBSD console
keymap_t keymap{};
if ( fsystem && fsystem->ioctl(0, GIO_KEYMAP, &keymap) == 0 )
return true;
else
return false;
}
//----------------------------------------------------------------------
void FTermFreeBSD::setBeep (int Hz, int ms)
{
if ( ! FTerm::isFreeBSDTerm() )
return;
// range for frequency: 21-32766
if ( Hz < 21 || Hz > 32766 )
return;
// range for duration: 0-1999
if ( ms < 0 || ms > 1999 )
return;
constexpr int timer_frequency = 1193182;
int period = timer_frequency / Hz;
ms /= 10;
FTerm::putstringf ( CSI "=%d;%dB", period, ms );
std::fflush(stdout);
}
//----------------------------------------------------------------------
void FTermFreeBSD::resetBeep()
{
if ( ! FTerm::isFreeBSDTerm() )
return;
// default frequency: 1491 Hz
// default duration: 50 ms
FTerm::putstring ( CSI "=800;5B" );
std::fflush(stdout);
}
//----------------------------------------------------------------------
void FTermFreeBSD::init()
{
// initialize BSD console
fsystem = FTerm::getFSystem();
if ( ! isFreeBSDConsole() )
return;
if ( meta_sends_escape )
{
// save current left alt key mapping
saveFreeBSDAltKey();
// map meta key to left alt key
setFreeBSDAlt2Meta();
}
if ( change_cursorstyle )
{
// Initialize FreeBSD console cursor
setCursorStyle (fc::destructive_cursor, true);
}
}
//----------------------------------------------------------------------
void FTermFreeBSD::initCharMap (uInt char_map[][fc::NUM_OF_ENCODINGS])
{
// A FreeBSD console can't show ASCII codes from 0x00 to 0x1b
if ( ! isFreeBSDConsole() )
return;
for (std::size_t i = 0; i <= fc::lastCharItem; i++)
if ( char_map[i][fc::PC] < 0x1c )
char_map[i][fc::PC] = char_map[i][fc::ASCII];
}
//----------------------------------------------------------------------
void FTermFreeBSD::finish()
{
// Resetting the FreeBSD console settings
if ( ! isFreeBSDConsole() )
return;
if ( meta_sends_escape )
resetFreeBSDAlt2Meta();
setCursorStyle (fc::normal_cursor, false);
}
//----------------------------------------------------------------------
void FTermFreeBSD::restoreCursorStyle()
{
// Reset to the last used FreeBSD console cursor style
setCursorStyle (getCursorStyle(), false);
}
// private methods of FTermFreeBSD
//----------------------------------------------------------------------
bool FTermFreeBSD::saveFreeBSDAltKey()
{
// Saving the current mapping for the alt key
static constexpr int left_alt = 0x38;
int ret = -1;
keymap_t keymap{};
if ( fsystem )
ret = fsystem->ioctl (0, GIO_KEYMAP, &keymap);
if ( ret < 0 )
return false;
// save current mapping
bsd_alt_keymap = keymap.key[left_alt].map[0];
return true;
}
//----------------------------------------------------------------------
bool FTermFreeBSD::setFreeBSDAltKey (uInt key)
{
// Remapping the alt key
static constexpr int left_alt = 0x38;
int ret = -1;
keymap_t keymap{};
if ( fsystem )
ret = fsystem->ioctl (0, GIO_KEYMAP, &keymap);
if ( ret < 0 )
return false;
// Mapping "key" on the left alt key
keymap.key[left_alt].map[0] = key;
if ( (keymap.n_keys > 0)
&& fsystem && (fsystem->ioctl(0, PIO_KEYMAP, &keymap) < 0) )
return false;
else
return true;
}
//----------------------------------------------------------------------
bool FTermFreeBSD::setFreeBSDAlt2Meta()
{
// Use the meta key when pressing the Alt key
return setFreeBSDAltKey (META);
}
//----------------------------------------------------------------------
bool FTermFreeBSD::resetFreeBSDAlt2Meta()
{
// Restore the alt key mapping
return setFreeBSDAltKey (bsd_alt_keymap);
}
#endif // defined(__FreeBSD__) || defined(__DragonFly__) || defined(UNIT_TEST)
} // namespace finalcut