/*
* "fwin.h" 2003-2007, A C Norman
*
* This defines the public interface supported by the "fwin" window
* interface.
*
*/
/******************************************************************************
* 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. *
******************************************************************************/
/*
* The code here is provides a windowed framework in which reasonably
* ordinary C code can run. The functions described here are the
* interface. The code is built on and relies upon the Fox Toolkit
* and an associated threads package: by virtue of that it is expected
* to be reasonably cross-platform portable, and in particular it supports
* Linux and Windows (via MinGW32). It is (somewhat) modelled on an earlier
* windowed framwork that I had that I called "cwin". Cwin was built using
* the Microsoft Foundation Classes and only ran on Windows.
*/
/* Signature: 220b05b2 18-Mar-2008 */
#ifndef header_fwin_h
#define header_fwin_h 1
#include <stdarg.h>
#include <stdlib.h>
/*
* I use 'extern "C"' for the entrypoints here so that even though the
* code for fwin itself is all in C++ it is callable without any fuss
* from plain old-fashioned C code.
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef MS_CDECL
#ifdef _MSC_VER
/*
* With the Microsoft Compilers I may have set some other calling convention
* as default, and then for these I must explicitly use the ordinary one.
*/
#define MS_CDECL __cdecl
#else
#define MS_CDECL
#endif
#endif
/*
* The "C" code will eventually be entered at fwin_main() in what looks like a
* normal way.
*/
extern int fwin_main(int argc, char *argv[]);
/*
* fwin_full_program_name is a string like "d:\xxx\yyy\something.exe" This is
* made available so that applications can edit it to generate names of
* resource files (eg by just altering the ".exe" bit on the end into some
* other suffix. I will try to find a full path for the executable on
* Unix too.
*/
extern const char *fwin_full_program_name;
/*
* programName holds just the "something" out of fwin_full_program_name.
* Note that I impose an arbitrary limit on the length of the name of the
* executable.
*/
extern const char *programName;
/*
* programDir gives the directory from which this application was launched.
* If you try to put your executables in a directory with a very long path,
* or possibly in a path that has really funny characters in in, you do so
* at your own risk!
*/
extern const char *programDir;
/*
* This returns bits that indicates what options fwin is running with:
*
* 0 A plain command-line system in circumstances where I do not do any
* local editing or special trapping of ^C. I just leave the
* underlying operating system to do all that, to the extent that it
* will. This is used if stdin/stdout are not directly connected to
* a terminal or if the terminal does not seem to support cursor
* addressability.
* 1 A command-line version, but where I use raw keyboard access and
* cursor-addressible terminal output to support local editing and
* a simple history mechanism styles after the GNU readline model.
* 2 Running in a window with character input via window events and a
* GNU readline-like set of local editing facilities.
*/
#define FWIN_WITH_TERMED 1
#define FWIN_IN_WINDOW 2
extern int fwin_windowmode();
/*
* Normally in SOME circumstances (at present just when wanting to do
* displayed maths) my code will use Xft and client-side font rendering.
* To dsaible that option a program can set fwin_use_xft to 0.
*/
extern int fwin_use_xft;
/*
* To finish off you can either return from fwin_main(), or you can go
* fwin_exit(n);
* The system will forcibly close down for you if the EXIT item on
* the FILE menu or the CLOSE item on the SYSTEM menu gets selected. But
* direct use of the C function "exit()" is not considered proper.
*/
extern void fwin_exit(int return_code);
/*
* If, when the program is stopping, fwin_pause_at_end has been set to
* be non-zero (by default it will be zero) then an alert box is displayed
* forcing the user to give positive confirmation before the main window
* is closed. This does not give an opportunity to cancel the exit, just to
* read the final state of the screen... This effect does not occur if
* program exit is caused by selecting EXIT from the FILE menu or CLOSE
* from the system menu. That is (deliberate in my code) because in those
* cases the user has taken explicit interactive action to terminate the
* program so an extra prompt seems unnecessary.
*/
extern int fwin_pause_at_end;
/*
* fwin_minimize() indicates that the window should be shrunk to be just
* an icon.
* NOTE that if the command-line arguments to an application include
* "--", "-f" or "-F" then the application will be started off minimised.
* this is ugly and represents ways that options I want for *MY* application
* have crept in where things ought to be generic. My reasoning at one
* stage was that I wanted the window to eb minimised right from the start
* so letting my code begin and then calling fwin_minimize would not be
* so good.
*/
extern void fwin_minimize(void);
/*
* fwin_restore() indicates that the window should be restored to
* regular size.
*/
extern void fwin_restore(void);
/*
* Rather than using putchar() and printf(), here are the calls
* the can be made to get output onto the screen. NOTE that fwin_puts()
* is more like fputs than puts in that it just dumps the characters in its
* string to the screen [it does not add an extra newline in the way that
* puts does].
* These functions support printable ASCII characters.
* I have not thought too hard about TAB and FormFeed here... yet.
*/
extern void fwin_putchar(int c);
extern void fwin_puts(const char *s);
extern void fwin_showmath(const char *s);
extern void MS_CDECL fwin_printf(const char *fmt, ...);
extern void fwin_vfprintf(const char *fmt, va_list a);
/*
* fwin_linelength holds the number of normal-sized (ie the basic
* fixed-pitch font being used) characters that fit across the screen.
* Its value can change at any time if the user re-sizes the window.
* When the screen is minimized its value will remain at the pre-minimized
* value. An attempt is made to create the initial window to make this
* have the value 80. Actually just at preesent fwin insists on keeping
* its window at a width of 80 so this value will never change!
*/
extern int fwin_linelength;
/*
* ensure_screen() causes the display to catch up with whatever else has
* been going on.
*/
extern void fwin_ensure_screen(void);
/*
* fwin_getchar() behaves rather as one might expect getchar() to - it
* grabs a character from the keyboard input buffer.
*/
extern int fwin_getchar(void);
/*
* fwin_set_prompt() tells fwin what string (of up to some limited
* number of characters) should be used as a prompt.
*/
#ifndef MAX_PROMPT_LENGTH
# define MAX_PROMPT_LENGTH 80
#endif
extern void fwin_set_prompt(const char *s);
/*
* Clears screen.
*/
extern void fwin_clear_screen();
/*
* Returns window size (measured in character positions) packed as
* (width << 16) + height
*/
extern int fwin_screen_size();
/*
* fwin will call the function passed here before (with an arg of 1)
* and after (with an arg of 0) any time it is liable to delay. In
* particular when it might be about to block waiting for keyboard
* input. The idea is that this can be used to help the caller discount
* time spent in such cases.
*/
typedef void delay_callback_t(int);
extern void fwin_callback_on_delay(delay_callback_t *f);
/*
* fwin will call the function passed here to try to signal an
* exception to the worker thread. The idea is that the user-passed
* function can then do whatever it takes to synchronise with the
* worker. It can either signal the worker thread (but note that you need
* to do a bit of background reading before you try to mix exceptions
* and threads), or it can set a simple flag and the worker can poll.
*
* The intent is that if it passes QUIET_INTERRUPT or NOISY_INTERRUPT the
* worker is interrupted without or with it giving messages (eg a
* backtrace). If QUERY_INTERRUPT is passed no exception is raised, but
* the expectation is that 0 is returned if the previous exception has
* now been accepted and processed.
* The case TICK_INTERRUPT is to be triggered roughly every second to
* give the worket thread a chance to do any chores. It is NOT intended
* to disrupt the main thread of the computation.
*
* If fwin detects an interrupt condition while it is waiting for keyboard
* input or if it has generated an interrupt just before the start of
* such a wait and a QUERY_INTERRUPT call indicates that its interrupt
* request is still pending then as well as the activation of the callback
* function fwin_getchar returns promptly, discarding any typed-ahead
* stuff and returning character code 3 ("^C").
*
* If the callback function tries to raise exceptions etc then great care
* may be needed to ensure it can not abort the worker in the middle of
* a handshake where it synchronizes with the GUI thread. Hmm yet more
* thought is called for here!
*/
#define QUERY_INTERRUPT 0
#define TICK_INTERRUPT 1
#define QUIET_INTERRUPT 2
#define NOISY_INTERRUPT 3
typedef int interrupt_callback_t(int);
extern void fwin_callback_to_interrupt(interrupt_callback_t *f);
/*
* When a TICK is handed to the user the following should be called
* to confirm that it has been seen.
*/
extern void fwin_acknowledge_tick();
#ifdef CSL
/*
* The following is just for use by REDUCE. It adjusts menu entries
* to support loading packages and setting/clearing REDUCE switches.
* So observe that if you want to use this you must #define CSL to pretend
* you are my own customised application.
*/
extern void fwin_menus(char **modules, char **switches);
/*
* The next is used when the application has re-set some switches without the
* GUI's help, and it updates the menu
*/
extern void fwin_refresh_switches(char **switches, char **packages);
#endif
/*
* Short messages can be displayed at the left middle and right of the
* main title-ribbon of your window. These functions set the text to be
* displayed there. If there is not much room then only the middle one
* will remain visible. Each message should be limited to around 30 chars
* (and will be best if kept shorter than that). The default position was
* once that the left position displayed the time & date (but it is
* now left blank), the middle one the name of the program being run and
* the right one is blank. fwin_report_left(NULL) or fwin_report_mid(NULL)
* re-instate the default display. Use fwin_report_left("") is a yet clearer
* way of indicating that blank info to the left is required.
*/
extern void fwin_report_left(const char *msg);
extern void fwin_report_mid(const char *msg);
extern void fwin_report_right(const char *msg);
/*
* The following four strings may be updated (but PLEASE keep within the
* length limit) to make the display in the "ABOUT" box reflect your
* particular application.
*/
extern char about_box_title[32]; /* "About XXX"; */
extern char about_box_description[32]; /* "XXX version 1.1"; */
/* <icon appears here> */
extern char about_box_rights_1[32]; /* "Copyright Whoever"; */
extern char about_box_rights_2[32]; /* "Date or whatever"; */
extern char about_box_rights_3[32]; /* "Credit to FOX"; */
/*
* The HELP drop-down menu in fwin always has some basic items on it, but
* the user can add more by calling fwin_setHelpFile() where arg 1 is the
* text to appear on the menu and arg 2 identifies the help file that will be
* opened if the menu item is selected. Specifying NULL as the second item
* removes the key. The information about help keys is kept in the registry
* not in any file that CSL has direct access to, and the new help items may
* not be visible until the user exits from CSL and re-starts it.
*/
extern void fwin_set_help_file(const char *key, const char *path);
/*
* The declarations below here are to be treated as private and should
* not be touched by users.
*/
extern int plain_worker(int argc, char **argv);
extern delay_callback_t *delay_callback;
extern interrupt_callback_t *interrupt_callback;
/*
* The following three functions (putchar_overwrite, move_cursor_vertically
* and move_to_column) are not intended for use by end-users, and they
* only apply when fwin is running in windowed mode. They are used internally
* to support local editing and history.
*/
/*
* like fwin_putchar(), but overwrites what exists on the screen rather
* than inserting.
*/
extern void fwin_putchar_overwrite(int c);
/*
* Move the cursor up or down n lines. n is positive for movement
* down the screen.
*/
extern void fwin_move_cursor_vertically(int n);
/*
* Move the cursor directly to the indicated column. "0" indicates
* the first position in the row.
*/
extern void fwin_move_to_column(int column);
/*
* What follows is to do with a history mechanism... and again is not
* intended for public export.
*/
#define INPUT_HISTORY_SIZE 100
extern char *input_history[INPUT_HISTORY_SIZE];
extern int input_history_next, input_history_current;
extern void input_history_init();
extern void input_history_end();
extern void input_history_add(const char *s);
extern const char *input_history_get(int n);
/*
* This is for version-specific control
*/
#ifndef INT_VERSION
#define INT_VERSION(a,b,c) (((a*1000) + b)*1000 + c)
#endif
/*
* Some things that are really intended to be private to the implementation
* but at present it seems easiest to mention them in this header rather
* than inventing a new header file.
*/
extern int windowed;
extern int windowed_worker(int argc, char *argv[]);
extern int fwin_use_xft;
extern int directoryp(char *f, char *o, size_t n);
extern int file_readable(char *f, char *o, size_t n);
extern int using_termed;
extern int fwin_plain_getchar();
extern int texmacs_mode;
extern void MS_CDECL sigint_handler(int code);
extern void MS_CDECL sigbreak_handler(int code);
extern int plain_worker(int argc, char *argv[]);
#ifndef MAX_PROMPT_LENGTH
# define MAX_PROMPT_LENGTH 80
#endif
extern char fwin_prompt_string[MAX_PROMPT_LENGTH];
#ifdef __cplusplus
}
#endif
#endif /* header_fwin_h */
/* end of "fwin.h" */