2017-11-04 07:03:53 +01:00
|
|
|
/***********************************************************************
|
|
|
|
* foptimove.cpp - Cursor movement optimization *
|
|
|
|
* *
|
|
|
|
* This file is part of the Final Cut widget toolkit *
|
|
|
|
* *
|
2018-01-02 20:38:45 +01:00
|
|
|
* Copyright 2015-2018 Markus Gans *
|
2017-11-04 07:03:53 +01:00
|
|
|
* *
|
|
|
|
* The Final Cut is free software; you can redistribute it and/or *
|
|
|
|
* modify it under the terms of the GNU Lesser General Public License *
|
|
|
|
* as published by the Free Software Foundation; either version 3 of *
|
|
|
|
* the License, or (at your option) any later version. *
|
|
|
|
* *
|
|
|
|
* The Final Cut is distributed in the hope that it will be useful, *
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
|
|
* GNU Lesser General Public License for more details. *
|
|
|
|
* *
|
|
|
|
* You should have received a copy of the GNU Lesser General Public *
|
|
|
|
* License along with this program. If not, see *
|
|
|
|
* <http://www.gnu.org/licenses/>. *
|
|
|
|
***********************************************************************/
|
2017-10-02 07:32:33 +02:00
|
|
|
|
|
|
|
/* Standalone class
|
|
|
|
* ════════════════
|
|
|
|
*
|
|
|
|
* ▕▔▔▔▔▔▔▔▔▔▔▔▏
|
|
|
|
* ▕ FOptiMove ▏
|
|
|
|
* ▕▁▁▁▁▁▁▁▁▁▁▁▏
|
|
|
|
*/
|
2015-09-25 21:37:19 +02:00
|
|
|
|
2015-12-21 18:37:20 +01:00
|
|
|
// The cursor optimization based on ncurses lib_mvcur.c
|
2015-05-23 13:35:12 +02:00
|
|
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
2017-04-09 20:08:53 +02:00
|
|
|
#ifndef FOPTIMOVE_H
|
|
|
|
#define FOPTIMOVE_H
|
2015-05-23 13:35:12 +02:00
|
|
|
|
2017-10-31 00:41:59 +01:00
|
|
|
#if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT)
|
|
|
|
#error "Only <final/final.h> can be included directly."
|
|
|
|
#endif
|
|
|
|
|
2015-05-23 13:35:12 +02:00
|
|
|
#include <assert.h>
|
2017-12-17 01:06:53 +01:00
|
|
|
|
|
|
|
#if defined(__sun) && defined(__SVR4)
|
|
|
|
#include <termio.h>
|
|
|
|
typedef struct termio SGTTY;
|
|
|
|
typedef struct termios SGTTYS;
|
|
|
|
|
|
|
|
#ifdef _LP64
|
|
|
|
typedef unsigned int chtype;
|
|
|
|
#else
|
|
|
|
typedef unsigned long chtype;
|
2018-09-20 23:59:01 +02:00
|
|
|
#endif // _LP64
|
2017-12-17 01:06:53 +01:00
|
|
|
|
|
|
|
#include <term.h> // need for tparm
|
|
|
|
#else
|
|
|
|
#include <term.h> // need for tparm
|
2018-09-20 23:59:01 +02:00
|
|
|
#endif // defined(__sun) && defined(__SVR4)
|
2015-05-23 13:35:12 +02:00
|
|
|
|
|
|
|
#include <cctype>
|
2016-12-11 16:42:50 +01:00
|
|
|
#include <climits>
|
2015-05-23 13:35:12 +02:00
|
|
|
#include <cstdio> // need for printf
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <cstring>
|
2017-08-27 09:50:30 +02:00
|
|
|
#include <iostream>
|
2015-05-23 13:35:12 +02:00
|
|
|
|
2018-05-06 21:41:55 +02:00
|
|
|
#include "final/ftypes.h"
|
2015-09-25 21:37:19 +02:00
|
|
|
|
2018-09-20 23:59:01 +02:00
|
|
|
namespace finalcut
|
|
|
|
{
|
|
|
|
|
2015-05-23 13:35:12 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// class FOptiMove
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
#pragma pack(push)
|
|
|
|
#pragma pack(1)
|
|
|
|
|
|
|
|
class FOptiMove
|
|
|
|
{
|
2017-09-11 03:06:02 +02:00
|
|
|
public:
|
2018-07-01 14:48:53 +02:00
|
|
|
// Typedef
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
bool automatic_left_margin;
|
|
|
|
bool eat_nl_glitch;
|
|
|
|
int tabstop;
|
|
|
|
char* t_cursor_home;
|
|
|
|
char* t_carriage_return;
|
|
|
|
char* t_cursor_to_ll;
|
|
|
|
char* t_tab;
|
|
|
|
char* t_back_tab;
|
|
|
|
char* t_cursor_up;
|
|
|
|
char* t_cursor_down;
|
|
|
|
char* t_cursor_left;
|
|
|
|
char* t_cursor_right;
|
|
|
|
char* t_cursor_address;
|
|
|
|
char* t_column_address;
|
|
|
|
char* t_row_address;
|
|
|
|
char* t_parm_up_cursor;
|
|
|
|
char* t_parm_down_cursor;
|
|
|
|
char* t_parm_left_cursor;
|
|
|
|
char* t_parm_right_cursor;
|
|
|
|
char* t_erase_chars;
|
|
|
|
char* t_repeat_char;
|
|
|
|
char* t_clr_bol;
|
|
|
|
char* t_clr_eol;
|
|
|
|
} termEnv;
|
|
|
|
|
2017-09-11 03:06:02 +02:00
|
|
|
// Constructor
|
|
|
|
explicit FOptiMove (int = 0);
|
|
|
|
|
|
|
|
// Destructor
|
|
|
|
~FOptiMove();
|
|
|
|
|
2018-03-28 00:03:57 +02:00
|
|
|
// Accessors
|
|
|
|
const char* getClassName() const;
|
2018-07-01 14:48:53 +02:00
|
|
|
uInt getCursorHomeLength() const;
|
|
|
|
uInt getCarriageReturnLength() const;
|
|
|
|
uInt getCursorToLLLength() const;
|
|
|
|
uInt getTabLength() const;
|
|
|
|
uInt getBackTabLength() const;
|
|
|
|
uInt getCursorUpLength() const;
|
|
|
|
uInt getCursorDownLength() const;
|
|
|
|
uInt getCursorLeftLength() const;
|
|
|
|
uInt getCursorRightLength() const;
|
|
|
|
uInt getCursorAddressLength() const;
|
|
|
|
uInt getColumnAddressLength() const;
|
|
|
|
uInt getRowAddressLength() const;
|
|
|
|
uInt getParmUpCursorLength() const;
|
|
|
|
uInt getParmDownCursorLength() const;
|
|
|
|
uInt getParmLeftCursorLength() const;
|
|
|
|
uInt getParmRightCursorLength() const;
|
|
|
|
uInt getEraseCharsLength() const;
|
|
|
|
uInt getRepeatCharLength() const;
|
|
|
|
uInt getClrBolLength() const;
|
|
|
|
uInt getClrEolLength() const;
|
2018-03-28 00:03:57 +02:00
|
|
|
|
2017-09-11 03:06:02 +02:00
|
|
|
// Mutators
|
|
|
|
void setBaudRate (int);
|
|
|
|
void setTabStop (int);
|
|
|
|
void setTermSize (int, int);
|
2018-07-01 14:48:53 +02:00
|
|
|
void setTermEnvironment (termEnv&);
|
|
|
|
void set_cursor_home (char[]);
|
|
|
|
void set_cursor_to_ll (char[]);
|
|
|
|
void set_carriage_return (char[]);
|
|
|
|
void set_tabular (char[]);
|
|
|
|
void set_back_tab (char[]);
|
|
|
|
void set_cursor_up (char[]);
|
|
|
|
void set_cursor_down (char[]);
|
|
|
|
void set_cursor_left (char[]);
|
|
|
|
void set_cursor_right (char[]);
|
|
|
|
void set_cursor_address (char[]);
|
|
|
|
void set_column_address (char[]);
|
|
|
|
void set_row_address (char[]);
|
|
|
|
void set_parm_up_cursor (char[]);
|
|
|
|
void set_parm_down_cursor (char[]);
|
|
|
|
void set_parm_left_cursor (char[]);
|
|
|
|
void set_parm_right_cursor (char[]);
|
|
|
|
void set_erase_chars (char[]);
|
|
|
|
void set_repeat_char (char[]);
|
|
|
|
void set_clr_bol (char[]);
|
|
|
|
void set_clr_eol (char[]);
|
2017-09-11 03:06:02 +02:00
|
|
|
void set_auto_left_margin (const bool&);
|
|
|
|
void set_eat_newline_glitch (const bool&);
|
|
|
|
|
|
|
|
// Methods
|
2018-03-28 00:03:57 +02:00
|
|
|
void check_boundaries (int&, int&, int&, int&);
|
2017-09-11 03:06:02 +02:00
|
|
|
char* moveCursor (int, int, int, int);
|
|
|
|
void printDurations();
|
|
|
|
|
|
|
|
private:
|
2018-01-05 00:49:00 +01:00
|
|
|
// Constant
|
|
|
|
static const std::size_t BUF_SIZE = 512;
|
|
|
|
|
2018-05-06 21:41:55 +02:00
|
|
|
// Typedef
|
2017-09-11 03:06:02 +02:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
char* cap;
|
|
|
|
int duration;
|
|
|
|
int length;
|
|
|
|
} capability;
|
|
|
|
|
|
|
|
// Constants
|
|
|
|
static const int LONG_DURATION = INT_MAX;
|
|
|
|
// value for a long capability waiting time
|
|
|
|
static const int MOVE_LIMIT = 7;
|
|
|
|
// maximum character distance to avoid direct cursor addressing
|
|
|
|
|
|
|
|
// Methods
|
|
|
|
void calculateCharDuration();
|
2017-12-19 02:06:27 +01:00
|
|
|
int capDuration (char[], int);
|
2017-09-11 03:06:02 +02:00
|
|
|
int capDurationToLength (int);
|
2018-01-02 20:38:45 +01:00
|
|
|
int repeatedAppend (const capability&, volatile int, char*);
|
2017-12-19 02:06:27 +01:00
|
|
|
int relativeMove (char[], int, int, int, int);
|
2018-01-03 22:58:07 +01:00
|
|
|
int verticalMove (char[], int, int);
|
2018-02-10 17:35:09 +01:00
|
|
|
void downMove (char[], int&, int, int);
|
|
|
|
void upMove (char[], int&, int, int);
|
2018-01-03 22:58:07 +01:00
|
|
|
int horizontalMove (char[], int, int);
|
2018-02-10 17:35:09 +01:00
|
|
|
void rightMove (char[], int&, int, int);
|
|
|
|
void leftMove (char[], int&, int, int);
|
|
|
|
|
2017-09-11 03:06:02 +02:00
|
|
|
bool isWideMove (int, int, int, int);
|
2017-11-26 19:00:04 +01:00
|
|
|
bool isMethod0Faster (int&, int, int);
|
|
|
|
bool isMethod1Faster (int&, int, int, int, int);
|
|
|
|
bool isMethod2Faster (int&, int, int, int);
|
|
|
|
bool isMethod3Faster (int&, int, int);
|
|
|
|
bool isMethod4Faster (int&, int, int);
|
|
|
|
bool isMethod5Faster (int&, int, int, int);
|
|
|
|
void moveByMethod (int, int, int, int, int);
|
2017-09-11 03:06:02 +02:00
|
|
|
|
|
|
|
// Data Members
|
2018-01-05 00:49:00 +01:00
|
|
|
capability F_cursor_home;
|
|
|
|
capability F_carriage_return;
|
|
|
|
capability F_cursor_to_ll;
|
|
|
|
capability F_tab;
|
|
|
|
capability F_back_tab;
|
|
|
|
capability F_cursor_up;
|
|
|
|
capability F_cursor_down;
|
|
|
|
capability F_cursor_left;
|
|
|
|
capability F_cursor_right;
|
|
|
|
capability F_cursor_address;
|
|
|
|
capability F_column_address;
|
|
|
|
capability F_row_address;
|
|
|
|
capability F_parm_up_cursor;
|
|
|
|
capability F_parm_down_cursor;
|
|
|
|
capability F_parm_left_cursor;
|
|
|
|
capability F_parm_right_cursor;
|
|
|
|
capability F_erase_chars;
|
|
|
|
capability F_repeat_char;
|
|
|
|
capability F_clr_bol;
|
|
|
|
capability F_clr_eol;
|
|
|
|
|
|
|
|
bool automatic_left_margin;
|
|
|
|
bool eat_nl_glitch;
|
|
|
|
|
|
|
|
char move_buf[BUF_SIZE];
|
|
|
|
int char_duration;
|
|
|
|
int baudrate;
|
|
|
|
int tabstop;
|
|
|
|
int screen_width;
|
|
|
|
int screen_height;
|
2015-05-23 13:35:12 +02:00
|
|
|
};
|
|
|
|
#pragma pack(pop)
|
|
|
|
|
|
|
|
|
|
|
|
// FOptiMove inline functions
|
2018-03-28 00:03:57 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline const char* FOptiMove::getClassName() const
|
|
|
|
{ return "FOptiMove"; }
|
|
|
|
|
2018-07-01 14:48:53 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline uInt FOptiMove::getCursorHomeLength() const
|
|
|
|
{ return uInt(F_cursor_home.length); }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline uInt FOptiMove::getCarriageReturnLength() const
|
|
|
|
{ return uInt(F_carriage_return.length); }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline uInt FOptiMove::getCursorToLLLength() const
|
|
|
|
{ return uInt(F_cursor_to_ll.length); }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline uInt FOptiMove::getTabLength() const
|
|
|
|
{ return uInt(F_tab.length); }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline uInt FOptiMove::getBackTabLength() const
|
|
|
|
{ return uInt(F_back_tab.length); }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline uInt FOptiMove::getCursorUpLength() const
|
|
|
|
{ return uInt(F_cursor_up.length); }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline uInt FOptiMove::getCursorDownLength() const
|
|
|
|
{ return uInt(F_cursor_down.length); }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline uInt FOptiMove::getCursorLeftLength() const
|
|
|
|
{ return uInt(F_cursor_left.length); }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline uInt FOptiMove::getCursorRightLength() const
|
|
|
|
{ return uInt(F_cursor_right.length); }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline uInt FOptiMove::getCursorAddressLength() const
|
|
|
|
{ return uInt(F_cursor_address.length); }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline uInt FOptiMove::getColumnAddressLength() const
|
|
|
|
{ return uInt(F_column_address.length); }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline uInt FOptiMove::getRowAddressLength() const
|
|
|
|
{ return uInt(F_row_address.length); }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline uInt FOptiMove::getParmUpCursorLength() const
|
|
|
|
{ return uInt(F_parm_up_cursor.length); }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline uInt FOptiMove::getParmDownCursorLength() const
|
|
|
|
{ return uInt(F_parm_down_cursor.length); }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline uInt FOptiMove::getParmLeftCursorLength() const
|
|
|
|
{ return uInt(F_parm_left_cursor.length); }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline uInt FOptiMove::getParmRightCursorLength() const
|
|
|
|
{ return uInt(F_parm_right_cursor.length); }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline uInt FOptiMove::getEraseCharsLength() const
|
|
|
|
{ return uInt(F_erase_chars.length); }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline uInt FOptiMove::getRepeatCharLength() const
|
|
|
|
{ return uInt(F_repeat_char.length); }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline uInt FOptiMove::getClrBolLength() const
|
|
|
|
{ return uInt(F_clr_bol.length); }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline uInt FOptiMove::getClrEolLength() const
|
|
|
|
{ return uInt(F_clr_eol.length); }
|
|
|
|
|
2015-05-23 13:35:12 +02:00
|
|
|
//----------------------------------------------------------------------
|
2017-09-11 03:06:02 +02:00
|
|
|
inline void FOptiMove::set_auto_left_margin (const bool& bcap)
|
2015-05-23 13:35:12 +02:00
|
|
|
{ automatic_left_margin = bcap; }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2017-09-11 03:06:02 +02:00
|
|
|
inline void FOptiMove::set_eat_newline_glitch (const bool& bcap)
|
2015-05-23 13:35:12 +02:00
|
|
|
{ eat_nl_glitch = bcap; }
|
|
|
|
|
2018-09-20 23:59:01 +02:00
|
|
|
} // namespace finalcut
|
|
|
|
|
2017-04-09 20:08:53 +02:00
|
|
|
#endif // FOPTIMOVE_H
|