/******************************************************************************
* *
* T e x t w i n d o w t h a t a l l o w s s i m p l e I / O *
* *
*******************************************************************************
* Copyright (C) 2003-4 by Arthur Norman, Codemist Ltd. All Rights Reserved. *
*******************************************************************************
* This library 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; *
* version 2.1 of the License. *
* *
* This library 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 library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
* *
* See also the FOX Toolkit addendum to the LGPL, which also applies to this *
* code. This addedum gives, in addition to the rights granted by the LGPL, *
* permission to distribute this code statically linked against other code *
* without any need for that other code to have its source released. *
******************************************************************************/
#ifndef FXTERMINAL_H
#define FXTERMINAL_H
/* Signature: 7c908797 03-Jun-2006 */
#include "FXMathText.h"
#include "FXDCNativePrinter.h"
// Include header files that give access to thread primitives.
#ifdef WIN32
#include <windows.h>
#else
#include <pthread.h>
#endif
#ifndef WIN64
#include <unistd.h>
#endif
// Firstly I will define a Mutex. This is something made pretty directly
// available in both Windows and Posix threads. Because of this I will
// just map names using some C macros.
// Mutex m;
// InitMutex(m);
// ... LockMutex(m) ... UnlockMutex(m) ...
// DestroyMutex(m);
// It will often make sense to put calls to DestroyMutex in the destuctor
// for a class where its constructor did the InitMutex.
#ifdef WIN32
typedef CRITICAL_SECTION Mutex;
#define InitMutex(m) InitializeCriticalSection(&m)
#define DestroyMutex(m) DeleteCriticalSection(&m)
#define LockMutex(m) EnterCriticalSection(&m)
#define UnlockMutex(m) LeaveCriticalSection(&m)
#else
typedef pthread_mutex_t Mutex;
#define InitMutex(m) pthread_mutex_init(&m, NULL)
#define DestroyMutex(m) pthread_mutex_destroy(&m)
#define LockMutex(m) pthread_mutex_lock(&m)
#define UnlockMutex(m) pthread_mutex_unlock(&m)
#endif
// signalling from one task to another
#ifdef WIN32
extern HANDLE pipedes;
extern int event_code;
#else
extern int pipedes[2];
#endif
#define PIPE_READ_PORT 0
#define PIPE_WRITE_PORT 1
#if INT_VERSION(FOX_MAJOR,FOX_MINOR,0) == INT_VERSION(1,0,0)
#define FXMenuBar FXMenubar
#endif
extern FXMenuBar *main_menu_bar;
#ifdef CSL
extern char **modules_list, **switches_list;
#endif
extern const char *fwin_maths;
extern "C"
{
extern int showmathInitialised;
}
//
// I derive a sub-class from MainWindow just so I can notice when the
// window is re-sized and record information in the registry.
//
class FXAPI FXMainWindow1 : public FXMainWindow
{
FXDECLARE(FXMainWindow1)
public:
FXMainWindow1(FXApp *, const FXString &, FXIcon *, FXIcon *, FXuint,
FXint,FXint,FXint,FXint,FXint,FXint,FXint,FXint,FXint,FXint);
FXMainWindow1();
virtual void create();
long onConfigure(FXObject *,FXSelector,void *);
};
extern int windowed;
extern const char *colour_spec;
extern FXApp *application_object;
extern FXMainWindow1 *main_window;
extern "C" {
#ifdef WIN32
extern DWORD __stdcall worker_thread(void *);
#else
extern void *worker_thread(void *);
#endif
}
extern FXTimer *timer;
extern char mid_stuff[32], full_title[90];
extern FXFont *selectFont(const char *name, int size,
int weight, int slant, int encoding, int setwidth, int hints);
#ifdef WIN32
extern HANDLE thread1;
#else
extern pthread_t thread1;
#endif
extern int rootWidth, rootHeight;
/// Multiline text widget supporting use as a terminal-window style
/// interface to other worker code.
class FXAPI FXTerminal : FXMathText {
FXDECLARE(FXTerminal)
public:
enum {
STYLE_UNDERLINE = 0x0001, /// Underline text
STYLE_STRIKEOUT = 0x0002, /// Strike out text
STYLE_BOLD = 0x0004, /// bold text
STYLE_PROMPT = 0x0008, /// displayed in alternate colour
STYLE_INPUT = 0x0010, /// displayed in yet another colour
STYLE_MATH = 0x0020, /// mathematics in TeX internal style
STYLE_GREEK = 0x0040 /// displayed in alternate font (sometime?)
};
long onTimeout(FXObject*,FXSelector,void*);
long onCmdInsertNewline(FXObject*,FXSelector,void*);
long onIPC(FXObject*,FXSelector,void*);
long requestFlushBuffer();
long requestSetPrompt();
long requestRequestInput();
long requestWorkerExiting();
long requestRefreshTitle();
long requestShowMath();
#ifdef CSL
long requestSetMenus();
long requestRefreshSwitches();
#endif
long onCmdRead(FXObject *c, FXSelector s, void *ptr);
long onCmdSave(FXObject *c, FXSelector s, void *ptr);
long onCmdSaveSelection(FXObject *c, FXSelector s, void *ptr);
long onCmdToFile(FXObject *c, FXSelector s, void *ptr);
long onCmdPrint(FXObject *c, FXSelector s, void *ptr);
long onCmdPrintSelection(FXObject *c, FXSelector s, void *ptr);
long doPrinting(int startp, int endp);
long onCmdCutSel(FXObject *c, FXSelector s, void *ptr);
long onCmdPasteSel(FXObject *c, FXSelector s, void *ptr);
long onCmdPasteMiddle(FXObject *c, FXSelector s, void *ptr);
long onCmdCopySel(FXObject *c, FXSelector s, void *ptr);
long onCmdReinput(FXObject *c, FXSelector s, void *ptr);
long onCmdClear(FXObject *c, FXSelector s, void *ptr);
long onCmdRedraw(FXObject *c, FXSelector s, void *ptr);
long onCmdHome(FXObject *c, FXSelector s, void *ptr);
long onCmdEnd(FXObject *c, FXSelector s, void *ptr);
long onCmdFont(FXObject *c, FXSelector s, void *ptr);
long onCmdResetFont(FXObject *c, FXSelector s, void *ptr);
long onCmdResetWindow(FXObject *c, FXSelector s, void *ptr);
long onCmdBreak(FXObject *c, FXSelector s, void *ptr);
long onCmdBacktrace(FXObject *c, FXSelector s, void *ptr);
long onCmdPause(FXObject *c, FXSelector s, void *ptr);
long onCmdResume(FXObject *c, FXSelector s, void *ptr);
long onCmdStop(FXObject *c, FXSelector s, void *ptr);
long onCmdDiscard(FXObject *c, FXSelector s, void *ptr);
long onCmdLoadModule(FXObject *c, FXSelector s, void *ptr);
long onCmdFlipSwitch(FXObject *c, FXSelector s, void *ptr);
long onCmdReduceUpdate(FXObject *c, FXSelector s, void *ptr);
long onCmdSelectBrowser(FXObject *c, FXSelector s, void *ptr);
long onCmdHelp(FXObject *c, FXSelector s, void *ptr);
long onCmdAbout(FXObject *c, FXSelector s, void *ptr);
void setEditable(FXbool st = TRUE);
void performPaste(FXchar *, FXint);
int insertFromPaste();
int isStartPrompt(const char *s);
int isStyle(const char *s);
// The next batch are for the "readline-like" input interface
int keyFlags, searchFlags, startMatch, pauseFlags,
historyFirst, historyLast, historyNumber, promptEnd;
unsigned short int searchStack[256];
char searchString[256];
Mutex pauseMutex;
#define ANY_KEYS 1
#define ESC_PENDING 2
#define SEARCH_LENGTH (searchFlags & 0xff)
#define SEARCH_FORWARD 0x100
#define SEARCH_BACKWARD 0x200
#define PAUSE_PAUSE 1
#define PAUSE_STOP 2
#define PAUSE_DISCARD 4
int getHistoryEvent();
int trySearch();
int matchString(const char *p, int n, const char *t);
int editBacktrace();
int editRedisplay();
int editUppercase();
int editCopyRegion();
int editExtendedCommand();
int editObeyCommand();
int editSetMark();
int editMoveLineStart();
int editPrevChar();
int editPrevWord();
int editBreak();
int editCapitalize();
int editDeleteForward();
int editDeleteForwardWord();
int editMoveLineEnd();
int editNextChar();
int editNextWord();
int editStartAgain();
int editDeleteBackward();
int editDeleteBackwardWord();
int editNewline();
int editCutLine();
int editLowercase();
int editHistoryNext();
int editHistoryPrev();
int editSearchHistoryNext();
int editSearchHistoryPrev();
int editUpLine();
int editTranspose();
int editDeleteLastWord();
int editPaste();
int editRotateClipboard();
int editEscape();
int editReinput();
int editUndo();
int editCopyPreviousWord();
int setInputText(const FXchar *text, int n);
int charForShowMath();
void insertMathsLines();
void recordBoxAddress(int n, union Box *b);
union Box *getBoxAddress(int n) const;
enum { // used with signalling
FLUSH_BUFFER,
SET_PROMPT,
REQUEST_INPUT,
MINIMIZE_MAIN,
RESTORE_MAIN,
WORKER_EXITING,
REFRESH_TITLE,
SHOW_MATH,
#ifdef CSL
SET_MENUS,
REFRESH_SWITCHES,
#endif
DUMMY_MESSAGE
};
enum {
ID_IPC=FXMathText::ID_LAST,
ID_TIMEOUT,
ID_READ,
ID_SAVE,
ID_SAVE_SELECTION,
ID_TO_FILE,
ID_PRINT,
ID_PRINT_SELECTION,
ID_CUT_SEL_X, // NB exists in FXMathText but here I will want to...
ID_PASTE_SEL_X, // adjust the cursor position as I go.
ID_COPY_SEL_X,
ID_REINPUT,
// ID_SELECT_ALL, // done by the underlying FXMathText
ID_CLEAR,
ID_REDRAW,
ID_HOME,
ID_END,
ID_FONT,
ID_RESET_FONT,
ID_RESET_WINDOW,
ID_BREAK,
ID_BACKTRACE,
ID_PAUSE,
ID_RESUME,
ID_STOP,
ID_DISCARD,
ID_BROWSER,
ID_HELP,
ID_ABOUT,
#ifdef CSL
ID_LOAD_MODULE,
ID_FLIP_SWITCH,
ID_REDUCE_UPDATE,
#endif
ID_LAST
};
void calcVisRows(FXint startline,FXint endline);
void drawContents(FXDCWindow& dc,FXint x,FXint y,FXint w,FXint h) const;
void drawTextRow(FXDCWindow& dc,FXint line,FXint left,FXint right) const;
void drawBufferText(FXDCWindow &dc, FXint x, FXint y,
FXint w, FXint h, FXint pos, FXint n,
FXuint style) const;
int cmrFontsEmbedded; // Used in ShowMath case
int printBufferText(FXDCNativePrinter &dc, FXint x, FXint y,
char *str, FXint n,
FXuint style);
int printTextRow(FXDCNativePrinter &dc, int p, int y, int left, int right);
void printContents(FXDCNativePrinter &dc, int startpos, int endpos,
int left, int right, int top, int bottom);
/// Construct multi-line text widget
FXTerminal(FXComposite *p, FXObject* tgt=NULL, FXSelector sel=0,
FXuint opts=0, FXint x=0, FXint y=0, FXint w=0, FXint h=0);
virtual void create();
/// Change text font
void setFont(FXFont* fnt);
/// forces everything to 80 columns
int forceWidth();
/// enable or disable text styles
void setStyled(FXbool st=TRUE);
/// Change number of visible rows
void setVisibleRows(FXint rows);
/// Change number of visible columns
void setVisibleColumns(FXint cols);
/// Append n characters of text at the end of the buffer
void appendText(const FXchar *text,FXint n,FXbool notify=FALSE);
/// Append n characters of text at the end of the buffer
void appendStyledText(const FXchar *text,FXint n,
FXint style=0,FXbool notify=FALSE);
/// Handle keyboard input
long onKeyPress(FXObject *,FXSelector, void *);
/// Test if editable
FXbool isEditable();
int isEditableForBackspace();
/// Destructor
virtual ~FXTerminal();
FXTimer *timer;
void setupShowMath();
void reportDestroy(int p);
int sync_even;
Mutex mutex1, mutex2, mutex3, mutex4;
FILE *logfile;
void type_ahead(int c);
void string_ahead(const char *s);
// I will have a buffer for transfer of characters from the application
// to the user-interface. Use of printf-like things is a bit delicate
// because buffer overflow in vsprintf is a danger. I allow a margin
// of length (200).
// When I (eventually) gain confidence in C99 I will use vsnprintf and
// be safer.
#define FWIN_BUFFER_SIZE 1000
#define SPARE_FOR_VFPRINTF 200
char fwin_buffer[FWIN_BUFFER_SIZE];
// The following two are used by both worker and interface tasks, and so
// over-clever compiler optimisation of them is undesirable.
//
// fwin_in belongs to the worker thread, while fwin_out is owned by the
// user interface. Each will use read-only access to the other (unless the
// two are synchronised, in which case full access is permitted). I will
// assume that my hardware makes simple reads and writes of these variables
// atomic.
volatile int fwin_in, fwin_out;
#define INPUT_BUFFER_LENGTH 256
int inputBufferLen;
int inputBufferP;
char inputBuffer[INPUT_BUFFER_LENGTH];
int recently_flushed;
int argc;
char **argv;
#ifdef WIN32
DWORD worker_thread(void *);
#else
void *worker_thread(void *);
#endif
int lineSpacing;
FXColor promptColor; // prompt string colour
FXColor inputColor; // input text colour
FXTerminal();
};
extern "C"
{
extern FXTerminal *text;
}
#ifdef WIN32
#define DEFAULT_FONT_NAME "Courier New"
#else
#define DEFAULT_FONT_NAME "courier"
#endif
#endif
// end of FXTerminal.h