/****************************************************************************** * * * 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 #else #include #endif #ifndef WIN64 #include #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