From b0b73df498ba3288269346fe69351c7289d32611 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Mon, 7 Oct 2002 04:41:03 +0000 Subject: [PATCH] Update to S-Lang 1.4.5. Move include files to "include" directory to avoid the need to rename slang.h. * Makefile.am: Adjust file list. Add "-Iinclude" to the compiler flags. * include/jdmacros.h: Rewrite to use glib. * slmisc.c: Trim to include only needed functions. --- slang/ChangeLog | 9 + slang/Makefile.am | 23 +- slang/_slang.h | 327 ---- slang/include/_slang.h | 743 +++++++++ slang/include/jdmacros.h | 20 + slang/include/sl-feat.h | 61 + slang/include/slang.h | 1947 ++++++++++++++++++++++++ slang/include/slinclud.h | 30 + slang/include/sllimits.h | 64 + slang/jdmacros.h | 76 - slang/sl-feat.h | 2 - slang/slang-mc.h | 1290 ---------------- slang/sldisply.c | 1936 ++++++++++++++---------- slang/slerr.c | 181 ++- slang/slgetkey.c | 264 +++- slang/slmemcpy.c | 50 - slang/slmemset.c | 42 - slang/slmisc.c | 78 + slang/slsignal.c | 250 ++- slang/slsmg.c | 1127 +++++++++----- slang/sltermin.c | 1042 ++++++++----- slang/sltoken.c | 354 ----- slang/slutty.c | 360 +++-- slang/slvideo.c | 3088 +++++++++++++++++++++++--------------- slang/slw32tty.c | 409 +++-- 25 files changed, 8529 insertions(+), 5244 deletions(-) delete mode 100644 slang/_slang.h create mode 100644 slang/include/_slang.h create mode 100644 slang/include/jdmacros.h create mode 100644 slang/include/sl-feat.h create mode 100644 slang/include/slang.h create mode 100644 slang/include/slinclud.h create mode 100644 slang/include/sllimits.h delete mode 100644 slang/jdmacros.h delete mode 100644 slang/sl-feat.h delete mode 100644 slang/slang-mc.h delete mode 100644 slang/slmemcpy.c delete mode 100644 slang/slmemset.c create mode 100644 slang/slmisc.c delete mode 100644 slang/sltoken.c diff --git a/slang/ChangeLog b/slang/ChangeLog index 6fc386065..009299840 100644 --- a/slang/ChangeLog +++ b/slang/ChangeLog @@ -1,3 +1,12 @@ +2002-10-07 Pavel Roskin + + Update to S-Lang 1.4.5. Move include files to "include" + directory to avoid the need to rename slang.h. + * Makefile.am: Adjust file list. Add "-Iinclude" to the + compiler flags. + * include/jdmacros.h: Rewrite to use glib. + * slmisc.c: Trim to include only needed functions. + 2002-09-18 Andrew V. Samoilov * slerr.c (SLang_doerror): Use error parameter. Eliminate diff --git a/slang/Makefile.am b/slang/Makefile.am index 731bd7cba..d43a3ae5e 100644 --- a/slang/Makefile.am +++ b/slang/Makefile.am @@ -1,4 +1,4 @@ -AM_CFLAGS = $(GLIB_CFLAGS) +AM_CFLAGS = $(GLIB_CFLAGS) -Iinclude if INCLUDED_SLANG noinst_LIBRARIES = libmcslang.a @@ -6,9 +6,24 @@ else noinst_LIBRARIES = endif -libmcslang_a_SOURCES = sldisply.c slerr.c slsmg.c slutty.c slgetkey.c \ - slmemcpy.c slmemset.c sltermin.c sltoken.c slsignal.c \ - slang-mc.h _slang.h sl-feat.h jdmacros.h +SLANG_INCLUDES = \ + include/_slang.h \ + include/jdmacros.h \ + include/sl-feat.h \ + include/slang.h \ + include/slinclud.h \ + include/sllimits.h + +libmcslang_a_SOURCES = \ + sldisply.c \ + slerr.c \ + slgetkey.c \ + slmisc.c \ + slsignal.c \ + slsmg.c \ + sltermin.c \ + slutty.c \ + $(SLANG_INCLUDES) EXTRASRC = slvideo.c slw32tty.c EXTRADOCS = ChangeLog README diff --git a/slang/_slang.h b/slang/_slang.h deleted file mode 100644 index 2afca11b3..000000000 --- a/slang/_slang.h +++ /dev/null @@ -1,327 +0,0 @@ -/* header file for S-Lang internal structures that users do not (should not) - need. Use slang.h for that purpose. */ -/* Copyright (c) 1992, 1995 John E. Davis - * All rights reserved. - * - * You may distribute under the terms of either the GNU General Public - * License or the Perl Artistic License. - */ - - -#include "config.h" - -#include -#include - -#include "slang-mc.h" -#include "jdmacros.h" - -#ifdef VMS -# define SLANG_SYSTEM_NAME "_VMS" -#else -# if defined (__GO32__) || defined (__EMX__) || \ - defined (msdos) || defined (__os2__) -# define SLANG_SYSTEM_NAME "_IBMPC" -# else -# define SLANG_SYSTEM_NAME "_UNIX" -# endif -#endif /* VMS */ - -#ifdef msdos -#define SLANG_MAX_SYMBOLS 500 -#else -#define SLANG_MAX_SYMBOLS 2500 -#endif -/* maximum number of global symbols--- slang builtin, functions, global vars */ - - -/* These quantities are main_types for byte-compiled code. They are used - * by the inner_interp routine. The ones commented out with a // are - * actually defined in slang.h because they are also used as the main_type in - * the name table. - */ - -/* // #define SLANG_LVARIABLE 0x01 */ -#define SLANG_LOGICAL 0x02 -#define SLANG_BINARY 0x03 -/* // #define SLANG_INTRINSIC 0x06 */ -/* // #define SLANG_FUNCTION 0x07 */ -#define SLANG_LITERAL 0x08 /* constant objects */ -#define SLANG_BLOCK 0x09 -#define SLANG_EQS 0x0A -#define SLANG_UNARY 0x0B -#define SLANG_LUNARY 0x0C - -/* // #define SLANG_GVARIABLE 0x0D */ -/* // #define SLANG_IVARIABLE 0x0E */ /* intrinsic variables */ -/* // #define SLANG_RVARIABLE 0x0F */ /* read only variable */ - -/* These 3 MUST be in this order too ! */ -#define SLANG_RETURN 0x10 -#define SLANG_BREAK 0x11 -#define SLANG_CONTINUE 0x12 - -#define SLANG_EXCH 0x13 -#define SLANG_LABEL 0x14 -#define SLANG_LOBJPTR 0x15 -#define SLANG_GOBJPTR 0x16 -#define SLANG_X_ERROR 0x17 -/* These must be in this order */ -#define SLANG_X_USER0 0x18 -#define SLANG_X_USER1 0x19 -#define SLANG_X_USER2 0x1A -#define SLANG_X_USER3 0x1B -#define SLANG_X_USER4 0x1C - -#ifdef SLANG_NOOP -# define SLANG_NOOP_DIRECTIVE 0x2F -#endif - -/* If SLANG_DATA occurs as the main_type for an object in the interpreter's - * byte-code, it currently refers to a STRING. - */ -/* // #define SLANG_DATA 0x30 */ /* real objects which may be destroyed */ - - -/* Subtypes */ -#define ERROR_BLOCK 0x01 -/* gets executed if block encounters error other than stack related */ -#define EXIT_BLOCK 0x02 -#define USER_BLOCK0 0x03 -#define USER_BLOCK1 0x04 -#define USER_BLOCK2 0x05 -#define USER_BLOCK3 0x06 -#define USER_BLOCK4 0x07 -/* The user blocks MUST be in the above order */ - -/* directive subtypes */ -#define SLANG_LOOP_MASK 0x80 -#define SLANG_LOOP 0x81 -#define SLANG_WHILE 0x82 -#define SLANG_FOR 0x83 -#define SLANG_FOREVER 0x84 -#define SLANG_CFOR 0x85 -#define SLANG_DOWHILE 0x86 - -#define SLANG_IF_MASK 0x40 -#define SLANG_IF 0x41 -#define SLANG_IFNOT 0x42 -#define SLANG_ELSE 0x43 - - -/* local, global variable assignments - * The order here is important. See interp_variable_eqs to see how this - * is exploited. */ -#define SLANG_EQS_MASK 0x20 -/* local variables */ -/* Keep these in this order!! */ -#define SLANG_LEQS 0x21 -#define SLANG_LPEQS 0x22 -#define SLANG_LMEQS 0x23 -#define SLANG_LPP 0x24 -#define SLANG_LMM 0x25 -/* globals */ -/* Keep this on this order!! */ -#define SLANG_GEQS 0x26 -#define SLANG_GPEQS 0x27 -#define SLANG_GMEQS 0x28 -#define SLANG_GPP 0x29 -#define SLANG_GMM 0x2A -/* intrinsic variables */ -#define SLANG_IEQS 0x2B -#define SLANG_IPEQS 0x2C -#define SLANG_IMEQS 0x2D -#define SLANG_IPP 0x2E -#define SLANG_IMM 0x2F - - -#define SLANG_ELSE_MASK 0x10 -#define SLANG_ANDELSE 0x11 -#define SLANG_ORELSE 0x12 -#define SLANG_SWITCH 0x13 - -/* LOGICAL SUBTYPES (operate on integers) */ -#define SLANG_MOD 16 -#define SLANG_OR 17 -#define SLANG_AND 18 -#define SLANG_BAND 19 -#define SLANG_BOR 20 -#define SLANG_BXOR 21 -#define SLANG_SHL 22 -#define SLANG_SHR 23 - -/* LUnary Subtypes */ -#define SLANG_NOT 24 -#define SLANG_BNOT 25 - -typedef struct SLBlock_Type - { - unsigned char main_type; - unsigned char sub_type; - union - { - struct SLBlock_Type *blk; - int i_blk; - SLang_Name_Type *n_blk; - char *s_blk; -#ifdef FLOAT_TYPE - float64 *f_blk; /*literal float is a pointer */ -#endif - long l_blk; - } - b; - } -SLBlock_Type; - - -typedef struct -{ - unsigned char main_type; /* block, intrinsic... */ - unsigned char sub_type; /* SLANG_WHILE, SLANG_DATA, ... */ - union - { - long l_val; - char *s_val; - int i_val; - SLuser_Object_Type *uobj; - SLang_Name_Type *n_val; -#ifdef FLOAT_TYPE - float64 f_val; -#endif - } v; -} SLang_Object_Type; - - -extern void SLang_free_object (SLang_Object_Type *); - -extern int SLang_pop_non_object (SLang_Object_Type *); - -extern void _SLdo_error (char *, ...); -extern void SLcompile(char *); -extern void (*SLcompile_ptr)(char *); - -typedef struct -{ - char *name; int type; -} SLang_Name2_Type; - -extern void SLstupid_hash(void); - -typedef struct SLName_Table -{ - struct SLName_Table *next; /* next table */ - SLang_Name_Type *table; /* pointer to table */ - int n; /* entries in this table */ - char name[32]; /* name of table */ - int ofs[256]; /* offsets into table */ -} SLName_Table; - -extern SLName_Table *SLName_Table_Root; -#ifdef MSWINDOWS -extern SLang_Name_Type *SLang_Name_Table; -#else -extern SLang_Name_Type SLang_Name_Table[SLANG_MAX_SYMBOLS]; -#endif - -extern SLang_Name2_Type SL_Binary_Ops []; -extern SLang_Object_Type *SLStack_Pointer; -extern char *SLbyte_compile_name(char *); -extern int SLang_pop(SLang_Object_Type *); -extern char *SLexpand_escaped_char(char *, char *); -extern void SLexpand_escaped_string (char *, char *, char *); - -extern SLang_Object_Type *_SLreverse_stack (int); -extern SLang_Name_Type *SLang_locate_name(char *); - -/* returns a pointer to a MALLOCED string */ -extern char *SLstringize_object (SLang_Object_Type *); - -/* array types */ -typedef struct SLArray_Type -{ - unsigned char type; /* int, float, etc... */ - int dim; /* # of dims (max 3) */ - int x, y, z; /* actual dims */ - union - { - unsigned char *c_ptr; - unsigned char **s_ptr; - int *i_ptr; -#ifdef FLOAT_TYPE - float64 *f_ptr; -#endif - SLuser_Object_Type **u_ptr; - } - buf; - unsigned char flags; /* readonly, etc... If this is non-zero, - * the buf pointer will NOT be freed. - * See SLarray_free_array. - */ -} SLArray_Type; - - -/* Callback to delete array */ -extern void SLarray_free_array (long *); - - -/* maximum size of run time stack */ -#ifdef msdos -#define SLANG_MAX_STACK_LEN 500 -#else -#define SLANG_MAX_STACK_LEN 2500 -#endif - -#ifdef MSWINDOWS -extern SLang_Object_Type *SLRun_Stack; -#else -extern SLang_Object_Type SLRun_Stack[SLANG_MAX_STACK_LEN]; -#endif - -extern SLang_Object_Type *SLStack_Pointer; - -extern int SLang_Trace; -extern int SLstack_depth(void); - -extern void SLang_trace_fun(char *); -extern void SLexecute_function(SLang_Name_Type *); -extern char *SLmake_string (char *); - -extern int _SLeqs_name(char *, SLang_Name2_Type *); -extern void SLang_push(SLang_Object_Type *); -extern void SLang_push_float(float64); -extern void SLadd_variable(char *); -extern void SLang_clear_error(void); -extern void SLarray_info (void); -extern int SLPreprocess_Only; /* preprocess instead of - * bytecompiling - */ - -extern void SLdo_pop (void); -extern unsigned int SLsys_getkey (void); -extern int SLsys_input_pending (int); - -#ifdef REAL_UNIX_SYSTEM -extern int SLtt_tigetflag (char *, char **); -extern int SLtt_tigetnum (char *, char **); -extern char *SLtt_tigetstr (char *, char **); -extern char *SLtt_tigetent (char *); -#endif - -#ifdef msdos -#define MAX_INPUT_BUFFER_LEN 40 -#else -#define MAX_INPUT_BUFFER_LEN 1024 -#endif -extern unsigned char SLang_Input_Buffer [MAX_INPUT_BUFFER_LEN]; -extern unsigned int SLang_Input_Buffer_Len; - -extern int SLregister_types (void); - -#ifndef pc_system -extern char *SLtt_Graphics_Char_Pairs; -#endif /* NOT pc_system */ - -extern void _SLerrno_set_return_status (void); -extern char *_SLerrno_strerror (void); -extern int _SLerrno_Return_Status; - diff --git a/slang/include/_slang.h b/slang/include/_slang.h new file mode 100644 index 000000000..a7dd7912f --- /dev/null +++ b/slang/include/_slang.h @@ -0,0 +1,743 @@ +#ifndef _PRIVATE_SLANG_H_ +#define _PRIVATE_SLANG_H_ +/* header file for S-Lang internal structures that users do not (should not) + need. Use slang.h for that purpose. */ +/* Copyright (c) 1992, 1999, 2001, 2002 John E. Davis + * This file is part of the S-Lang library. + * + * You may distribute under the terms of either the GNU General Public + * License or the Perl Artistic License. + */ + +/* #include "config.h" */ +#include "jdmacros.h" +#include "sllimits.h" + +#ifdef VMS +# define SLANG_SYSTEM_NAME "_VMS" +#else +# if defined (IBMPC_SYSTEM) +# define SLANG_SYSTEM_NAME "_IBMPC" +# else +# define SLANG_SYSTEM_NAME "_UNIX" +# endif +#endif /* VMS */ + +/* These quantities are main_types for byte-compiled code. They are used + * by the inner_interp routine. The _BC_ means byte-code. + */ + +#define _SLANG_BC_LVARIABLE SLANG_LVARIABLE /* 0x01 */ +#define _SLANG_BC_GVARIABLE SLANG_GVARIABLE /* 0x02 */ +#define _SLANG_BC_IVARIABLE SLANG_IVARIABLE /* 0x03 */ +#define _SLANG_BC_RVARIABLE SLANG_RVARIABLE /* 0x04 */ +#define _SLANG_BC_INTRINSIC SLANG_INTRINSIC /* 0x05 */ +#define _SLANG_BC_FUNCTION SLANG_FUNCTION /* 0x06 */ +#define _SLANG_BC_MATH_UNARY SLANG_MATH_UNARY /* 0x07 */ +#define _SLANG_BC_APP_UNARY SLANG_APP_UNARY /* 0x08 */ +#define _SLANG_BC_ICONST SLANG_ICONSTANT /* 0x09 */ +#define _SLANG_BC_DCONST SLANG_DCONSTANT /* 0x0A */ +#define _SLANG_BC_PVARIABLE SLANG_PVARIABLE /* 0x0B */ +#define _SLANG_BC_PFUNCTION SLANG_PFUNCTION /* 0x0C */ + +#define _SLANG_BC_BINARY 0x10 +#define _SLANG_BC_LITERAL 0x11 /* constant objects */ +#define _SLANG_BC_LITERAL_INT 0x12 +#define _SLANG_BC_LITERAL_STR 0x13 +#define _SLANG_BC_BLOCK 0x14 + +/* These 3 MUST be in this order too ! */ +#define _SLANG_BC_RETURN 0x15 +#define _SLANG_BC_BREAK 0x16 +#define _SLANG_BC_CONTINUE 0x17 + +#define _SLANG_BC_EXCH 0x18 +#define _SLANG_BC_LABEL 0x19 +#define _SLANG_BC_LOBJPTR 0x1A +#define _SLANG_BC_GOBJPTR 0x1B +#define _SLANG_BC_X_ERROR 0x1C +/* These must be in this order */ +#define _SLANG_BC_X_USER0 0x1D +#define _SLANG_BC_X_USER1 0x1E +#define _SLANG_BC_X_USER2 0x1F +#define _SLANG_BC_X_USER3 0x20 +#define _SLANG_BC_X_USER4 0x21 + +#define _SLANG_BC_CALL_DIRECT 0x24 +#define _SLANG_BC_CALL_DIRECT_FRAME 0x25 +#define _SLANG_BC_UNARY 0x26 +#define _SLANG_BC_UNARY_FUNC 0x27 + +#define _SLANG_BC_DEREF_ASSIGN 0x30 +#define _SLANG_BC_SET_LOCAL_LVALUE 0x31 +#define _SLANG_BC_SET_GLOBAL_LVALUE 0x32 +#define _SLANG_BC_SET_INTRIN_LVALUE 0x33 +#define _SLANG_BC_SET_STRUCT_LVALUE 0x34 +#define _SLANG_BC_FIELD 0x35 +#define _SLANG_BC_SET_ARRAY_LVALUE 0x36 + +#define _SLANG_BC_LINE_NUM 0x40 + +#define _SLANG_BC_TMP 0x50 +#define _SLANG_BC_LVARIABLE_AGET 0x60 +#define _SLANG_BC_LVARIABLE_APUT 0x61 +#define _SLANG_BC_INTEGER_PLUS 0x62 +#define _SLANG_BC_INTEGER_MINUS 0x63 +#define _SLANG_BC_ARG_LVARIABLE 0x64 +#define _SLANG_BC_EARG_LVARIABLE 0x65 + +#define _SLANG_BC_CALL_DIRECT_INTRINSIC 0x80 +#define _SLANG_BC_INTRINSIC_CALL_DIRECT 0x81 +#define _SLANG_BC_CALL_DIRECT_LSTR 0x82 +#define _SLANG_BC_CALL_DIRECT_SLFUN 0x83 +#define _SLANG_BC_CALL_DIRECT_INTRSTOP 0x84 +#define _SLANG_BC_INTRINSIC_STOP 0x85 +#define _SLANG_BC_CALL_DIRECT_EARG_LVAR 0x86 +#define _SLANG_BC_CALL_DIRECT_LINT 0x87 +#define _SLANG_BC_CALL_DIRECT_LVAR 0x88 + + +/* Byte-Code Sub Types (_BCST_) */ + +/* These are sub_types of _SLANG_BC_BLOCK */ +#define _SLANG_BCST_ERROR_BLOCK 0x01 +#define _SLANG_BCST_EXIT_BLOCK 0x02 +#define _SLANG_BCST_USER_BLOCK0 0x03 +#define _SLANG_BCST_USER_BLOCK1 0x04 +#define _SLANG_BCST_USER_BLOCK2 0x05 +#define _SLANG_BCST_USER_BLOCK3 0x06 +#define _SLANG_BCST_USER_BLOCK4 0x07 +/* The user blocks MUST be in the above order */ +#define _SLANG_BCST_LOOP 0x10 +#define _SLANG_BCST_WHILE 0x11 +#define _SLANG_BCST_FOR 0x12 +#define _SLANG_BCST_FOREVER 0x13 +#define _SLANG_BCST_CFOR 0x14 +#define _SLANG_BCST_DOWHILE 0x15 +#define _SLANG_BCST_FOREACH 0x16 + +#define _SLANG_BCST_IF 0x20 +#define _SLANG_BCST_IFNOT 0x21 +#define _SLANG_BCST_ELSE 0x22 +#define _SLANG_BCST_ANDELSE 0x23 +#define _SLANG_BCST_ORELSE 0x24 +#define _SLANG_BCST_SWITCH 0x25 +#define _SLANG_BCST_NOTELSE 0x26 + +/* assignment (_SLANG_BC_SET_*_LVALUE) subtypes. The order MUST correspond + * to the assignment token order with the ASSIGN_TOKEN as the first! + */ +#define _SLANG_BCST_ASSIGN 0x01 +#define _SLANG_BCST_PLUSEQS 0x02 +#define _SLANG_BCST_MINUSEQS 0x03 +#define _SLANG_BCST_TIMESEQS 0x04 +#define _SLANG_BCST_DIVEQS 0x05 +#define _SLANG_BCST_BOREQS 0x06 +#define _SLANG_BCST_BANDEQS 0x07 +#define _SLANG_BCST_PLUSPLUS 0x08 +#define _SLANG_BCST_POST_PLUSPLUS 0x09 +#define _SLANG_BCST_MINUSMINUS 0x0A +#define _SLANG_BCST_POST_MINUSMINUS 0x0B + +/* These use SLANG_PLUS, SLANG_MINUS, SLANG_PLUSPLUS, etc... */ + +typedef union +{ +#if SLANG_HAS_FLOAT + double double_val; + float float_val; +#endif + long long_val; + unsigned long ulong_val; + VOID_STAR ptr_val; + char *s_val; + int int_val; + unsigned int uint_val; + SLang_MMT_Type *ref; + SLang_Name_Type *n_val; + struct _SLang_Struct_Type *struct_val; + struct _SLang_Array_Type *array_val; + short short_val; + unsigned short ushort_val; + char char_val; + unsigned char uchar_val; +} +_SL_Object_Union_Type; + +typedef struct _SLang_Object_Type +{ + SLtype data_type; /* SLANG_INT_TYPE, ... */ + _SL_Object_Union_Type v; +} +SLang_Object_Type; + +struct _SLang_MMT_Type +{ + SLtype data_type; /* int, string, etc... */ + VOID_STAR user_data; /* address of user structure */ + unsigned int count; /* number of references */ +}; + +extern int _SLang_pop_object_of_type (SLtype, SLang_Object_Type *, int); + +typedef struct +{ + char *name; /* slstring */ + SLang_Object_Type obj; +} +_SLstruct_Field_Type; + +typedef struct _SLang_Struct_Type +{ + _SLstruct_Field_Type *fields; + unsigned int nfields; /* number used */ + unsigned int num_refs; +} +_SLang_Struct_Type; + +extern void _SLstruct_delete_struct (_SLang_Struct_Type *); +extern int _SLang_push_struct (_SLang_Struct_Type *); +extern int _SLang_pop_struct (_SLang_Struct_Type **); +extern int _SLstruct_init (void); +/* extern int _SLstruct_get_field (char *); */ +extern int _SLstruct_define_struct (void); +extern int _SLstruct_define_typedef (void); + +struct _SLang_Ref_Type +{ + int is_global; + union + { + SLang_Name_Type *nt; + SLang_Object_Type *local_obj; + } + v; +}; + +extern int _SLang_dereference_ref (SLang_Ref_Type *); +extern int _SLang_deref_assign (SLang_Ref_Type *); +extern int _SLang_push_ref (int, VOID_STAR); + +extern int _SL_increment_frame_pointer (void); +extern int _SL_decrement_frame_pointer (void); + +extern int SLang_pop(SLang_Object_Type *); +extern void SLang_free_object (SLang_Object_Type *); +extern int _SLanytype_typecast (SLtype, VOID_STAR, unsigned int, + SLtype, VOID_STAR); +extern void _SLstring_intrinsic (void); + + +/* These functions are used to create slstrings of a fixed length. Be + * very careful how they are used. In particular, if len bytes are allocated, + * then the string must be len characters long, no more and no less. + */ +extern char *_SLallocate_slstring (unsigned int); +extern char *_SLcreate_via_alloced_slstring (char *, unsigned int); +extern void _SLunallocate_slstring (char *, unsigned int); +extern int _SLpush_alloced_slstring (char *, unsigned int); + +typedef struct +{ + char **buf; + unsigned int max_num; + unsigned int num; + unsigned int delta_num; +} +_SLString_List_Type; +extern int _SLstring_list_append (_SLString_List_Type *, char *); +extern int _SLstring_list_init (_SLString_List_Type *, unsigned int, unsigned int); +extern void _SLstring_list_delete (_SLString_List_Type *); +extern int _SLstring_list_push (_SLString_List_Type *); + +/* This function assumes that s is an slstring. */ +extern char *_SLstring_dup_slstring (char *); +extern int _SLang_dup_and_push_slstring (char *); + + +extern int _SLang_init_import (void); + +/* This function checks to see if the referenced object is initialized */ +extern int _SLang_is_ref_initialized (SLang_Ref_Type *); +extern int _SLcheck_identifier_syntax (char *); +extern int _SLang_uninitialize_ref (SLang_Ref_Type *); + +extern int _SLpush_slang_obj (SLang_Object_Type *); + +extern char *_SLexpand_escaped_char(char *, char *); +extern void _SLexpand_escaped_string (char *, char *, char *); + +/* returns a pointer to an SLstring string-- use SLang_free_slstring */ +extern char *_SLstringize_object (SLang_Object_Type *); +extern int _SLdump_objects (char *, SLang_Object_Type *, unsigned int, int); + +extern SLang_Object_Type *_SLRun_Stack; +extern SLang_Object_Type *_SLStack_Pointer; + +struct _SLang_NameSpace_Type +{ + struct _SLang_NameSpace_Type *next; + char *name; /* this is the load_type name */ + char *namespace_name; /* this name is assigned by implements */ + unsigned int table_size; + SLang_Name_Type **table; +}; +extern SLang_NameSpace_Type *_SLns_allocate_namespace (char *, unsigned int); +extern SLang_NameSpace_Type *_SLns_find_namespace (char *); +extern int _SLns_set_namespace_name (SLang_NameSpace_Type *, char *); +extern SLang_Array_Type *_SLnspace_apropos (SLang_NameSpace_Type *, char *, unsigned int); +extern void _SLang_use_namespace_intrinsic (char *name); +extern char *_SLang_cur_namespace_intrinsic (void); +extern SLang_Array_Type *_SLang_apropos (char *, char *, unsigned int); +extern void _SLang_implements_intrinsic (char *); + +extern int _SLang_Trace; +extern int _SLstack_depth(void); +extern char *_SLang_Current_Function_Name; + +extern int _SLang_trace_fun(char *); +extern int _SLang_Compile_Line_Num_Info; + +extern char *_SLstring_dup_hashed_string (char *, unsigned long); +extern unsigned long _SLcompute_string_hash (char *); +extern char *_SLstring_make_hashed_string (char *, unsigned int, unsigned long *); +extern void _SLfree_hashed_string (char *, unsigned int, unsigned long); +unsigned long _SLstring_hash (unsigned char *, unsigned char *); +extern int _SLinit_slcomplex (void); + +extern int _SLang_init_slstrops (void); +extern int _SLstrops_do_sprintf_n (int); +extern int _SLang_sscanf (void); +extern double _SLang_atof (char *); +extern int _SLang_init_bstring (void); +extern int _SLang_init_sltime (void); +extern void _SLpack (void); +extern void _SLunpack (char *, SLang_BString_Type *); +extern void _SLpack_pad_format (char *); +extern unsigned int _SLpack_compute_size (char *); +extern int _SLusleep (unsigned long); + +/* frees upon error. NULL __NOT__ ok. */ +extern int _SLang_push_slstring (char *); + +extern SLtype _SLarith_promote_type (SLtype); +extern int _SLarith_get_precedence (SLtype); +extern int _SLarith_typecast (SLtype, VOID_STAR, unsigned int, + SLtype, VOID_STAR); + +extern int SLang_push(SLang_Object_Type *); +extern int SLadd_global_variable (char *); +extern void _SLang_clear_error (void); + +extern int _SLdo_pop (void); +extern unsigned int _SLsys_getkey (void); +extern int _SLsys_input_pending (int); +#ifdef IBMPC_SYSTEM +extern unsigned int _SLpc_convert_scancode (unsigned int, unsigned int, int); +#define _SLTT_KEY_SHIFT 1 +#define _SLTT_KEY_CTRL 2 +#define _SLTT_KEY_ALT 4 +#endif + +typedef struct _SLterminfo_Type SLterminfo_Type; +extern SLterminfo_Type *_SLtt_tigetent (char *); +extern char *_SLtt_tigetstr (SLterminfo_Type *, char *); +extern int _SLtt_tigetnum (SLterminfo_Type *, char *); +extern int _SLtt_tigetflag (SLterminfo_Type *, char *); + +#if SLTT_HAS_NON_BCE_SUPPORT +extern int _SLtt_get_bce_color_offset (void); +#endif +extern void (*_SLtt_color_changed_hook)(void); + +extern unsigned char SLang_Input_Buffer [SL_MAX_INPUT_BUFFER_LEN]; + +extern int _SLregister_types (void); +extern SLang_Class_Type *_SLclass_get_class (SLtype); +extern VOID_STAR _SLclass_get_ptr_to_value (SLang_Class_Type *, SLang_Object_Type *); +extern void _SLclass_type_mismatch_error (SLtype, SLtype); +extern int _SLclass_init (void); +extern int _SLclass_copy_class (SLtype, SLtype); + +extern SLtype _SLclass_Class_Type [256]; + +extern int (*_SLclass_get_typecast (SLtype, SLtype, int)) +(SLtype, VOID_STAR, unsigned int, + SLtype, VOID_STAR); + +extern int (*_SLclass_get_binary_fun (int, SLang_Class_Type *, SLang_Class_Type *, SLang_Class_Type **, int)) +(int, + SLtype, VOID_STAR, unsigned int, + SLtype, VOID_STAR, unsigned int, + VOID_STAR); + +extern int (*_SLclass_get_unary_fun (int, SLang_Class_Type *, SLang_Class_Type **, int)) +(int, SLtype, VOID_STAR, unsigned int, VOID_STAR); + +extern int _SLarith_register_types (void); +extern SLtype _SLarith_Arith_Types []; +extern SLtype _SLarith_Is_Arith_Type [256]; +extern int _SLarith_bin_op (SLang_Object_Type *, SLang_Object_Type *, int); + +extern int _SLarray_add_bin_op (SLtype); + +extern int _SLang_call_funptr (SLang_Name_Type *); +extern void _SLset_double_format (char *); +extern SLang_Name_Type *_SLlocate_global_name (char *); +extern SLang_Name_Type *_SLlocate_name (char *); + +extern char *_SLdefines[]; + +#define SL_ERRNO_NOT_IMPLEMENTED 0x7FFF +extern int _SLerrno_errno; +extern int _SLerrno_init (void); + +extern int _SLstdio_fdopen (char *, int, char *); + +extern void _SLstruct_pop_args (int *); +extern void _SLstruct_push_args (SLang_Array_Type *); + +extern int _SLarray_aput (void); +extern int _SLarray_aget (void); +extern int _SLarray_inline_implicit_array (void); +extern int _SLarray_inline_array (void); +extern int _SLarray_wildcard_array (void); + +extern int +_SLarray_typecast (SLtype, VOID_STAR, unsigned int, + SLtype, VOID_STAR, int); + +extern int _SLarray_aput_transfer_elem (SLang_Array_Type *, int *, + VOID_STAR, unsigned int, int); +extern int _SLarray_aget_transfer_elem (SLang_Array_Type *, int *, + VOID_STAR, unsigned int, int); +extern void _SLarray_free_array_elements (SLang_Class_Type *, VOID_STAR, unsigned int); + +extern SLang_Foreach_Context_Type * +_SLarray_cl_foreach_open (SLtype, unsigned int); +extern void _SLarray_cl_foreach_close (SLtype, SLang_Foreach_Context_Type *); +extern int _SLarray_cl_foreach (SLtype, SLang_Foreach_Context_Type *); + +extern int _SLarray_matrix_multiply (void); +extern void (*_SLang_Matrix_Multiply)(void); + +extern int _SLarray_init_slarray (void); +extern SLang_Array_Type * +SLang_create_array1 (SLtype, int, VOID_STAR, int *, unsigned int, int); + +extern int _SLcompile_push_context (SLang_Load_Type *); +extern int _SLcompile_pop_context (void); +extern int _SLang_Auto_Declare_Globals; + +typedef struct +{ + union + { + long long_val; + char *s_val; /* Used for IDENT_TOKEN, FLOAT, etc... */ + SLang_BString_Type *b_val; + } v; + int free_sval_flag; + unsigned int num_refs; + unsigned long hash; +#if _SLANG_HAS_DEBUG_CODE + int line_number; +#endif + SLtype type; +} +_SLang_Token_Type; + +extern void _SLcompile (_SLang_Token_Type *); +extern void (*_SLcompile_ptr)(_SLang_Token_Type *); + +/* *** TOKENS *** */ + +/* Note that that tokens corresponding to ^J, ^M, and ^Z should not be used. + * This is because a file that contains any of these characters will + * have an OS dependent interpretation, e.g., ^Z is EOF on MSDOS. + */ + +/* Special tokens */ +#define ILLEGAL_TOKEN 0x00 /* no token has this value */ +#define EOF_TOKEN 0x01 +#define RPN_TOKEN 0x02 +#define NL_TOKEN 0x03 +#define NOP_TOKEN 0x05 +#define FARG_TOKEN 0x06 +#define TMP_TOKEN 0x07 + +#define RESERVED1_TOKEN 0x0A /* \n */ +#define RESERVED2_TOKEN 0x0D /* \r */ + +/* Literal tokens */ +#define CHAR_TOKEN 0x10 +#define UCHAR_TOKEN 0x11 +#define SHORT_TOKEN 0x12 +#define USHORT_TOKEN 0x13 +#define INT_TOKEN 0x14 +#define UINT_TOKEN 0x15 +#define LONG_TOKEN 0x16 +#define ULONG_TOKEN 0x17 +#define IS_INTEGER_TOKEN(x) ((x >= CHAR_TOKEN) && (x <= ULONG_TOKEN)) +#define FLOAT_TOKEN 0x18 +#define DOUBLE_TOKEN 0x19 +#define RESERVED3_TOKEN 0x1A /* ^Z */ +#define COMPLEX_TOKEN 0x1B +#define STRING_TOKEN 0x1C +#define BSTRING_TOKEN 0x1D +#define _BSTRING_TOKEN 0x1E /* byte-compiled BSTRING */ +#define ESC_STRING_TOKEN 0x1F + +/* Tokens that can be LVALUES */ +#define IDENT_TOKEN 0x20 +#define ARRAY_TOKEN 0x21 +#define DOT_TOKEN 0x22 +#define METHOD_TOKEN 0x24 +#define IS_LVALUE_TOKEN (((t) <= METHOD_TOKEN) && ((t) >= IDENT_TOKEN)) +/* do not use these values */ +#define RESERVED4_TOKEN 0x23 /* # */ +#define RESERVED5_TOKEN 0x25 /* % */ + +/* Flags for struct fields */ +#define STATIC_TOKEN 0x26 +#define READONLY_TOKEN 0x27 +#define PRIVATE_TOKEN 0x28 +#define PUBLIC_TOKEN 0x29 + +/* Punctuation tokens */ +#define OBRACKET_TOKEN 0x2a +#define CBRACKET_TOKEN 0x2b +#define OPAREN_TOKEN 0x2c +#define CPAREN_TOKEN 0x2d +#define OBRACE_TOKEN 0x2e +#define CBRACE_TOKEN 0x2f + +#define COMMA_TOKEN 0x31 +#define SEMICOLON_TOKEN 0x32 +#define COLON_TOKEN 0x33 +#define NAMESPACE_TOKEN 0x34 + +/* Operators */ +#define POW_TOKEN 0x38 + +/* The order here must match the order in the Binop_Level table in slparse.c */ +#define FIRST_BINARY_OP 0x39 +#define ADD_TOKEN 0x39 +#define SUB_TOKEN 0x3a +#define TIMES_TOKEN 0x3b +#define DIV_TOKEN 0x3c +#define LT_TOKEN 0x3d +#define LE_TOKEN 0x3e +#define GT_TOKEN 0x3f +#define GE_TOKEN 0x40 +#define EQ_TOKEN 0x41 +#define NE_TOKEN 0x42 +#define AND_TOKEN 0x43 +#define OR_TOKEN 0x44 +#define MOD_TOKEN 0x45 +#define BAND_TOKEN 0x46 +#define SHL_TOKEN 0x47 +#define SHR_TOKEN 0x48 +#define BXOR_TOKEN 0x49 +#define BOR_TOKEN 0x4a +#define POUND_TOKEN 0x4b /* matrix multiplication */ + +#define LAST_BINARY_OP 0x4b +#define IS_BINARY_OP(t) ((t >= FIRST_BINARY_OP) && (t <= LAST_BINARY_OP)) + +/* unary tokens -- but not all of them (see grammar) */ +#define DEREF_TOKEN 0x4d +#define NOT_TOKEN 0x4e +#define BNOT_TOKEN 0x4f + +#define IS_INTERNAL_FUNC(t) ((t >= 0x50) && (t <= 0x56)) +#define POP_TOKEN 0x50 +#define CHS_TOKEN 0x51 +#define SIGN_TOKEN 0x52 +#define ABS_TOKEN 0x53 +#define SQR_TOKEN 0x54 +#define MUL2_TOKEN 0x55 +#define EXCH_TOKEN 0x56 + +/* Assignment tokens. Note: these must appear with sequential values. + * The order here must match the specific lvalue assignments below. + * These tokens are used by rpn routines in slang.c. slparse.c maps them + * onto the specific lvalue tokens while parsing infix. + * Also the assignment _SLANG_BCST_ assumes this order + */ +#define ASSIGN_TOKEN 0x57 +#define PLUSEQS_TOKEN 0x58 +#define MINUSEQS_TOKEN 0x59 +#define TIMESEQS_TOKEN 0x5A +#define DIVEQS_TOKEN 0x5B +#define BOREQS_TOKEN 0x5C +#define BANDEQS_TOKEN 0x5D +#define PLUSPLUS_TOKEN 0x5E +#define POST_PLUSPLUS_TOKEN 0x5F +#define MINUSMINUS_TOKEN 0x60 +#define POST_MINUSMINUS_TOKEN 0x61 + +/* Directives */ +#define FIRST_DIRECTIVE_TOKEN 0x62 +#define IFNOT_TOKEN 0x62 +#define IF_TOKEN 0x63 +#define ELSE_TOKEN 0x64 +#define FOREVER_TOKEN 0x65 +#define WHILE_TOKEN 0x66 +#define FOR_TOKEN 0x67 +#define _FOR_TOKEN 0x68 +#define LOOP_TOKEN 0x69 +#define SWITCH_TOKEN 0x6A +#define DOWHILE_TOKEN 0x6B +#define ANDELSE_TOKEN 0x6C +#define ORELSE_TOKEN 0x6D +#define ERRBLK_TOKEN 0x6E +#define EXITBLK_TOKEN 0x6F +/* These must be sequential */ +#define USRBLK0_TOKEN 0x70 +#define USRBLK1_TOKEN 0x71 +#define USRBLK2_TOKEN 0x72 +#define USRBLK3_TOKEN 0x73 +#define USRBLK4_TOKEN 0x74 + +#define CONT_TOKEN 0x75 +#define BREAK_TOKEN 0x76 +#define RETURN_TOKEN 0x77 + +#define CASE_TOKEN 0x78 +#define DEFINE_TOKEN 0x79 +#define DO_TOKEN 0x7a +#define VARIABLE_TOKEN 0x7b +#define GVARIABLE_TOKEN 0x7c +#define _REF_TOKEN 0x7d +#define PUSH_TOKEN 0x7e +#define STRUCT_TOKEN 0x7f +#define TYPEDEF_TOKEN 0x80 +#define NOTELSE_TOKEN 0x81 +#define DEFINE_STATIC_TOKEN 0x82 +#define FOREACH_TOKEN 0x83 +#define USING_TOKEN 0x84 +#define DEFINE_PRIVATE_TOKEN 0x85 +#define DEFINE_PUBLIC_TOKEN 0x86 + +/* Note: the order here must match the order of the generic assignment tokens. + * Also, the first token of each group must be the ?_ASSIGN_TOKEN. + * slparse.c exploits this order, as well as slang.h. + */ +#define FIRST_ASSIGN_TOKEN 0x90 +#define _STRUCT_ASSIGN_TOKEN 0x90 +#define _STRUCT_PLUSEQS_TOKEN 0x91 +#define _STRUCT_MINUSEQS_TOKEN 0x92 +#define _STRUCT_TIMESEQS_TOKEN 0x93 +#define _STRUCT_DIVEQS_TOKEN 0x94 +#define _STRUCT_BOREQS_TOKEN 0x95 +#define _STRUCT_BANDEQS_TOKEN 0x96 +#define _STRUCT_PLUSPLUS_TOKEN 0x97 +#define _STRUCT_POST_PLUSPLUS_TOKEN 0x98 +#define _STRUCT_MINUSMINUS_TOKEN 0x99 +#define _STRUCT_POST_MINUSMINUS_TOKEN 0x9A + +#define _ARRAY_ASSIGN_TOKEN 0xA0 +#define _ARRAY_PLUSEQS_TOKEN 0xA1 +#define _ARRAY_MINUSEQS_TOKEN 0xA2 +#define _ARRAY_TIMESEQS_TOKEN 0xA3 +#define _ARRAY_DIVEQS_TOKEN 0xA4 +#define _ARRAY_BOREQS_TOKEN 0xA5 +#define _ARRAY_BANDEQS_TOKEN 0xA6 +#define _ARRAY_PLUSPLUS_TOKEN 0xA7 +#define _ARRAY_POST_PLUSPLUS_TOKEN 0xA8 +#define _ARRAY_MINUSMINUS_TOKEN 0xA9 +#define _ARRAY_POST_MINUSMINUS_TOKEN 0xAA + +#define _SCALAR_ASSIGN_TOKEN 0xB0 +#define _SCALAR_PLUSEQS_TOKEN 0xB1 +#define _SCALAR_MINUSEQS_TOKEN 0xB2 +#define _SCALAR_TIMESEQS_TOKEN 0xB3 +#define _SCALAR_DIVEQS_TOKEN 0xB4 +#define _SCALAR_BOREQS_TOKEN 0xB5 +#define _SCALAR_BANDEQS_TOKEN 0xB6 +#define _SCALAR_PLUSPLUS_TOKEN 0xB7 +#define _SCALAR_POST_PLUSPLUS_TOKEN 0xB8 +#define _SCALAR_MINUSMINUS_TOKEN 0xB9 +#define _SCALAR_POST_MINUSMINUS_TOKEN 0xBA + +#define _DEREF_ASSIGN_TOKEN 0xC0 +#define _DEREF_PLUSEQS_TOKEN 0xC1 +#define _DEREF_MINUSEQS_TOKEN 0xC2 +#define _DEREF_TIMESEQS_TOKEN 0xC3 +#define _DEREF_DIVEQS_TOKEN 0xC4 +#define _DEREF_BOREQS_TOKEN 0xC5 +#define _DEREF_BANDEQS_TOKEN 0xC6 +#define _DEREF_PLUSPLUS_TOKEN 0xC7 +#define _DEREF_POST_PLUSPLUS_TOKEN 0xC8 +#define _DEREF_MINUSMINUS_TOKEN 0xC9 +#define _DEREF_POST_MINUSMINUS_TOKEN 0xCA + +#define LAST_ASSIGN_TOKEN 0xCA +#define IS_ASSIGN_TOKEN(t) (((t)>=FIRST_ASSIGN_TOKEN)&&((t)<=LAST_ASSIGN_TOKEN)) + +#define _INLINE_ARRAY_TOKEN 0xE0 +#define _INLINE_IMPLICIT_ARRAY_TOKEN 0xE1 +#define _NULL_TOKEN 0xE2 +#define _INLINE_WILDCARD_ARRAY_TOKEN 0xE3 + +#define LINE_NUM_TOKEN 0xFC +#define ARG_TOKEN 0xFD +#define EARG_TOKEN 0xFE +#define NO_OP_LITERAL 0xFF + +typedef struct +{ + /* sltoken.c */ + /* SLang_eval_object */ + SLang_Load_Type *llt; + SLPreprocess_Type *this_slpp; + /* prep_get_char() */ + char *input_line; + char cchar; + /* get_token() */ + int want_nl_token; + + /* slparse.c */ + _SLang_Token_Type ctok; + int block_depth; + int assignment_expression; + + /* slang.c : SLcompile() */ + _SLang_Token_Type save_token; + _SLang_Token_Type next_token; + void (*slcompile_ptr)(_SLang_Token_Type *); +} +_SLEval_Context; + +extern int _SLget_token (_SLang_Token_Type *); +extern void _SLparse_error (char *, _SLang_Token_Type *, int); +extern void _SLparse_start (SLang_Load_Type *); +extern int _SLget_rpn_token (_SLang_Token_Type *); +extern void _SLcompile_byte_compiled (void); + +extern int (*_SLprep_eval_hook) (char *); + +#ifndef _SLvsnprintf +#ifdef HAVE_VSNPRINTF +#define _SLvsnprintf vsnprintf +#else +extern int _SLvsnprintf (char *, unsigned int, char *, va_list); +#endif +#endif + +#ifdef HAVE_SNPRINTF +# define _SLsnprintf snprintf +#else +extern int _SLsnprintf (char *, unsigned int, char *, ...); +#endif + +#undef _INLINE_ +#if defined(__GNUC__) && _SLANG_USE_INLINE_CODE +# define _INLINE_ __inline__ +#else +# define _INLINE_ +#endif + + +#endif /* _PRIVATE_SLANG_H_ */ diff --git a/slang/include/jdmacros.h b/slang/include/jdmacros.h new file mode 100644 index 000000000..2ecdd9716 --- /dev/null +++ b/slang/include/jdmacros.h @@ -0,0 +1,20 @@ +/* Fully rewritten to use glib */ + +#ifndef _JD_MACROS_H_ +#define _JD_MACROS_H_ + +#include + +#ifndef SLMEMSET +#define SLMEMSET memset +#endif + +#ifndef SLMEMCPY +#define SLMEMCPY memcpy +#endif + +#define SLfree(x) g_free(x) +#define SLmalloc(x) g_malloc(x) +#define _SLvsnprintf g_vsnprintf + +#endif /* _JD_MACROS_H_ */ diff --git a/slang/include/sl-feat.h b/slang/include/sl-feat.h new file mode 100644 index 000000000..c13a9032c --- /dev/null +++ b/slang/include/sl-feat.h @@ -0,0 +1,61 @@ +/* Setting this to 1 enables automatic support for associative arrays. + * If this is set to 0, an application must explicitly enable associative + * array support via SLang_init_slassoc. + */ +#define SLANG_HAS_ASSOC_ARRAYS 1 + +#define SLANG_HAS_COMPLEX 1 +#define SLANG_HAS_FLOAT 1 + +/* This is the old space-speed trade off. To reduce memory usage and code + * size, set this to zero. + */ +/*#define _SLANG_OPTIMIZE_FOR_SPEED 2 */ +#define _SLANG_OPTIMIZE_FOR_SPEED 2 + +#define _SLANG_USE_INLINE_CODE 1 + +/* This is experimental. It adds extra information for tracking down + * errors. + */ +#define _SLANG_HAS_DEBUG_CODE 1 + +/* Allow optimizations based upon the __tmp operator. */ +#define _SLANG_USE_TMP_OPTIMIZATION 1 + +/* Setting this to one will map 8 bit vtxxx terminals to 7 bit. Terminals + * such as the vt320 can be set up to output the two-character escape sequence + * encoded as 'ESC [' as single character. Setting this variable to 1 will + * insert code to map such characters to the 7 bit equivalent. + * This affects just input characters in the range 128-160 on non PC + * systems. + */ +#if defined(VMS) || defined(AMIGA) +# define _SLANG_MAP_VTXXX_8BIT 1 +#else +# define _SLANG_MAP_VTXXX_8BIT 0 +#endif + +/* Add support for color terminals that cannot do background color erases + * Such terminals are poorly designed and are slowly disappearing but they + * are still quite common. For example, screen is one of them! + * + * This is experimental. In particular, it is not known to work if + * KANJI suupport is enabled. + */ +#if !defined(IBMPC_SYSTEM) +# define SLTT_HAS_NON_BCE_SUPPORT 1 +#else +# define SLTT_HAS_NON_BCE_SUPPORT 0 +#endif + +/* If you want slang to assume that an xterm always has the background color + * erase feature, then set this to 1. Otherwise, it will check the terminfo + * database. This may or may not be a good idea since most good color xterms + * support bce but many terminfo systems do not support it. + */ +#define SLTT_XTERM_ALWAYS_BCE 0 + +/* Set this to 1 to enable Kanji support. See above comment. */ +#define SLANG_HAS_KANJI_SUPPORT 0 + diff --git a/slang/include/slang.h b/slang/include/slang.h new file mode 100644 index 000000000..af7a1592c --- /dev/null +++ b/slang/include/slang.h @@ -0,0 +1,1947 @@ +#ifndef DAVIS_SLANG_H_ +#define DAVIS_SLANG_H_ +/* -*- mode: C; mode: fold; -*- */ +/* Copyright (c) 1992, 1999, 2001, 2002 John E. Davis + * This file is part of the S-Lang library. + * + * You may distribute under the terms of either the GNU General Public + * License or the Perl Artistic License. + */ +#define SLANG_VERSION 10405 +#define SLANG_VERSION_STRING "1.4.5" + +/*{{{ System Dependent Macros and Typedefs */ + +#if defined(__WATCOMC__) && defined(DOS) +# ifndef __MSDOS__ +# define __MSDOS__ +# endif +# ifndef DOS386 +# define DOS386 +# endif +# ifndef IBMPC_SYSTEM +# define IBMPC_SYSTEM +# endif +#endif /* __watcomc__ */ + +#if defined(unix) || defined(__unix) +# ifndef __unix__ +# define __unix__ 1 +# endif +#endif + +#if !defined(__GO32__) +# ifdef __unix__ +# define REAL_UNIX_SYSTEM +# endif +#endif + +/* Set of the various defines for pc systems. This includes OS/2 */ +#ifdef __GO32__ +# ifndef __DJGPP__ +# define __DJGPP__ 1 +# endif +# ifndef IBMPC_SYSTEM +# define IBMPC_SYSTEM +# endif +#endif + +#ifdef __BORLANDC__ +# ifndef IBMPC_SYSTEM +# define IBMPC_SYSTEM +# endif +#endif + +#ifdef __MSDOS__ +# ifndef IBMPC_SYSTEM +# define IBMPC_SYSTEM +# endif +#endif + +#if defined(OS2) || defined(__os2__) +# ifndef IBMPC_SYSTEM +# define IBMPC_SYSTEM +# endif +# ifndef __os2__ +# define __os2__ +# endif +#endif + +#if defined(__NT__) || defined(__MINGW32__) /* || defined(__CYGWIN32__) */ +# ifndef IBMPC_SYSTEM +# define IBMPC_SYSTEM +# endif +#endif + +#if defined(IBMPC_SYSTEM) || defined(VMS) +# ifdef REAL_UNIX_SYSTEM +# undef REAL_UNIX_SYSTEM +# endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif +#if 0 +} +#endif + +#include +#include +#if defined(__STDC__) || defined(__BORLANDC__) || defined(__cplusplus) +# include /* for offsetof */ +#endif + +/* ---------------------------- Generic Macros ----------------------------- */ + +/* __SC__ is defined for Symantec C++ + DOS386 is defined for -mx memory model, 32 bit DOS extender. */ + +#if defined(__SC__) && !defined(DOS386) +# include +#endif + +#if defined(__BORLANDC__) +# include +#endif + +#if defined (__cplusplus) || defined(__STDC__) || defined(IBMPC_SYSTEM) + typedef void *VOID_STAR; +#else + typedef unsigned char *VOID_STAR; +#endif + +typedef int (*FVOID_STAR)(void); + +#if defined(__MSDOS__) && defined(__BORLANDC__) +# define SLFREE(buf) farfree((void far *)(buf)) +# define SLMALLOC(x) farmalloc((unsigned long) (x)) +# define SLREALLOC(buf, n) farrealloc((void far *) (buf), (unsigned long) (n)) +# define SLCALLOC(n, m) farcalloc((unsigned long) (n), (unsigned long) (m)) +#else +# if defined(VMS) && !defined(__DECC) +# define SLFREE VAXC$FREE_OPT +# define SLMALLOC VAXC$MALLOC_OPT +# define SLREALLOC VAXC$REALLOC_OPT +# define SLCALLOC VAXC$CALLOC_OPT +# else +# define SLFREE(x) free((char *)(x)) +# define SLMALLOC malloc +# define SLREALLOC realloc +# define SLCALLOC calloc +# endif +#endif + + extern char *SLdebug_malloc (unsigned long); + extern char *SLdebug_calloc (unsigned long, unsigned long); + extern char *SLdebug_realloc (char *, unsigned long); + extern void SLdebug_free (char *); + extern void SLmalloc_dump_statistics (void); + extern char *SLstrcpy(register char *, register char *); + extern int SLstrcmp(register char *, register char *); + extern char *SLstrncpy(char *, register char *, register int); + + extern void SLmemset (char *, char, int); + extern char *SLmemchr (register char *, register char, register int); + extern char *SLmemcpy (char *, char *, int); + extern int SLmemcmp (char *, char *, int); + +/*}}}*/ + +/*{{{ Interpreter Typedefs */ + +typedef unsigned char SLtype; /* This will be unsigned int in V2 */ + +typedef struct _SLang_Name_Type +{ + char *name; + struct _SLang_Name_Type *next; + char name_type; + /* These values must be less than 0x10 because they map directly + * to byte codes. See _slang.h. + */ +#define SLANG_LVARIABLE 0x01 +#define SLANG_GVARIABLE 0x02 +#define SLANG_IVARIABLE 0x03 /* intrinsic variables */ + /* Note!!! For Macro MAKE_VARIABLE below to work, SLANG_IVARIABLE Must + be 1 less than SLANG_RVARIABLE!!! */ +#define SLANG_RVARIABLE 0x04 /* read only variable */ +#define SLANG_INTRINSIC 0x05 +#define SLANG_FUNCTION 0x06 +#define SLANG_MATH_UNARY 0x07 +#define SLANG_APP_UNARY 0x08 +#define SLANG_ICONSTANT 0x09 +#define SLANG_DCONSTANT 0x0A +#define SLANG_PVARIABLE 0x0B /* private */ +#define SLANG_PFUNCTION 0x0C /* private */ + + /* Rest of fields depend on name type */ +} +SLang_Name_Type; + +typedef struct +{ + char *name; + struct _SLang_Name_Type *next; /* this is for the hash table */ + char name_type; + + FVOID_STAR i_fun; /* address of object */ + + /* Do not change this without modifying slang.c:execute_intrinsic_fun */ +#define SLANG_MAX_INTRIN_ARGS 7 + SLtype arg_types [SLANG_MAX_INTRIN_ARGS]; + unsigned char num_args; + SLtype return_type; +} +SLang_Intrin_Fun_Type; + +typedef struct +{ + char *name; + SLang_Name_Type *next; + char name_type; + + VOID_STAR addr; + SLtype type; +} +SLang_Intrin_Var_Type; + +typedef struct +{ + char *name; + SLang_Name_Type *next; + char name_type; + + int unary_op; +} +SLang_App_Unary_Type; + +typedef struct +{ + char *name; + SLang_Name_Type *next; + char name_type; + + int unary_op; +} +SLang_Math_Unary_Type; + +typedef struct +{ + char *name; + SLang_Name_Type *next; + char name_type; + int i; +} +SLang_IConstant_Type; + +typedef struct +{ + char *name; + SLang_Name_Type *next; + char name_type; + double d; +} +SLang_DConstant_Type; + +typedef struct +{ + char *field_name; + unsigned int offset; + SLtype type; + unsigned char read_only; +} +SLang_IStruct_Field_Type; + +extern int SLadd_intrin_fun_table (SLang_Intrin_Fun_Type *, char *); +extern int SLadd_intrin_var_table (SLang_Intrin_Var_Type *, char *); +extern int SLadd_app_unary_table (SLang_App_Unary_Type *, char *); +extern int SLadd_math_unary_table (SLang_Math_Unary_Type *, char *); +extern int SLadd_iconstant_table (SLang_IConstant_Type *, char *); +extern int SLadd_dconstant_table (SLang_DConstant_Type *, char *); +extern int SLadd_istruct_table (SLang_IStruct_Field_Type *, VOID_STAR, char *); + +typedef struct _SLang_NameSpace_Type SLang_NameSpace_Type; + +extern int SLns_add_intrin_fun_table (SLang_NameSpace_Type *, SLang_Intrin_Fun_Type *, char *); +extern int SLns_add_intrin_var_table (SLang_NameSpace_Type *, SLang_Intrin_Var_Type *, char *); +extern int SLns_add_app_unary_table (SLang_NameSpace_Type *, SLang_App_Unary_Type *, char *); +extern int SLns_add_math_unary_table (SLang_NameSpace_Type *, SLang_Math_Unary_Type *, char *); +extern int SLns_add_iconstant_table (SLang_NameSpace_Type *, SLang_IConstant_Type *, char *); +extern int SLns_add_dconstant_table (SLang_NameSpace_Type *, SLang_DConstant_Type *, char *); +extern int SLns_add_istruct_table (SLang_NameSpace_Type *, SLang_IStruct_Field_Type *, VOID_STAR, char *); + +extern SLang_NameSpace_Type *SLns_create_namespace (char *); +extern void SLns_delete_namespace (SLang_NameSpace_Type *); + +typedef struct SLang_Load_Type +{ + int type; + + VOID_STAR client_data; + /* Pointer to data that client needs for loading */ + + int auto_declare_globals; + /* if non-zero, undefined global variables are declared as static */ + + char *(*read)(struct SLang_Load_Type *); + /* function to call to read next line from obj. */ + + unsigned int line_num; + /* Number of lines read, used for error reporting */ + + int parse_level; + /* 0 if at top level of parsing */ + + char *name; + /* Name of this object, e.g., filename. This name should be unique because + * it alone determines the name space for static objects associated with + * the compilable unit. + */ + + unsigned long reserved[4]; + /* For future expansion */ +} SLang_Load_Type; + +extern SLang_Load_Type *SLallocate_load_type (char *); +extern void SLdeallocate_load_type (SLang_Load_Type *); + +/* Returns SLang_Error upon failure */ +extern int SLang_load_object (SLang_Load_Type *); +extern int (*SLang_Load_File_Hook)(char *); +extern int (*SLang_Auto_Declare_Var_Hook) (char *); + +extern int SLang_generate_debug_info (int); + + +#if defined(ultrix) && !defined(__GNUC__) +# ifndef NO_PROTOTYPES +# define NO_PROTOTYPES +# endif +#endif + +#ifndef NO_PROTOTYPES +# define _PROTO(x) x +#else +# define _PROTO(x) () +#endif + +typedef struct SL_OOBinary_Type +{ + SLtype data_type; /* partner type for binary op */ + + int (*binary_function)_PROTO((int, + SLtype, VOID_STAR, unsigned int, + SLtype, VOID_STAR, unsigned int, + VOID_STAR)); + + int (*binary_result) _PROTO((int, SLtype, SLtype, SLtype *)); + struct SL_OOBinary_Type *next; +} +SL_OOBinary_Type; + +typedef struct _SL_Typecast_Type +{ + SLtype data_type; /* to_type */ + int allow_implicit; + + int (*typecast)_PROTO((SLtype, VOID_STAR, unsigned int, + SLtype, VOID_STAR)); + struct _SL_Typecast_Type *next; +} +SL_Typecast_Type; + +typedef struct _SLang_Struct_Type SLang_Struct_Type; +typedef struct _SLang_Foreach_Context_Type SLang_Foreach_Context_Type; + +#if 0 +#if defined(SL_APP_WANTS_FOREACH) +typedef struct _SLang_Foreach_Context_Type SLang_Foreach_Context_Type; +/* It is up to the application to define struct _SLang_Foreach_Context_Type */ +#else +typedef int SLang_Foreach_Context_Type; +#endif +#endif + +typedef struct +{ + unsigned char cl_class_type; +#define SLANG_CLASS_TYPE_MMT 0 +#define SLANG_CLASS_TYPE_SCALAR 1 +#define SLANG_CLASS_TYPE_VECTOR 2 +#define SLANG_CLASS_TYPE_PTR 3 + + unsigned int cl_data_type; /* SLANG_INTEGER_TYPE, etc... */ + char *cl_name; /* slstring type */ + + unsigned int cl_sizeof_type; + VOID_STAR cl_transfer_buf; /* cl_sizeof_type bytes*/ + + /* Methods */ + + /* Most of the method functions are prototyped: + * int method (SLtype type, VOID_STAR addr); + * Here, @type@ represents the type of object that the method is asked + * to deal with. The second parameter @addr@ will contain the ADDRESS of + * the object. For example, if type is SLANG_INT_TYPE, then @addr@ will + * actually be int *. Similary, if type is SLANG_STRING_TYPE, + * then @addr@ will contain the address of the string, i.e., char **. + */ + + void (*cl_destroy)_PROTO((SLtype, VOID_STAR)); + /* Prototype: void destroy(unsigned type, VOID_STAR val) + * Called to delete/free the object */ + + char *(*cl_string)_PROTO((SLtype, VOID_STAR)); + /* Prototype: char *to_string (SLtype t, VOID_STAR p); + * Here p is a pointer to the object for which a string representation + * is to be returned. The returned pointer is to be a MALLOCED string. + */ + + /* Prototype: void push(SLtype type, VOID_STAR v); + * Push a copy of the object of type @type@ at address @v@ onto the + * stack. + */ + int (*cl_push)_PROTO((SLtype, VOID_STAR)); + + /* Prototype: int pop(SLtype type, VOID_STAR v); + * Pops value from stack and assign it to object, whose address is @v@. + */ + int (*cl_pop)_PROTO((SLtype, VOID_STAR)); + + int (*cl_unary_op_result_type)_PROTO((int, SLtype, SLtype *)); + int (*cl_unary_op)_PROTO((int, SLtype, VOID_STAR, unsigned int, VOID_STAR)); + + int (*cl_app_unary_op_result_type)_PROTO((int, SLtype, SLtype *)); + int (*cl_app_unary_op)_PROTO((int, SLtype, VOID_STAR, unsigned int, VOID_STAR)); + + /* If this function is non-NULL, it will be called for sin, cos, etc... */ +#define SLMATH_SIN 1 +#define SLMATH_COS 2 +#define SLMATH_TAN 3 +#define SLMATH_ATAN 4 +#define SLMATH_ASIN 5 +#define SLMATH_ACOS 6 +#define SLMATH_EXP 7 +#define SLMATH_LOG 8 +#define SLMATH_SQRT 9 +#define SLMATH_LOG10 10 +#define SLMATH_REAL 11 +#define SLMATH_IMAG 12 +#define SLMATH_SINH 13 +#define SLMATH_COSH 14 +#define SLMATH_TANH 15 +#define SLMATH_ATANH 16 +#define SLMATH_ASINH 17 +#define SLMATH_ACOSH 18 +#define SLMATH_TODOUBLE 19 +#define SLMATH_CONJ 20 + + int (*cl_math_op)_PROTO((int, SLtype, VOID_STAR, unsigned int, VOID_STAR)); + int (*cl_math_op_result_type)_PROTO((int, SLtype, SLtype *)); + + SL_OOBinary_Type *cl_binary_ops; + SL_Typecast_Type *cl_typecast_funs; + + void (*cl_byte_code_destroy)_PROTO((SLtype, VOID_STAR)); + void (*cl_user_destroy_fun)_PROTO((SLtype, VOID_STAR)); + int (*cl_init_array_object)_PROTO((SLtype, VOID_STAR)); + int (*cl_datatype_deref)_PROTO((SLtype)); + SLang_Struct_Type *cl_struct_def; + int (*cl_dereference) _PROTO((SLtype, VOID_STAR)); + int (*cl_acopy) (SLtype, VOID_STAR, VOID_STAR); + int (*cl_apop) _PROTO((SLtype, VOID_STAR)); + int (*cl_apush) _PROTO((SLtype, VOID_STAR)); + int (*cl_push_literal) _PROTO((SLtype, VOID_STAR)); + void (*cl_adestroy)_PROTO((SLtype, VOID_STAR)); + int (*cl_push_intrinsic)_PROTO((SLtype, VOID_STAR)); + int (*cl_void_typecast)_PROTO((SLtype, VOID_STAR, unsigned int, SLtype, VOID_STAR)); + + int (*cl_anytype_typecast)_PROTO((SLtype, VOID_STAR, unsigned int, SLtype, VOID_STAR)); + + /* Array access functions */ + int (*cl_aput) (SLtype, unsigned int); + int (*cl_aget) (SLtype, unsigned int); + int (*cl_anew) (SLtype, unsigned int); + + /* length method */ + int (*cl_length) (SLtype, VOID_STAR, unsigned int *); + + /* foreach */ + SLang_Foreach_Context_Type *(*cl_foreach_open) (SLtype, unsigned int); + void (*cl_foreach_close) (SLtype, SLang_Foreach_Context_Type *); + int (*cl_foreach) (SLtype, SLang_Foreach_Context_Type *); + + /* Structure access: get and put (assign to) fields */ + int (*cl_sput) (SLtype, char *); + int (*cl_sget) (SLtype, char *); + + /* File I/O */ + int (*cl_fread) (SLtype, FILE *, VOID_STAR, unsigned int, unsigned int *); + int (*cl_fwrite) (SLtype, FILE *, VOID_STAR, unsigned int, unsigned int *); + int (*cl_fdread) (SLtype, int, VOID_STAR, unsigned int, unsigned int *); + int (*cl_fdwrite) (SLtype, int, VOID_STAR, unsigned int, unsigned int *); + + int (*cl_to_bool) (SLtype, int *); + + int (*cl_cmp)(SLtype, VOID_STAR, VOID_STAR, int *); +} SLang_Class_Type; + +/* These are the low-level functions for building push/pop methods. They + * know nothing about memory management. For SLANG_CLASS_TYPE_MMT, use the + * MMT push/pop functions instead. + */ +extern int SLclass_push_double_obj (SLtype, double); +extern int SLclass_push_float_obj (SLtype, float); +extern int SLclass_push_long_obj (SLtype, long); +extern int SLclass_push_int_obj (SLtype, int); +extern int SLclass_push_short_obj (SLtype, short); +extern int SLclass_push_char_obj (SLtype, char); +extern int SLclass_push_ptr_obj (SLtype, VOID_STAR); +extern int SLclass_pop_double_obj (SLtype, double *); +extern int SLclass_pop_float_obj (SLtype, float *); +extern int SLclass_pop_long_obj (SLtype, long *); +extern int SLclass_pop_int_obj (SLtype, int *); +extern int SLclass_pop_short_obj (SLtype, short *); +extern int SLclass_pop_char_obj (SLtype, char *); +extern int SLclass_pop_ptr_obj (SLtype, VOID_STAR *); + +extern SLang_Class_Type *SLclass_allocate_class (char *); +extern int SLclass_get_class_id (SLang_Class_Type *cl); +extern int SLclass_create_synonym (char *, SLtype); +extern int SLclass_is_class_defined (SLtype); +extern int SLclass_dup_object (SLtype type, VOID_STAR from, VOID_STAR to); + +extern int SLclass_register_class (SLang_Class_Type *, SLtype, unsigned int, SLtype); +extern int SLclass_set_string_function (SLang_Class_Type *, char *(*)(SLtype, VOID_STAR)); +extern int SLclass_set_destroy_function (SLang_Class_Type *, void (*)(SLtype, VOID_STAR)); +extern int SLclass_set_push_function (SLang_Class_Type *, int (*)(SLtype, VOID_STAR)); +extern int SLclass_set_pop_function (SLang_Class_Type *, int (*)(SLtype, VOID_STAR)); + +extern int SLclass_set_aget_function (SLang_Class_Type *, int (*)(SLtype, unsigned int)); +extern int SLclass_set_aput_function (SLang_Class_Type *, int (*)(SLtype, unsigned int)); +extern int SLclass_set_anew_function (SLang_Class_Type *, int (*)(SLtype, unsigned int)); + +extern int SLclass_set_sget_function (SLang_Class_Type *, int (*)(SLtype, char *)); +extern int SLclass_set_sput_function (SLang_Class_Type *, int (*)(SLtype, char *)); + +extern int SLclass_set_acopy_function (SLang_Class_Type *, int (*)(SLtype, VOID_STAR, VOID_STAR)); + +/* Typecast object on the stack to type p1. p2 and p3 should be set to 1 */ +extern int SLclass_typecast (SLtype, int, int); + +extern int SLclass_add_unary_op (SLtype, + int (*) (int, + SLtype, VOID_STAR, unsigned int, + VOID_STAR), + int (*) (int, SLtype, SLtype *)); + +extern int +SLclass_add_app_unary_op (SLtype, + int (*) (int, + SLtype, VOID_STAR, unsigned int, + VOID_STAR), + int (*) (int, SLtype, SLtype *)); + +extern int +SLclass_add_binary_op (SLtype, SLtype, + int (*) (int, + SLtype, VOID_STAR, unsigned int, + SLtype, VOID_STAR, unsigned int, + VOID_STAR), + int (*) (int, SLtype, SLtype, SLtype *)); + +extern int +SLclass_add_math_op (SLtype, + int (*)(int, + SLtype, VOID_STAR, unsigned int, + VOID_STAR), + int (*)(int, SLtype, SLtype *)); + +extern int +SLclass_add_typecast (SLtype /* from */, SLtype /* to */, + int (*)_PROTO((SLtype, VOID_STAR, unsigned int, + SLtype, VOID_STAR)), + int /* allow implicit typecasts */ + ); + +extern char *SLclass_get_datatype_name (SLtype); + +extern double SLcomplex_abs (double *); +extern double *SLcomplex_times (double *, double *, double *); +extern double *SLcomplex_divide (double *, double *, double *); +extern double *SLcomplex_sin (double *, double *); +extern double *SLcomplex_cos (double *, double *); +extern double *SLcomplex_tan (double *, double *); +extern double *SLcomplex_asin (double *, double *); +extern double *SLcomplex_acos (double *, double *); +extern double *SLcomplex_atan (double *, double *); +extern double *SLcomplex_exp (double *, double *); +extern double *SLcomplex_log (double *, double *); +extern double *SLcomplex_log10 (double *, double *); +extern double *SLcomplex_sqrt (double *, double *); +extern double *SLcomplex_sinh (double *, double *); +extern double *SLcomplex_cosh (double *, double *); +extern double *SLcomplex_tanh (double *, double *); +extern double *SLcomplex_pow (double *, double *, double *); +extern double SLmath_hypot (double x, double y); + +/* Not implemented yet */ +extern double *SLcomplex_asinh (double *, double *); +extern double *SLcomplex_acosh (double *, double *); +extern double *SLcomplex_atanh (double *, double *); + +#ifdef _SLANG_SOURCE_ +typedef struct _SLang_MMT_Type SLang_MMT_Type; +#else +typedef int SLang_MMT_Type; +#endif + +extern void SLang_free_mmt (SLang_MMT_Type *); +extern VOID_STAR SLang_object_from_mmt (SLang_MMT_Type *); +extern SLang_MMT_Type *SLang_create_mmt (SLtype, VOID_STAR); +extern int SLang_push_mmt (SLang_MMT_Type *); +extern SLang_MMT_Type *SLang_pop_mmt (SLtype); +extern void SLang_inc_mmt (SLang_MMT_Type *); + +/* Maximum number of dimensions of an array. */ +#define SLARRAY_MAX_DIMS 7 +typedef struct _SLang_Array_Type +{ + SLtype data_type; + unsigned int sizeof_type; + VOID_STAR data; + unsigned int num_elements; + unsigned int num_dims; + int dims [SLARRAY_MAX_DIMS]; + VOID_STAR (*index_fun)_PROTO((struct _SLang_Array_Type *, int *)); + /* This function is designed to allow a type to store an array in + * any manner it chooses. This function returns the address of the data + * value at the specified index location. + */ + unsigned int flags; +#define SLARR_DATA_VALUE_IS_READ_ONLY 1 +#define SLARR_DATA_VALUE_IS_POINTER 2 +#define SLARR_DATA_VALUE_IS_RANGE 4 +#define SLARR_DATA_VALUE_IS_INTRINSIC 8 + SLang_Class_Type *cl; + unsigned int num_refs; + void (*free_fun)_PROTO((struct _SLang_Array_Type *)); + VOID_STAR client_data; +} +SLang_Array_Type; + +extern int SLang_pop_array_of_type (SLang_Array_Type **, SLtype); +extern int SLang_pop_array (SLang_Array_Type **, int); +extern int SLang_push_array (SLang_Array_Type *, int); +extern void SLang_free_array (SLang_Array_Type *); +extern SLang_Array_Type *SLang_create_array (SLtype, int, VOID_STAR, int *, unsigned int); +extern SLang_Array_Type *SLang_duplicate_array (SLang_Array_Type *); +extern int SLang_get_array_element (SLang_Array_Type *, int *, VOID_STAR); +extern int SLang_set_array_element (SLang_Array_Type *, int *, VOID_STAR); + + +/*}}}*/ + +/*{{{ Interpreter Function Prototypes */ + + extern volatile int SLang_Error; +/* Non zero if error occurs. Must be reset to zero to continue. */ +/* error codes, severe errors are less than 0 */ +#define SL_APPLICATION_ERROR -2 +#define SL_VARIABLE_UNINITIALIZED -3 +#define SL_INTERNAL_ERROR -5 +#define SL_STACK_OVERFLOW -6 +#define SL_STACK_UNDERFLOW -7 +#define SL_UNDEFINED_NAME -8 +#define SL_SYNTAX_ERROR -9 +#define SL_DUPLICATE_DEFINITION -10 +#define SL_TYPE_MISMATCH -11 +#define SL_OBJ_UNKNOWN -13 +#define SL_UNKNOWN_ERROR -14 +#define SL_TYPE_UNDEFINED_OP_ERROR -16 + +#define SL_INTRINSIC_ERROR 1 +/* Intrinsic error is an error generated by intrinsic functions */ +#define SL_USER_BREAK 2 +#define SL_DIVIDE_ERROR 3 +#define SL_OBJ_NOPEN 4 +#define SL_USER_ERROR 5 +#define SL_USAGE_ERROR 6 +#define SL_READONLY_ERROR 7 +#define SL_INVALID_PARM 8 +#define SL_NOT_IMPLEMENTED 9 +#define SL_MALLOC_ERROR 10 +#define SL_OVERFLOW 11 +#define SL_FLOATING_EXCEPTION 12 + +/* Compatibility */ +#define USER_BREAK SL_USER_BREAK +#define INTRINSIC_ERROR SL_INTRINSIC_ERROR + + extern int SLang_Traceback; + /* If non-zero, dump an S-Lang traceback upon error. Available as + _traceback in S-Lang. */ + + extern char *SLang_User_Prompt; + /* Prompt to use when reading from stdin */ + extern int SLang_Version; + extern char *SLang_Version_String; +extern char *SLang_Doc_Dir; + +extern void (*SLang_VMessage_Hook) (char *, va_list); +extern void SLang_vmessage (char *, ...); + + extern void (*SLang_Error_Hook)(char *); + /* Pointer to application dependent error messaging routine. By default, + messages are displayed on stderr. */ + + extern void (*SLang_Exit_Error_Hook)(char *, va_list); + extern void SLang_exit_error (char *, ...); + extern void (*SLang_Dump_Routine)(char *); + /* Called if S-Lang traceback is enabled as well as other debugging + routines (e.g., trace). By default, these messages go to stderr. */ + + extern void (*SLang_Interrupt)(void); + /* function to call whenever inner interpreter is entered. This is + a good place to set SLang_Error to USER_BREAK. */ + + extern void (*SLang_User_Clear_Error)(void); + /* function that gets called when '_clear_error' is called. */ + + /* If non null, these call C functions before and after a slang function. */ + extern void (*SLang_Enter_Function)(char *); +extern void (*SLang_Exit_Function)(char *); + +extern int SLang_Num_Function_Args; + +/* Functions: */ + +extern int SLang_init_all (void); +/* Initializes interpreter and all modules */ + +extern int SLang_init_slang (void); +/* This function is mandatory and must be called by all applications that + * use the interpreter + */ +extern int SLang_init_posix_process (void); /* process specific intrinsics */ +extern int SLang_init_stdio (void); /* fgets, etc. stdio functions */ +extern int SLang_init_posix_dir (void); +extern int SLang_init_ospath (void); + +extern int SLang_init_slmath (void); +/* called if math functions sin, cos, etc... are needed. */ + + extern int SLang_init_slfile (void); + extern int SLang_init_slunix (void); + /* These functions are obsolte. Use init_stdio, posix_process, etc. */ + +extern int SLang_init_slassoc (void); +/* Assoc Arrays (Hashes) */ + +extern int SLang_init_array (void); +/* Additional arrays functions: transpose, etc... */ + +/* Dynamic linking facility */ +extern int SLang_init_import (void); + + extern int SLang_load_file (char *); + /* Load a file of S-Lang code for interpreting. If the parameter is + * NULL, input comes from stdin. */ + + extern void SLang_restart(int); + /* should be called if an error occurs. If the passed integer is + * non-zero, items are popped off the stack; otherwise, the stack is + * left intact. Any time the stack is believed to be trashed, this routine + * should be called with a non-zero argument (e.g., if setjmp/longjmp is + * called). */ + + extern int SLang_byte_compile_file(char *, int); + /* takes a file of S-Lang code and ``byte-compiles'' it for faster + * loading. The new filename is equivalent to the old except that a `c' is + * appended to the name. (e.g., init.sl --> init.slc). The second + * specified the method; currently, it is not used. + */ + + extern int SLang_autoload(char *, char *); + /* Automatically load S-Lang function p1 from file p2. This function + is also available via S-Lang */ + + extern int SLang_load_string(char *); + /* Like SLang_load_file except input is from a null terminated string. */ + + extern int SLdo_pop(void); + /* pops item off stack and frees any memory associated with it */ + extern int SLdo_pop_n(unsigned int); + /* pops n items off stack and frees any memory associated with them */ + +extern int SLang_pop_datatype (SLtype *); +extern int SLang_push_datatype (SLtype); + +extern int SLang_pop_integer(int *); +extern int SLang_pop_uinteger(unsigned int *); + /* pops integer *p0 from the stack. Returns 0 upon success and non-zero + * if the stack is empty or a type mismatch occurs, setting SLang_Error. + */ +extern int SLang_pop_char (char *); +extern int SLang_pop_uchar (SLtype *); +extern int SLang_pop_short(short *); +extern int SLang_pop_ushort(unsigned short *); +extern int SLang_pop_long(long *); +extern int SLang_pop_ulong(unsigned long *); + +extern int SLang_pop_float(float *); +extern int SLang_pop_double(double *, int *, int *); + /* Pops double *p1 from stack. If *p3 is non-zero, *p1 was derived + from the integer *p2. Returns zero upon success. */ + + extern int SLang_pop_complex (double *, double *); + + extern int SLpop_string (char **); + extern int SLang_pop_string(char **, int *); + /* pops string *p0 from stack. If *p1 is non-zero, the string must be + * freed after its use. DO NOT FREE p0 if *p1 IS ZERO! Returns 0 upon + * success */ + + extern int SLang_push_complex (double, double); + + extern int SLang_push_char (char); + extern int SLang_push_uchar (SLtype); + + extern int SLang_push_integer(int); + extern int SLang_push_uinteger(unsigned int); + /* push integer p1 on stack */ + + extern int SLang_push_short(short); + extern int SLang_push_ushort(unsigned short); + extern int SLang_push_long(long); + extern int SLang_push_ulong(unsigned long); + extern int SLang_push_float(float); + extern int SLang_push_double(double); + /* Push double onto stack */ + + extern int SLang_push_string(char *); + /* Push string p1 onto stack */ + + extern int SLang_push_malloced_string(char *); + /* The normal SLang_push_string pushes an slstring. This one converts + * a normally malloced string to an slstring, and then frees the + * malloced string. So, do NOT use the malloced string after calling + * this routine because it will be freed! The routine returns -1 upon + * error, but the string will be freed. + */ + +extern int SLang_push_null (void); +extern int SLang_pop_null (void); + +extern int SLang_push_value (SLtype type, VOID_STAR); +extern int SLang_pop_value (SLtype type, VOID_STAR); +extern void SLang_free_value (SLtype type, VOID_STAR); + +typedef struct _SLang_Object_Type SLang_Any_Type; + +extern int SLang_pop_anytype (SLang_Any_Type **); +extern int SLang_push_anytype (SLang_Any_Type *); +extern void SLang_free_anytype (SLang_Any_Type *); + +#ifdef _SLANG_SOURCE_ +typedef struct _SLang_Ref_Type SLang_Ref_Type; +#else +typedef int SLang_Ref_Type; +#endif + +extern int SLang_pop_ref (SLang_Ref_Type **); +extern void SLang_free_ref (SLang_Ref_Type *); +extern int SLang_assign_to_ref (SLang_Ref_Type *, SLtype, VOID_STAR); +extern SLang_Name_Type *SLang_pop_function (void); +extern SLang_Name_Type *SLang_get_fun_from_ref (SLang_Ref_Type *); +extern void SLang_free_function (SLang_Name_Type *f); + + extern int SLang_is_defined(char *); + /* Return non-zero is p1 is defined otherwise returns 0. */ + + extern int SLang_run_hooks(char *, unsigned int, ...); + /* calls S-Lang function p1 pushing p2 strings in the variable argument + * list onto the stack first. + * Returns -1 upon error, 1 if hooks exists and it ran, + * or 0 if hook does not exist. Thus it returns non-zero is hook was called. + */ + +/* These functions return 1 if the indicated function exists and the function + * runs without error. If the function does not exist, the function returns + * 0. Otherwise -1 is returned with SLang_Error set appropriately. + */ +extern int SLexecute_function (SLang_Name_Type *); +extern int SLang_execute_function(char *); + + +extern int SLang_end_arg_list (void); +extern int SLang_start_arg_list (void); + +extern void SLang_verror (int, char *, ...); + +extern void SLang_doerror(char *); + /* set SLang_Error and display p1 as error message */ + +extern int SLang_add_intrinsic_array (char *, /* name */ + SLtype, /* type */ + int, /* readonly */ + VOID_STAR, /* data */ + unsigned int, ...); /* num dims */ + +extern int SLextract_list_element (char *, unsigned int, char, + char *, unsigned int); + +extern void SLexpand_escaped_string (register char *, register char *, + register char *); + +extern SLang_Name_Type *SLang_get_function (char *); +extern void SLang_release_function (SLang_Name_Type *); + +extern int SLreverse_stack (int); +extern int SLroll_stack (int); +/* If argument p is positive, the top p objects on the stack are rolled + * up. If negative, the stack is rolled down. + */ +extern int SLdup_n (int n); +/* Duplicate top n elements of stack */ + +extern int SLang_peek_at_stack1 (void); +extern int SLang_peek_at_stack (void); +/* Returns type of next object on stack-- -1 upon stack underflow. */ +extern void SLmake_lut (unsigned char *, unsigned char *, unsigned char); + + extern int SLang_guess_type (char *); + +extern int SLstruct_create_struct (unsigned int, + char **, + SLtype *, + VOID_STAR *); + +/*}}}*/ + +/*{{{ Misc Functions */ + +/* This is an interface to atexit */ +extern int SLang_add_cleanup_function (void (*)(void)); + +extern char *SLmake_string (char *); +extern char *SLmake_nstring (char *, unsigned int); +/* Returns a null terminated string made from the first n characters of the + * string. + */ + +/* The string created by this routine must be freed by SLang_free_slstring + * and nothing else!! Also these strings must not be modified. Use + * SLmake_string if you intend to modify them!! + */ +extern char *SLang_create_nslstring (char *, unsigned int); +extern char *SLang_create_slstring (char *); +extern void SLang_free_slstring (char *); /* handles NULL */ +extern int SLang_pop_slstring (char **); /* free with SLang_free_slstring */ +extern char *SLang_concat_slstrings (char *a, char *b); +extern char *SLang_create_static_slstring (char *); /* adds a string that will not get deleted */ +extern void SLstring_dump_stats (void); + +/* Binary strings */ +/* The binary string is an opaque type. Use the SLbstring_get_pointer function + * to get a pointer and length. + */ +typedef struct _SLang_BString_Type SLang_BString_Type; +extern unsigned char *SLbstring_get_pointer (SLang_BString_Type *, unsigned int *); + +extern SLang_BString_Type *SLbstring_dup (SLang_BString_Type *); +extern SLang_BString_Type *SLbstring_create (unsigned char *, unsigned int); + +/* The create_malloced function used the first argument which is assumed + * to be a pointer to a len + 1 malloced string. The extra byte is for + * \0 termination. + */ +extern SLang_BString_Type *SLbstring_create_malloced (unsigned char *, unsigned int, int); + +/* Create a bstring from an slstring */ +extern SLang_BString_Type *SLbstring_create_slstring (char *); + +extern void SLbstring_free (SLang_BString_Type *); +extern int SLang_pop_bstring (SLang_BString_Type **); +extern int SLang_push_bstring (SLang_BString_Type *); + +extern char *SLmalloc (unsigned int); +extern char *SLcalloc (unsigned int, unsigned int); +extern void SLfree(char *); /* This function handles NULL */ +extern char *SLrealloc (char *, unsigned int); + +extern char *SLcurrent_time_string (void); + +extern int SLatoi(unsigned char *); +extern long SLatol (unsigned char *); +extern unsigned long SLatoul (unsigned char *); + +extern int SLang_pop_fileptr (SLang_MMT_Type **, FILE **); +extern char *SLang_get_name_from_fileptr (SLang_MMT_Type *); + +typedef struct _SLFile_FD_Type SLFile_FD_Type; +extern SLFile_FD_Type *SLfile_create_fd (char *, int); +extern void SLfile_free_fd (SLFile_FD_Type *); +extern int SLfile_push_fd (SLFile_FD_Type *); +extern int SLfile_pop_fd (SLFile_FD_Type **); +extern int SLfile_get_fd (SLFile_FD_Type *, int *); +extern SLFile_FD_Type *SLfile_dup_fd (SLFile_FD_Type *f0); +extern int SLang_init_posix_io (void); + +typedef double (*SLang_To_Double_Fun_Type)(VOID_STAR); +extern SLang_To_Double_Fun_Type SLarith_get_to_double_fun (SLtype, unsigned int *); + +extern int SLang_set_argc_argv (int, char **); + +/*}}}*/ + +/*{{{ SLang getkey interface Functions */ + +#ifdef REAL_UNIX_SYSTEM +extern int SLang_TT_Baud_Rate; +extern int SLang_TT_Read_FD; +#endif + +extern int SLang_init_tty (int, int, int); +/* Initializes the tty for single character input. If the first parameter *p1 + * is in the range 0-255, it will be used for the abort character; + * otherwise, (unix only) if it is -1, the abort character will be the one + * used by the terminal. If the second parameter p2 is non-zero, flow + * control is enabled. If the last parmeter p3 is zero, output processing + * is NOT turned on. A value of zero is required for the screen management + * routines. Returns 0 upon success. In addition, if SLang_TT_Baud_Rate == + * 0 when this function is called, SLang will attempt to determine the + * terminals baud rate. As far as the SLang library is concerned, if + * SLang_TT_Baud_Rate is less than or equal to zero, the baud rate is + * effectively infinite. + */ + +extern void SLang_reset_tty (void); +/* Resets tty to what it was prior to a call to SLang_init_tty */ +#ifdef REAL_UNIX_SYSTEM +extern void SLtty_set_suspend_state (int); + /* If non-zero argument, terminal driver will be told to react to the + * suspend character. If 0, it will not. + */ +extern int (*SLang_getkey_intr_hook) (void); +#endif + +#define SLANG_GETKEY_ERROR 0xFFFF +extern unsigned int SLang_getkey (void); +/* reads a single key from the tty. If the read fails, 0xFFFF is returned. */ + +#ifdef IBMPC_SYSTEM +extern int SLgetkey_map_to_ansi (int); +#endif + +extern int SLang_ungetkey_string (unsigned char *, unsigned int); +extern int SLang_buffer_keystring (unsigned char *, unsigned int); +extern int SLang_ungetkey (unsigned char); +extern void SLang_flush_input (void); +extern int SLang_input_pending (int); +extern int SLang_Abort_Char; +/* The value of the character (0-255) used to trigger SIGINT */ +extern int SLang_Ignore_User_Abort; +/* If non-zero, pressing the abort character will not result in USER_BREAK + * SLang_Error. */ + +extern int SLang_set_abort_signal (void (*)(int)); +/* If SIGINT is generated, the function p1 will be called. If p1 is NULL + * the SLang_default signal handler is called. This sets SLang_Error to + * USER_BREAK. I suspect most users will simply want to pass NULL. + */ +extern unsigned int SLang_Input_Buffer_Len; + +extern volatile int SLKeyBoard_Quit; + +#ifdef VMS +/* If this function returns -1, ^Y will be added to input buffer. */ +extern int (*SLtty_VMS_Ctrl_Y_Hook) (void); +#endif +/*}}}*/ + +/*{{{ SLang Keymap routines */ + +typedef struct SLKeymap_Function_Type +{ + char *name; + int (*f)(void); +} +SLKeymap_Function_Type; + +#define SLANG_MAX_KEYMAP_KEY_SEQ 14 +typedef struct SLang_Key_Type +{ + struct SLang_Key_Type *next; + union + { + char *s; + FVOID_STAR f; + unsigned int keysym; + } + f; + unsigned char type; /* type of function */ +#define SLKEY_F_INTERPRET 0x01 +#define SLKEY_F_INTRINSIC 0x02 +#define SLKEY_F_KEYSYM 0x03 + unsigned char str[SLANG_MAX_KEYMAP_KEY_SEQ + 1];/* key sequence */ +} +SLang_Key_Type; + +typedef struct SLKeyMap_List_Type +{ + char *name; /* hashed string */ + SLang_Key_Type *keymap; + SLKeymap_Function_Type *functions; /* intrinsic functions */ +} +SLKeyMap_List_Type; + +/* This is arbitrary but I have got to start somewhere */ +#define SLANG_MAX_KEYMAPS 30 +extern SLKeyMap_List_Type SLKeyMap_List[SLANG_MAX_KEYMAPS]; + +extern char *SLang_process_keystring(char *); + +extern int SLkm_define_key (char *, FVOID_STAR, SLKeyMap_List_Type *); + +extern int SLang_define_key(char *, char *, SLKeyMap_List_Type *); +/* Like define_key1 except that p2 is a string that is to be associated with + * a function in the functions field of p3. + */ + +extern int SLkm_define_keysym (char *, unsigned int, SLKeyMap_List_Type *); + +extern void SLang_undefine_key(char *, SLKeyMap_List_Type *); + +extern SLKeyMap_List_Type *SLang_create_keymap(char *, SLKeyMap_List_Type *); +/* create and returns a pointer to a new keymap named p1 created by copying + * keymap p2. If p2 is NULL, it is up to the calling routine to initialize + * the keymap. + */ + +extern char *SLang_make_keystring(unsigned char *); + +extern SLang_Key_Type *SLang_do_key(SLKeyMap_List_Type *, int (*)(void)); +/* read a key using keymap p1 with getkey function p2 */ + +extern + FVOID_STAR + SLang_find_key_function(char *, SLKeyMap_List_Type *); + +extern SLKeyMap_List_Type *SLang_find_keymap(char *); + +extern int SLang_Last_Key_Char; +extern int SLang_Key_TimeOut_Flag; + +/*}}}*/ + +/*{{{ SLang Readline Interface */ + +typedef struct SLang_Read_Line_Type +{ + struct SLang_Read_Line_Type *prev, *next; + unsigned char *buf; + int buf_len; /* number of chars in the buffer */ + int num; /* num and misc are application specific*/ + int misc; +} SLang_Read_Line_Type; + +/* Maximum size of display */ +#define SLRL_DISPLAY_BUFFER_SIZE 256 + +typedef struct +{ + SLang_Read_Line_Type *root, *tail, *last; + unsigned char *buf; /* edit buffer */ + int buf_len; /* sizeof buffer */ + int point; /* current editing point */ + int tab; /* tab width */ + int len; /* current line size */ + + /* display variables */ + int edit_width; /* length of display field */ + int curs_pos; /* current column */ + int start_column; /* column offset of display */ + int dhscroll; /* amount to use for horiz scroll */ + char *prompt; + + FVOID_STAR last_fun; /* last function executed by rl */ + + /* These two contain an image of what is on the display */ + unsigned char upd_buf1[SLRL_DISPLAY_BUFFER_SIZE]; + unsigned char upd_buf2[SLRL_DISPLAY_BUFFER_SIZE]; + unsigned char *old_upd, *new_upd; /* pointers to previous two buffers */ + int new_upd_len, old_upd_len; /* length of output buffers */ + + SLKeyMap_List_Type *keymap; + + /* tty variables */ + unsigned int flags; /* */ +#define SL_RLINE_NO_ECHO 1 +#define SL_RLINE_USE_ANSI 2 +#define SL_RLINE_BLINK_MATCH 4 + unsigned int (*getkey)(void); /* getkey function -- required */ + void (*tt_goto_column)(int); + void (*tt_insert)(char); + void (*update_hook)(unsigned char *, int, int); + /* The update hook is called with a pointer to a buffer p1 that contains + * an image of what the update hook is suppoed to produce. The length + * of the buffer is p2 and after the update, the cursor is to be placed + * in column p3. + */ + /* This function is only called when blinking matches */ + int (*input_pending)(int); + unsigned long reserved[4]; +} SLang_RLine_Info_Type; + +extern int SLang_RL_EOF_Char; + +extern SLang_Read_Line_Type * SLang_rline_save_line (SLang_RLine_Info_Type *); +extern int SLang_init_readline (SLang_RLine_Info_Type *); +extern int SLang_read_line (SLang_RLine_Info_Type *); +extern int SLang_rline_insert (char *); +extern void SLrline_redraw (SLang_RLine_Info_Type *); +extern int SLang_Rline_Quit; + +/*}}}*/ + +/*{{{ Low Level Screen Output Interface */ + +extern unsigned long SLtt_Num_Chars_Output; +extern int SLtt_Baud_Rate; + +typedef unsigned long SLtt_Char_Type; + +#define SLTT_BOLD_MASK 0x01000000UL +#define SLTT_BLINK_MASK 0x02000000UL +#define SLTT_ULINE_MASK 0x04000000UL +#define SLTT_REV_MASK 0x08000000UL +#define SLTT_ALTC_MASK 0x10000000UL + +extern int SLtt_Screen_Rows; +extern int SLtt_Screen_Cols; +extern int SLtt_Term_Cannot_Insert; +extern int SLtt_Term_Cannot_Scroll; +extern int SLtt_Use_Ansi_Colors; +extern int SLtt_Ignore_Beep; +#if defined(REAL_UNIX_SYSTEM) +extern int SLtt_Force_Keypad_Init; +extern int SLang_TT_Write_FD; +#endif + +#ifndef IBMPC_SYSTEM +extern char *SLtt_Graphics_Char_Pairs; +#endif + +#ifndef __GO32__ +#if defined(VMS) || defined(REAL_UNIX_SYSTEM) +extern int SLtt_Blink_Mode; +extern int SLtt_Use_Blink_For_ACS; +extern int SLtt_Newline_Ok; +extern int SLtt_Has_Alt_Charset; +extern int SLtt_Has_Status_Line; /* if 0, NO. If > 0, YES, IF -1, ?? */ +# ifndef VMS +extern int SLtt_Try_Termcap; +# endif +#endif +#endif + +#if defined(IBMPC_SYSTEM) +extern int SLtt_Msdos_Cheap_Video; +#endif + +typedef unsigned short SLsmg_Char_Type; +#define SLSMG_EXTRACT_CHAR(x) ((x) & 0xFF) +#define SLSMG_EXTRACT_COLOR(x) (((x)>>8)&0xFF) +#define SLSMG_BUILD_CHAR(ch,color) (((SLsmg_Char_Type)(unsigned char)(ch))|((color)<<8)) + +extern int SLtt_flush_output (void); +extern void SLtt_set_scroll_region(int, int); +extern void SLtt_reset_scroll_region(void); +extern void SLtt_reverse_video (int); +extern void SLtt_bold_video (void); +extern void SLtt_begin_insert(void); +extern void SLtt_end_insert(void); +extern void SLtt_del_eol(void); +extern void SLtt_goto_rc (int, int); +extern void SLtt_delete_nlines(int); +extern void SLtt_delete_char(void); +extern void SLtt_erase_line(void); +extern void SLtt_normal_video(void); +extern void SLtt_cls(void); +extern void SLtt_beep(void); +extern void SLtt_reverse_index(int); +extern void SLtt_smart_puts(SLsmg_Char_Type *, SLsmg_Char_Type *, int, int); +extern void SLtt_write_string (char *); +extern void SLtt_putchar(char); +extern int SLtt_init_video (void); +extern int SLtt_reset_video (void); +extern void SLtt_get_terminfo(void); +extern void SLtt_get_screen_size (void); +extern int SLtt_set_cursor_visibility (int); + +extern int SLtt_set_mouse_mode (int, int); + +#if defined(VMS) || defined(REAL_UNIX_SYSTEM) +extern int SLtt_initialize (char *); +extern void SLtt_enable_cursor_keys(void); +extern void SLtt_set_term_vtxxx(int *); +extern void SLtt_set_color_esc (int, char *); +extern void SLtt_wide_width(void); +extern void SLtt_narrow_width(void); +extern void SLtt_set_alt_char_set (int); +extern int SLtt_write_to_status_line (char *, int); +extern void SLtt_disable_status_line (void); +# ifdef REAL_UNIX_SYSTEM +/* These are termcap/terminfo routines that assume SLtt_initialize has + * been called. + */ +extern char *SLtt_tgetstr (char *); +extern int SLtt_tgetnum (char *); +extern int SLtt_tgetflag (char *); + +/* The following are terminfo-only routines -- these prototypes will change + * in V2.x. + */ +extern char *SLtt_tigetent (char *); +extern char *SLtt_tigetstr (char *, char **); +extern int SLtt_tigetnum (char *, char **); +# endif +#endif + +extern SLtt_Char_Type SLtt_get_color_object (int); +extern void SLtt_set_color_object (int, SLtt_Char_Type); +extern void SLtt_set_color (int, char *, char *, char *); +extern void SLtt_set_mono (int, char *, SLtt_Char_Type); +extern void SLtt_add_color_attribute (int, SLtt_Char_Type); +extern void SLtt_set_color_fgbg (int, SLtt_Char_Type, SLtt_Char_Type); + +/*}}}*/ + +/*{{{ SLang Preprocessor Interface */ + +typedef struct +{ + int this_level; + int exec_level; + int prev_exec_level; + char preprocess_char; + char comment_char; + unsigned char flags; +#define SLPREP_BLANK_LINES_OK 1 +#define SLPREP_COMMENT_LINES_OK 2 +} +SLPreprocess_Type; + +extern int SLprep_open_prep (SLPreprocess_Type *); +extern void SLprep_close_prep (SLPreprocess_Type *); +extern int SLprep_line_ok (char *, SLPreprocess_Type *); + extern int SLdefine_for_ifdef (char *); + /* Adds a string to the SLang #ifdef preparsing defines. SLang already + defines MSDOS, UNIX, and VMS on the appropriate system. */ +extern int (*SLprep_exists_hook) (char *, char); + +/*}}}*/ + +/*{{{ SLsmg Screen Management Functions */ + +extern void SLsmg_fill_region (int, int, unsigned int, unsigned int, unsigned char); +extern void SLsmg_set_char_set (int); +#ifndef IBMPC_SYSTEM +extern int SLsmg_Scroll_Hash_Border; +#endif +extern int SLsmg_suspend_smg (void); +extern int SLsmg_resume_smg (void); +extern void SLsmg_erase_eol (void); +extern void SLsmg_gotorc (int, int); +extern void SLsmg_erase_eos (void); +extern void SLsmg_reverse_video (void); +extern void SLsmg_set_color (int); +extern void SLsmg_normal_video (void); +extern void SLsmg_printf (char *, ...); +extern void SLsmg_vprintf (char *, va_list); +extern void SLsmg_write_string (char *); +extern void SLsmg_write_nstring (char *, unsigned int); +extern void SLsmg_write_char (char); +extern void SLsmg_write_nchars (char *, unsigned int); +extern void SLsmg_write_wrapped_string (char *, int, int, unsigned int, unsigned int, int); +extern void SLsmg_cls (void); +extern void SLsmg_refresh (void); +extern void SLsmg_touch_lines (int, unsigned int); +extern void SLsmg_touch_screen (void); +extern int SLsmg_init_smg (void); +extern int SLsmg_reinit_smg (void); +extern void SLsmg_reset_smg (void); +extern SLsmg_Char_Type SLsmg_char_at(void); +extern void SLsmg_set_screen_start (int *, int *); +extern void SLsmg_draw_hline (unsigned int); +extern void SLsmg_draw_vline (int); +extern void SLsmg_draw_object (int, int, unsigned char); +extern void SLsmg_draw_box (int, int, unsigned int, unsigned int); +extern int SLsmg_get_column(void); +extern int SLsmg_get_row(void); +extern void SLsmg_forward (int); +extern void SLsmg_write_color_chars (SLsmg_Char_Type *, unsigned int); +extern unsigned int SLsmg_read_raw (SLsmg_Char_Type *, unsigned int); +extern unsigned int SLsmg_write_raw (SLsmg_Char_Type *, unsigned int); +extern void SLsmg_set_color_in_region (int, int, int, unsigned int, unsigned int); +extern int SLsmg_Display_Eight_Bit; +extern int SLsmg_Tab_Width; + +#define SLSMG_NEWLINE_IGNORED 0 /* default */ +#define SLSMG_NEWLINE_MOVES 1 /* moves to next line, column 0 */ +#define SLSMG_NEWLINE_SCROLLS 2 /* moves but scrolls at bottom of screen */ +#define SLSMG_NEWLINE_PRINTABLE 3 /* prints as ^J */ +extern int SLsmg_Newline_Behavior; + +extern int SLsmg_Backspace_Moves; + +#ifdef IBMPC_SYSTEM +# define SLSMG_HLINE_CHAR 0xC4 +# define SLSMG_VLINE_CHAR 0xB3 +# define SLSMG_ULCORN_CHAR 0xDA +# define SLSMG_URCORN_CHAR 0xBF +# define SLSMG_LLCORN_CHAR 0xC0 +# define SLSMG_LRCORN_CHAR 0xD9 +# define SLSMG_RTEE_CHAR 0xB4 +# define SLSMG_LTEE_CHAR 0xC3 +# define SLSMG_UTEE_CHAR 0xC2 +# define SLSMG_DTEE_CHAR 0xC1 +# define SLSMG_PLUS_CHAR 0xC5 +/* There are several to choose from: 0xB0, 0xB1, and 0xB2 */ +# define SLSMG_CKBRD_CHAR 0xB0 +# define SLSMG_DIAMOND_CHAR 0x04 +# define SLSMG_DEGREE_CHAR 0xF8 +# define SLSMG_PLMINUS_CHAR 0xF1 +# define SLSMG_BULLET_CHAR 0xF9 +# define SLSMG_LARROW_CHAR 0x1B +# define SLSMG_RARROW_CHAR 0x1A +# define SLSMG_DARROW_CHAR 0x19 +# define SLSMG_UARROW_CHAR 0x18 +# define SLSMG_BOARD_CHAR 0xB2 +# define SLSMG_BLOCK_CHAR 0xDB +#else +# if defined(AMIGA) +# define SLSMG_HLINE_CHAR '-' +# define SLSMG_VLINE_CHAR '|' +# define SLSMG_ULCORN_CHAR '+' +# define SLSMG_URCORN_CHAR '+' +# define SLSMG_LLCORN_CHAR '+' +# define SLSMG_LRCORN_CHAR '+' +# define SLSMG_CKBRD_CHAR '#' +# define SLSMG_RTEE_CHAR '+' +# define SLSMG_LTEE_CHAR '+' +# define SLSMG_UTEE_CHAR '+' +# define SLSMG_DTEE_CHAR '+' +# define SLSMG_PLUS_CHAR '+' +# define SLSMG_DIAMOND_CHAR '+' +# define SLSMG_DEGREE_CHAR '\\' +# define SLSMG_PLMINUS_CHAR '#' +# define SLSMG_BULLET_CHAR 'o' +# define SLSMG_LARROW_CHAR '<' +# define SLSMG_RARROW_CHAR '>' +# define SLSMG_DARROW_CHAR 'v' +# define SLSMG_UARROW_CHAR '^' +# define SLSMG_BOARD_CHAR '#' +# define SLSMG_BLOCK_CHAR '#' +# else +# define SLSMG_HLINE_CHAR 'q' +# define SLSMG_VLINE_CHAR 'x' +# define SLSMG_ULCORN_CHAR 'l' +# define SLSMG_URCORN_CHAR 'k' +# define SLSMG_LLCORN_CHAR 'm' +# define SLSMG_LRCORN_CHAR 'j' +# define SLSMG_CKBRD_CHAR 'a' +# define SLSMG_RTEE_CHAR 'u' +# define SLSMG_LTEE_CHAR 't' +# define SLSMG_UTEE_CHAR 'w' +# define SLSMG_DTEE_CHAR 'v' +# define SLSMG_PLUS_CHAR 'n' +# define SLSMG_DIAMOND_CHAR '`' +# define SLSMG_DEGREE_CHAR 'f' +# define SLSMG_PLMINUS_CHAR 'g' +# define SLSMG_BULLET_CHAR '~' +# define SLSMG_LARROW_CHAR ',' +# define SLSMG_RARROW_CHAR '+' +# define SLSMG_DARROW_CHAR '.' +# define SLSMG_UARROW_CHAR '-' +# define SLSMG_BOARD_CHAR 'h' +# define SLSMG_BLOCK_CHAR '0' +# endif /* AMIGA */ +#endif /* IBMPC_SYSTEM */ + +#ifndef IBMPC_SYSTEM +# define SLSMG_COLOR_BLACK 0x000000 +# define SLSMG_COLOR_RED 0x000001 +# define SLSMG_COLOR_GREEN 0x000002 +# define SLSMG_COLOR_BROWN 0x000003 +# define SLSMG_COLOR_BLUE 0x000004 +# define SLSMG_COLOR_MAGENTA 0x000005 +# define SLSMG_COLOR_CYAN 0x000006 +# define SLSMG_COLOR_LGRAY 0x000007 +# define SLSMG_COLOR_GRAY 0x000008 +# define SLSMG_COLOR_BRIGHT_RED 0x000009 +# define SLSMG_COLOR_BRIGHT_GREEN 0x00000A +# define SLSMG_COLOR_BRIGHT_BROWN 0x00000B +# define SLSMG_COLOR_BRIGHT_BLUE 0x00000C +# define SLSMG_COLOR_BRIGHT_CYAN 0x00000D +# define SLSMG_COLOR_BRIGHT_MAGENTA 0x00000E +# define SLSMG_COLOR_BRIGHT_WHITE 0x00000F +#endif + +typedef struct +{ + void (*tt_normal_video)(void); + void (*tt_set_scroll_region)(int, int); + void (*tt_goto_rc)(int, int); + void (*tt_reverse_index)(int); + void (*tt_reset_scroll_region)(void); + void (*tt_delete_nlines)(int); + void (*tt_cls) (void); + void (*tt_del_eol) (void); + void (*tt_smart_puts) (SLsmg_Char_Type *, SLsmg_Char_Type *, int, int); + int (*tt_flush_output) (void); + int (*tt_reset_video) (void); + int (*tt_init_video) (void); + + int *tt_screen_rows; + int *tt_screen_cols; + + int *tt_term_cannot_scroll; + int *tt_has_alt_charset; + int *tt_use_blink_for_acs; + char **tt_graphic_char_pairs; + + long reserved[4]; +} +SLsmg_Term_Type; +extern void SLsmg_set_terminal_info (SLsmg_Term_Type *); + +/*}}}*/ + +/*{{{ SLang Keypad Interface */ + +#define SL_KEY_ERR 0xFFFF + +#define SL_KEY_UP 0x101 +#define SL_KEY_DOWN 0x102 +#define SL_KEY_LEFT 0x103 +#define SL_KEY_RIGHT 0x104 +#define SL_KEY_PPAGE 0x105 +#define SL_KEY_NPAGE 0x106 +#define SL_KEY_HOME 0x107 +#define SL_KEY_END 0x108 +#define SL_KEY_A1 0x109 +#define SL_KEY_A3 0x10A +#define SL_KEY_B2 0x10B +#define SL_KEY_C1 0x10C +#define SL_KEY_C3 0x10D +#define SL_KEY_REDO 0x10E +#define SL_KEY_UNDO 0x10F +#define SL_KEY_BACKSPACE 0x110 +#define SL_KEY_ENTER 0x111 +#define SL_KEY_IC 0x112 +#define SL_KEY_DELETE 0x113 + +#define SL_KEY_F0 0x200 +#define SL_KEY_F(X) (SL_KEY_F0 + X) + +/* I do not intend to use keysymps > 0x1000. Applications can use those. */ +/* Returns 0 upon success or -1 upon error. */ +extern int SLkp_define_keysym (char *, unsigned int); + +/* This function must be called AFTER SLtt_get_terminfo and not before. */ +extern int SLkp_init (void); + +/* By default, SLang_getkey is used as the low-level function. This hook + * allows you to specify something else. + */ +extern void SLkp_set_getkey_function (int (*)(void)); + +/* This function uses SLang_getkey and assumes that what ever initialization + * is required for SLang_getkey has been performed. If you do not want + * SLang_getkey to be used, then specify another function via + * SLkp_set_getkey_function. + */ +extern int SLkp_getkey (void); + +/*}}}*/ + +/*{{{ SLang Scroll Interface */ + +typedef struct _SLscroll_Type +{ + struct _SLscroll_Type *next; + struct _SLscroll_Type *prev; + unsigned int flags; +} +SLscroll_Type; + +typedef struct +{ + unsigned int flags; + SLscroll_Type *top_window_line; /* list element at top of window */ + SLscroll_Type *bot_window_line; /* list element at bottom of window */ + SLscroll_Type *current_line; /* current list element */ + SLscroll_Type *lines; /* first list element */ + unsigned int nrows; /* number of rows in window */ + unsigned int hidden_mask; /* applied to flags in SLscroll_Type */ + unsigned int line_num; /* current line number (visible) */ + unsigned int num_lines; /* total number of lines (visible) */ + unsigned int window_row; /* row of current_line in window */ + unsigned int border; /* number of rows that form scroll border */ + int cannot_scroll; /* should window scroll or recenter */ +} +SLscroll_Window_Type; + +extern int SLscroll_find_top (SLscroll_Window_Type *); +extern int SLscroll_find_line_num (SLscroll_Window_Type *); +extern unsigned int SLscroll_next_n (SLscroll_Window_Type *, unsigned int); +extern unsigned int SLscroll_prev_n (SLscroll_Window_Type *, unsigned int); +extern int SLscroll_pageup (SLscroll_Window_Type *); +extern int SLscroll_pagedown (SLscroll_Window_Type *); + +/*}}}*/ + +/*{{{ Signal Routines */ + +typedef void SLSig_Fun_Type (int); +extern SLSig_Fun_Type *SLsignal (int, SLSig_Fun_Type *); +extern SLSig_Fun_Type *SLsignal_intr (int, SLSig_Fun_Type *); +extern int SLsig_block_signals (void); +extern int SLsig_unblock_signals (void); +extern int SLsystem (char *); + +extern char *SLerrno_strerror (int); +extern int SLerrno_set_errno (int); + +/*}}}*/ + +/*{{{ Interpreter Macro Definitions */ + +/* The definitions here are for objects that may be on the run-time stack. + * They are actually sub_types of literal and data main_types. The actual + * numbers are historical. + */ +#define SLANG_UNDEFINED_TYPE 0x00 /* MUST be 0 */ +#define SLANG_VOID_TYPE 0x01 /* also matches ANY type */ +#define SLANG_INT_TYPE 0x02 +#define SLANG_DOUBLE_TYPE 0x03 +#define SLANG_CHAR_TYPE 0x04 +#define SLANG_INTP_TYPE 0x05 +/* An object of SLANG_INTP_TYPE should never really occur on the stack. Rather, + * the integer to which it refers will be there instead. It is defined here + * because it is a valid type for MAKE_VARIABLE. + */ +#define SLANG_REF_TYPE 0x06 +/* SLANG_REF_TYPE refers to an object on the stack that is a pointer (reference) + * to some other object. + */ +#define SLANG_COMPLEX_TYPE 0x07 +#define SLANG_NULL_TYPE 0x08 +#define SLANG_UCHAR_TYPE 0x09 +#define SLANG_SHORT_TYPE 0x0A +#define SLANG_USHORT_TYPE 0x0B +#define SLANG_UINT_TYPE 0x0C +#define SLANG_LONG_TYPE 0x0D +#define SLANG_ULONG_TYPE 0x0E +#define SLANG_STRING_TYPE 0x0F +#define SLANG_FLOAT_TYPE 0x10 +#define SLANG_STRUCT_TYPE 0x11 +#define SLANG_ISTRUCT_TYPE 0x12 +#define SLANG_ARRAY_TYPE 0x20 +#define SLANG_DATATYPE_TYPE 0x21 +#define SLANG_FILE_PTR_TYPE 0x22 +#define SLANG_ASSOC_TYPE 0x23 +#define SLANG_ANY_TYPE 0x24 +#define SLANG_BSTRING_TYPE 0x25 +#define SLANG_FILE_FD_TYPE 0x26 + +/* Compatibility */ +#ifdef FLOAT_TYPE +# undef FLOAT_TYPE +#endif +#define VOID_TYPE SLANG_VOID_TYPE +#define INT_TYPE SLANG_INT_TYPE +#define INTP_TYPE SLANG_INTP_TYPE +#define FLOAT_TYPE SLANG_DOUBLE_TYPE +#define ARRAY_TYPE SLANG_ARRAY_TYPE +#define CHAR_TYPE SLANG_CHAR_TYPE +#define STRING_TYPE SLANG_STRING_TYPE + +/* I am reserving values greater than or equal to 128 for user applications. + * The first 127 are reserved for S-Lang. + */ + +/* Binary and Unary Subtypes */ +/* Since the application can define new types and can overload the binary + * and unary operators, these definitions must be present in this file. + * The current implementation assumes both unary and binary are distinct. + */ +#define SLANG_PLUS 0x01 +#define SLANG_MINUS 0x02 +#define SLANG_TIMES 0x03 +#define SLANG_DIVIDE 0x04 +#define SLANG_EQ 0x05 +#define SLANG_NE 0x06 +#define SLANG_GT 0x07 +#define SLANG_GE 0x08 +#define SLANG_LT 0x09 +#define SLANG_LE 0x0A +#define SLANG_POW 0x0B +#define SLANG_OR 0x0C +#define SLANG_AND 0x0D +#define SLANG_BAND 0x0E +#define SLANG_BOR 0x0F +#define SLANG_BXOR 0x10 +#define SLANG_SHL 0x11 +#define SLANG_SHR 0x12 +#define SLANG_MOD 0x13 + +/* UNARY subtypes (may be overloaded) */ +#define SLANG_PLUSPLUS 0x20 +#define SLANG_MINUSMINUS 0x21 +#define SLANG_ABS 0x22 +#define SLANG_SIGN 0x23 +#define SLANG_SQR 0x24 +#define SLANG_MUL2 0x25 +#define SLANG_CHS 0x26 +#define SLANG_NOT 0x27 +#define SLANG_BNOT 0x28 + +extern char *SLang_Error_Message; + +int SLadd_intrinsic_variable (char *, VOID_STAR, unsigned char, int); +int SLadd_intrinsic_function (char *, FVOID_STAR, unsigned char, unsigned int,...); + +int SLns_add_intrinsic_variable (SLang_NameSpace_Type *, char *, VOID_STAR, unsigned char, int); +int SLns_add_intrinsic_function (SLang_NameSpace_Type *, char *, FVOID_STAR, unsigned char, unsigned int,...); + +#define MAKE_INTRINSIC_N(n,f,out,in,a1,a2,a3,a4,a5,a6,a7) \ + {(n), NULL, SLANG_INTRINSIC, (FVOID_STAR) (f), \ + {a1,a2,a3,a4,a5,a6,a7}, (in), (out)} + +#define MAKE_INTRINSIC_7(n,f,out,a1,a2,a3,a4,a5,a6,a7) \ + MAKE_INTRINSIC_N(n,f,out,7,a1,a2,a3,a4,a5,a6,a7) +#define MAKE_INTRINSIC_6(n,f,out,a1,a2,a3,a4,a5,a6) \ + MAKE_INTRINSIC_N(n,f,out,6,a1,a2,a3,a4,a5,a6,0) +#define MAKE_INTRINSIC_5(n,f,out,a1,a2,a3,a4,a5) \ + MAKE_INTRINSIC_N(n,f,out,5,a1,a2,a3,a4,a5,0,0) +#define MAKE_INTRINSIC_4(n,f,out,a1,a2,a3,a4) \ + MAKE_INTRINSIC_N(n,f,out,4,a1,a2,a3,a4,0,0,0) +#define MAKE_INTRINSIC_3(n,f,out,a1,a2,a3) \ + MAKE_INTRINSIC_N(n,f,out,3,a1,a2,a3,0,0,0,0) +#define MAKE_INTRINSIC_2(n,f,out,a1,a2) \ + MAKE_INTRINSIC_N(n,f,out,2,a1,a2,0,0,0,0,0) +#define MAKE_INTRINSIC_1(n,f,out,a1) \ + MAKE_INTRINSIC_N(n,f,out,1,a1,0,0,0,0,0,0) +#define MAKE_INTRINSIC_0(n,f,out) \ + MAKE_INTRINSIC_N(n,f,out,0,0,0,0,0,0,0,0) + +#define MAKE_INTRINSIC_S(n,f,r) \ + MAKE_INTRINSIC_1(n,f,r,SLANG_STRING_TYPE) +#define MAKE_INTRINSIC_I(n,f,r) \ + MAKE_INTRINSIC_1(n,f,r,SLANG_INT_TYPE) + +#define MAKE_INTRINSIC_SS(n,f,r) \ + MAKE_INTRINSIC_2(n,f,r,SLANG_STRING_TYPE,SLANG_STRING_TYPE) +#define MAKE_INTRINSIC_SI(n,f,r) \ + MAKE_INTRINSIC_2(n,f,r,SLANG_STRING_TYPE,SLANG_INT_TYPE) +#define MAKE_INTRINSIC_IS(n,f,r) \ + MAKE_INTRINSIC_2(n,f,r,SLANG_INT_TYPE,SLANG_STRING_TYPE) +#define MAKE_INTRINSIC_II(n,f,r) \ + MAKE_INTRINSIC_2(n,f,r,SLANG_INT_TYPE,SLANG_INT_TYPE) + +#define MAKE_INTRINSIC_SSS(n,f,r) \ + MAKE_INTRINSIC_3(n,f,r,SLANG_STRING_TYPE,SLANG_STRING_TYPE,SLANG_STRING_TYPE) +#define MAKE_INTRINSIC_SSI(n,f,r) \ + MAKE_INTRINSIC_3(n,f,r,SLANG_STRING_TYPE,SLANG_STRING_TYPE,SLANG_INT_TYPE) +#define MAKE_INTRINSIC_SIS(n,f,r) \ + MAKE_INTRINSIC_3(n,f,r,SLANG_STRING_TYPE,SLANG_INT_TYPE,SLANG_STRING_TYPE) +#define MAKE_INTRINSIC_SII(n,f,r) \ + MAKE_INTRINSIC_3(n,f,r,SLANG_STRING_TYPE,SLANG_INT_TYPE,SLANG_INT_TYPE) +#define MAKE_INTRINSIC_ISS(n,f,r) \ + MAKE_INTRINSIC_3(n,f,r,SLANG_INT_TYPE,SLANG_STRING_TYPE,SLANG_STRING_TYPE) +#define MAKE_INTRINSIC_ISI(n,f,r) \ + MAKE_INTRINSIC_3(n,f,r,SLANG_INT_TYPE,SLANG_STRING_TYPE,SLANG_INT_TYPE) +#define MAKE_INTRINSIC_IIS(n,f,r) \ + MAKE_INTRINSIC_3(n,f,r,SLANG_INT_TYPE,SLANG_INT_TYPE,SLANG_STRING_TYPE) +#define MAKE_INTRINSIC_III(n,f,r) \ + MAKE_INTRINSIC_3(n,f,r,SLANG_INT_TYPE,SLANG_INT_TYPE,SLANG_INT_TYPE) + +#define MAKE_INTRINSIC(n, f, out, in) \ + MAKE_INTRINSIC_N(n,f,out,in,0,0,0,0,0,0,0) + +#define MAKE_VARIABLE(n, v, t, r) \ + {n, NULL, SLANG_IVARIABLE + (r), (VOID_STAR)(v), (t)} + +#define MAKE_APP_UNARY(n,op) \ + {(n), NULL, SLANG_APP_UNARY, (op)} + +#define MAKE_MATH_UNARY(n,op) \ + {(n), NULL, SLANG_MATH_UNARY, (op)} + +#define MAKE_ICONSTANT(n,val) \ + {(n),NULL, SLANG_ICONSTANT, (val)} + +#define MAKE_DCONSTANT(n,val) \ + {(n),NULL, SLANG_DCONSTANT, (val)} + +#ifndef offsetof +# define offsetof(T,F) ((unsigned int)((char *)&((T *)0L)->F - (char *)0L)) +#endif +#define MAKE_ISTRUCT_FIELD(s,f,n,t,r) {(n), offsetof(s,f), (t), (r)} + +#define SLANG_END_TABLE {NULL} +#define SLANG_END_INTRIN_FUN_TABLE MAKE_INTRINSIC_0(NULL,NULL,0) +#define SLANG_END_DCONST_TABLE MAKE_DCONSTANT(NULL,0) +#define SLANG_END_MATH_UNARY_TABLE MAKE_MATH_UNARY(NULL,0) +#define SLANG_END_INTRIN_VAR_TABLE MAKE_VARIABLE(NULL,NULL,0,0) +#define SLANG_END_ICONST_TABLE MAKE_ICONSTANT(NULL,0) +#define SLANG_END_ISTRUCT_TABLE {NULL, 0, 0, 0} + + + +/*}}}*/ + +/*{{{ Upper/Lowercase Functions */ + +extern void SLang_define_case(int *, int *); +extern void SLang_init_case_tables (void); + +extern unsigned char _SLChg_UCase_Lut[256]; +extern unsigned char _SLChg_LCase_Lut[256]; +#define UPPER_CASE(x) (_SLChg_UCase_Lut[(unsigned char) (x)]) +#define LOWER_CASE(x) (_SLChg_LCase_Lut[(unsigned char) (x)]) +#define CHANGE_CASE(x) (((x) == _SLChg_LCase_Lut[(unsigned char) (x)]) ?\ + _SLChg_UCase_Lut[(unsigned char) (x)] : _SLChg_LCase_Lut[(unsigned char) (x)]) + +/*}}}*/ + +/*{{{ Regular Expression Interface */ + +typedef struct +{ + /* These must be set by calling routine. */ + unsigned char *pat; /* regular expression pattern */ + unsigned char *buf; /* buffer for compiled regexp */ + unsigned int buf_len; /* length of buffer */ + int case_sensitive; /* 1 if match is case sensitive */ + + /* The rest are set by SLang_regexp_compile */ + + int must_match; /* 1 if line must contain substring */ + int must_match_bol; /* true if it must match beginning of line */ + unsigned char must_match_str[16]; /* 15 char null term substring */ + int osearch; /* 1 if ordinary search suffices */ + unsigned int min_length; /* minimum length the match must be */ + int beg_matches[10]; /* offset of start of \( */ + unsigned int end_matches[10]; /* length of nth submatch + * Note that the entire match corresponds + * to \0 + */ + int offset; /* offset to be added to beg_matches */ + int reserved[10]; +} SLRegexp_Type; + +extern unsigned char *SLang_regexp_match(unsigned char *, + unsigned int, + SLRegexp_Type *); + +/* Returns 0 upon success. If failure, the offset into the + * pattern is returned (start = 1). + */ +extern int SLang_regexp_compile (SLRegexp_Type *); +extern char *SLregexp_quote_string (char *, char *, unsigned int); + +/*}}}*/ + +/*{{{ SLang Command Interface */ + +struct _SLcmd_Cmd_Type; /* Pre-declaration is needed below */ +typedef struct +{ + struct _SLcmd_Cmd_Type *table; + int argc; + /* Version 2.0 needs to use a union!! */ + char **string_args; + int *int_args; + double *double_args; + unsigned char *arg_type; + unsigned long reserved[4]; +} SLcmd_Cmd_Table_Type; + +typedef struct _SLcmd_Cmd_Type +{ + int (*cmdfun)(int, SLcmd_Cmd_Table_Type *); + char *cmd; + char *arg_type; +} SLcmd_Cmd_Type; + +extern int SLcmd_execute_string (char *, SLcmd_Cmd_Table_Type *); + +/*}}}*/ + +/*{{{ SLang Search Interface */ + +typedef struct +{ + int cs; /* case sensitive */ + unsigned char key[256]; + int ind[256]; + int key_len; + int dir; +} SLsearch_Type; + +extern int SLsearch_init (char *, int, int, SLsearch_Type *); +/* This routine must first be called before any search can take place. + * The second parameter specifies the direction of the search: greater than + * zero for a forwrd search and less than zero for a backward search. The + * third parameter specifies whether the search is case sensitive or not. + * The last parameter is a pointer to a structure that is filled by this + * function and it is this structure that must be passed to SLsearch. + */ + +extern unsigned char *SLsearch (unsigned char *, unsigned char *, SLsearch_Type *); +/* To use this routine, you must first call 'SLsearch_init'. Then the first + * two parameters p1 and p2 serve to define the region over which the search + * is to take place. The third parameter is the structure that was previously + * initialized by SLsearch_init. + * + * The routine returns a pointer to the match if found otherwise it returns + * NULL. + */ + +/*}}}*/ + +/*{{{ SLang Pathname Interface */ + +/* These function return pointers to the original space */ +extern char *SLpath_basename (char *); +extern char *SLpath_extname (char *); +extern int SLpath_is_absolute_path (char *); + +/* These return malloced strings--- NOT slstrings */ +extern char *SLpath_dircat (char *, char *); +extern char *SLpath_find_file_in_path (char *, char *); +extern char *SLpath_dirname (char *); +extern int SLpath_file_exists (char *); +extern char *SLpath_pathname_sans_extname (char *); + +/*}}}*/ + +extern int SLang_set_module_load_path (char *); + +#define SLANG_MODULE(name) \ + extern int init_##name##_module_ns (char *); \ + extern void deinit_##name##_module (void) + +#if 0 +{ +#endif +#ifdef __cplusplus +} +#endif + +#endif /* _DAVIS_SLANG_H_ */ diff --git a/slang/include/slinclud.h b/slang/include/slinclud.h new file mode 100644 index 000000000..c65812f4f --- /dev/null +++ b/slang/include/slinclud.h @@ -0,0 +1,30 @@ +#ifndef _SLANG_INCLUDE_H_ +#define _SLANG_INCLUDE_H_ + +#include "config.h" +#include "sl-feat.h" + +#include +#include + +#if defined(__QNX__) && defined(__WATCOMC__) +# include +#endif + +#ifdef HAVE_STDLIB_H +# include +#endif + +#ifdef HAVE_UNISTD_H +# include +#endif + +#ifdef HAVE_MALLOC_H +# include +#endif + +#ifdef HAVE_MEMORY_H +# include +#endif + +#endif /* _SLANG_INCLUDE_H_ */ diff --git a/slang/include/sllimits.h b/slang/include/sllimits.h new file mode 100644 index 000000000..35a5eae3b --- /dev/null +++ b/slang/include/sllimits.h @@ -0,0 +1,64 @@ +/* Copyright (c) 1998, 1999, 2001, 2002 John E. Davis + * This file is part of the S-Lang library. + * + * You may distribute under the terms of either the GNU General Public + * License or the Perl Artistic License. + */ +/* sllimits.h */ + +/* slstring.c: Size of the hash table used for strings (prime numbers) */ +#ifdef __MSDOS_16BIT__ +# define SLSTRING_HASH_TABLE_SIZE 601 +# define SLASSOC_HASH_TABLE_SIZE 601 +#else +# define SLSTRING_HASH_TABLE_SIZE 2909 +# define SLASSOC_HASH_TABLE_SIZE 2909 +#endif + +/* slang.c: maximum size of run time stack */ +#ifdef __MSDOS_16BIT__ +# define SLANG_MAX_STACK_LEN 500 +#else +# define SLANG_MAX_STACK_LEN 2500 +#endif + +/* slang.c: This sets the size on the depth of function calls */ +#ifdef __MSDOS_16BIT__ +# define SLANG_MAX_RECURSIVE_DEPTH 50 +#else +# define SLANG_MAX_RECURSIVE_DEPTH 250 +#endif + +/* slang.c: Size of the stack used for local variables */ +#ifdef __MSDOS_16BIT__ +# define SLANG_MAX_LOCAL_STACK 200 +#else +# define SLANG_MAX_LOCAL_STACK 1024 +#endif + +/* slang.c: The size of the hash table used for local and global objects. + * These should be prime numbers. + */ +#define SLGLOBALS_HASH_TABLE_SIZE 2909 +#define SLLOCALS_HASH_TABLE_SIZE 73 +#define SLSTATIC_HASH_TABLE_SIZE 73 + +/* Size of the keyboard buffer use by the ungetkey routines */ +#ifdef __MSDOS_16BIT__ +# define SL_MAX_INPUT_BUFFER_LEN 40 +#else +# define SL_MAX_INPUT_BUFFER_LEN 1024 +#endif + +/* Maximum number of nested switch statements */ +#define SLANG_MAX_NESTED_SWITCH 10 + +/* Size of the block stack (used in byte-compiling) */ +#define SLANG_MAX_BLOCK_STACK_LEN 50 + +/* slfile.c: Max number of open file pointers */ +#ifdef __MSDOS_16BIT__ +# define SL_MAX_FILES 32 +#else +# define SL_MAX_FILES 256 +#endif diff --git a/slang/jdmacros.h b/slang/jdmacros.h deleted file mode 100644 index b94eae4fd..000000000 --- a/slang/jdmacros.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef _JD_MACROS_H_ -#define _JD_MACROS_H_ - -/* This file defines some macros that I use with programs that link to - * the slang library. - */ - -#ifdef HAVE_STDLIB_H -# include -#endif - -#if !defined(STDC_HEADERS) && defined(HAVE_MALLOC_H) -# include -#endif - -#ifdef HAVE_MEMORY_H -# include -#endif - -#ifndef SLMEMSET -# ifdef HAVE_MEMSET -# define SLMEMSET memset -# else -# define SLMEMSET SLmemset -# endif -#endif - -#ifndef SLMEMCHR -# ifdef HAVE_MEMCHR -# define SLMEMCHR memchr -# else -# define SLMEMCHR SLmemchr -# endif -#endif - -#ifndef SLMEMCPY -# ifdef HAVE_MEMCPY -# define SLMEMCPY memcpy -# else -# define SLMEMCPY SLmemcpy -# endif -#endif - -/* Note: HAVE_MEMCMP requires an unsigned memory comparison!!! */ -#ifndef SLMEMCMP -# ifdef HAVE_MEMCMP -# define SLMEMCMP memcmp -# else -# define SLMEMCMP SLmemcmp -# endif -#endif - -#if SLANG_VERSION < 9934 -# define SLmemcmp jed_memcmp -# define SLmemcpy jed_memcpy -# define SLmemset jed_memset -# define SLmemchr jed_memchr -#endif - -#ifndef SLFREE -# define SLFREE free -#endif - -#ifndef SLMALLOC -# define SLMALLOC malloc -#endif - -#ifndef SLCALLOC -# define SLCALLOC calloc -#endif - -#ifndef SLREALLOC -# define SLREALLOC realloc -#endif - -#endif /* _JD_MACROS_H_ */ diff --git a/slang/sl-feat.h b/slang/sl-feat.h deleted file mode 100644 index 2fea3ca2a..000000000 --- a/slang/sl-feat.h +++ /dev/null @@ -1,2 +0,0 @@ -/* Set this to 1 to enable Kanji support */ -#define SLANG_HAS_KANJI_SUPPORT 0 diff --git a/slang/slang-mc.h b/slang/slang-mc.h deleted file mode 100644 index 9bcee4e92..000000000 --- a/slang/slang-mc.h +++ /dev/null @@ -1,1290 +0,0 @@ -#ifndef DAVIS_SLANG_H_ -#define DAVIS_SLANG_H_ -/* -*- mode: C; mode: fold; -*- */ -/* Copyright (c) 1992, 1995 John E. Davis - * All rights reserved. - * - * You may distribute under the terms of either the GNU General Public - * License or the Perl Artistic License. - */ -#define SLANG_VERSION 9938 - -#ifdef HAVE_SYSTEM_SLANG - #error "This file must not be used with system installed S-Lang library" -#endif - -/*{{{ System Dependent Macros and Typedefs */ - -#if defined(__WATCOMC__) && !defined(__QNX__) -# ifndef msdos -# define msdos -# endif -# ifndef DOS386 -# define DOS386 -# endif -# ifndef FLOAT_TYPE -# define FLOAT_TYPE -# endif -# ifndef pc_system -# define pc_system -# endif -#endif /* __watcomc__ */ - -#ifdef unix -# ifndef __unix__ -# define __unix__ 1 -# endif -#endif - -#ifndef __GO32__ -# ifdef __unix__ -# define REAL_UNIX_SYSTEM -# endif -#endif - -/* Set of the various defines for pc systems. This includes OS/2 */ -#ifdef __MSDOS__ -# ifndef msdos -# define msdos -# endif -# ifndef pc_system -# define pc_system -# endif -#endif - -#ifdef __GO32__ -# ifndef pc_system -# define pc_system -# endif -# ifdef REAL_UNIX_SYSTEM -# undef REAL_UNIX_SYSTEM -# endif -#endif - -#if defined(__EMX__) && defined(OS2) -# ifndef pc_system -# define pc_system -# endif -# ifndef __os2__ -# define __os2__ -# define NEEDS_LOCAL_DIRENT_H -# endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif -#if 0 -} -#endif -/* ---------------------------- Generic Macros ----------------------------- */ - -/* __SC__ is defined for Symantec C++ - DOS386 is defined for -mx memory model, 32 bit DOS extender. */ - -#ifdef VOID -# undef VOID -#endif - -#if defined(msdos) && !defined(DOS386) & !defined(__WIN32__) && !defined(__GO32__) -# ifdef __SC__ -# include -# endif - typedef void *VOID_STAR; -# define VOID void -# include -#else -# if defined (__cplusplus) || defined(__STDC__) - typedef void *VOID_STAR; -# define VOID void -# else - typedef unsigned char *VOID_STAR; -# define VOID unsigned char -# endif -#endif - -#if 1 - typedef int (*FVOID_STAR)(void); -#else -# define FVOID_STAR VOID_STAR -#endif - -#if defined(msdos) && !defined(DOS386) && !defined(__GO32__) && !defined(__WIN32__) -# define SLFREE(buf) farfree((void far *)(buf)) -# define SLMALLOC(x) farmalloc((unsigned long) (x)) -# define SLREALLOC(buf, n) farrealloc((void far *) (buf), (unsigned long) (n)) -# define SLCALLOC(n, m) farcalloc((unsigned long) (n), (unsigned long) (m)) -#else -# if defined(VMS) && !defined(__DECC) -# define SLFREE VAXC$FREE_OPT -# define SLMALLOC VAXC$MALLOC_OPT -# define SLREALLOC VAXC$REALLOC_OPT -# define SLCALLOC VAXC$CALLOC_OPT -# else -# define SLFREE(x) free((char *)(x)) -# define SLMALLOC malloc -# if defined(__cplusplus) && !defined(__BEOS__) -# define SLREALLOC(p,n) realloc((malloc_t) (p), (n)) -# else -# define SLREALLOC realloc -# endif -# define SLCALLOC calloc -# endif -#endif - -#ifdef SL_MALLOC_DEBUG -# undef SLMALLOC -# undef SLCALLOC -# undef SLREALLOC -# undef SLFREE -# define SLMALLOC(x) SLdebug_malloc((unsigned long) (x)) -# define SLFREE(x) SLdebug_free((unsigned char *)(x)) -# define SLCALLOC(n, m) SLdebug_calloc((unsigned long) (n), (unsigned long)(m)) -# define SLREALLOC(p, x) SLdebug_realloc((unsigned char *)(p), (unsigned long)(x)) -#endif /* SL_MALLOC_DEBUG */ - - extern unsigned char *SLdebug_malloc (unsigned long); - extern unsigned char *SLdebug_calloc (unsigned long, unsigned long); - extern unsigned char *SLdebug_realloc (unsigned char *, unsigned long); - extern void SLdebug_free (unsigned char *); - extern void SLmalloc_dump_statistics (void); - extern char *SLstrcpy(register char *, register char *); - extern int SLstrcmp(register char *, register char *); - extern char *SLstrncpy(char *, register char *, register int); - - extern void SLmemset (char *, char, int); - extern char *SLmemchr (register char *, register char, register int); - extern char *SLmemcpy (char *, char *, int); - extern int SLmemcmp (char *, char *, int); - -#ifdef float64 -# undef float64 -#endif - -#ifndef FLOAT64_TYPEDEFED -# define FLOAT64_TYPEDEFED - typedef double float64; -#endif - - -/*}}}*/ - -/*{{{ Interpreter Typedefs */ - -#define SLANG_MAX_NAME_LEN 30 -/* maximum length of an identifier */ -/* first char in identifiers is the hash */ - - /* Note that long is used for addresses instead of void *. The reason for - * this is that I have a gut feeling that sizeof (long) > sizeof(void *) - * on some machines. This is certainly the case for MSDOS where addresses - * can be 16 bit. - */ -typedef struct SLang_Name_Type - { -#ifdef SLANG_STATS - int n; /* number of times referenced */ -#endif - char name[SLANG_MAX_NAME_LEN + 2]; /* [0] is hash */ - - unsigned char sub_type; - -/* Values for main_type may be as follows. The particlular values are - * for compatability. - */ -#define SLANG_LVARIABLE 0x01 -#define SLANG_INTRINSIC 0x06 -#define SLANG_FUNCTION 0x07 -#define SLANG_GVARIABLE 0x0D -#define SLANG_IVARIABLE 0x0E /* intrinsic variables */ -/* Note!!! For Macro MAKE_VARIABLE below to work, SLANG_IVARIABLE Must - be 1 less than SLANG_RVARIABLE!!! */ -#define SLANG_RVARIABLE 0x0F /* read only variable */ - unsigned char main_type; - long addr; - } -SLang_Name_Type; - - -typedef struct SLang_Load_Type -{ - long name; /* file name, string address, ... */ - long handle; /* FILE *, string address, etc... */ - - char *ptr; /* input pointer to next line in object - * to be read. - */ - /* Things below here are used by S-Lang. */ - int type; /* 'F' = file, 'S' = String, etc.. */ - char *buf; /* buffer for file, etc... */ - char *(*read)(struct SLang_Load_Type *); /* function to call to read obj */ - int n; /* line number, etc... */ - char token[256]; /* token to be parsed */ - int ofs; /* offset from buf where last read - * took place - */ - int top_level; /* 1 if at top level of parsing */ -} SLang_Load_Type; - -#if defined(ultrix) && !defined(__GNUC__) -# ifndef NO_PROTOTYPES -# define NO_PROTOTYPES -# endif -#endif - -#ifndef NO_PROTOTYPES -# define _PROTO(x) x -#else -# define _PROTO(x) () -#endif - -typedef struct SL_OOBinary_Type -{ - unsigned char sub_type; /* partner type for binary op */ - - /* The function take the binary op as first argument, the operand types - * form the second and third parameters and the last two parameters are - * pointers to the objects themselves. It is up to the function to push - * the result on the stack. It must return 1 if it handled the operation - * return zero if the operation is not defined. - */ - int (*binary_function)_PROTO((int, unsigned char, unsigned char, - VOID_STAR, VOID_STAR)); - - struct SL_OOBinary_Type *next; -} -SL_OOBinary_Type; - -typedef struct -{ - /* Methods */ - void (*destroy)_PROTO((VOID_STAR)); - /* called to delete/free the object */ - char *(*string)_PROTO((VOID_STAR)); - /* returns a string representation of the object */ - int (*unary_function)_PROTO((int, unsigned char, VOID_STAR)); - /* unary operation function */ - SL_OOBinary_Type *binary_ops; - - int (*copy_function)_PROTO((unsigned char, VOID_STAR)); - /* This function is called do make a copy of the object */ -} SLang_Class_Type; - -extern SLang_Class_Type *SLang_Registered_Types[256]; - -typedef struct -{ - unsigned char main_type; /* SLANG_RVARIABLE, etc.. */ - unsigned char sub_type; /* int, string, etc... */ - long *obj; /* address of user structure */ - - /* Everything below is considered private */ - unsigned int count; /* number of references */ -} -SLuser_Object_Type; - - -/*}}}*/ -/*{{{ Interpreter Function Prototypes */ - - extern volatile int SLang_Error; - /* Non zero if error occurs. Must be reset to zero to continue. */ - - extern int SLang_Traceback; - /* If non-zero, dump an S-Lang traceback upon error. Available as - _traceback in S-Lang. */ - - extern char *SLang_User_Prompt; - /* Prompt to use when reading from stdin */ - extern int SLang_Version; - - extern void (*SLang_Error_Routine)(char *); - /* Pointer to application dependent error messaging routine. By default, - messages are displayed on stderr. */ - - extern void (*SLang_Exit_Error_Hook)(char *); - extern void SLang_exit_error (char *); - extern void (*SLang_Dump_Routine)(char *); - /* Called if S-Lang traceback is enabled as well as other debugging - routines (e.g., trace). By default, these messages go to stderr. */ - - extern void (*SLang_Interrupt)(void); - /* function to call whenever inner interpreter is entered. This is - a good place to set SLang_Error to USER_BREAK. */ - - extern void (*SLang_User_Clear_Error)(void); - /* function that gets called when '_clear_error' is called. */ - extern int (*SLang_User_Open_Slang_Object)(SLang_Load_Type *); - extern int (*SLang_User_Close_Slang_Object)(SLang_Load_Type *); - /* user defined loading routines. */ - - - /* If non null, these call C functions before and after a slang function. */ - extern void (*SLang_Enter_Function)(char *); - extern void (*SLang_Exit_Function)(char *); - - -/* Functions: */ - - extern int init_SLang(void); - /* This function is mandatory and must be called by all applications */ - extern int init_SLfiles(void); - /* called if fputs, fgets, etc are need in S-Lang */ - extern int init_SLmath(void); - /* called if math functions sin, cos, etc... are needed. */ - - extern int init_SLunix(void); - /* unix system functions chmod, stat, etc... */ - - extern int init_SLmatrix(void); - - extern int SLang_add_table(SLang_Name_Type *, char *); - /* add application dependent function table p1 to S-Lang. A name p2 less - * than 32 characters must also be supplied. - * Returns 0 upon failure or 1 upon success. */ - - extern int SLang_add_global_variable (char *); - extern int SLang_load_object(SLang_Load_Type *); - extern int SLang_load_file(char *); - /* Load a file of S-Lang code for interpreting. If the parameter is - NULL, input comes from stdin. */ - - extern void SLang_restart(int); - /* should be called if an error occurs. If the passed integer is - * non-zero, items are popped off the stack; otherwise, the stack is - * left intact. Any time the stack is believed to be trashed, this routine - * should be called with a non-zero argument (e.g., if setjmp/longjmp is - * called). */ - - extern void SLang_byte_compile_file(char *, int *); - /* takes a file of S-Lang code and ``byte-compiles'' it for faster - * loading. The new filename is equivalent to the old except that a `c' is - * appended to the name. (e.g., init.sl --> init.slc). If the second - * parameter is non-zero, preprocess the file only. - */ - - extern void SLang_autoload(char *, char *); - /* Automatically load S-Lang function p1 from file p2. This function - is also available via S-Lang */ - - extern char *SLang_load_string(char *); - /* Like SLang_load_file except input is from a null terminated string. */ - - extern void SLang_do_pop(void); - /* pops item off stack and frees any memory associated with it */ - - extern int SLang_pop_integer(int *); - /* pops integer *p0 from the stack. Returns 0 upon success and non-zero - * if the stack is empty or a type mismatch occurs, setting SLang_Error. - */ - - extern int SLpop_string (char **); - extern int SLang_pop_string(char **, int *); - /* pops string *p0 from stack. If *p1 is non-zero, the string must be - * freed after its use. DO NOT FREE p0 if *p1 IS ZERO! Returns 0 upon - * success */ - - extern int SLang_pop_float(float64 *, int *, int *); - /* Pops float *p1 from stack. If *p3 is non-zero, *p1 was derived - from the integer *p2. Returns zero upon success. */ - - extern SLuser_Object_Type *SLang_pop_user_object (unsigned char); - extern void SLang_free_user_object (SLuser_Object_Type *); - extern void SLang_free_intrinsic_user_object (SLuser_Object_Type *); - /* This is like SLang_free_user_object but is meant to free those - * that have been declared as intrinsic variables by the application. - * Normally an application would never need to call this. - */ - - extern void SLang_push_user_object (SLuser_Object_Type *); - extern SLuser_Object_Type *SLang_create_user_object (unsigned char); - - extern int SLang_add_unary_op (unsigned char, FVOID_STAR); - extern int SLang_add_binary_op (unsigned char, unsigned char, FVOID_STAR); - extern int SLang_register_class (unsigned char, FVOID_STAR, FVOID_STAR); - extern int SLang_add_copy_operation (unsigned char, FVOID_STAR); - - extern long *SLang_pop_pointer(unsigned char *, unsigned char *, int *); - /* Returns a pointer to object of type *p1,*p2 on top of stack. - If *p3 is non-zero, the Object must be freed after use. */ - - - extern void SLang_push_float(float64); - /* Push Float onto stack */ - - extern void SLang_push_string(char *); - /* Push string p1 onto stack */ - - extern void SLang_push_integer(int); - /* push integer p1 on stack */ - - extern void SLang_push_malloced_string(char *); - /* The normal SLang_push_string mallocs space for the string. This one - does not. DO NOT FREE IT IF YOU USE THIS ROUTINE */ - - extern int SLang_is_defined(char *); - /* Return non-zero is p1 is defined otherwise returns 0. */ - - extern int SLang_run_hooks(char *, char *, char *); - /* calls S-Lang function p1 pushing strings p2 and p3 onto the stack - * first. If either string is NULL, it is not pushed. If p1 is not - * defined, 0 is returned. */ - - extern int SLang_execute_function(char *); - /* Call S-Lang function p1. Returns 0 if the function is not defined - * and 1 if it is. - */ - - extern char *SLang_find_name(char *); - /* Return a pointer to p1 in table if it is defined. Returns NULL - * otherwise. This is useful when one wants to avoid redundant strings. - */ - - extern char *SLang_rpn_interpret(char *); - /* Interpret string as reverse polish notation */ - - extern void SLang_doerror(char *); - /* set SLang_Error and display p1 as error message */ - - extern SLuser_Object_Type *SLang_add_array(char *, long *, - int, int, int, int, - unsigned char, unsigned char); - /* This function has not been tested thoroughly yet. Its purpose is to - * allow a S-Lang procedure to access a C array. For example, suppose that - * you have an array of 100 ints defined as: - * - * int c_array[100]; - * - * By calling something like: - * - * SLang_add_array ("array_name", (long *) c_array, 1, 100, 0, 0, - * 'i', SLANG_IVARIABLE); - * - * the array can be accessed by the name 'array_name'. This function - * returns -1 upon failure. The 3rd argument specifies the dimension - * of the array, the 4th, and 5th arguments specify how many elements - * there are in the x,y, and z directions. The last argument must - * be one of: - * - * SLANG_IVARIABLE: indicates array is writable - * SLANG_RVARIABLE: indicates array is read only - * - * Returns NULL upon failure. - */ - - -extern int SLang_free_array_handle (int); -/* This routine may be called by application to free array handle created by - * the application. Returns 0 upon success, -1 if the handle is invalid and - * -2 if the handle is not associated with a C array. - */ - - extern char *SLang_extract_list_element(char *, int *, int*); - extern void SLexpand_escaped_string (register char *, register char *, - register char *); - -extern SLang_Name_Type *SLang_get_function (char *); -/* The parameter is the name of a user defined S-Lang function. This - * routine returns NULL if the function does not exist or it returns the - * a pointer to it in an internal S-Lang table. This pointer can be used - * by 'SLexecute_function' to call the function directly from C. - */ - -extern void SLexecute_function(SLang_Name_Type *); -/* This function allows an application to call a S-Lang function from within - * the C program. The parameter must be non-NULL and must have been - * previously obtained by a call to 'SLang_get_function'. - */ -extern void SLroll_stack (int *); -/* If argument *p is positive, the top |*p| objects on the stack are rolled - * up. If negative, the stack is rolled down. - */ - -extern void SLmake_lut (unsigned char *, unsigned char *, unsigned char); - - extern int SLang_guess_type (char *); - - -/*}}}*/ - -/*{{{ Misc Functions */ - -extern char *SLmake_string (char *); -extern char *SLmake_nstring (char *, unsigned int); -/* Returns a null terminated string made from the first n characters of the - * string. - */ - -extern char *SLcurrent_time_string (void); - -extern int SLatoi(unsigned char *); - -extern int SLang_extract_token(char **, char *, int); -/* returns 0 upon failure and non-zero upon success. The first parameter - * is a pointer to the input stream which this function will bump along. - * The second parameter is the buffer where the token is placed. The third - * parameter is used internally by the S-Lang library and should be 0 for - * user applications. - */ - -/*}}}*/ - -/*{{{ SLang getkey interface Functions */ - -#ifdef REAL_UNIX_SYSTEM -extern int SLang_TT_Baud_Rate; -extern int SLang_TT_Read_FD; -#endif - -extern int SLang_init_tty (int, int, int); -/* Initializes the tty for single character input. If the first parameter *p1 - * is in the range 0-255, it will be used for the abort character; - * otherwise, (unix only) if it is -1, the abort character will be the one - * used by the terminal. If the second parameter p2 is non-zero, flow - * control is enabled. If the last parmeter p3 is zero, output processing - * is NOT turned on. A value of zero is required for the screen management - * routines. Returns 0 upon success. In addition, if SLang_TT_Baud_Rate == - * 0 when this function is called, SLang will attempt to determine the - * terminals baud rate. As far as the SLang library is concerned, if - * SLang_TT_Baud_Rate is less than or equal to zero, the baud rate is - * effectively infinite. - */ - -extern void SLang_reset_tty (void); -/* Resets tty to what it was prior to a call to SLang_init_tty */ -#ifdef REAL_UNIX_SYSTEM -extern void SLtty_set_suspend_state (int); - /* If non-zero argument, terminal driver will be told to react to the - * suspend character. If 0, it will not. - */ -extern int (*SLang_getkey_intr_hook) (void); -#endif - -#define SLANG_GETKEY_ERROR 0xFFFF -extern unsigned int SLang_getkey (void); -/* reads a single key from the tty. If the read fails, 0xFFFF is returned. */ - -extern void SLang_ungetkey_string (unsigned char *, unsigned int); -extern void SLang_buffer_keystring (unsigned char *, unsigned int); -extern void SLang_ungetkey (unsigned char); -extern void SLang_flush_input (void); -extern int SLang_input_pending (int); -extern int SLang_Abort_Char; -/* The value of the character (0-255) used to trigger SIGINT */ -extern int SLang_Ignore_User_Abort; -/* If non-zero, pressing the abort character will not result in USER_BREAK - * SLang_Error. */ - -extern void SLang_set_abort_signal (void (*)(int)); -/* If SIGINT is generated, the function p1 will be called. If p1 is NULL - * the SLang_default signal handler is called. This sets SLang_Error to - * USER_BREAK. I suspect most users will simply want to pass NULL. - */ - -extern volatile int SLKeyBoard_Quit; - -#ifdef VMS -/* If this function returns -1, ^Y will be added to input buffer. */ -extern int (*SLtty_VMS_Ctrl_Y_Hook) (void); -#endif -/*}}}*/ - -/*{{{ SLang Keymap routines */ - -typedef struct SLKeymap_Function_Type - { - char *name; - int (*f)(void); - } -SLKeymap_Function_Type; - -typedef struct SLang_Key_Type - { - unsigned char str[13]; /* key sequence */ -#define SLKEY_F_INTERPRET 0x01 -#define SLKEY_F_INTRINSIC 0x02 -#define SLKEY_F_KEYSYM 0x03 - unsigned char type; /* type of function */ -#ifdef SLKEYMAP_OBSOLETE - VOID_STAR f; /* function to invoke */ -#else - union - { - char *s; - FVOID_STAR f; - unsigned int keysym; - } - f; -#endif - struct SLang_Key_Type *next; /* */ - } -SLang_Key_Type; - -#define MAX_KEYMAP_NAME_LEN 8 -typedef struct SLKeyMap_List_Type -{ - char name[MAX_KEYMAP_NAME_LEN + 1]; - SLang_Key_Type *keymap; - SLKeymap_Function_Type *functions; /* intrinsic functions */ -} -SLKeyMap_List_Type; - -/* This is arbitrary but I have got to start somewhere */ -#ifdef msdos -#define SLANG_MAX_KEYMAPS 10 -#else -#define SLANG_MAX_KEYMAPS 30 -#endif - -extern SLKeyMap_List_Type SLKeyMap_List[SLANG_MAX_KEYMAPS]; /* these better be inited to 0! */ - - -extern char *SLang_process_keystring(char *); - -#ifdef SLKEYMAP_OBSOLETE -extern int SLang_define_key1(char *, VOID_STAR, unsigned int, SLKeyMap_List_Type *); -/* define key p1 in keymap p4 to invoke function p2. If type p3 is given by - * SLKEY_F_INTRINSIC, p2 is an intrinsic function, else it is a string to be - * passed to the interpreter for evaluation. The return value is important. - * It returns 0 upon success, -1 upon malloc error, and -2 if the key is - * inconsistent. SLang_Error is set upon error. */ -#else -extern int SLkm_define_key (char *, FVOID_STAR, SLKeyMap_List_Type *); -#endif - -extern int SLang_define_key(char *, char *, SLKeyMap_List_Type *); -/* Like define_key1 except that p2 is a string that is to be associated with - * a function in the functions field of p3. This routine calls define_key1. - */ - -extern int SLkm_define_keysym (char *, unsigned int, SLKeyMap_List_Type *); - -extern void SLang_undefine_key(char *, SLKeyMap_List_Type *); - -extern SLKeyMap_List_Type *SLang_create_keymap(char *, SLKeyMap_List_Type *); -/* create and returns a pointer to a new keymap named p1 created by copying - * keymap p2. If p2 is NULL, it is up to the calling routine to initialize - * the keymap. - */ - -extern char *SLang_make_keystring(unsigned char *); - -extern SLang_Key_Type *SLang_do_key(SLKeyMap_List_Type *, int (*)(void)); -/* read a key using keymap p1 with getkey function p2 */ - -extern -#ifdef SLKEYMAP_OBSOLETE - VOID_STAR -#else - FVOID_STAR -#endif - SLang_find_key_function(char *, SLKeyMap_List_Type *); - -extern SLKeyMap_List_Type *SLang_find_keymap(char *); - -extern int SLang_Last_Key_Char; -extern int SLang_Key_TimeOut_Flag; - - -/*}}}*/ - -/*{{{ SLang Readline Interface */ - -typedef struct SLang_Read_Line_Type -{ - struct SLang_Read_Line_Type *prev, *next; - unsigned char *buf; - int buf_len; /* number of chars in the buffer */ - int num; /* num and misc are application specific*/ - int misc; -} SLang_Read_Line_Type; - -/* Maximum size of display */ -#define SLRL_DISPLAY_BUFFER_SIZE 256 - -typedef struct -{ - SLang_Read_Line_Type *root, *tail, *last; - unsigned char *buf; /* edit buffer */ - int buf_len; /* sizeof buffer */ - int point; /* current editing point */ - int tab; /* tab width */ - int len; /* current line size */ - - /* display variables */ - int edit_width; /* length of display field */ - int curs_pos; /* current column */ - int start_column; /* column offset of display */ - int dhscroll; /* amount to use for horiz scroll */ - char *prompt; - - FVOID_STAR last_fun; /* last function executed by rl */ - - /* These two contain an image of what is on the display */ - unsigned char upd_buf1[SLRL_DISPLAY_BUFFER_SIZE]; - unsigned char upd_buf2[SLRL_DISPLAY_BUFFER_SIZE]; - unsigned char *old_upd, *new_upd; /* pointers to previous two buffers */ - int new_upd_len, old_upd_len; /* length of output buffers */ - - SLKeyMap_List_Type *keymap; - - /* tty variables */ - unsigned int flags; /* */ -#define SL_RLINE_NO_ECHO 1 -#define SL_RLINE_USE_ANSI 2 - unsigned int (*getkey)(void); /* getkey function -- required */ - void (*tt_goto_column)(int); - void (*tt_insert)(char); - void (*update_hook)(unsigned char *, int, int); - /* The update hook is called with a pointer to a buffer p1 that contains - * an image of what the update hook is suppoed to produce. The length - * of the buffer is p2 and after the update, the cursor is to be placed - * in column p3. - */ -} SLang_RLine_Info_Type; - -extern int SLang_RL_EOF_Char; - -extern SLang_Read_Line_Type * SLang_rline_save_line (SLang_RLine_Info_Type *); -extern int SLang_init_readline (SLang_RLine_Info_Type *); -extern int SLang_read_line (SLang_RLine_Info_Type *); -extern int SLang_rline_insert (char *); -extern void SLrline_redraw (SLang_RLine_Info_Type *); -extern int SLang_Rline_Quit; - -/*}}}*/ - -/*{{{ Low Level Screen Output Interface */ - -extern unsigned long SLtt_Num_Chars_Output; -extern int SLtt_Baud_Rate; - -typedef unsigned long SLtt_Char_Type; - -#define SLTT_BOLD_MASK 0x01000000 -#define SLTT_BLINK_MASK 0x02000000 -#define SLTT_ULINE_MASK 0x04000000 -#define SLTT_REV_MASK 0x08000000 -#define SLTT_ALTC_MASK 0x10000000 - -extern int SLtt_Screen_Rows; -extern int SLtt_Screen_Cols; -extern int SLtt_Term_Cannot_Insert; -extern int SLtt_Term_Cannot_Scroll; -extern int SLtt_Use_Ansi_Colors; -extern int SLtt_Ignore_Beep; -#if defined(REAL_UNIX_SYSTEM) -extern int SLtt_Force_Keypad_Init; -#endif - -#ifndef __GO32__ -#if defined(VMS) || defined(REAL_UNIX_SYSTEM) -extern int SLtt_Blink_Mode; -extern int SLtt_Use_Blink_For_ACS; -extern int SLtt_Newline_Ok; -extern int SLtt_Has_Alt_Charset; -extern int SLtt_Has_Status_Line; /* if 0, NO. If > 0, YES, IF -1, ?? */ -# ifndef VMS -extern int SLtt_Try_Termcap; -# endif -#endif -#endif - -#ifdef msdos -extern int SLtt_Msdos_Cheap_Video; -#endif - - -extern int SLtt_flush_output (void); -extern void SLtt_set_scroll_region(int, int); -extern void SLtt_reset_scroll_region(void); -extern void SLtt_reverse_video (int); -extern void SLtt_bold_video (void); -extern void SLtt_begin_insert(void); -extern void SLtt_end_insert(void); -extern void SLtt_del_eol(void); -extern void SLtt_goto_rc (int, int); -extern void SLtt_delete_nlines(int); -extern void SLtt_delete_char(void); -extern void SLtt_erase_line(void); -extern void SLtt_normal_video(void); -extern void SLtt_cls(void); -extern void SLtt_beep(void); -extern void SLtt_reverse_index(int); -extern void SLtt_smart_puts(unsigned short *, unsigned short *, int, int); -extern void SLtt_write_string (char *); -extern void SLtt_putchar(char); -extern void SLtt_init_video (void); -extern void SLtt_reset_video (void); -extern void SLtt_get_terminfo(void); -extern void SLtt_get_screen_size (void); -extern int SLtt_set_cursor_visibility (int); - -#if defined(VMS) || defined(REAL_UNIX_SYSTEM) -extern void SLtt_enable_cursor_keys(void); -extern void SLtt_set_term_vtxxx(int *); -extern void SLtt_set_color_esc (int, char *); -extern void SLtt_wide_width(void); -extern void SLtt_narrow_width(void); -extern int SLtt_set_mouse_mode (int, int); -extern void SLtt_set_alt_char_set (int); -extern int SLtt_write_to_status_line (char *, int); -extern void SLtt_disable_status_line (void); -# ifdef REAL_UNIX_SYSTEM - extern char *SLtt_tgetstr (char *); - extern int SLtt_tgetnum (char *); - extern int SLtt_tgetflag (char *); - extern char *SLtt_tigetent (char *); - extern char *SLtt_tigetstr (char *, char **); - extern int SLtt_tigetnum (char *, char **); -# endif -#endif - -extern SLtt_Char_Type SLtt_get_color_object (int); -extern void SLtt_set_color_object (int, SLtt_Char_Type); -extern void SLtt_set_color (int, char *, char *, char *); -extern void SLtt_set_mono (int, char *, SLtt_Char_Type); -extern void SLtt_add_color_attribute (int, SLtt_Char_Type); -extern void SLtt_set_color_fgbg (int, SLtt_Char_Type, SLtt_Char_Type); - -/*}}}*/ - -/*{{{ SLang Preprocessor Interface */ - -typedef struct -{ - int this_level; - int exec_level; - int prev_exec_level; - char preprocess_char; - char comment_char; - unsigned char flags; -#define SLPREP_BLANK_LINES_OK 1 -#define SLPREP_COMMENT_LINES_OK 2 -} -SLPreprocess_Type; - -extern int SLprep_open_prep (SLPreprocess_Type *); -extern void SLprep_close_prep (SLPreprocess_Type *); -extern int SLprep_line_ok (char *, SLPreprocess_Type *); - extern int SLdefine_for_ifdef (char *); - /* Adds a string to the SLang #ifdef preparsing defines. SLang already - defines MSDOS, UNIX, and VMS on the appropriate system. */ -extern int (*SLprep_exists_hook) (char *, char); - - -/*}}}*/ - -/*{{{ SLsmg Screen Management Functions */ - -#include -extern void SLsmg_fill_region (int, int, int, int, unsigned char); -#ifndef pc_system -extern void SLsmg_set_char_set (int); -extern int SLsmg_Scroll_Hash_Border; -#endif -extern void SLsmg_suspend_smg (void); -extern void SLsmg_resume_smg (void); -extern void SLsmg_erase_eol (void); -extern void SLsmg_gotorc (int, int); -extern void SLsmg_erase_eos (void); -extern void SLsmg_reverse_video (void); -extern void SLsmg_set_color (int); -extern void SLsmg_normal_video (void); -extern void SLsmg_printf (char *, ...); -extern void SLsmg_vprintf (char *, va_list); -extern void SLsmg_write_string (char *); -extern void SLsmg_write_nstring (char *, int); -extern void SLsmg_write_char (char); -extern void SLsmg_write_nchars (char *, int); -extern void SLsmg_write_wrapped_string (char *, int, int, int, int, int); -extern void SLsmg_cls (void); -extern void SLsmg_refresh (void); -extern void SLsmg_touch_lines (int, int); -extern int SLsmg_init_smg (void); -extern void SLsmg_reset_smg (void); -extern unsigned short SLsmg_char_at(void); -extern void SLsmg_set_screen_start (int *, int *); -extern void SLsmg_draw_hline (int); -extern void SLsmg_draw_vline (int); -extern void SLsmg_draw_object (int, int, unsigned char); -extern void SLsmg_draw_box (int, int, int, int); -extern int SLsmg_get_column(void); -extern int SLsmg_get_row(void); -extern void SLsmg_forward (int); -extern void SLsmg_write_color_chars (unsigned short *, unsigned int); -extern unsigned int SLsmg_read_raw (unsigned short *, unsigned int); -extern unsigned int SLsmg_write_raw (unsigned short *, unsigned int); - -extern int SLsmg_Display_Eight_Bit; -extern int SLsmg_Tab_Width; -extern int SLsmg_Newline_Moves; -extern int SLsmg_Backspace_Moves; - -#ifdef pc_system -# define SLSMG_HLINE_CHAR 0xC4 -# define SLSMG_VLINE_CHAR 0xB3 -# define SLSMG_ULCORN_CHAR 0xDA -# define SLSMG_URCORN_CHAR 0xBF -# define SLSMG_LLCORN_CHAR 0xC0 -# define SLSMG_LRCORN_CHAR 0xD9 -# define SLSMG_RTEE_CHAR 0xB4 -# define SLSMG_LTEE_CHAR 0xC3 -# define SLSMG_UTEE_CHAR 0xC2 -# define SLSMG_DTEE_CHAR 0xC1 -# define SLSMG_PLUS_CHAR 0xC5 -/* There are several to choose from: 0xB0, 0xB1, and 0xB2 */ -# define SLSMG_CKBRD_CHAR 0xB0 -#else -# define SLSMG_HLINE_CHAR 'q' -# define SLSMG_VLINE_CHAR 'x' -# define SLSMG_ULCORN_CHAR 'l' -# define SLSMG_URCORN_CHAR 'k' -# define SLSMG_LLCORN_CHAR 'm' -# define SLSMG_LRCORN_CHAR 'j' -# define SLSMG_CKBRD_CHAR 'a' -# define SLSMG_RTEE_CHAR 'u' -# define SLSMG_LTEE_CHAR 't' -# define SLSMG_UTEE_CHAR 'w' -# define SLSMG_DTEE_CHAR 'v' -# define SLSMG_PLUS_CHAR 'n' -#endif - -#ifndef pc_system -# define SLSMG_COLOR_BLACK 0x000000 -# define SLSMG_COLOR_RED 0x000001 -# define SLSMG_COLOR_GREEN 0x000002 -# define SLSMG_COLOR_BROWN 0x000003 -# define SLSMG_COLOR_BLUE 0x000004 -# define SLSMG_COLOR_MAGENTA 0x000005 -# define SLSMG_COLOR_CYAN 0x000006 -# define SLSMG_COLOR_LGRAY 0x000007 -# define SLSMG_COLOR_GRAY 0x000008 -# define SLSMG_COLOR_BRIGHT_RED 0x000009 -# define SLSMG_COLOR_BRIGHT_GREEN 0x00000A -# define SLSMG_COLOR_BRIGHT_BROWN 0x00000B -# define SLSMG_COLOR_BRIGHT_BLUE 0x00000C -# define SLSMG_COLOR_BRIGHT_CYAN 0x00000D -# define SLSMG_COLOR_BRIGHT_MAGENTA 0x00000E -# define SLSMG_COLOR_BRIGHT_WHITE 0x00000F -#endif - -/*}}}*/ - -/*{{{ SLang Keypad Interface */ - -#define SL_KEY_ERR 0xFFFF - -#define SL_KEY_UP 0x101 -#define SL_KEY_DOWN 0x102 -#define SL_KEY_LEFT 0x103 -#define SL_KEY_RIGHT 0x104 -#define SL_KEY_PPAGE 0x105 -#define SL_KEY_NPAGE 0x106 -#define SL_KEY_HOME 0x107 -#define SL_KEY_END 0x108 -#define SL_KEY_A1 0x109 -#define SL_KEY_A3 0x10A -#define SL_KEY_B2 0x10B -#define SL_KEY_C1 0x10C -#define SL_KEY_C3 0x10D -#define SL_KEY_REDO 0x10E -#define SL_KEY_UNDO 0x10F -#define SL_KEY_BACKSPACE 0x110 -#define SL_KEY_ENTER 0x111 -#define SL_KEY_IC 0x112 -#define SL_KEY_DELETE 0x113 - -#define SL_KEY_F0 0x200 -#define SL_KEY_F(X) (SL_KEY_F0 + X) - -/* I do not intend to use keysymps > 0x1000. Applications can use those. */ -/* Returns 0 upon success or -1 upon error. */ -int SLkp_define_keysym (char *, unsigned int); - -/* This function must be called AFTER SLtt_get_terminfo and not before. */ -extern int SLkp_init (void); - -/* This function uses SLang_getkey and assumes that what ever initialization - * is required for SLang_getkey has been performed. - */ -extern int SLkp_getkey (void); - -/*}}}*/ - -/*{{{ SLang Scroll Interface */ - -typedef struct _SLscroll_Type -{ - struct _SLscroll_Type *next; - struct _SLscroll_Type *prev; - unsigned int flags; -} -SLscroll_Type; - -typedef struct -{ - unsigned int flags; - SLscroll_Type *top_window_line; /* list element at top of window */ - SLscroll_Type *bot_window_line; /* list element at bottom of window */ - SLscroll_Type *current_line; /* current list element */ - SLscroll_Type *lines; /* first list element */ - unsigned int nrows; /* number of rows in window */ - unsigned int hidden_mask; /* applied to flags in SLscroll_Type */ - unsigned int line_num; /* current line number (visible) */ - unsigned int num_lines; /* total number of lines (visible) */ - unsigned int window_row; /* row of current_line in window */ - unsigned int border; /* number of rows that form scroll border */ - int cannot_scroll; /* should window scroll or recenter */ -} -SLscroll_Window_Type; - -extern int SLscroll_find_top (SLscroll_Window_Type *); -extern int SLscroll_find_line_num (SLscroll_Window_Type *); -extern unsigned int SLscroll_next_n (SLscroll_Window_Type *, unsigned int); -extern unsigned int SLscroll_prev_n (SLscroll_Window_Type *, unsigned int); -extern int SLscroll_pageup (SLscroll_Window_Type *); -extern int SLscroll_pagedown (SLscroll_Window_Type *); - -/*}}}*/ - -/*{{{ Signal Routines */ - -typedef void SLSig_Fun_Type (int); -extern SLSig_Fun_Type *SLsignal (int, SLSig_Fun_Type *); -extern SLSig_Fun_Type *SLsignal_intr (int, SLSig_Fun_Type *); -#ifndef pc_system -extern int SLsig_block_signals (void); -extern int SLsig_unblock_signals (void); -#endif -/*}}}*/ - -/*{{{ Interpreter Macro Definitions */ - -/* This value is a main_type just like the other main_types defined - * near the definition of SLang_Name_Type. Applications should avoid using - * this so if you do not understands its role, do not use it. - */ -#define SLANG_DATA 0x30 /* real objects which may be destroyed */ - -/* Subtypes */ - -/* The definitions here are for objects that may be on the run-time stack. - * They are actually sub_types of literal and data main_types. - */ -#define VOID_TYPE 1 -#define INT_TYPE 2 -#ifdef FLOAT_TYPE -# undef FLOAT_TYPE -# define FLOAT_TYPE 3 -#endif -#define CHAR_TYPE 4 -#define INTP_TYPE 5 -/* An object of INTP_TYPE should never really occur on the stack. Rather, - * the integer to which it refers will be there instead. It is defined here - * because it is a valid type for MAKE_VARIABLE. - */ - -#define SLANG_OBJ_TYPE 6 -/* SLANG_OBJ_TYPE refers to an object on the stack that is a pointer to - * some other object. - */ - -#if 0 -/* This is not ready yet. */ -# define SLANG_NOOP 9 -#endif - -/* Everything above string should correspond to a pointer in the object - * structure. See do_binary (slang.c) for exploitation of this fact. - */ -#define STRING_TYPE 10 -/* Array type MUST be the smallest number for SLuser_Object_Type structs */ -#define ARRAY_TYPE 20 -/* I am reserving values greater than or equal to user applications. The - * first 99 are used for S-Lang. - */ - - -/* Binary and Unary Subtypes */ -/* Since the application can define new types and can overload the binary - * and unary operators, these definitions must be present in this file. - */ -#define SLANG_PLUS 1 -#define SLANG_MINUS 2 -#define SLANG_TIMES 3 -#define SLANG_DIVIDE 4 -#define SLANG_EQ 5 -#define SLANG_NE 6 -#define SLANG_GT 7 -#define SLANG_GE 8 -#define SLANG_LT 9 -#define SLANG_LE 10 - -/* UNARY subtypes (may be overloaded) */ -#define SLANG_ABS 11 -#define SLANG_SIGN 12 -#define SLANG_SQR 13 -#define SLANG_MUL2 14 -#define SLANG_CHS 15 - -/* error codes, severe errors are less than 0 */ -#define SL_INVALID_PARM -6 -#define SL_MALLOC_ERROR -5 -#define INTERNAL_ERROR -4 -#define UNKNOWN_ERROR -3 -#define STACK_OVERFLOW -1 -#define STACK_UNDERFLOW -2 -#define INTRINSIC_ERROR 1 -/* Intrinsic error is an error generated by intrinsic functions */ -#define USER_BREAK 2 -#define UNDEFINED_NAME 3 -#define SYNTAX_ERROR 4 -#define DUPLICATE_DEFINITION 5 -#define TYPE_MISMATCH 6 -#define READONLY_ERROR 7 -#define DIVIDE_ERROR 8 -/* object could not be opened */ -#define SL_OBJ_NOPEN 9 -/* unknown object */ -#define SL_OBJ_UNKNOWN 10 - -extern char *SLang_Error_Message; - -extern void SLadd_name(char *, long, unsigned char, unsigned char); -extern void SLadd_at_handler (long *, char *); - -#define SLANG_MAKE_ARGS(out, in) ((unsigned char)(out) | ((unsigned short) (in) << 4)) - -#ifdef SLANG_STATS - -#define MAKE_INTRINSIC(n, f, out, in) \ - {0, n, (out | (in << 4)), SLANG_INTRINSIC, (long) f} - -#define MAKE_VARIABLE(n, v, t, r) \ - {0, n, t, (SLANG_IVARIABLE + r), (long) v} - -#else -#define MAKE_INTRINSIC(n, f, out, in) \ - {n, (out | (in << 4)), SLANG_INTRINSIC, (long) f} - -#define MAKE_VARIABLE(n, v, t, r) \ - {n, t, (SLANG_IVARIABLE + r), (long) v} -#endif - -#define SLANG_END_TABLE MAKE_INTRINSIC("", 0, 0, 0) - - -/*}}}*/ - -/*{{{ Upper/Lowercase Functions */ - -extern void SLang_define_case(int *, int *); -extern void SLang_init_case_tables (void); - -extern unsigned char Chg_UCase_Lut[256]; -extern unsigned char Chg_LCase_Lut[256]; -#define UPPER_CASE(x) (Chg_UCase_Lut[(unsigned char) (x)]) -#define LOWER_CASE(x) (Chg_LCase_Lut[(unsigned char) (x)]) -#define CHANGE_CASE(x) (((x) == Chg_LCase_Lut[(unsigned char) (x)]) ?\ - Chg_UCase_Lut[(unsigned char) (x)] : Chg_LCase_Lut[(unsigned char) (x)]) - - -/*}}}*/ - -/*{{{ Regular Expression Interface */ - -typedef struct -{ - unsigned char *pat; /* regular expression pattern */ - unsigned char *buf; /* buffer for compiled regexp */ - unsigned int buf_len; /* length of buffer */ - int case_sensitive; /* 1 if match is case sensitive */ - int must_match; /* 1 if line must contain substring */ - int must_match_bol; /* true if it must match beginning of line */ - unsigned char must_match_str[16]; /* 15 char null term substring */ - int osearch; /* 1 if ordinary search suffices */ - unsigned int min_length; /* minimum length the match must be */ - int beg_matches[10]; /* offset of start of \( */ - unsigned int end_matches[10]; /* length of nth submatch - * Note that the entire match corresponds - * to \0 - */ - int offset; /* offset to be added to beg_matches */ -} SLRegexp_Type; - -extern unsigned char *SLang_regexp_match(unsigned char *, - unsigned int, - SLRegexp_Type *); -extern int SLang_regexp_compile (SLRegexp_Type *); -extern char *SLregexp_quote_string (char *, char *, unsigned int); - - -/*}}}*/ - -/*{{{ SLang Command Interface */ - -#define SLCMD_MAX_ARGS 10 -struct _SLcmd_Cmd_Type; /* Pre-declaration is needed below */ -typedef struct -{ - struct _SLcmd_Cmd_Type *table; - int argc; - char *string_args[SLCMD_MAX_ARGS]; - int int_args[SLCMD_MAX_ARGS]; - float64 float_args[SLCMD_MAX_ARGS]; - unsigned char arg_type[SLCMD_MAX_ARGS]; -} SLcmd_Cmd_Table_Type; - - -typedef struct _SLcmd_Cmd_Type -{ - int (*cmdfun)(int, SLcmd_Cmd_Table_Type *); - char cmd[32]; - char arg_type[SLCMD_MAX_ARGS]; -} SLcmd_Cmd_Type; - -extern int SLcmd_execute_string (char *, SLcmd_Cmd_Table_Type *); - -/*}}}*/ - -/*{{{ SLang Search Interface */ - -typedef struct -{ - int cs; /* case sensitive */ - unsigned char key[256]; - int ind[256]; - int key_len; - int dir; -} SLsearch_Type; - -extern int SLsearch_init (char *, int, int, SLsearch_Type *); -/* This routine must first be called before any search can take place. - * The second parameter specifies the direction of the search: greater than - * zero for a forwrd search and less than zero for a backward search. The - * third parameter specifies whether the search is case sensitive or not. - * The last parameter is a pointer to a structure that is filled by this - * function and it is this structure that must be passed to SLsearch. - */ - -unsigned char *SLsearch (unsigned char *, unsigned char *, SLsearch_Type *); -/* To use this routine, you must first call 'SLsearch_init'. Then the first - * two parameters p1 and p2 serve to define the region over which the search - * is to take place. The third parameter is the structure that was previously - * initialized by SLsearch_init. - * - * The routine returns a pointer to the match if found otherwise it returns - * NULL. - */ - -/*}}}*/ - -#if 0 -{ -#endif -#ifdef __cplusplus -} -#endif - -#endif /* _DAVIS_SLANG_H_ */ diff --git a/slang/sldisply.c b/slang/sldisply.c index 4ad93c437..9afc942ab 100644 --- a/slang/sldisply.c +++ b/slang/sldisply.c @@ -1,73 +1,18 @@ -/* Copyright (c) 1992, 1995 John E. Davis - * All rights reserved. - * +/* Copyright (c) 1992, 1999, 2001, 2002 John E. Davis + * This file is part of the S-Lang library. + * * You may distribute under the terms of either the GNU General Public * License or the Perl Artistic License. */ +#include "slinclud.h" -/* - * SLTT_TRANSP_ACS_PATCH (#define/#undef): - * - * The problem: some terminals (e.g. QNX/qansi*) map the whole upper half of - * the ASCII table to the lower half, when alt-char-set is activated with - * the smacs/as string-sequence. This means, that if 0 <= ch < 128 written - * to the terminal, it will be translated to (ch+128) automatically by the - * terminal: so not only the line-drawing characters can be written, when - * the alt-char-set is activated. It implicitly means, that space, NL, CR, - * etc. characters (exactly: anything besides the "standard" line drawing - * characters) can not be written directly to the terminal, when the - * alt-char-set is activated, because writing these characters doesn't cause - * an implicit/temporary switching-back to the standard char-set! - * - * The original code in SLang assumes that space, NL, CR, etc. can be - * printed when alt-char-set is activated. If SLTT_TRANSP_ACS_PATCH is - * defined, the modified code will not use this assumption. - * [Remark: the patch-code is not the most exact solution, but works...] - */ -/*#define SLTT_TRANSP_ACS_PATCH 1*/ - -/* - * QNX_QANSI_SLANG_COMPAT_ACS (#define/#undef): - * - * A more OS/terminal-specific solution for the problem mentioned above - * (->SLTT_TRANSP_ACS_PATCH). - * - * If QNX_QANSI_SLANG_COMPAT_ACS is defined, the default smacs/sa, rmacs/ae, - * acsc/ac [and sgr/sa, if it would be used!] command sequences will be - * replaced internally with the "old style" (pre-QNX 4.23) sequences in case - * of QNX/qansi terminals. Using these optional command sequences the terminal - * remains compatible with the original SLang code (without using the - * workaround-code enabled by defining SLTT_TRANSP_ACS_PATCH). - */ -/*#define QNX_QANSI_SLANG_COMPAT_ACS 1*/ - -/* auto-configuration */ -#ifdef SLTT_TRANSP_ACS_PATCH -# if defined(__QNX__) && defined(QNX_QANSI_SLANG_COMPAT_ACS) -# undef SLTT_TRANSP_ACS_PATCH -# endif -#else -# if defined(__QNX__) && !defined(QNX_QANSI_SLANG_COMPAT_ACS) -# define QNX_QANSI_SLANG_COMPAT_ACS 1 -# endif -#endif - -#include "sl-feat.h" -#include "config.h" - -#include -#include -#ifdef SCO_FLAVOR -# include -# include /* for struct timeb, used in time.h */ -#endif #include #include -#ifndef VMS +#if !defined(VMS) || (__VMS_VER >= 70000000) # include # ifdef __QNX__ -# include +# include # endif # include #endif @@ -94,7 +39,6 @@ # endif #endif - #ifdef SYSV # include # include @@ -107,15 +51,6 @@ #endif #include -#include "_slang.h" - -#ifdef HAVE_STDLIB_H -# include -#endif - -#ifdef HAVE_UNISTD_H -# include -#endif #if defined(__DECC) && defined(VMS) /* These get prototypes for write an sleep */ @@ -123,8 +58,10 @@ #endif #include +#include "slang.h" +#include "_slang.h" -/* Colors: These definitions are used for the display. However, the +/* Colors: These definitions are used for the display. However, the * application only uses object handles which get mapped to this * internal representation. The mapping is performed by the Color_Map * structure below. */ @@ -139,8 +76,6 @@ * not include this attribute. */ - - #define GET_FG(color) ((color & FG_MASK) >> 8) #define GET_BG(color) ((color & BG_MASK) >> 16) #define MAKE_COLOR(fg, bg) (((fg) | ((bg) << 8)) << 8) @@ -156,84 +91,85 @@ int SLtt_Newline_Ok = 0; int SLtt_Has_Alt_Charset = 0; int SLtt_Force_Keypad_Init = 0; +void (*_SLtt_color_changed_hook)(void); + +#if SLTT_HAS_NON_BCE_SUPPORT +static int Bce_Color_Offset = 0; +#endif +static int Can_Background_Color_Erase = 1; + /* -1 means unknown */ int SLtt_Has_Status_Line = -1; /* hs */ +int SLang_TT_Write_FD = -1; static int Automatic_Margins; /* static int No_Move_In_Standout; */ static int Worthless_Highlight; #define HP_GLITCH_CODE #ifdef HP_GLITCH_CODE -/* This glitch is exclusive to HP term. Basically it means that to clear +/* This glitch is exclusive to HP term. Basically it means that to clear * attributes, one has to erase to the end of the line. */ static int Has_HP_Glitch; #endif static char *Reset_Color_String; +static int Is_Color_Terminal = 0; static int Linux_Console; /* It is crucial that JMAX_COLORS must be less than 128 since the high bit * is used to indicate a character from the ACS (alt char set). The exception - * to this rule is if SLtt_Use_Blink_For_ACS is true. This means that of - * the highbit is set, we interpret that as a blink character. This is + * to this rule is if SLtt_Use_Blink_For_ACS is true. This means that of + * the highbit is set, we interpret that as a blink character. This is * exploited by DOSemu. */ #define JMAX_COLORS 256 #define JNORMAL_COLOR 0 -typedef struct +typedef struct { SLtt_Char_Type fgbg; SLtt_Char_Type mono; char *custom_esc; -} Ansi_Color_Type; +} +Ansi_Color_Type; #define RGB1(r, g, b) ((r) | ((g) << 1) | ((b) << 2)) #define RGB(r, g, b, br, bg, bb) ((RGB1(r, g, b) << 8) | (RGB1(br, bg, bb) << 16)) -static Ansi_Color_Type Ansi_Color_Map[JMAX_COLORS] = +static Ansi_Color_Type Ansi_Color_Map[JMAX_COLORS] = { - {RGB(1, 1, 1, 0, 0, 0), 0x00000000, NULL}, /* white/black */ - {RGB(0, 1, 0, 0, 0, 0), SLTT_REV_MASK, NULL}, /* green/black */ - {RGB(1, 0, 1, 0, 0, 0), SLTT_REV_MASK, NULL}, /* magenta/black */ - {RGB(0, 1, 1, 0, 0, 0), SLTT_REV_MASK, NULL}, /* cyan/black */ - {RGB(1, 0, 0, 0, 0, 0), SLTT_REV_MASK, NULL}, - {RGB(0, 1, 0, 0, 0, 1), SLTT_REV_MASK, NULL}, - {RGB(1, 0, 0, 0, 0, 1), SLTT_REV_MASK, NULL}, - {RGB(1, 0, 0, 0, 1, 0), SLTT_REV_MASK, NULL}, - {RGB(0, 0, 1, 1, 0, 0), SLTT_REV_MASK, NULL}, - {RGB(0, 1, 0, 1, 0, 0), SLTT_REV_MASK, NULL}, - {RGB(0, 1, 1, 1, 1, 1), SLTT_REV_MASK, NULL}, - {RGB(1, 1, 0, 1, 1, 1), SLTT_REV_MASK, NULL}, - {RGB(1, 0, 1, 1, 1, 1), SLTT_REV_MASK, NULL}, - {RGB(0, 0, 0, 0, 1, 1), SLTT_REV_MASK, NULL}, - {RGB(0, 1, 0, 1, 1, 1), SLTT_REV_MASK, NULL}, - {RGB(0, 1, 0, 1, 1, 1), SLTT_REV_MASK, NULL}, - {RGB(0, 1, 0, 1, 1, 1), SLTT_REV_MASK, NULL}, - {RGB(0, 1, 0, 1, 1, 1), SLTT_REV_MASK, NULL} + {RGB(1, 1, 1, 0, 0, 0), 0x00000000, NULL}, /* white/black */ + {RGB(0, 1, 0, 0, 0, 0), SLTT_REV_MASK, NULL}, /* green/black */ + {RGB(1, 0, 1, 0, 0, 0), SLTT_REV_MASK, NULL}, /* magenta/black */ + {RGB(0, 1, 1, 0, 0, 0), SLTT_REV_MASK, NULL}, /* cyan/black */ + {RGB(1, 0, 0, 0, 0, 0), SLTT_REV_MASK, NULL}, + {RGB(0, 1, 0, 0, 0, 1), SLTT_REV_MASK, NULL}, + {RGB(1, 0, 0, 0, 0, 1), SLTT_REV_MASK, NULL}, + {RGB(1, 0, 0, 0, 1, 0), SLTT_REV_MASK, NULL}, + {RGB(0, 0, 1, 1, 0, 0), SLTT_REV_MASK, NULL}, + {RGB(0, 1, 0, 1, 0, 0), SLTT_REV_MASK, NULL}, + {RGB(0, 1, 1, 1, 1, 1), SLTT_REV_MASK, NULL}, + {RGB(1, 1, 0, 1, 1, 1), SLTT_REV_MASK, NULL}, + {RGB(1, 0, 1, 1, 1, 1), SLTT_REV_MASK, NULL}, + {RGB(0, 0, 0, 0, 1, 1), SLTT_REV_MASK, NULL}, + {RGB(0, 1, 0, 1, 1, 1), SLTT_REV_MASK, NULL}, + {RGB(0, 1, 0, 1, 1, 1), SLTT_REV_MASK, NULL}, + {RGB(0, 1, 0, 1, 1, 1), SLTT_REV_MASK, NULL}, + {RGB(0, 1, 0, 1, 1, 1), SLTT_REV_MASK, NULL} }; +static char *Color_Fg_Str = "\033[3%dm"; +static char *Color_Bg_Str = "\033[4%dm"; +static char *Default_Color_Fg_Str = "\033[39m"; +static char *Default_Color_Bg_Str = "\033[49m"; -/* This is the string to use to use when outputting color information. - */ -#ifdef M_UNIX -/* work around for sco console bug that can't handle combined sequences */ - static char *Color_Escape_Sequence = "\033[3%dm\033[4%dm"; -#else -/* Believe it or not, this is what is in the linux terminfo database. It - * produces the same escape sequence but it is much more CPU intensive. - * Why not just encode it as "\033[3%p1%dm\033[4%p2%dm" ??? - */ - /* static char *Color_Escape_Sequence = "\033[%p1%{30}%+%dm\033[%p2%{40}%+%dm"; */ -static char *Color_Escape_Sequence = "\033[3%d;4%dm"; -#endif +static int Max_Terminfo_Colors = 8; /* termcap Co */ char *SLtt_Graphics_Char_Pairs; /* ac termcap string -- def is vt100 */ - -/* 1 if terminal lacks the ability to do into insert mode or into delete +/* 1 if terminal lacks the ability to go into insert mode or into delete mode. Currently controlled by S-Lang but later perhaps termcap. */ static char *UnderLine_Vid_Str; @@ -246,6 +182,7 @@ static char *Cls_Str; /* = "\033[2J\033[H"; */ /* cl termcap STR for ansi term static char *Rev_Vid_Str; /* = "\033[7m"; */ /* mr,so termcap string */ static char *Norm_Vid_Str; /* = "\033[m"; */ /* me,se termcap string */ static char *Del_Eol_Str; /* = "\033[K"; */ /* ce */ +static char *Del_Bol_Str; /* = "\033[1K"; */ /* cb */ static char *Del_Char_Str; /* = "\033[P"; */ /* dc */ static char *Del_N_Lines_Str; /* = "\033[%dM"; */ /* DL */ static char *Add_N_Lines_Str; /* = "\033[%dL"; */ /* AL */ @@ -254,7 +191,10 @@ static char *Curs_Up_Str; static char *Curs_F_Str; /* RI termcap string */ static char *Cursor_Visible_Str; /* ve termcap string */ static char *Cursor_Invisible_Str; /* vi termcap string */ - +#if 0 +static char *Start_Mouse_Rpt_Str; /* Start mouse reporting mode */ +static char *End_Mouse_Rpt_Str; /* End mouse reporting mode */ +#endif static char *Start_Alt_Chars_Str; /* as */ static char *End_Alt_Chars_Str; /* ae */ static char *Enable_Alt_Char_Set; /* eA */ @@ -269,7 +209,7 @@ static char *Disable_Status_line_Str; /* ds */ static char *Return_From_Status_Line_Str; /* fs */ static char *Goto_Status_Line_Str; /* ts */ static int Num_Status_Line_Columns; /* ws */ -static int Status_Line_Esc_Ok; /* es */ +/* static int Status_Line_Esc_Ok; */ /* es */ /* static int Len_Curs_F_Str = 5; */ @@ -277,7 +217,6 @@ static int Status_Line_Esc_Ok; /* es */ /* char *CURS_POS_STR = "\033[%d;%df"; ansi-- hor and vert pos */ static char *Curs_Pos_Str; /* = "\033[%i%d;%dH";*/ /* cm termcap string */ - /* scrolling region */ static int Scroll_r1 = 0, Scroll_r2 = 23; static int Cursor_r, Cursor_c; /* 0 based */ @@ -289,7 +228,6 @@ static int Cursor_Set; /* 1 if cursor position known, 0 * if not. -1 if only row is known */ - #define MAX_OUTPUT_BUFFER_SIZE 4096 static unsigned char Output_Buffer[MAX_OUTPUT_BUFFER_SIZE]; @@ -297,13 +235,9 @@ static unsigned char *Output_Bufferp = Output_Buffer; unsigned long SLtt_Num_Chars_Output; -#ifdef SLTT_TRANSP_ACS_PATCH -static int SLtt_ACS_Active = 0; -#endif - -static int sl_usleep (unsigned long usecs) +int _SLusleep (unsigned long usecs) { -#ifndef VMS +#if !defined(VMS) || (__VMS_VER >= 70000000) struct timeval tv; tv.tv_sec = usecs / 1000000; tv.tv_usec = usecs % 1000000; @@ -318,27 +252,27 @@ int SLtt_flush_output (void) int nwrite = 0; unsigned int total; int n = (int) (Output_Bufferp - Output_Buffer); - + SLtt_Num_Chars_Output += n; - + total = 0; while (n > 0) { - nwrite = write (fileno(stdout), (char *) Output_Buffer + total, n); + nwrite = write (SLang_TT_Write_FD, (char *) Output_Buffer + total, n); if (nwrite == -1) { nwrite = 0; #ifdef EAGAIN - if (errno == EAGAIN) + if (errno == EAGAIN) { - sl_usleep (100000); /* 1/10 sec */ + _SLusleep (100000); /* 1/10 sec */ continue; } #endif #ifdef EWOULDBLOCK if (errno == EWOULDBLOCK) { - sl_usleep (100000); + _SLusleep (100000); continue; } #endif @@ -354,7 +288,6 @@ int SLtt_flush_output (void) return n; } - int SLtt_Baud_Rate; static void tt_write(char *str, unsigned int n) { @@ -362,10 +295,10 @@ static void tt_write(char *str, unsigned int n) static int total; unsigned long now; unsigned int ndiff; - + if ((str == NULL) || (n == 0)) return; total += n; - + while (1) { ndiff = MAX_OUTPUT_BUFFER_SIZE - (int) (Output_Bufferp - Output_Buffer); @@ -377,14 +310,14 @@ static void tt_write(char *str, unsigned int n) n -= ndiff; str += ndiff; } - else + else { SLMEMCPY ((char *) Output_Bufferp, str, n); Output_Bufferp += n; break; } } - + if (((SLtt_Baud_Rate > 150) && (SLtt_Baud_Rate <= 9600)) && (10 * total > SLtt_Baud_Rate)) { @@ -398,197 +331,339 @@ static void tt_write(char *str, unsigned int n) } } - -void SLtt_write_string (char *str) +static void tt_write_string (char *str) { if (str != NULL) tt_write(str, strlen(str)); } +void SLtt_write_string (char *str) +{ + tt_write_string (str); + Cursor_Set = 0; +} void SLtt_putchar (char ch) { -#ifdef SLTT_TRANSP_ACS_PATCH - int restore_acs = 0; -#endif - SLtt_normal_video (); if (Cursor_Set == 1) { if (ch >= ' ') Cursor_c++; -#ifndef SLTT_TRANSP_ACS_PATCH else if (ch == '\b') Cursor_c--; -#else - if (ch <= ' ' && SLtt_ACS_Active) - { - SLtt_set_alt_char_set (0); - restore_acs = 1; - } - if (ch == '\b') Cursor_c--; -#endif else if (ch == '\r') Cursor_c = 0; else Cursor_Set = 0; - - if ((Cursor_c + 1 == SLtt_Screen_Cols) + + if ((Cursor_c + 1 == SLtt_Screen_Cols) && Automatic_Margins) Cursor_Set = 0; } - + if (Output_Bufferp < Output_Buffer + MAX_OUTPUT_BUFFER_SIZE) { *Output_Bufferp++ = (unsigned char) ch; } else tt_write (&ch, 1); - -#ifdef SLTT_TRANSP_ACS_PATCH - if (restore_acs) - { - SLtt_set_alt_char_set (1); - } -#endif } -/* this is supposed to be fast--- also handles - termcap: %d, &i, %., %+, %r strings as well as terminfo stuff */ static unsigned int tt_sprintf(char *buf, char *fmt, int x, int y) { - register unsigned char *f = (unsigned char *) fmt, *b, ch; - int offset = 0, tinfo = 0; - int stack[10]; - int i = 0, z; - stack[0] = y; stack[1] = x; i = 2; - - b = (unsigned char *) buf; - if (fmt != NULL) while ((ch = *f++) != 0) + char *fmt_max; + register unsigned char *b, ch; + int offset; + int z, z1, parse_level; + int zero_pad; + int field_width; + int variables [26]; + int stack [64]; + unsigned int stack_len; + int parms [10]; +#define STACK_POP (stack_len ? stack[--stack_len] : 0) + + if (fmt == NULL) { - if (ch != '%') *b++ = ch; - else + *buf = 0; + return 0; + } + + stack [0] = y; /* pushed for termcap */ + stack [1] = x; + stack_len = 2; + + parms [1] = x; /* p1 */ + parms [2] = y; /* p2 */ + + offset = 0; + zero_pad = 0; + field_width = 0; + + b = (unsigned char *) buf; + fmt_max = fmt + strlen (fmt); + + while (fmt < fmt_max) + { + ch = *fmt++; + + if (ch != '%') { - ch = *f++; - if (tinfo) + *b++ = ch; + continue; + } + + if (fmt == fmt_max) break; + ch = *fmt++; + + switch (ch) + { + default: + *b++ = ch; + break; + + case 'p': + + if (fmt == fmt_max) break; + ch = *fmt++; + if ((ch >= '0') && (ch <= '9')) + stack [stack_len++] = parms [ch - '0']; + break; + + case '\'': /* 'x' */ + if (fmt == fmt_max) break; + stack [stack_len++] = *fmt++; + if (fmt < fmt_max) fmt++; /* skip ' */ + break; + + case '{': /* literal constant, e.g. {30} */ + z = 0; + while ((fmt < fmt_max) && ((ch = *fmt) <= '9') && (ch >= '0')) { - if ((ch <= '3') && (ch >= '0')) - { - /* map it to termcap. Since this is terminfo, - * it must be one of: - * %2d, %3d, %02d, %03d - * - * I am assuming that a terminal that understands - * %2d form will also understand the %02d form. These - * only differ by a space padding the field. - */ - - /* skip the 'd'-- hope it is there */ - if (ch == '0') - { - ch = *f; - f += 2; - } - else f++; - } + z = z * 10 + (ch - '0'); + fmt++; } - - switch (ch) + stack [stack_len++] = z; + if ((ch == '}') && (fmt < fmt_max)) fmt++; + break; + + case '0': + if (fmt == fmt_max) break; + ch = *fmt; + if ((ch != '2') && (ch != '3')) + break; + zero_pad = 1; + fmt++; + /* drop */ + + case '2': + case '3': + if (fmt == fmt_max) + if (*fmt == 'x') { - case 'p': - tinfo = 1; - ch = *f++; - if (ch == '1') stack[i++] = x; else stack[i++] = y; - break; - - case '\'': /* 'x' */ - stack[i++] = *f++; - f++; - break; - - case '{': /* literal constant, e.g. {30} */ - z = 0; - while (((ch = *f) <= '9') && (ch >= '0')) - { - z = z * 10 + (ch - '0'); - f++; - } - stack[i++] = z; - if (ch == '}') f++; - break; - - case 'd': - case '2': - case '3': - z = stack[--i]; + char x_fmt_buf [4]; + char *x_fmt_buf_ptr; + + x_fmt_buf_ptr = x_fmt_buf; + if (zero_pad) *x_fmt_buf_ptr++ = '0'; + *x_fmt_buf_ptr++ = ch; + *x_fmt_buf_ptr++ = 'X'; + *x_fmt_buf_ptr = 0; + + z = STACK_POP; z += offset; - if (z >= 100) - { - *b++ = z / 100 + '0'; - z = z % 100; - goto ten; - } - else if (ch == 3) - { - *b++ = '0'; - ch = '2'; - } - - if (z >= 10) - { - ten: - *b++ = z / 10 + '0'; - z = z % 10; - } - else if (ch == 2) *b++ = '0'; - - *b++ = z + '0'; + + sprintf ((char *)b, x_fmt_buf, z); + b += strlen ((char *)b); + zero_pad = 0; break; - - case 'i': - offset = 1; - break; - - case '+': - if (tinfo) - { - z = stack[--i]; - stack[i-1] += z; - } - else - { - ch = *f++; - if ((unsigned char) ch == 128) ch = 0; - ch = ch + (unsigned char) stack[--i]; - if (ch == '\n') ch++; - *b++ = ch; - } - break; - - case 'r': - stack[0] = x; - stack[1] = y; - break; - - case '.': - case 'c': - ch = (unsigned char) stack[--i]; + } + + field_width = (ch - '0'); + /* drop */ + + case 'd': + z = STACK_POP; + z += offset; + if (z >= 100) + { + *b++ = z / 100 + '0'; + z = z % 100; + zero_pad = 1; + field_width = 2; + } + else if (zero_pad && (field_width == 3)) + *b++ = '0'; + + if (z >= 10) + { + *b++ = z / 10 + '0'; + z = z % 10; + } + else if (zero_pad && (field_width >= 2)) + *b++ = '0'; + + *b++ = z + '0'; + field_width = zero_pad = 0; + break; + + case 'x': + z = STACK_POP; + z += offset; + sprintf ((char *) b, "%X", z); + b += strlen ((char *)b); + break; + + case 'i': + offset = 1; + break; + + case '+': + /* Handling this depends upon whether or not we are parsing + * terminfo. Terminfo requires the stack so use it as an + * indicator. + */ + if (stack_len > 2) + { + z = STACK_POP; + stack [stack_len - 1] += z; + } + else if (fmt < fmt_max) + { + ch = *fmt++; + if ((unsigned char) ch == 128) ch = 0; + ch = ch + (unsigned char) STACK_POP; if (ch == '\n') ch++; *b++ = ch; - break; - - default: - *b++ = ch; } + break; + + /* Binary operators */ + case '-': + case '*': + case '/': + case 'm': + case '&': + case '|': + case '^': + case '=': + case '>': + case '<': + case 'A': + case 'O': + z1 = STACK_POP; + z = STACK_POP; + switch (ch) + { + case '-': z = (z - z1); break; + case '*': z = (z * z1); break; + case '/': z = (z / z1); break; + case 'm': z = (z % z1); break; + case '&': z = (z & z1); break; + case '|': z = (z | z1); break; + case '^': z = (z ^ z1); break; + case '=': z = (z == z1); break; + case '>': z = (z > z1); break; + case '<': z = (z < z1); break; + case 'A': z = (z && z1); break; + case 'O': z = (z || z1); break; + } + stack [stack_len++] = z; + break; + + /* unary */ + case '!': + z = STACK_POP; + stack [stack_len++] = !z; + break; + + case '~': + z = STACK_POP; + stack [stack_len++] = ~z; + break; + + case 'r': /* termcap -- swap parameters */ + z = stack [0]; + stack [0] = stack [1]; + stack [1] = z; + break; + + case '.': /* termcap */ + case 'c': + ch = (unsigned char) STACK_POP; + if (ch == '\n') ch++; + *b++ = ch; + break; + + case 'g': + if (fmt == fmt_max) break; + ch = *fmt++; + if ((ch >= 'a') && (ch <= 'z')) + stack [stack_len++] = variables [ch - 'a']; + break; + + case 'P': + if (fmt == fmt_max) break; + ch = *fmt++; + if ((ch >= 'a') && (ch <= 'z')) + variables [ch - 'a'] = STACK_POP; + break; + + /* If then else parsing. Actually, this is rather easy. The + * key is to notice that 'then' does all the work. 'if' simply + * there to indicate the start of a test and endif indicates + * the end of tests. If 'else' is seen, then skip to + * endif. + */ + case '?': /* if */ + case ';': /* endif */ + break; + + case 't': /* then */ + z = STACK_POP; + if (z != 0) + break; /* good. Continue parsing. */ + + /* z == 0 and test has failed. So, skip past this entire if + * expression to the matching else or matching endif. + */ + /* drop */ + case 'e': /* else */ + + parse_level = 0; + while (fmt < fmt_max) + { + unsigned char ch1; + + ch1 = *fmt++; + if ((ch1 != '%') || (fmt == fmt_max)) + continue; + + ch1 = *fmt++; + + if (ch1 == '?') parse_level++; /* new if */ + else if (ch1 == 'e') + { + if ((ch != 'e') && (parse_level == 0)) + break; + } + else if (ch1 == ';') + { + if (parse_level == 0) + break; + parse_level--; + } + } + break; } } *b = 0; - return((unsigned int) (b - (unsigned char *) buf)); + return (unsigned int) (b - (unsigned char *) buf); } static void tt_printf(char *fmt, int x, int y) { - char buf[256]; + char buf[1024]; unsigned int n; if (fmt == NULL) return; n = tt_sprintf(buf, fmt, x, y); tt_write(buf, n); } - void SLtt_set_scroll_region (int r1, int r2) { Scroll_r1 = r1; @@ -599,60 +674,53 @@ void SLtt_set_scroll_region (int r1, int r2) void SLtt_reset_scroll_region (void) { - SLtt_set_scroll_region(0, SLtt_Screen_Rows - 1); + SLtt_set_scroll_region(0, SLtt_Screen_Rows - 1); } int SLtt_set_cursor_visibility (int show) { if ((Cursor_Visible_Str == NULL) || (Cursor_Invisible_Str == NULL)) return -1; - - SLtt_write_string (show ? Cursor_Visible_Str : Cursor_Invisible_Str); + + tt_write_string (show ? Cursor_Visible_Str : Cursor_Invisible_Str); return 0; } - /* the goto_rc function moves to row relative to scrolling region */ void SLtt_goto_rc(int r, int c) { char *s = NULL; int n; char buf[6]; -#ifdef SLTT_TRANSP_ACS_PATCH - int check_alt_acs = 0; -#endif - - if (c < 0) + + if ((c < 0) || (r < 0)) { - c = -c - 1; Cursor_Set = 0; + return; } - + /* if (No_Move_In_Standout && Current_Fgbg) SLtt_normal_video (); */ r += Scroll_r1; - + if ((Cursor_Set > 0) || ((Cursor_Set < 0) && !Automatic_Margins)) { n = r - Cursor_r; - if ((n == -1) && (Cursor_Set > 0) && (Cursor_c == c) + if ((n == -1) && (Cursor_Set > 0) && (Cursor_c == c) && (Curs_Up_Str != NULL)) { s = Curs_Up_Str; } else if ((n >= 0) && (n <= 4)) { - if ((n == 0) && (Cursor_Set == 1) + if ((n == 0) && (Cursor_Set == 1) && ((c > 1) || (c == Cursor_c))) { if (Cursor_c == c) return; - if (Cursor_c == c + 1) + if (Cursor_c == c + 1) { s = buf; *s++ = '\b'; *s = 0; s = buf; -#ifdef SLTT_TRANSP_ACS_PATCH - check_alt_acs = 1; -#endif } } else if (c == 0) @@ -666,13 +734,10 @@ void SLtt_goto_rc(int r, int c) #endif *s = 0; s = buf; -#ifdef SLTT_TRANSP_ACS_PATCH - check_alt_acs = 1; -#endif } /* Will fail on VMS */ #ifndef VMS - else if (SLtt_Newline_Ok && (Cursor_Set == 1) && + else if (SLtt_Newline_Ok && (Cursor_Set == 1) && (Cursor_c >= c) && (c + 3 > Cursor_c)) { s = buf; @@ -681,27 +746,11 @@ void SLtt_goto_rc(int r, int c) while (n--) *s++ = '\b'; *s = 0; s = buf; -#ifdef SLTT_TRANSP_ACS_PATCH - check_alt_acs = 1; -#endif } #endif } } -#ifndef SLTT_TRANSP_ACS_PATCH - if (s != NULL) SLtt_write_string(s); -#else - if (s != NULL) - { - if (check_alt_acs && SLtt_ACS_Active) - { - SLtt_set_alt_char_set (0); - SLtt_write_string(s); - SLtt_set_alt_char_set (1); - } - else SLtt_write_string(s); - } -#endif + if (s != NULL) tt_write_string(s); else tt_printf(Curs_Pos_Str, r, c); Cursor_c = c; Cursor_r = r; Cursor_Set = 1; @@ -709,37 +758,51 @@ void SLtt_goto_rc(int r, int c) void SLtt_begin_insert (void) { - SLtt_write_string(Ins_Mode_Str); + tt_write_string(Ins_Mode_Str); } void SLtt_end_insert (void) { - SLtt_write_string(Eins_Mode_Str); + tt_write_string(Eins_Mode_Str); } void SLtt_delete_char (void) { SLtt_normal_video (); - SLtt_write_string(Del_Char_Str); + tt_write_string(Del_Char_Str); } void SLtt_erase_line (void) { - SLtt_write_string("\r"); + tt_write_string("\r"); Cursor_Set = 1; Cursor_c = 0; SLtt_del_eol(); } +/* It appears that the Linux console, and most likely others do not + * like scrolling regions that consist of one line. So I have to + * resort to this stupidity to make up for that stupidity. + */ +static void delete_line_in_scroll_region (void) +{ + SLtt_goto_rc (Cursor_r - Scroll_r1, 0); + SLtt_del_eol (); +} + void SLtt_delete_nlines (int n) { int r1, curs; char buf[132]; -#ifdef SLTT_TRANSP_ACS_PATCH - int restore_acs = 0; -#endif - + if (n <= 0) return; SLtt_normal_video (); + + if (Scroll_r1 == Scroll_r2) + { + delete_line_in_scroll_region (); + return; + } + if (Del_N_Lines_Str != NULL) tt_printf(Del_N_Lines_Str,n, 0); else /* get a new terminal */ @@ -748,18 +811,8 @@ void SLtt_delete_nlines (int n) curs = Cursor_r; SLtt_set_scroll_region(curs, Scroll_r2); SLtt_goto_rc(Scroll_r2 - Scroll_r1, 0); -#ifdef SLTT_TRANSP_ACS_PATCH - if (SLtt_ACS_Active) - { - SLtt_set_alt_char_set (0); - restore_acs = 1; - } -#endif SLMEMSET(buf, '\n', (unsigned int) n); tt_write(buf, (unsigned int) n); -#ifdef SLTT_TRANSP_ACS_PATCH - if (restore_acs) SLtt_set_alt_char_set (1); -#endif /* while (n--) tt_putchar('\n'); */ SLtt_set_scroll_region(r1, Scroll_r2); SLtt_goto_rc(curs, 0); @@ -768,54 +821,97 @@ void SLtt_delete_nlines (int n) void SLtt_cls (void) { + /* If the terminal is a color terminal but the user wants black and + * white, then make sure that the colors are reset. This appears to be + * necessary. + */ + if ((SLtt_Use_Ansi_Colors == 0) && Is_Color_Terminal) + { + if (Reset_Color_String != NULL) + tt_write_string (Reset_Color_String); + else + tt_write_string ("\033[0m\033[m"); + } + SLtt_normal_video(); SLtt_reset_scroll_region (); - SLtt_write_string(Cls_Str); + tt_write_string(Cls_Str); } void SLtt_reverse_index (int n) { if (!n) return; - + SLtt_normal_video(); + + if (Scroll_r1 == Scroll_r2) + { + delete_line_in_scroll_region (); + return; + } + if (Add_N_Lines_Str != NULL) tt_printf(Add_N_Lines_Str,n, 0); else { - while(n--) SLtt_write_string(Rev_Scroll_Str); + while(n--) tt_write_string(Rev_Scroll_Str); } } - int SLtt_Ignore_Beep = 1; static char *Visible_Bell_Str; void SLtt_beep (void) { if (SLtt_Ignore_Beep & 0x1) SLtt_putchar('\007'); - + if (SLtt_Ignore_Beep & 0x2) { - if (Visible_Bell_Str != NULL) SLtt_write_string (Visible_Bell_Str); + if (Visible_Bell_Str != NULL) tt_write_string (Visible_Bell_Str); #ifdef __linux__ else if (Linux_Console) { - SLtt_write_string ("\033[?5h"); + tt_write_string ("\033[?5h"); SLtt_flush_output (); - sl_usleep (50000); - SLtt_write_string ("\033[?5l"); + _SLusleep (50000); + tt_write_string ("\033[?5l"); } #endif } SLtt_flush_output (); } +static void del_eol (void) +{ + int c; + + if (Del_Eol_Str != NULL) + { + tt_write_string(Del_Eol_Str); + return; + } + + c = Cursor_c; + /* Avoid writing to the lower right corner. If the terminal does not + * have Del_Eol_Str, then it probably does not have what it takes to play + * games with insert for for a space into that corner. + */ + if (Cursor_r + 1 < SLtt_Screen_Rows) + c++; + + while (c < SLtt_Screen_Cols) + { + tt_write (" ", 1); + c++; + } +} + void SLtt_del_eol (void) { if (Current_Fgbg != 0xFFFFFFFFU) SLtt_normal_video (); - SLtt_write_string(Del_Eol_Str); + del_eol (); } -typedef const struct +typedef struct { char *name; SLtt_Char_Type color; @@ -825,33 +921,33 @@ Color_Def_Type; #define MAX_COLOR_NAMES 17 static Color_Def_Type Color_Defs [MAX_COLOR_NAMES] = { - {"black", SLSMG_COLOR_BLACK}, - {"red", SLSMG_COLOR_RED}, - {"green", SLSMG_COLOR_GREEN}, - {"brown", SLSMG_COLOR_BROWN}, - {"blue", SLSMG_COLOR_BLUE}, - {"magenta", SLSMG_COLOR_MAGENTA}, - {"cyan", SLSMG_COLOR_CYAN}, - {"lightgray", SLSMG_COLOR_LGRAY}, - {"gray", SLSMG_COLOR_GRAY}, - {"brightred", SLSMG_COLOR_BRIGHT_RED}, - {"brightgreen", SLSMG_COLOR_BRIGHT_GREEN}, - {"yellow", SLSMG_COLOR_BRIGHT_BROWN}, - {"brightblue", SLSMG_COLOR_BRIGHT_BLUE}, - {"brightmagenta", SLSMG_COLOR_BRIGHT_CYAN}, - {"brightcyan", SLSMG_COLOR_BRIGHT_MAGENTA}, - {"white", SLSMG_COLOR_BRIGHT_WHITE}, - {"default", 25} + {"black", SLSMG_COLOR_BLACK}, + {"red", SLSMG_COLOR_RED}, + {"green", SLSMG_COLOR_GREEN}, + {"brown", SLSMG_COLOR_BROWN}, + {"blue", SLSMG_COLOR_BLUE}, + {"magenta", SLSMG_COLOR_MAGENTA}, + {"cyan", SLSMG_COLOR_CYAN}, + {"lightgray", SLSMG_COLOR_LGRAY}, + {"gray", SLSMG_COLOR_GRAY}, + {"brightred", SLSMG_COLOR_BRIGHT_RED}, + {"brightgreen", SLSMG_COLOR_BRIGHT_GREEN}, + {"yellow", SLSMG_COLOR_BRIGHT_BROWN}, + {"brightblue", SLSMG_COLOR_BRIGHT_BLUE}, + {"brightmagenta", SLSMG_COLOR_BRIGHT_CYAN}, + {"brightcyan", SLSMG_COLOR_BRIGHT_MAGENTA}, + {"white", SLSMG_COLOR_BRIGHT_WHITE}, +#define SLSMG_COLOR_DEFAULT 0xFF + {"default", SLSMG_COLOR_DEFAULT} }; - void SLtt_set_mono (int obj, char *what, SLtt_Char_Type mask) { (void) what; if ((obj < 0) || (obj >= JMAX_COLORS)) { return; - } + } Ansi_Color_Map[obj].mono = mask & ATTR_MASK; } @@ -859,20 +955,20 @@ static char *check_color_for_digit_form (char *color) { unsigned int i, ich; char *s = color; - + i = 0; while ((ich = (int) *s) != 0) { if ((ich < '0') || (ich > '9')) return color; - + i = i * 10 + (ich - '0'); s++; } - + if (i < MAX_COLOR_NAMES) color = Color_Defs[i].name; - + return color; } @@ -881,7 +977,7 @@ static int get_default_colors (char **fgp, char **bgp) static char fg_buf[16], bg_buf[16], *bg, *fg; static int already_parsed; char *p, *pmax; - + if (already_parsed == -1) return -1; @@ -891,9 +987,9 @@ static int get_default_colors (char **fgp, char **bgp) *bgp = bg; return 0; } - + already_parsed = -1; - + bg = getenv ("COLORFGBG"); if (bg == NULL) @@ -902,22 +998,22 @@ static int get_default_colors (char **fgp, char **bgp) if (bg == NULL) return -1; } - + p = fg_buf; pmax = p + (sizeof (fg_buf) - 1); - + while ((*bg != 0) && (*bg != ';')) { if (p < pmax) *p++ = *bg; bg++; } *p = 0; - + if (*bg) bg++; - + p = bg_buf; pmax = p + (sizeof (bg_buf) - 1); - + /* Mark suggested allowing for extra spplication specific stuff following * the background color. That is what the check for the semi-colon is for. */ @@ -941,7 +1037,6 @@ static int get_default_colors (char **fgp, char **bgp) return 0; } - static unsigned char FgBg_Stats[JMAX_COLORS]; static int Color_0_Modified = 0; @@ -949,19 +1044,22 @@ static int Color_0_Modified = 0; void SLtt_set_color_object (int obj, SLtt_Char_Type attr) { char *cust_esc; - + if ((obj < 0) || (obj >= JMAX_COLORS)) return; - + cust_esc = Ansi_Color_Map[obj].custom_esc; - if (cust_esc != NULL) + if (cust_esc != NULL) { - SLFREE (cust_esc); + SLfree (cust_esc); FgBg_Stats[(Ansi_Color_Map[obj].fgbg >> 8) & 0x7F] -= 1; Ansi_Color_Map[obj].custom_esc = NULL; } - + Ansi_Color_Map[obj].fgbg = attr; if (obj == 0) Color_0_Modified = 1; + + if (_SLtt_color_changed_hook != NULL) + (*_SLtt_color_changed_hook)(); } SLtt_Char_Type SLtt_get_color_object (int obj) @@ -970,71 +1068,120 @@ SLtt_Char_Type SLtt_get_color_object (int obj) return Ansi_Color_Map[obj].fgbg; } - void SLtt_add_color_attribute (int obj, SLtt_Char_Type attr) { if ((obj < 0) || (obj >= JMAX_COLORS)) return; - + Ansi_Color_Map[obj].fgbg |= (attr & ATTR_MASK); if (obj == 0) Color_0_Modified = 1; + if (_SLtt_color_changed_hook != NULL) + (*_SLtt_color_changed_hook)(); } static SLtt_Char_Type fb_to_fgbg (SLtt_Char_Type f, SLtt_Char_Type b) -{ - SLtt_Char_Type attr = 0; +{ + SLtt_Char_Type attr; - if ((f & 0xF0) == 0) + if (Max_Terminfo_Colors != 8) + { + if (f != SLSMG_COLOR_DEFAULT) f %= Max_Terminfo_Colors; + if (b != SLSMG_COLOR_DEFAULT) b %= Max_Terminfo_Colors; + return ((f << 8) | (b << 16)); + } + + /* Otherwise we have 8 ansi colors. Try to get bright versions + * by using the BOLD and BLINK attributes. + */ + + attr = 0; + + /* Note: If f represents default, it will have the value 0xFF */ + if (f != SLSMG_COLOR_DEFAULT) { if (f & 0x8) attr = SLTT_BOLD_MASK; f &= 0x7; } - else f = 9; - - if ((b & 0xF0) == 0) + + if (b != SLSMG_COLOR_DEFAULT) { if (b & 0x8) attr |= SLTT_BLINK_MASK; b &= 0x7; } - else b = 9; - + return ((f << 8) | (b << 16) | attr); } +/* This looks for colors with name form 'colorN'. If color is of this + * form, N is passed back via paramter list. + */ +static int parse_color_digit_name (char *color, SLtt_Char_Type *f) +{ + unsigned int i; + unsigned char ch; + + if (strncmp (color, "color", 5)) + return -1; + + color += 5; + if (*color == 0) + return -1; + + i = 0; + while (1) + { + ch = (unsigned char) *color++; + if (ch == 0) + break; + if ((ch > '9') || (ch < '0')) + return -1; + i = 10 * i + (ch - '0'); + } + + *f = (SLtt_Char_Type) i; + return 0; +} + static int make_color_fgbg (char *fg, char *bg, SLtt_Char_Type *fgbg) { SLtt_Char_Type f = 0xFFFFFFFFU, b = 0xFFFFFFFFU; char *dfg, *dbg; unsigned int i; - + if ((fg != NULL) && (*fg == 0)) fg = NULL; if ((bg != NULL) && (*bg == 0)) bg = NULL; - + if ((fg == NULL) || (bg == NULL)) { if (-1 == get_default_colors (&dfg, &dbg)) return -1; - + if (fg == NULL) fg = dfg; if (bg == NULL) bg = dbg; } - - for (i = 0; i < MAX_COLOR_NAMES; i++) + + if (-1 == parse_color_digit_name (fg, &f)) { - if (strcmp(fg, Color_Defs[i].name)) continue; - f = Color_Defs[i].color; - break; + for (i = 0; i < MAX_COLOR_NAMES; i++) + { + if (strcmp(fg, Color_Defs[i].name)) continue; + f = Color_Defs[i].color; + break; + } } - for (i = 0; i < MAX_COLOR_NAMES; i++) + if (-1 == parse_color_digit_name (bg, &b)) { - if (strcmp(bg, Color_Defs[i].name)) continue; - b = Color_Defs[i].color; - break; + for (i = 0; i < MAX_COLOR_NAMES; i++) + { + if (strcmp(bg, Color_Defs[i].name)) continue; + b = Color_Defs[i].color; + break; + } } - + if ((f == 0xFFFFFFFFU) || (b == 0xFFFFFFFFU)) return -1; - + *fgbg = fb_to_fgbg (f, b); return 0; } @@ -1061,22 +1208,22 @@ void SLtt_set_color_esc (int obj, char *esc) char *cust_esc; SLtt_Char_Type fgbg = 0; int i; - + if ((obj < 0) || (obj >= JMAX_COLORS)) { return; } - + cust_esc = Ansi_Color_Map[obj].custom_esc; - if (cust_esc != NULL) + if (cust_esc != NULL) { - SLFREE (cust_esc); + SLfree (cust_esc); FgBg_Stats[(Ansi_Color_Map[obj].fgbg >> 8) & 0x7F] -= 1; } - - cust_esc = (char *) SLMALLOC (strlen(esc) + 1); + + cust_esc = (char *) SLmalloc (strlen(esc) + 1); if (cust_esc != NULL) strcpy (cust_esc, esc); - + Ansi_Color_Map[obj].custom_esc = cust_esc; if (cust_esc == NULL) fgbg = 0; else @@ -1085,7 +1232,7 @@ void SLtt_set_color_esc (int obj, char *esc) for (i = 0; i < JMAX_COLORS; i++) { if (FgBg_Stats[i] == 0) fgbg = i; - + if (obj == i) continue; if ((Ansi_Color_Map[i].custom_esc) == NULL) continue; if (!strcmp (Ansi_Color_Map[i].custom_esc, cust_esc)) @@ -1096,73 +1243,91 @@ void SLtt_set_color_esc (int obj, char *esc) } FgBg_Stats[fgbg] += 1; } - + fgbg |= 0x80; Ansi_Color_Map[obj].fgbg = (fgbg | (fgbg << 8)) << 8; if (obj == 0) Color_0_Modified = 1; + if (_SLtt_color_changed_hook != NULL) + (*_SLtt_color_changed_hook)(); } void SLtt_set_alt_char_set (int i) { -#ifndef SLTT_TRANSP_ACS_PATCH static int last_i; -#else -#define last_i SLtt_ACS_Active -#endif if (SLtt_Has_Alt_Charset == 0) return; + + i = (i != 0); + if (i == last_i) return; - SLtt_write_string (i ? Start_Alt_Chars_Str : End_Alt_Chars_Str ); - /* if (i) Current_Fgbg |= SLTT_ALTC_MASK; - else Current_Fgbg &= ~SLTT_ALTC_MASK; */ + tt_write_string (i ? Start_Alt_Chars_Str : End_Alt_Chars_Str ); last_i = i; -#ifdef SLTT_TRANSP_ACS_PATCH -#undef last_i -#endif } static void write_attributes (SLtt_Char_Type fgbg) { int bg0, fg0; + int unknown_attributes; if (Worthless_Highlight) return; if (fgbg == Current_Fgbg) return; - + + unknown_attributes = 0; + /* Before spitting out colors, fix attributes */ if ((fgbg & ATTR_MASK) != (Current_Fgbg & ATTR_MASK)) { if (Current_Fgbg & ATTR_MASK) { - SLtt_write_string(Norm_Vid_Str); + tt_write_string(Norm_Vid_Str); /* In case normal video turns off ALL attributes: */ - if (fgbg & SLTT_ALTC_MASK) + if (fgbg & SLTT_ALTC_MASK) Current_Fgbg &= ~SLTT_ALTC_MASK; SLtt_set_alt_char_set (0); } - - if ((fgbg & SLTT_ALTC_MASK) + + if ((fgbg & SLTT_ALTC_MASK) != (Current_Fgbg & SLTT_ALTC_MASK)) { SLtt_set_alt_char_set ((int) (fgbg & SLTT_ALTC_MASK)); } - - if (fgbg & SLTT_ULINE_MASK) SLtt_write_string (UnderLine_Vid_Str); + + if (fgbg & SLTT_ULINE_MASK) tt_write_string (UnderLine_Vid_Str); if (fgbg & SLTT_BOLD_MASK) SLtt_bold_video (); - if (fgbg & SLTT_REV_MASK) SLtt_write_string (Rev_Vid_Str); + if (fgbg & SLTT_REV_MASK) tt_write_string (Rev_Vid_Str); if (fgbg & SLTT_BLINK_MASK) { /* Someday Linux will have a blink mode that set high intensity * background. Lets be prepared. */ - if (SLtt_Blink_Mode) SLtt_write_string (Blink_Vid_Str); + if (SLtt_Blink_Mode) tt_write_string (Blink_Vid_Str); } + unknown_attributes = 1; } - + if (SLtt_Use_Ansi_Colors) { fg0 = (int) GET_FG(fgbg); bg0 = (int) GET_BG(fgbg); - tt_printf(Color_Escape_Sequence, fg0, bg0); + + if (unknown_attributes + || (fg0 != (int)GET_FG(Current_Fgbg))) + { + if (fg0 == SLSMG_COLOR_DEFAULT) + tt_write_string (Default_Color_Fg_Str); + else + tt_printf (Color_Fg_Str, fg0, 0); + } + + if (unknown_attributes + || (bg0 != (int)GET_BG(Current_Fgbg))) + { + if (bg0 == SLSMG_COLOR_DEFAULT) + tt_write_string (Default_Color_Bg_Str); + else + tt_printf (Color_Bg_Str, bg0, 0); + } } + Current_Fgbg = fgbg; } @@ -1172,22 +1337,22 @@ void SLtt_reverse_video (int color) { SLtt_Char_Type fgbg; char *esc; - + if (Worthless_Highlight) return; if ((color < 0) || (color >= JMAX_COLORS)) return; - + if (Video_Initialized == 0) { if (color == JNORMAL_COLOR) { - SLtt_write_string (Norm_Vid_Str); + tt_write_string (Norm_Vid_Str); } - else SLtt_write_string (Rev_Vid_Str); + else tt_write_string (Rev_Vid_Str); Current_Fgbg = 0xFFFFFFFFU; return; } - - if (SLtt_Use_Ansi_Colors) + + if (SLtt_Use_Ansi_Colors) { fgbg = Ansi_Color_Map[color].fgbg; if ((esc = Ansi_Color_Map[color].custom_esc) != NULL) @@ -1195,7 +1360,7 @@ void SLtt_reverse_video (int color) if (fgbg != Current_Fgbg) { Current_Fgbg = fgbg; - SLtt_write_string (esc); + tt_write_string (esc); return; } } @@ -1206,9 +1371,6 @@ void SLtt_reverse_video (int color) write_attributes (fgbg); } - - - void SLtt_normal_video (void) { SLtt_reverse_video(JNORMAL_COLOR); @@ -1216,43 +1378,61 @@ void SLtt_normal_video (void) void SLtt_narrow_width (void) { - SLtt_write_string("\033[?3l"); + tt_write_string("\033[?3l"); } void SLtt_wide_width (void) { - SLtt_write_string("\033[?3h"); + tt_write_string("\033[?3h"); } /* Highest bit represents the character set. */ #define COLOR_MASK 0x7F00 -#define COLOR_OF(x) (((unsigned int)(x) & COLOR_MASK) >> 8) -/* -#define COLOR_EQS(a, b) \ - (Ansi_Color_Map[COLOR_OF(a)].fgbg == Ansi_Color_Map[COLOR_OF(b)].fgbg) -*/ +#if SLTT_HAS_NON_BCE_SUPPORT +static int bce_color_eqs (unsigned int a, unsigned int b) +{ + a = (a & COLOR_MASK) >> 8; + b = (b & COLOR_MASK) >> 8; + + if (a == b) + return 1; -#define COLOR_EQS(a, b) \ + if (SLtt_Use_Ansi_Colors == 0) + return Ansi_Color_Map[a].mono == Ansi_Color_Map[b].mono; + + if (Bce_Color_Offset == 0) + return Ansi_Color_Map[a].fgbg == Ansi_Color_Map[b].fgbg; + + /* If either are color 0, then we do not know what that means since the + * terminal does not support BCE */ + if ((a == 0) || (b == 0)) + return 0; + + return Ansi_Color_Map[a-1].fgbg == Ansi_Color_Map[b-1].fgbg; +} +#define COLOR_EQS(a,b) bce_color_eqs (a,b) +#else +# define COLOR_OF(x) (((unsigned int)(x) & COLOR_MASK) >> 8) +# define COLOR_EQS(a, b) \ (SLtt_Use_Ansi_Colors \ ? (Ansi_Color_Map[COLOR_OF(a)].fgbg == Ansi_Color_Map[COLOR_OF(b)].fgbg)\ : (Ansi_Color_Map[COLOR_OF(a)].mono == Ansi_Color_Map[COLOR_OF(b)].mono)) - +#endif #define CHAR_EQS(a, b) (((a) == (b))\ || ((((a) & ~COLOR_MASK) == ((b) & ~COLOR_MASK))\ && COLOR_EQS((a), (b)))) - /* The whole point of this routine is to prevent writing to the last column * and last row on terminals with automatic margins. */ static void write_string_with_care (char *str) { unsigned int len; - + if (str == NULL) return; - + len = strlen (str); if (Automatic_Margins && (Cursor_r + 1 == SLtt_Screen_Rows)) { @@ -1263,52 +1443,56 @@ static void write_string_with_care (char *str) */ if (SLtt_Screen_Cols > Cursor_c) len = SLtt_Screen_Cols - Cursor_c - 1; - else len = 0; + else + len = 0; } } tt_write (str, len); } -static void send_attr_str (unsigned short *s) +static void send_attr_str (SLsmg_Char_Type *s) { unsigned char out[256], ch, *p; register SLtt_Char_Type attr; - register unsigned short sh; + register SLsmg_Char_Type sh; int color, last_color = -1; - + p = out; while (0 != (sh = *s++)) { ch = sh & 0xFF; color = ((int) sh & 0xFF00) >> 8; -#ifdef SLTT_TRANSP_ACS_PATCH - if (ch <= ' ' && (color & 0x80)) color &= ~0x80; + +#if SLTT_HAS_NON_BCE_SUPPORT + if (Bce_Color_Offset + && (color >= Bce_Color_Offset)) + color -= Bce_Color_Offset; #endif + if (color != last_color) { if (SLtt_Use_Ansi_Colors) attr = Ansi_Color_Map[color & 0x7F].fgbg; else attr = Ansi_Color_Map[color & 0x7F].mono; - - /* sh => color */ - if (color & 0x80) /* alternate char set */ + + if (sh & 0x8000) /* alternate char set */ { if (SLtt_Use_Blink_For_ACS) { if (SLtt_Blink_Mode) attr |= SLTT_BLINK_MASK; } - else attr |= SLTT_ALTC_MASK; + else attr |= SLTT_ALTC_MASK; } - - + if (attr != Current_Fgbg) { -#ifndef SLTT_TRANSP_ACS_PATCH if ((ch != ' ') || /* it is a space so only consider it different if it * has different attributes. */ - (attr & BGALL_MASK) != (Current_Fgbg & BGALL_MASK)) -#endif + (attr != Current_Fgbg)) + /* The previous line was: */ + /* (attr & BGALL_MASK) != (Current_Fgbg & BGALL_MASK)) */ + /* However, it does not account for ACS */ { if (p != out) { @@ -1320,7 +1504,7 @@ static void send_attr_str (unsigned short *s) if (SLtt_Use_Ansi_Colors && (NULL != Ansi_Color_Map[color & 0x7F].custom_esc)) { - SLtt_write_string (Ansi_Color_Map[color & 0x7F].custom_esc); + tt_write_string (Ansi_Color_Map[color & 0x7F].custom_esc); /* Just in case the custom escape sequence screwed up * the alt character set state... */ @@ -1329,7 +1513,7 @@ static void send_attr_str (unsigned short *s) Current_Fgbg = attr; } else write_attributes (attr); - + last_color = color; } } @@ -1343,10 +1527,9 @@ static void send_attr_str (unsigned short *s) static void forward_cursor (unsigned int n, int row) { - char buf[30]; - - - if (n <= 4) + char buf [1024]; + + if (n <= 4) { SLtt_normal_video (); SLMEMSET (buf, ' ', n); @@ -1364,36 +1547,53 @@ static void forward_cursor (unsigned int n, int row) } -#define SPACE_CHAR (0x20 | (JNORMAL_COLOR << 8)) - -void SLtt_smart_puts(unsigned short *neww, unsigned short *oldd, int len, int row) +void SLtt_smart_puts(SLsmg_Char_Type *neww, SLsmg_Char_Type *oldd, int len, int row) { - register unsigned short *p, *q, *qmax, *pmax, *buf; - unsigned short buffer[256]; + register SLsmg_Char_Type *p, *q, *qmax, *pmax, *buf; + SLsmg_Char_Type buffer[256]; unsigned int n_spaces; - unsigned short *space_match, *last_buffered_match; + SLsmg_Char_Type *space_match, *last_buffered_match; #ifdef HP_GLITCH_CODE int handle_hp_glitch = 0; #endif - + SLsmg_Char_Type space_char; +#define SLTT_USE_INSERT_HACK 1 +#if SLTT_USE_INSERT_HACK + SLsmg_Char_Type insert_hack_prev = 0; + SLsmg_Char_Type insert_hack_char = 0; + + if ((row + 1 == SLtt_Screen_Rows) + && (len == SLtt_Screen_Cols) + && (len > 1) + && (SLtt_Term_Cannot_Insert == 0) + && Automatic_Margins) + { + insert_hack_char = neww[len-1]; + if (oldd[len-1] == insert_hack_char) + insert_hack_char = 0; + else + insert_hack_prev = neww[len-2]; + } +#endif + q = oldd; p = neww; qmax = oldd + len; pmax = p + len; - + /* Find out where to begin --- while they match, we are ok */ while (1) { if (q == qmax) return; #if SLANG_HAS_KANJI_SUPPORT - if (*p & 0x80) + if (*p & 0x80) { /* new is kanji */ if ((*q & 0x80) && ((q + 1) < qmax)) { /* old is also kanji */ if (((0xFF & *q) != (0xFF & *p)) || ((0xFF & q[1]) != (0xFF & p[1]))) break; /* both kanji, but not match */ - - else + + else { /* kanji match ! */ if (!COLOR_EQS(*q, *p)) break; q++; p++; @@ -1405,7 +1605,7 @@ void SLtt_smart_puts(unsigned short *neww, unsigned short *oldd, int len, int ro } else break; /* old is not kanji */ } - else + else { /* new is not kanji */ if (*q & 0x80) break; /* old is kanji */ } @@ -1414,13 +1614,13 @@ void SLtt_smart_puts(unsigned short *neww, unsigned short *oldd, int len, int ro q++; p++; } - /*position the cursor */ - SLtt_goto_rc (row, (int) (p - neww)); - #ifdef HP_GLITCH_CODE if (Has_HP_Glitch) { - unsigned short *qq = q; + SLsmg_Char_Type *qq = q; + + SLtt_goto_rc (row, (int) (p - neww)); + while (qq < qmax) { if (*qq & 0xFF00) @@ -1436,27 +1636,42 @@ void SLtt_smart_puts(unsigned short *neww, unsigned short *oldd, int len, int ro } #endif /* Find where the last non-blank character on old/new screen is */ - + + space_char = ' '; + if ((*(pmax-1) & 0xFF) == ' ') + { + /* If we get here, then we can erase to the end of the line to create + * the final space. However, this will only work _if_ erasing will + * get us the correct color. If the terminal supports BCE, then this + * is easy. If it does not, then we can only perform this operation + * if the color is known via something like COLORFGBG. For now, + * I just will not perform the optimization for such terminals. + */ + if ((Can_Background_Color_Erase) + && SLtt_Use_Ansi_Colors) + space_char = *(pmax - 1); + + while (pmax > p) + { + pmax--; + if (!CHAR_EQS(*pmax, space_char)) + { + pmax++; + break; + } + } + } + while (qmax > q) { qmax--; - if (!CHAR_EQS(*qmax, SPACE_CHAR)) + if (!CHAR_EQS(*qmax, space_char)) { qmax++; break; } } - - while (pmax > p) - { - pmax--; - if (!CHAR_EQS(*pmax, SPACE_CHAR)) - { - pmax++; - break; - } - } - + last_buffered_match = buf = buffer; /* buffer is empty */ #ifdef HP_GLITCH_CODE @@ -1469,6 +1684,55 @@ void SLtt_smart_puts(unsigned short *neww, unsigned short *oldd, int len, int ro } #endif +#ifdef HP_GLITCH_CODE + if (Has_HP_Glitch == 0) + { +#endif + /* Try use use erase to bol if possible */ + if ((Del_Bol_Str != NULL) && ((*neww & 0xFF) == 32)) + { + SLsmg_Char_Type *p1; + SLsmg_Char_Type blank; + + p1 = neww; + if ((Can_Background_Color_Erase) + && SLtt_Use_Ansi_Colors) + blank = *p1; + /* black+white attributes do not support bce */ + else + blank = 32; + + while ((p1 < pmax) && (CHAR_EQS (*p1, blank))) + p1++; + + /* Is this optimization worth it? Assume Del_Bol_Str is ESC [ 1 K + * It costs 4 chars + the space needed to properly position the + * cursor, e.g., ESC [ 10;10H. So, it costs at least 13 characters. + */ + if ((p1 > neww + 13) + && (p1 >= p) + /* Avoid erasing from the end of the line */ + && ((p1 != pmax) || (pmax < neww + len))) + { + int ofs = (int) (p1 - neww); + q = oldd + ofs; + p = p1; + SLtt_goto_rc (row, ofs - 1); + SLtt_reverse_video (blank >> 8); + tt_write_string (Del_Bol_Str); + tt_write (" ", 1); + Cursor_c += 1; + } + else + SLtt_goto_rc (row, (int) (p - neww)); + } + else + SLtt_goto_rc (row, (int) (p - neww)); +#ifdef HP_GLITCH_CODE + } +#endif + + /* loop using overwrite then skip algorithm until done */ while (1) { @@ -1476,17 +1740,17 @@ void SLtt_smart_puts(unsigned short *neww, unsigned short *oldd, int len, int ro n_spaces = 0; while (p < pmax) { - if (CHAR_EQS(*q,SPACE_CHAR) && CHAR_EQS(*p, SPACE_CHAR)) + if (CHAR_EQS(*q, 32) && CHAR_EQS(*p, 32)) { - /* If *q is not a space, we would have to overwrite it. - * However, if *q is a space, then while *p is also one, + /* If *q is not a space, we would have to overwrite it. + * However, if *q is a space, then while *p is also one, * we only need to skip over the blank field. */ space_match = p; p++; q++; - while ((p < pmax) - && CHAR_EQS(*q,SPACE_CHAR) - && CHAR_EQS(*p, SPACE_CHAR)) + while ((p < pmax) + && CHAR_EQS(*q, 32) + && CHAR_EQS(*p, 32)) { p++; q++; @@ -1497,10 +1761,10 @@ void SLtt_smart_puts(unsigned short *neww, unsigned short *oldd, int len, int ro #if SLANG_HAS_KANJI_SUPPORT if ((*p & 0x80) && ((p + 1) < pmax)) { /* new is kanji */ - if (*q & 0x80) + if (*q & 0x80) { /* old is also kanji */ - if (((0xFF & *q) != (0xFF & *p)) - || ((0xFF & q[1]) != (0xFF & p[1]))) + if (((0xFF & *q) != (0xFF & *p)) + || ((0xFF & q[1]) != (0xFF & p[1]))) { /* both kanji, but not match */ *buf++ = *p++; @@ -1508,20 +1772,21 @@ void SLtt_smart_puts(unsigned short *neww, unsigned short *oldd, int len, int ro q += 2; continue; } - else + else { /* kanji match ? */ - if (!COLOR_EQS(*q, *p) || !COLOR_EQS(*(q+1), *(p+1))) + if (!COLOR_EQS(*q, *p) || !COLOR_EQS(*(q+1), *(p+1))) { - /* code is match ,but color is diff */ + /* code is match, but color is diff */ *buf++ = *p++; *buf++ = *p++; + q += 2; continue; } /* really match ! */ break; } } - else + else { /* old is not kanji */ *buf++ = *p++; *buf++ = *p++; @@ -1529,9 +1794,9 @@ void SLtt_smart_puts(unsigned short *neww, unsigned short *oldd, int len, int ro continue; } } - else + else { /* new is not kanji */ - if (*q & 0x80) + if (*q & 0x80) { /* old is kanji */ *buf++ = *p++; q++; @@ -1545,20 +1810,22 @@ void SLtt_smart_puts(unsigned short *neww, unsigned short *oldd, int len, int ro q++; } *buf = 0; - + if (buf != buffer) send_attr_str (buffer); buf = buffer; - - if (n_spaces && (p < pmax)) + + if (n_spaces + && ((p < pmax) /* erase to eol will achieve this effect*/ + || (space_char != 32)))/* unless space_char is not a simple space */ { forward_cursor (n_spaces, row); } - - /* Now we overwrote what we could and cursor is placed at position - * of a possible match of new and old. If this is the case, skip + + /* Now we overwrote what we could and cursor is placed at position + * of a possible match of new and old. If this is the case, skip * some more. */ -#if !SLANG_HAS_KANJI_SUPPORT +#if !SLANG_HAS_KANJI_SUPPORT while ((p < pmax) && CHAR_EQS(*p, *q)) { *buf++ = *p++; @@ -1566,29 +1833,29 @@ void SLtt_smart_puts(unsigned short *neww, unsigned short *oldd, int len, int ro } #else /* Kanji */ - while (p < pmax) + while (p < pmax) { if ((*p & 0x80) && ((p + 1) < pmax)) { /* new is kanji */ - if (*q & 0x80) + if (*q & 0x80) { /* old is also kanji */ - if (((0xFF & *q) == (0xFF & *p)) + if (((0xFF & *q) == (0xFF & *p)) && ((0xFF & q[1]) == (0xFF & p[1]))) { /* kanji match ? */ - if (!COLOR_EQS(*q, *p) + if (!COLOR_EQS(*q, *p) || !COLOR_EQS(q[1], p[1])) break; - + *buf++ = *p++; q++; - if (p >= pmax) + if (p >= pmax) { - *buf++ = SPACE_CHAR; + *buf++ = 32; p++; break; } - else + else { *buf++ = *p++; q++; @@ -1599,7 +1866,7 @@ void SLtt_smart_puts(unsigned short *neww, unsigned short *oldd, int len, int ro } else break; /* old is not kanji */ } - else + else { /* new is not kanji */ if (*q & 0x80) break; /* old is kanji */ if (!CHAR_EQS(*q, *p)) break; @@ -1610,11 +1877,11 @@ void SLtt_smart_puts(unsigned short *neww, unsigned short *oldd, int len, int ro #endif last_buffered_match = buf; if (p >= pmax) break; - + /* jump to new position is it is greater than 5 otherwise * let it sit in the buffer and output it later. */ - if ((int) (buf - buffer) >= 5) + if ((int) (buf - buffer) >= 5) { forward_cursor ((unsigned int) (buf - buffer), row); last_buffered_match = buf = buffer; @@ -1625,7 +1892,7 @@ void SLtt_smart_puts(unsigned short *neww, unsigned short *oldd, int len, int ro { if (q < qmax) { - if ((buf == last_buffered_match) + if ((buf == last_buffered_match) && ((int) (buf - buffer) >= 5)) { forward_cursor ((unsigned int) (buf - buffer), row); @@ -1637,185 +1904,276 @@ void SLtt_smart_puts(unsigned short *neww, unsigned short *oldd, int len, int ro } } } - if (q < qmax) SLtt_del_eol (); - if (Automatic_Margins && (Cursor_c + 1 >= SLtt_Screen_Cols)) Cursor_Set = 0; -} + if (q < qmax) + { + SLtt_reverse_video (space_char >> 8); + del_eol (); + } + +#if SLTT_USE_INSERT_HACK + else if (insert_hack_char) + { + SLtt_goto_rc (SLtt_Screen_Rows-1, SLtt_Screen_Cols-2); + buffer[0] = insert_hack_char; + buffer[1] = 0; + send_attr_str (buffer); + SLtt_goto_rc (SLtt_Screen_Rows-1, SLtt_Screen_Cols-2); + buffer[0] = insert_hack_prev; + SLtt_begin_insert (); + send_attr_str (buffer); + SLtt_end_insert (); + } +#endif + + if (Automatic_Margins && (Cursor_c + 1 >= SLtt_Screen_Cols)) Cursor_Set = 0; +} static void get_color_info (void) { char *fg, *bg; - - SLtt_Use_Ansi_Colors = (NULL != getenv ("COLORTERM")); - + + /* Allow easy mechanism to override inadequate termcap/terminfo files. */ + if (SLtt_Use_Ansi_Colors == 0) + SLtt_Use_Ansi_Colors = (NULL != getenv ("COLORTERM")); + + if (SLtt_Use_Ansi_Colors) + Is_Color_Terminal = 1; + +#if SLTT_HAS_NON_BCE_SUPPORT + if (Can_Background_Color_Erase == 0) + Can_Background_Color_Erase = (NULL != getenv ("COLORTERM_BCE")); +#endif + if (-1 == get_default_colors (&fg, &bg)) return; - + /* Check to see if application has already set them. */ if (Color_0_Modified) return; - + SLtt_set_color (0, NULL, fg, bg); SLtt_set_color (1, NULL, bg, fg); } - /* termcap stuff */ #ifdef __unix__ -#ifndef USE_TERMCAP -static char *Tbuf; -static char *Tstr_Buf; - -#define tgetstr SLtt_tigetstr -#define tgetent SLtt_tigetent -#define TGETNUM(x) SLtt_tigetnum((x), &Tbuf) -#define TGETFLAG(x) SLtt_tigetflag((x), &Tbuf) -#else +static int Termcap_Initalized = 0; +#ifdef USE_TERMCAP +/* Termcap based system */ +static char Termcap_Buf[4096]; +static char Termcap_String_Buf[4096]; +static char *Termcap_String_Ptr; extern char *tgetstr(char *, char **); extern int tgetent(char *, char *); extern int tgetnum(char *); extern int tgetflag(char *); -static char Tstr_Buf[1024]; -static char Tbuf[4096]; -#define TGETNUM tgetnum -#define TGETFLAG tgetflag +#else +/* Terminfo */ +static SLterminfo_Type *Terminfo; #endif -static char *my_tgetstr(char *what, char **p) +#define TGETFLAG(x) (SLtt_tgetflag(x) > 0) + +static char *fixup_tgetstr (char *what) { register char *w, *w1; char *wsave; - what = tgetstr(what, p); - if (what != NULL) + + if (what == NULL) + return NULL; + + /* Check for AIX brain-damage */ + if (*what == '@') + return NULL; + + /* lose pad info --- with today's technology, term is a loser if + it is really needed */ + while ((*what == '.') || + ((*what >= '0') && (*what <= '9'))) what++; + if (*what == '*') what++; + + /* lose terminfo padding--- looks like $<...> */ + w = what; + while (*w) if ((*w++ == '$') && (*w == '<')) { - /* Check for AIX brain-damage */ - if (*what == '@') - return NULL; - - /* lose pad info --- with today's technology, term is a loser if - it is really needed */ - while ((*what == '.') || - ((*what >= '0') && (*what <= '9'))) what++; - if (*what == '*') what++; - - /* lose terminfo padding--- looks like $<...> */ - w = what; - while (*w) if ((*w++ == '$') && (*w == '<')) - { - w1 = w - 1; - while (*w && (*w != '>')) w++; - if (*w == 0) break; - w++; - wsave = w1; - while ((*w1++ = *w++) != 0); - w = wsave; - } - if (*what == 0) what = NULL; + w1 = w - 1; + while (*w && (*w != '>')) w++; + if (*w == 0) break; + w++; + wsave = w1; + while ((*w1++ = *w++) != 0); + w = wsave; } - return(what); + + if (*what == 0) what = NULL; + return what; } -char *SLtt_tgetstr (char *s) +char *SLtt_tgetstr (char *cap) { + char *s; + + if (Termcap_Initalized == 0) + return NULL; + #ifdef USE_TERMCAP - static + s = tgetstr (cap, &Termcap_String_Ptr); +#else + s = _SLtt_tigetstr (Terminfo, cap); #endif - char *p = Tstr_Buf; - return my_tgetstr (s, &p); + + /* Do not strip pad info for alternate character set. I need to make + * this more general. + */ + /* FIXME: Priority=low; */ + if (0 == strcmp (cap, "ac")) + return s; + + return fixup_tgetstr (s); } int SLtt_tgetnum (char *s) { - return TGETNUM (s); -} -int SLtt_tgetflag (char *s) -{ - return TGETFLAG (s); + if (Termcap_Initalized == 0) + return -1; +#ifdef USE_TERMCAP + return tgetnum (s); +#else + return _SLtt_tigetnum (Terminfo, s); +#endif } +int SLtt_tgetflag (char *s) +{ + if (Termcap_Initalized == 0) + return -1; +#ifdef USE_TERMCAP + return tgetflag (s); +#else + return _SLtt_tigetflag (Terminfo, s); +#endif +} static int Vt100_Like = 0; void SLtt_get_terminfo (void) { - char *term, *t, ch; + char *term; + int status; + + term = getenv ("TERM"); + if (term == NULL) + SLang_exit_error("TERM environment variable needs set."); + + if (0 == (status = SLtt_initialize (term))) + return; + + if (status == -1) + { + SLang_exit_error ("Unknown terminal: %s\n\ +Check the TERM environment variable.\n\ +Also make sure that the terminal is defined in the terminfo database.\n\ +Alternatively, set the TERMCAP environment variable to the desired\n\ +termcap entry.", + term); + } + + if (status == -2) + { + SLang_exit_error ("\ +Your terminal lacks the ability to clear the screen or position the cursor.\n"); + } +} + +/* Returns 0 if all goes well, -1 if terminal capabilities cannot be deduced, + * or -2 if terminal cannot position the cursor. + */ +int SLtt_initialize (char *term) +{ + char *t, ch; int is_xterm; int almost_vtxxx; - - get_color_info (); - - if (NULL == (term = (char *) getenv("TERM"))) + + if (SLang_TT_Write_FD == -1) { - SLang_exit_error("TERM environment variable needs set."); + /* Apparantly, this cannot fail according to the man pages. */ + SLang_TT_Write_FD = fileno (stdout); } - Linux_Console = (!strncmp (term, "linux", 5) -#ifdef linux - || !strncmp(term, "con", 3) -#endif - ); - - t = term; - - if (strcmp(t, "vt52") && (*t++ == 'v') && (*t++ == 't') - && (ch = *t, (ch >= '1') && (ch <= '9'))) Vt100_Like = 1; + if (term == NULL) + { + term = getenv ("TERM"); + if (term == NULL) + return -1; + } + + Linux_Console = (!strncmp (term, "linux", 5) +# ifdef linux + || !strncmp(term, "con", 3) +# endif + ); + + t = term; + + if (strcmp(t, "vt52") && (*t++ == 'v') && (*t++ == 't') + && (ch = *t, (ch >= '1') && (ch <= '9'))) Vt100_Like = 1; + + is_xterm = ((0 == strncmp (term, "xterm", 5)) + || (0 == strncmp (term, "rxvt", 4)) + || (0 == strncmp (term, "Eterm", 5))); - is_xterm = !strncmp (term, "xterm", 5); almost_vtxxx = (Vt100_Like || Linux_Console || is_xterm || !strcmp (term, "screen")); - -#ifndef USE_TERMCAP - if (NULL == (Tbuf = tgetent (term))) + +# ifndef USE_TERMCAP + if (NULL == (Terminfo = _SLtt_tigetent (term))) { - char err_buf[512]; if (almost_vtxxx) /* Special cases. */ { int vt102 = 1; if (!strcmp (term, "vt100")) vt102 = 0; + get_color_info (); SLtt_set_term_vtxxx (&vt102); - return; + (void) SLtt_get_screen_size (); + return 0; } - g_snprintf (err_buf, sizeof (err_buf), "Unknown terminal: %s\n\ -Check the TERM environment variable.\n\ -Also make sure that the terminal is defined in the terminfo database.\n\ -Alternatively, set the TERMCAP environment variable to the desired\n\ -termcap entry.", term); - SLang_exit_error(err_buf); + return -1; } - Tstr_Buf = Tbuf; -#else /* USE_TERMCAP */ - if (1 != tgetent(Tbuf, term)) SLang_exit_error("Unknown terminal."); -#endif /* NOT USE_TERMCAP */ - - if ((NULL == (Cls_Str = SLtt_tgetstr("cl"))) - || (NULL == (Curs_Pos_Str = SLtt_tgetstr("cm")))) - { - SLang_exit_error("Terminal not powerful enough for SLang."); - } - +# else /* USE_TERMCAP */ + if (1 != tgetent(Termcap_Buf, term)) + return -1; + Termcap_String_Ptr = Termcap_String_Buf; +# endif /* NOT USE_TERMCAP */ + + Termcap_Initalized = 1; + + Cls_Str = SLtt_tgetstr ("cl"); + Curs_Pos_Str = SLtt_tgetstr ("cm"); + if ((NULL == (Ins_Mode_Str = SLtt_tgetstr("im"))) || ( NULL == (Eins_Mode_Str = SLtt_tgetstr("ei"))) || ( NULL == (Del_Char_Str = SLtt_tgetstr("dc")))) SLtt_Term_Cannot_Insert = 1; - + Visible_Bell_Str = SLtt_tgetstr ("vb"); Curs_Up_Str = SLtt_tgetstr ("up"); Rev_Scroll_Str = SLtt_tgetstr("sr"); Del_N_Lines_Str = SLtt_tgetstr("DL"); Add_N_Lines_Str = SLtt_tgetstr("AL"); - - /* Actually these are used to initialize terminals that use cursor + + /* Actually these are used to initialize terminals that use cursor * addressing. Hard to believe. */ Term_Init_Str = SLtt_tgetstr ("ti"); Term_Reset_Str = SLtt_tgetstr ("te"); - /* If I do this for vtxxx terminals, arrow keys start sending ESC O A, + /* If I do this for vtxxx terminals, arrow keys start sending ESC O A, * which I do not want. This is mainly for HP terminals. */ if ((almost_vtxxx == 0) || SLtt_Force_Keypad_Init) @@ -1833,12 +2191,12 @@ termcap entry.", term); if (Del_N_Lines_Str == NULL) Del_N_Lines_Str = "\033[%dM"; if (Add_N_Lines_Str == NULL) Add_N_Lines_Str = "\033[%dL"; } - + Scroll_R_Str = SLtt_tgetstr("cs"); - + SLtt_get_screen_size (); - if ((Scroll_R_Str == NULL) + if ((Scroll_R_Str == NULL) || (((NULL == Del_N_Lines_Str) || (NULL == Add_N_Lines_Str)) && (NULL == Rev_Scroll_Str))) { @@ -1851,12 +2209,17 @@ termcap entry.", term); } else SLtt_Term_Cannot_Scroll = 1; } - + Del_Eol_Str = SLtt_tgetstr("ce"); + Del_Bol_Str = SLtt_tgetstr("cb"); + if (is_xterm && (Del_Bol_Str == NULL)) + Del_Bol_Str = "\033[1K"; + if (is_xterm && (Del_Eol_Str == NULL)) + Del_Bol_Str = "\033[K"; Rev_Vid_Str = SLtt_tgetstr("mr"); if (Rev_Vid_Str == NULL) Rev_Vid_Str = SLtt_tgetstr("so"); - + Bold_Vid_Str = SLtt_tgetstr("md"); /* Although xterm cannot blink, it does display the blinking characters @@ -1865,39 +2228,14 @@ termcap entry.", term); if ((NULL == (Blink_Vid_Str = SLtt_tgetstr("mb"))) && is_xterm) Blink_Vid_Str = "\033[5m"; - + UnderLine_Vid_Str = SLtt_tgetstr("us"); - + Start_Alt_Chars_Str = SLtt_tgetstr ("as"); /* smacs */ End_Alt_Chars_Str = SLtt_tgetstr ("ae"); /* rmacs */ Enable_Alt_Char_Set = SLtt_tgetstr ("eA"); /* enacs */ SLtt_Graphics_Char_Pairs = SLtt_tgetstr ("ac"); -#ifndef NCURSES_BRAIN_DAMAGE_CONTROL -# define NCURSES_BRAIN_DAMAGE_CONTROL 0 -#endif - -#if NCURSES_BRAIN_DAMAGE_CONTROL - if (Linux_Console) - { -# if 0 - char *lgcp = "l\332m\300k\277j\331u\264t\303v\301w\302q\304x\263n\053o\176s\137`\004a\260f\370g\361~\011,\020+\021.\031-\030h\261i\0250\333"; - - SLtt_Graphics_Char_Pairs = lgcp; - Start_Alt_Chars_Str = "\033(B\033)U\016"; - End_Alt_Chars_Str = "\033(B\033)0\017"; - Enable_Alt_Char_Set = NULL; -# else - char *lgcp = "`\004a\261f\370g\361h\260j\331k\277l\332m\300n\305o\302q\304r\362s_t\303u\264v\301w\302x\263y\371z\372{\373|\374}\375~"; - - SLtt_Graphics_Char_Pairs = lgcp; - Start_Alt_Chars_Str = "\033[11m"; - End_Alt_Chars_Str = "\033[10m"; - Enable_Alt_Char_Set = NULL; -# endif - } -#endif - if (NULL == SLtt_Graphics_Char_Pairs) { /* make up for defective termcap/terminfo */ @@ -1908,7 +2246,7 @@ termcap entry.", term); Enable_Alt_Char_Set = "\033)0"; } } - + /* aixterm added by willi */ if (is_xterm || !strncmp (term, "aixterm", 7)) { @@ -1916,15 +2254,18 @@ termcap entry.", term); End_Alt_Chars_Str = "\017"; Enable_Alt_Char_Set = "\033(B\033)0"; } - - if ((SLtt_Graphics_Char_Pairs == NULL) && + + if ((SLtt_Graphics_Char_Pairs == NULL) && ((Start_Alt_Chars_Str == NULL) || (End_Alt_Chars_Str == NULL))) { SLtt_Has_Alt_Charset = 0; Enable_Alt_Char_Set = NULL; } else SLtt_Has_Alt_Charset = 1; - + +#ifdef AMIGA + Enable_Alt_Char_Set = Start_Alt_Chars_Str = End_Alt_Chars_Str = NULL; +#endif /* status line capabilities */ if ((SLtt_Has_Status_Line == -1) @@ -1933,85 +2274,92 @@ termcap entry.", term); Disable_Status_line_Str = SLtt_tgetstr ("ds"); Return_From_Status_Line_Str = SLtt_tgetstr ("fs"); Goto_Status_Line_Str = SLtt_tgetstr ("ts"); - Status_Line_Esc_Ok = TGETFLAG("es"); - Num_Status_Line_Columns = TGETNUM("ws"); + /* Status_Line_Esc_Ok = TGETFLAG("es"); */ + Num_Status_Line_Columns = SLtt_tgetnum ("ws"); if (Num_Status_Line_Columns < 0) Num_Status_Line_Columns = 0; } - - if (NULL == (Norm_Vid_Str = SLtt_tgetstr("me"))) + + if (NULL == (Norm_Vid_Str = SLtt_tgetstr("me"))) { Norm_Vid_Str = SLtt_tgetstr("se"); } - + Cursor_Invisible_Str = SLtt_tgetstr("vi"); Cursor_Visible_Str = SLtt_tgetstr("ve"); - + Curs_F_Str = SLtt_tgetstr("RI"); - -#if 0 + +# if 0 if (NULL != Curs_F_Str) { - Len_Curs_F_Str = strlen(Curs_F_Str); + Len_Curs_F_Str = strlen(Curs_F_Str); } else Len_Curs_F_Str = strlen(Curs_Pos_Str); -#endif - +# endif + Automatic_Margins = TGETFLAG ("am"); /* No_Move_In_Standout = !TGETFLAG ("ms"); */ -#ifdef HP_GLITCH_CODE +# ifdef HP_GLITCH_CODE Has_HP_Glitch = TGETFLAG ("xs"); -#else +# else Worthless_Highlight = TGETFLAG ("xs"); -#endif +# endif if (Worthless_Highlight == 0) { /* Magic cookie glitch */ - Worthless_Highlight = (TGETNUM ("sg") > 0); + Worthless_Highlight = (SLtt_tgetnum ("sg") > 0); } if (Worthless_Highlight) SLtt_Has_Alt_Charset = 0; - - /* Check for color information in the termcap. A program should not - * rely on this information being accurate. - */ - if (SLtt_Use_Ansi_Colors == 0) - { - Reset_Color_String = SLtt_tgetstr ("op"); - - SLtt_Use_Ansi_Colors = ((NULL != Reset_Color_String) - || (NULL != SLtt_tgetstr ("Sf")) - || (NULL != SLtt_tgetstr ("Sb")) - || (NULL != SLtt_tgetstr ("AF")) - || (NULL != SLtt_tgetstr ("AB")) - || (-1 != SLtt_tgetnum ("Co")) - || (-1 != SLtt_tgetnum ("pa"))); - - } - -#if defined(__QNX__) && defined(QNX_QANSI_SLANG_COMPAT_ACS) - /* - * Override the alt-char-set handling string in case of a - * QNX/qansi terminal: use the "old style" strings in order - * to be compatible with S-Lang without the SLTT_TRANSP_ACS_PATCH - * code... - */ - if (SLtt_Has_Alt_Charset && - strncmp(term, "qansi", 5) == 0 && - Start_Alt_Chars_Str[0] != '\016') - { - Start_Alt_Chars_Str = "\016"; /* smacs/as (^N) */ - End_Alt_Chars_Str = "\017"; /* rmacs/ae (^O) */ - SLtt_Graphics_Char_Pairs = /* acsc/ac */ - "``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~O\141"; - - /* - * it would be required to modify the sgr/sa entry also, if it - * would be used (->embedded as/ae sequences)... - */ - } -#endif /* __QNX__ && QNX_QANSI_SLANG_COMPAT_ACS */ + Reset_Color_String = SLtt_tgetstr ("op"); + Color_Fg_Str = SLtt_tgetstr ("AF"); /* ANSI setaf */ + Color_Bg_Str = SLtt_tgetstr ("AB"); /* ANSI setbf */ + if ((Color_Fg_Str == NULL) || (Color_Bg_Str == NULL)) + { + Color_Fg_Str = SLtt_tgetstr ("Sf"); /* setf */ + Color_Bg_Str = SLtt_tgetstr ("Sb"); /* setb */ + } + + if ((Max_Terminfo_Colors = SLtt_tgetnum ("Co")) < 0) + Max_Terminfo_Colors = 8; + + if ((Color_Bg_Str != NULL) && (Color_Fg_Str != NULL)) + SLtt_Use_Ansi_Colors = 1; + else + { +#if 0 + Color_Fg_Str = "%?%p1%{7}%>%t\033[1;3%p1%{8}%m%dm%e\033[3%p1%dm%;"; + Color_Bg_Str = "%?%p1%{7}%>%t\033[5;4%p1%{8}%m%dm%e\033[4%p1%dm%;"; + Max_Terminfo_Colors = 16; +#else + Color_Fg_Str = "\033[3%dm"; + Color_Bg_Str = "\033[4%dm"; + Max_Terminfo_Colors = 8; +#endif + } + +#if SLTT_HAS_NON_BCE_SUPPORT + Can_Background_Color_Erase = TGETFLAG ("ut"); /* bce */ + /* Modern xterms have the BCE capability as well as the linux console */ + if (Can_Background_Color_Erase == 0) + { + Can_Background_Color_Erase = (Linux_Console +# if SLTT_XTERM_ALWAYS_BCE + || is_xterm +# endif + ); + } +#endif + get_color_info (); + + + if ((Cls_Str == NULL) + || (Curs_Pos_Str == NULL)) + return -2; + + return 0; } #endif @@ -2023,14 +2371,24 @@ void SLtt_enable_cursor_keys (void) #ifdef __unix__ if (Vt100_Like) #endif - SLtt_write_string("\033=\033[?1l"); + tt_write_string("\033=\033[?1l"); } #ifdef VMS +int SLtt_initialize (char *term) +{ + SLtt_get_terminfo (); + return 0; +} + void SLtt_get_terminfo () { int zero = 0; - + + Color_Fg_Str = "\033[3%dm"; + Color_Bg_Str = "\033[4%dm"; + Max_Terminfo_Colors = 8; + get_color_info (); SLtt_set_term_vtxxx(&zero); @@ -2038,26 +2396,27 @@ void SLtt_get_terminfo () End_Alt_Chars_Str = "\017"; SLtt_Has_Alt_Charset = 1; SLtt_Graphics_Char_Pairs = "aaffgghhjjkkllmmnnooqqssttuuvvwwxx"; - Enable_Alt_Char_Set = "\033(B\033)0"; + Enable_Alt_Char_Set = "\033(B\033)0"; SLtt_get_screen_size (); } #endif /* This sets term for vt102 terminals it parameter vt100 is 0. If vt100 - * is non-zero, set terminal appropriate for a only vt100 + * is non-zero, set terminal appropriate for a only vt100 * (no add line capability). */ - + void SLtt_set_term_vtxxx(int *vt100) { Norm_Vid_Str = "\033[m"; - - Scroll_R_Str = "\033[%i%d;%dr"; + + Scroll_R_Str = "\033[%i%d;%dr"; Cls_Str = "\033[2J\033[H"; Rev_Vid_Str = "\033[7m"; Bold_Vid_Str = "\033[1m"; Blink_Vid_Str = "\033[5m"; UnderLine_Vid_Str = "\033[4m"; Del_Eol_Str = "\033[K"; + Del_Bol_Str = "\033[1K"; Rev_Scroll_Str = "\033M"; Curs_F_Str = "\033[%dC"; /* Len_Curs_F_Str = 5; */ @@ -2081,56 +2440,57 @@ void SLtt_set_term_vtxxx(int *vt100) /* No_Move_In_Standout = 0; */ } -void SLtt_init_video (void) +int SLtt_init_video (void) { /* send_string_to_term("\033[?6h"); */ /* relative origin mode */ - SLtt_write_string (Term_Init_Str); - SLtt_write_string (Keypad_Init_Str); + tt_write_string (Term_Init_Str); + tt_write_string (Keypad_Init_Str); SLtt_reset_scroll_region(); SLtt_end_insert(); - SLtt_write_string (Enable_Alt_Char_Set); + tt_write_string (Enable_Alt_Char_Set); Video_Initialized = 1; + return 0; } - -void SLtt_reset_video (void) +int SLtt_reset_video (void) { SLtt_goto_rc (SLtt_Screen_Rows - 1, 0); Cursor_Set = 0; SLtt_normal_video (); /* MSKermit requires this */ - SLtt_write_string(Norm_Vid_Str); + tt_write_string(Norm_Vid_Str); Current_Fgbg = 0xFFFFFFFFU; SLtt_set_alt_char_set (0); - if (SLtt_Use_Ansi_Colors) + if (SLtt_Use_Ansi_Colors) { if (Reset_Color_String == NULL) { SLtt_Char_Type attr; if (-1 != make_color_fgbg (NULL, NULL, &attr)) write_attributes (attr); - else SLtt_write_string ("\033[0m\033[m"); + else tt_write_string ("\033[0m\033[m"); } - else SLtt_write_string (Reset_Color_String); + else tt_write_string (Reset_Color_String); Current_Fgbg = 0xFFFFFFFFU; } SLtt_erase_line (); - SLtt_write_string (Keypad_Reset_Str); - SLtt_write_string (Term_Reset_Str); + tt_write_string (Keypad_Reset_Str); + tt_write_string (Term_Reset_Str); SLtt_flush_output (); Video_Initialized = 0; + return 0; } void SLtt_bold_video (void) { - SLtt_write_string (Bold_Vid_Str); + tt_write_string (Bold_Vid_Str); } int SLtt_set_mouse_mode (int mode, int force) { char *term; - + if (force == 0) { if (NULL == (term = (char *) getenv("TERM"))) return -1; @@ -2139,18 +2499,20 @@ int SLtt_set_mouse_mode (int mode, int force) } if (mode) - SLtt_write_string ("\033[?9h"); + tt_write_string ("\033[?9h"); else - SLtt_write_string ("\033[?9l"); - + tt_write_string ("\033[?9l"); + return 0; } - void SLtt_disable_status_line (void) { if (SLtt_Has_Status_Line > 0) - SLtt_write_string (Disable_Status_line_Str); + { + tt_write_string (Disable_Status_line_Str); + SLtt_flush_output (); + } } int SLtt_write_to_status_line (char *s, int col) @@ -2159,29 +2521,25 @@ int SLtt_write_to_status_line (char *s, int col) || (Goto_Status_Line_Str == NULL) || (Return_From_Status_Line_Str == NULL)) return -1; - + tt_printf (Goto_Status_Line_Str, col, 0); - SLtt_write_string (s); - SLtt_write_string (Return_From_Status_Line_Str); + tt_write_string (s); + tt_write_string (Return_From_Status_Line_Str); return 0; } - void SLtt_get_screen_size (void) -{ +{ #ifdef VMS int status, code; unsigned short chan; $DESCRIPTOR(dev_dsc, "SYS$INPUT:"); -#endif -#ifdef __os2__ - VIOMODEINFO vioModeInfo; #endif int r = 0, c = 0; - -#if defined(TIOCGWINSZ) && !defined(SCO_FLAVOR) + +#ifdef TIOCGWINSZ struct winsize wind_struct; - + do { if ((ioctl(1,TIOCGWINSZ,&wind_struct) == 0) @@ -2194,7 +2552,7 @@ void SLtt_get_screen_size (void) } } while (errno == EINTR); - + #endif #ifdef VMS @@ -2213,27 +2571,43 @@ void SLtt_get_screen_size (void) } #endif -#ifdef __os2__ - vioModeInfo.cb = sizeof(vioModeInfo); - VioGetMode (&vioModeInfo, 0); - c = vioModeInfo.col; - r = vioModeInfo.row; -#endif - if (r <= 0) { char *s = getenv ("LINES"); if (s != NULL) r = atoi (s); } - + if (c <= 0) { char *s = getenv ("COLUMNS"); if (s != NULL) c = atoi (s); } - + + if (r <= 0) r = 24; + if (c <= 0) c = 80; +#if 0 if ((r <= 0) || (r > 200)) r = 24; if ((c <= 0) || (c > 250)) c = 80; +#endif SLtt_Screen_Rows = r; SLtt_Screen_Cols = c; } + +#if SLTT_HAS_NON_BCE_SUPPORT +int _SLtt_get_bce_color_offset (void) +{ + if ((SLtt_Use_Ansi_Colors == 0) + || Can_Background_Color_Erase + || SLtt_Use_Blink_For_ACS) /* in this case, we cannot lose a color */ + Bce_Color_Offset = 0; + else + { + if (GET_BG(Ansi_Color_Map[0].fgbg) == SLSMG_COLOR_DEFAULT) + Bce_Color_Offset = 0; + else + Bce_Color_Offset = 1; + } + + return Bce_Color_Offset; +} +#endif diff --git a/slang/slerr.c b/slang/slerr.c index e2e22b46b..43486f429 100644 --- a/slang/slerr.c +++ b/slang/slerr.c @@ -1,48 +1,181 @@ /* error handling common to all routines. */ -/* Copyright (c) 1992, 1995 John E. Davis - * All rights reserved. - * +/* Copyright (c) 1992, 1999, 2001, 2002 John E. Davis + * This file is part of the S-Lang library. + * * You may distribute under the terms of either the GNU General Public * License or the Perl Artistic License. */ +#include "slinclud.h" -#include "config.h" - -#include -#include -#include - -#ifdef HAVE_STDLIB_H -# include -#endif - +#include "slang.h" #include "_slang.h" -void (*SLang_Error_Routine)(char *); -void (*SLang_Exit_Error_Hook)(char *); +void (*SLang_VMessage_Hook) (char *, va_list); +void (*SLang_Error_Hook)(char *); +void (*SLang_Exit_Error_Hook)(char *, va_list); volatile int SLang_Error = 0; char *SLang_Error_Message; volatile int SLKeyBoard_Quit = 0; +static char *get_error_string (void) +{ + char *str; + + if (!SLang_Error) SLang_Error = SL_UNKNOWN_ERROR; + if (SLang_Error_Message != NULL) str = SLang_Error_Message; + else switch(SLang_Error) + { + case SL_NOT_IMPLEMENTED: str = "Not Implemented"; break; + case SL_APPLICATION_ERROR: str = "Application Error"; break; + case SL_VARIABLE_UNINITIALIZED: str = "Variable Uninitialized"; break; + case SL_MALLOC_ERROR : str = "Malloc Error"; break; + case SL_INTERNAL_ERROR: str = "Internal Error"; break; + case SL_STACK_OVERFLOW: str = "Stack Overflow"; break; + case SL_STACK_UNDERFLOW: str = "Stack Underflow"; break; + case SL_INTRINSIC_ERROR: str = "Intrinsic Error"; break; + case SL_USER_BREAK: str = "User Break"; break; + case SL_UNDEFINED_NAME: str = "Undefined Name"; break; + case SL_SYNTAX_ERROR: str = "Syntax Error"; break; + case SL_DUPLICATE_DEFINITION: str = "Duplicate Definition"; break; + case SL_TYPE_MISMATCH: str = "Type Mismatch"; break; + case SL_READONLY_ERROR: str = "Variable is read-only"; break; + case SL_DIVIDE_ERROR: str = "Divide by zero"; break; + case SL_OBJ_NOPEN: str = "Object not opened"; break; + case SL_OBJ_UNKNOWN: str = "Object unknown"; break; + case SL_INVALID_PARM: str = "Invalid Parameter"; break; + case SL_TYPE_UNDEFINED_OP_ERROR: + str = "Operation not defined for datatype"; break; + case SL_USER_ERROR: + str = "User Error"; break; + case SL_USAGE_ERROR: + str = "Illegal usage of function"; + break; + case SL_FLOATING_EXCEPTION: + str = "Floating Point Exception"; + break; + case SL_UNKNOWN_ERROR: + default: str = "Unknown Error Code"; + } + + SLang_Error_Message = NULL; + return str; +} + void SLang_doerror (char *error) { - if (SLang_Error_Routine == NULL) + char *str = NULL; + char *err; + char *malloced_err_buf; + char err_buf [1024]; + + malloced_err_buf = NULL; + + if (((SLang_Error == SL_USER_ERROR) + || (SLang_Error == SL_USAGE_ERROR)) + && (error != NULL) && (*error != 0)) + err = error; + else { - fprintf (stderr, "S-Lang Error: %s\r\n", error); + char *sle = "S-Lang Error: "; + unsigned int len; + char *fmt; + + str = get_error_string (); + + fmt = "%s%s%s"; + if ((error == NULL) || (*error == 0)) + error = ""; + else if (SLang_Error == SL_UNKNOWN_ERROR) + /* Do not display an unknown error message if error is non-NULL */ + str = ""; + else + fmt = "%s%s: %s"; + + len = strlen (sle) + strlen (str) + strlen(error) + 1; + + err = err_buf; + if (len >= sizeof (err_buf)) + { + if (NULL == (malloced_err_buf = SLmalloc (len))) + err = NULL; + else + err = malloced_err_buf; + } + + if (err != NULL) sprintf (err, fmt, sle, str, error); + else err = "Out of memory"; + } + + if (SLang_Error_Hook == NULL) + { + fputs (err, stderr); + fputs("\r\n", stderr); + fflush (stderr); } else - (*SLang_Error_Routine)(error); + (*SLang_Error_Hook)(err); + + SLfree (malloced_err_buf); } - - -void SLang_exit_error (char *s) +void SLang_verror (int err_code, char *fmt, ...) { + va_list ap; + char err [1024]; + + if (err_code == 0) err_code = SL_INTRINSIC_ERROR; + if (SLang_Error == 0) SLang_Error = err_code; + + if (fmt != NULL) + { + va_start(ap, fmt); + (void) _SLvsnprintf (err, sizeof (err), fmt, ap); + fmt = err; + va_end(ap); + } + + SLang_doerror (fmt); +} + +void SLang_exit_error (char *fmt, ...) +{ + va_list ap; + + va_start (ap, fmt); if (SLang_Exit_Error_Hook != NULL) { - (*SLang_Exit_Error_Hook) (s); + (*SLang_Exit_Error_Hook) (fmt, ap); + exit (1); } - if (s != NULL) fprintf (stderr, "%s\n", s); - exit (-1); + + if (fmt != NULL) + { + vfprintf (stderr, fmt, ap); + fputs ("\r\n", stderr); + fflush (stderr); + } + va_end (ap); + + exit (1); +} + +void SLang_vmessage (char *fmt, ...) +{ + va_list ap; + + if (fmt == NULL) + return; + + va_start (ap, fmt); + + if (SLang_VMessage_Hook != NULL) + (*SLang_VMessage_Hook) (fmt, ap); + else + { + vfprintf (stdout, fmt, ap); + fputs ("\r\n", stdout); + } + + va_end (ap); } diff --git a/slang/slgetkey.c b/slang/slgetkey.c index 569e33f39..4795f0e14 100644 --- a/slang/slgetkey.c +++ b/slang/slgetkey.c @@ -1,68 +1,64 @@ -/* Copyright (c) 1992, 1995 John E. Davis - * All rights reserved. - * +/* Copyright (c) 1992, 1999, 2001, 2002 John E. Davis + * This file is part of the S-Lang library. + * * You may distribute under the terms of either the GNU General Public * License or the Perl Artistic License. */ -#include "config.h" +#include "slinclud.h" -#include +#include "slang.h" #include "_slang.h" unsigned int SLang_Input_Buffer_Len = 0; -unsigned char SLang_Input_Buffer [MAX_INPUT_BUFFER_LEN]; +unsigned char SLang_Input_Buffer [SL_MAX_INPUT_BUFFER_LEN]; int SLang_Abort_Char = 7; int SLang_Ignore_User_Abort = 0; /* This has the effect of mapping all characters in the range 128-169 to - * ESC [ something + * ESC [ something */ -#ifndef __GO32__ -# if defined(__unix__) || defined(vms) -# define DEC_8BIT_HACK 64 -# endif -#endif -#ifdef NATIVE_WIN32 /* see the replacement in src/slint.c */ unsigned int SLang_getkey (void) { unsigned int imax; unsigned int ch; - + if (SLang_Input_Buffer_Len) { ch = (unsigned int) *SLang_Input_Buffer; SLang_Input_Buffer_Len--; imax = SLang_Input_Buffer_Len; - - SLMEMCPY ((char *) SLang_Input_Buffer, + + SLMEMCPY ((char *) SLang_Input_Buffer, (char *) (SLang_Input_Buffer + 1), imax); } - else if (0xFFFF == (ch = SLsys_getkey ())) return ch; - -#ifdef DEC_8BIT_HACK + else if (SLANG_GETKEY_ERROR == (ch = _SLsys_getkey ())) return ch; + +#if _SLANG_MAP_VTXXX_8BIT +# if !defined(IBMPC_SYSTEM) if (ch & 0x80) { unsigned char i; i = (unsigned char) (ch & 0x7F); if (i < ' ') { - i += DEC_8BIT_HACK; + i += 64; SLang_ungetkey (i); ch = 27; } } +# endif #endif return(ch); } -#endif /* NATIVE_WIN32 */ -void SLang_ungetkey_string (unsigned char *s, unsigned int n) +int SLang_ungetkey_string (unsigned char *s, unsigned int n) { register unsigned char *bmax, *b, *b1; - if (SLang_Input_Buffer_Len + n + 3 > MAX_INPUT_BUFFER_LEN) return; + if (SLang_Input_Buffer_Len + n + 3 > SL_MAX_INPUT_BUFFER_LEN) + return -1; b = SLang_Input_Buffer; bmax = (b - 1) + SLang_Input_Buffer_Len; @@ -71,54 +67,240 @@ void SLang_ungetkey_string (unsigned char *s, unsigned int n) bmax = b + n; while (b < bmax) *b++ = *s++; SLang_Input_Buffer_Len += n; + return 0; } -void SLang_buffer_keystring (unsigned char *s, unsigned int n) +int SLang_buffer_keystring (unsigned char *s, unsigned int n) { - if (n + SLang_Input_Buffer_Len + 3 > MAX_INPUT_BUFFER_LEN) return; - - SLMEMCPY ((char *) SLang_Input_Buffer + SLang_Input_Buffer_Len, + if (n + SLang_Input_Buffer_Len + 3 > SL_MAX_INPUT_BUFFER_LEN) return -1; + + SLMEMCPY ((char *) SLang_Input_Buffer + SLang_Input_Buffer_Len, (char *) s, n); SLang_Input_Buffer_Len += n; + return 0; } -void SLang_ungetkey (unsigned char ch) +int SLang_ungetkey (unsigned char ch) { - SLang_ungetkey_string(&ch, 1); + return SLang_ungetkey_string(&ch, 1); } -#ifdef NATIVE_WIN32 /* see the replacement in src/slint.c */ int SLang_input_pending (int tsecs) { int n; unsigned char c; if (SLang_Input_Buffer_Len) return (int) SLang_Input_Buffer_Len; - - n = SLsys_input_pending (tsecs); - + + n = _SLsys_input_pending (tsecs); + if (n <= 0) return 0; - + c = (unsigned char) SLang_getkey (); SLang_ungetkey_string (&c, 1); - + return n; } -#endif /* NATIVE_WIN32 */ void SLang_flush_input (void) { int quit = SLKeyBoard_Quit; - + SLang_Input_Buffer_Len = 0; - SLKeyBoard_Quit = 0; - while (SLsys_input_pending (0) > 0) + SLKeyBoard_Quit = 0; + while (_SLsys_input_pending (0) > 0) { - (void) SLsys_getkey (); - /* Set this to 0 because SLsys_getkey may stuff keyboard buffer if + (void) _SLsys_getkey (); + /* Set this to 0 because _SLsys_getkey may stuff keyboard buffer if * key sends key sequence (OS/2, DOS, maybe VMS). */ SLang_Input_Buffer_Len = 0; } SLKeyBoard_Quit = quit; } + +#ifdef IBMPC_SYSTEM +static int Map_To_ANSI; +int SLgetkey_map_to_ansi (int enable) +{ + Map_To_ANSI = enable; + return 0; +} + +static int convert_scancode (unsigned int scan, + unsigned int shift, + int getkey, + unsigned int *ret_key) +{ + unsigned char buf[16]; + unsigned char *b; + unsigned char end; + int is_arrow; + + shift &= (_SLTT_KEY_ALT|_SLTT_KEY_SHIFT|_SLTT_KEY_CTRL); + + b = buf; + if (_SLTT_KEY_ALT == shift) + { + shift = 0; + *b++ = 27; + } + *b++ = 27; + *b++ = '['; + + is_arrow = 0; + end = '~'; + if (shift) + { + if (shift == _SLTT_KEY_CTRL) + end = '^'; + else if (shift == _SLTT_KEY_SHIFT) + end = '$'; + else shift = 0; + } + + /* These mappings correspond to what rxvt produces under Linux */ + switch (scan & 0xFF) + { + default: + return -1; + + case 0x47: /* home */ + *b++ = '1'; + break; + case 0x48: /* up */ + end = 'A'; + is_arrow = 1; + break; + case 0x49: /* PgUp */ + *b++ = '5'; + break; + case 0x4B: /* Left */ + end = 'D'; + is_arrow = 1; + break; + case 0x4D: /* Right */ + end = 'C'; + is_arrow = 1; + break; + case 0x4F: /* End */ + *b++ = '4'; + break; + case 0x50: /* Down */ + end = 'B'; + is_arrow = 1; + break; + case 0x51: /* PgDn */ + *b++ = '6'; + break; + case 0x52: /* Insert */ + *b++ = '2'; + break; + case 0x53: /* Delete */ + *b++ = '3'; + break; + case ';': /* F1 */ + *b++ = '1'; + *b++ = '1'; + break; + case '<': /* F2 */ + *b++ = '1'; + *b++ = '2'; + break; + case '=': /* F3 */ + *b++ = '1'; + *b++ = '3'; + break; + + case '>': /* F4 */ + *b++ = '1'; + *b++ = '4'; + break; + + case '?': /* F5 */ + *b++ = '1'; + *b++ = '5'; + break; + + case '@': /* F6 */ + *b++ = '1'; + *b++ = '7'; + break; + + case 'A': /* F7 */ + *b++ = '1'; + *b++ = '8'; + break; + + case 'B': /* F8 */ + *b++ = '1'; + *b++ = '9'; + break; + + case 'C': /* F9 */ + *b++ = '2'; + *b++ = '0'; + break; + + case 'D': /* F10 */ + *b++ = '2'; + *b++ = '1'; + break; + + case 0x57: /* F11 */ + *b++ = '2'; + *b++ = '3'; + break; + + case 0x58: /* F12 */ + *b++ = '2'; + *b++ = '4'; + break; + } + + if (is_arrow && shift) + { + if (shift == _SLTT_KEY_CTRL) + end &= 0x1F; + else + end |= 0x20; + } + *b++ = end; + + if (getkey) + { + (void) SLang_buffer_keystring (buf + 1, (unsigned int) (b - (buf + 1))); + *ret_key = buf[0]; + return 0; + } + + (void) SLang_buffer_keystring (buf, (unsigned int) (b - buf)); + return 0; +} + + +unsigned int _SLpc_convert_scancode (unsigned int scan, + unsigned int shift, + int getkey) +{ + unsigned char buf[16]; + + if (Map_To_ANSI) + { + if (0 == convert_scancode (scan, shift, getkey, &scan)) + return scan; + } + + if (getkey) + { + buf[0] = scan & 0xFF; + SLang_buffer_keystring (buf, 1); + return (scan >> 8) & 0xFF; + } + buf[0] = (scan >> 8) & 0xFF; + buf[1] = scan & 0xFF; + (void) SLang_buffer_keystring (buf, 2); + return 0; +} + +#endif diff --git a/slang/slmemcpy.c b/slang/slmemcpy.c deleted file mode 100644 index 9829c2e30..000000000 --- a/slang/slmemcpy.c +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (c) 1992, 1995 John E. Davis - * All rights reserved. - * - * You may distribute under the terms of either the GNU General Public - * License or the Perl Artistic License. - */ - - -/* These routines are fast memcpy, memset routines. When available, I - use system rouines. For msdos, I use inline assembly. */ - -/* The current versions only work in the forward direction only!! */ - -#include "config.h" - -#include -#include "_slang.h" - -char *SLmemcpy(char *s1, char *s2, int n) -{ -#if defined(msdos) && !defined(__WIN32__) && !defined(__GO32__) - asm mov ax, ds - asm mov bx, si - asm mov dx, di - asm mov cx, n - asm les di, s1 - asm lds si, s2 - asm cld - asm rep movsb - asm mov ds, ax - asm mov si, bx - asm mov di, dx - return(s1); - -#else - register char *smax, *s = s1; - int n2; - - n2 = n % 4; - smax = s + (n - 4); - while (s <= smax) - { - *s = *s2; *(s + 1) = *(s2 + 1); *(s + 2) = *(s2 + 2); *(s + 3) = *(s2 + 3); - s += 4; - s2 += 4; - } - while (n2--) *s++ = *s2++; - return(s1); -#endif -} diff --git a/slang/slmemset.c b/slang/slmemset.c deleted file mode 100644 index ebbe05764..000000000 --- a/slang/slmemset.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (c) 1992, 1995 John E. Davis - * All rights reserved. - * - * You may distribute under the terms of either the GNU General Public - * License or the Perl Artistic License. - */ - - -/* These routines are fast memcpy, memset routines. When available, I - use system rouines. For msdos, I use inline assembly. */ - -/* The current versions only work in the forward direction only!! */ - -#include "config.h" - -#include - - -#include "_slang.h" - -void SLmemset(char *p, char space, int n) -{ -#if defined(msdos) && !defined(__WIN32__) && !defined(__GO32__) - asm mov al, space - asm mov dx, di - asm mov cx, n - asm les di, p - asm cld - asm rep stosb - asm mov di, dx -#else - register char *pmax; - - pmax = p + (n - 4); - n = n % 4; - while (p <= pmax) - { - *p++ = space; *p++ = space; *p++ = space; *p++= space; - } - while (n--) *p++ = space; -#endif -} diff --git a/slang/slmisc.c b/slang/slmisc.c new file mode 100644 index 000000000..64af84cd1 --- /dev/null +++ b/slang/slmisc.c @@ -0,0 +1,78 @@ +/* Copyright (c) 1992, 1999, 2001, 2002 John E. Davis + * This file is part of the S-Lang library. + * + * Trimmed down for use in GNU Midnight Commander. + * + * You may distribute under the terms of either the GNU General Public + * License or the Perl Artistic License. + */ +#include "slinclud.h" + +#include "slang.h" +#include "_slang.h" + +/* p and ch may point to the same buffer */ +char *_SLexpand_escaped_char(char *p, char *ch) +{ + int i = 0; + int max = 0, num, base = 0; + char ch1; + + ch1 = *p++; + + switch (ch1) + { + default: num = ch1; break; + case 'n': num = '\n'; break; + case 't': num = '\t'; break; + case 'v': num = '\v'; break; + case 'b': num = '\b'; break; + case 'r': num = '\r'; break; + case 'f': num = '\f'; break; + case 'E': case 'e': num = 27; break; + case 'a': num = 7; + break; + + /* octal */ + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + max = '7'; + base = 8; i = 2; num = ch1 - '0'; + break; + + case 'd': /* decimal -- S-Lang extension */ + base = 10; + i = 3; + max = '9'; + num = 0; + break; + + case 'x': /* hex */ + base = 16; + max = '9'; + i = 2; + num = 0; + break; + } + + while (i--) + { + ch1 = *p; + + if ((ch1 <= max) && (ch1 >= '0')) + { + num = base * num + (ch1 - '0'); + } + else if (base == 16) + { + ch1 |= 0x20; + if ((ch1 < 'a') || ((ch1 > 'f'))) break; + num = base * num + 10 + (ch1 - 'a'); + } + else break; + p++; + } + + *ch = (char) num; + return p; +} diff --git a/slang/slsignal.c b/slang/slsignal.c index 659a52ccb..f6fa21c84 100644 --- a/slang/slsignal.c +++ b/slang/slsignal.c @@ -1,26 +1,38 @@ -#include "config.h" +/* Copyright (c) 1998, 1999, 2001, 2002 John E. Davis + * This file is part of the S-Lang library. + * + * You may distribute under the terms of either the GNU General Public + * License or the Perl Artistic License. + */ +#include "slinclud.h" -#include #include -#ifdef HAVE_STDLIB_H -# include +#ifdef HAVE_SYS_TYPES_H +# include #endif - -#ifdef HAVE_UNISTD_H -# include +#ifdef HAVE_SYS_WAIT_H +# include #endif #include +#include "slang.h" #include "_slang.h" +/* Do not trust these environments */ +#if defined(__CYGWIN32__) || defined(__MINGW32__) || defined(AMIGA) +# ifdef SLANG_POSIX_SIGNALS +# undef SLANG_POSIX_SIGNALS +# endif +#endif + /* This function will cause system calls to be restarted after signal if possible */ SLSig_Fun_Type *SLsignal (int sig, SLSig_Fun_Type *f) { -#ifdef SLANG_POSIX_SIGNALS +#if defined(SLANG_POSIX_SIGNALS) struct sigaction old_sa, new_sa; - + # ifdef SIGALRM /* We want system calls to be interrupted by SIGALRM. */ if (sig == SIGALRM) return SLsignal_intr (sig, f); @@ -28,15 +40,15 @@ SLSig_Fun_Type *SLsignal (int sig, SLSig_Fun_Type *f) sigemptyset (&new_sa.sa_mask); new_sa.sa_handler = f; - + new_sa.sa_flags = 0; # ifdef SA_RESTART new_sa.sa_flags |= SA_RESTART; # endif - + if (-1 == sigaction (sig, &new_sa, &old_sa)) return (SLSig_Fun_Type *) SIG_ERR; - + return old_sa.sa_handler; #else /* Not POSIX. */ @@ -44,25 +56,25 @@ SLSig_Fun_Type *SLsignal (int sig, SLSig_Fun_Type *f) #endif } -/* This function will NOT cause system calls to be restarted after - * signal if possible +/* This function will NOT cause system calls to be restarted after + * signal if possible */ SLSig_Fun_Type *SLsignal_intr (int sig, SLSig_Fun_Type *f) { #ifdef SLANG_POSIX_SIGNALS struct sigaction old_sa, new_sa; - + sigemptyset (&new_sa.sa_mask); new_sa.sa_handler = f; - + new_sa.sa_flags = 0; # ifdef SA_INTERRUPT new_sa.sa_flags |= SA_INTERRUPT; # endif - + if (-1 == sigaction (sig, &new_sa, &old_sa)) return (SLSig_Fun_Type *) SIG_ERR; - + return old_sa.sa_handler; #else /* Not POSIX. */ @@ -70,8 +82,7 @@ SLSig_Fun_Type *SLsignal_intr (int sig, SLSig_Fun_Type *f) #endif } - -/* We are primarily interested in blocking signals that would cause the +/* We are primarily interested in blocking signals that would cause the * application to reset the tty. These include suspend signals and * possibly interrupt signals. */ @@ -86,13 +97,13 @@ int SLsig_block_signals (void) #ifdef SLANG_POSIX_SIGNALS sigset_t new_mask; #endif - + Blocked_Depth++; if (Blocked_Depth != 1) { return 0; } - + #ifdef SLANG_POSIX_SIGNALS sigemptyset (&new_mask); # ifdef SIGQUIT @@ -110,7 +121,10 @@ int SLsig_block_signals (void) # ifdef SIGTTOU sigaddset (&new_mask, SIGTTOU); # endif - +# ifdef SIGWINCH + sigaddset (&new_mask, SIGWINCH); +# endif + (void) sigprocmask (SIG_BLOCK, &new_mask, &Old_Signal_Mask); return 0; #else @@ -123,12 +137,12 @@ int SLsig_unblock_signals (void) { if (Blocked_Depth == 0) return -1; - + Blocked_Depth--; - + if (Blocked_Depth != 0) return 0; - + #ifdef SLANG_POSIX_SIGNALS (void) sigprocmask (SIG_SETMASK, &Old_Signal_Mask, NULL); return 0; @@ -136,3 +150,187 @@ int SLsig_unblock_signals (void) return -1; #endif } + +#ifdef MSWINDOWS +int SLsystem (char *cmd) +{ + SLang_verror (SL_NOT_IMPLEMENTED, "system not implemented"); + return -1; +} + +#else +int SLsystem (char *cmd) +{ +#ifdef SLANG_POSIX_SIGNALS + pid_t pid; + int status; + struct sigaction ignore; +# ifdef SIGINT + struct sigaction save_intr; +# endif +# ifdef SIGQUIT + struct sigaction save_quit; +# endif +# ifdef SIGCHLD + sigset_t child_mask, save_mask; +# endif + + if (cmd == NULL) return 1; + + ignore.sa_handler = SIG_IGN; + sigemptyset (&ignore.sa_mask); + ignore.sa_flags = 0; + +# ifdef SIGINT + if (-1 == sigaction (SIGINT, &ignore, &save_intr)) + return -1; +# endif + +# ifdef SIGQUIT + if (-1 == sigaction (SIGQUIT, &ignore, &save_quit)) + { + (void) sigaction (SIGINT, &save_intr, NULL); + return -1; + } +# endif + +# ifdef SIGCHLD + sigemptyset (&child_mask); + sigaddset (&child_mask, SIGCHLD); + if (-1 == sigprocmask (SIG_BLOCK, &child_mask, &save_mask)) + { +# ifdef SIGINT + (void) sigaction (SIGINT, &save_intr, NULL); +# endif +# ifdef SIGQUIT + (void) sigaction (SIGQUIT, &save_quit, NULL); +# endif + return -1; + } +# endif + + pid = fork(); + + if (pid == -1) + status = -1; + else if (pid == 0) + { + /* Child */ +# ifdef SIGINT + (void) sigaction (SIGINT, &save_intr, NULL); +# endif +# ifdef SIGQUIT + (void) sigaction (SIGQUIT, &save_quit, NULL); +# endif +# ifdef SIGCHLD + (void) sigprocmask (SIG_SETMASK, &save_mask, NULL); +# endif + + execl ("/bin/sh", "sh", "-c", cmd, NULL); + _exit (127); + } + else + { + /* parent */ + while (-1 == waitpid (pid, &status, 0)) + { +# ifdef EINTR + if (errno == EINTR) + continue; +# endif +# ifdef ERESTARTSYS + if (errno == ERESTARTSYS) + continue; +# endif + status = -1; + break; + } + } +# ifdef SIGINT + if (-1 == sigaction (SIGINT, &save_intr, NULL)) + status = -1; +# endif +# ifdef SIGQUIT + if (-1 == sigaction (SIGQUIT, &save_quit, NULL)) + status = -1; +# endif +# ifdef SIGCHLD + if (-1 == sigprocmask (SIG_SETMASK, &save_mask, NULL)) + status = -1; +# endif + + return status; + +#else /* No POSIX Signals */ +# ifdef SIGINT + void (*sint)(int); +# endif +# ifdef SIGQUIT + void (*squit)(int); +# endif + int status; + +# ifdef SIGQUIT + squit = SLsignal (SIGQUIT, SIG_IGN); +# endif +# ifdef SIGINT + sint = SLsignal (SIGINT, SIG_IGN); +# endif + status = system (cmd); +# ifdef SIGINT + SLsignal (SIGINT, sint); +# endif +# ifdef SIGQUIT + SLsignal (SIGQUIT, squit); +# endif + return status; +#endif /* POSIX_SIGNALS */ +} +#endif + +#if 0 +#include +static int msw_system (char *cmd) +{ + STARTUPINFO startup_info; + PROCESS_INFORMATION process_info; + int status; + + if (cmd == NULL) return -1; + + memset ((char *) &startup_info, 0, sizeof (STARTUPINFO)); + startup_info.cb = sizeof(STARTUPINFO); + startup_info.dwFlags = STARTF_USESHOWWINDOW; + startup_info.wShowWindow = SW_SHOWDEFAULT; + + if (FALSE == CreateProcess (NULL, + cmd, + NULL, + NULL, + FALSE, + NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE, + NULL, + NULL, + &startup_info, + &process_info)) + { + SLang_verror (0, "%s: CreateProcess failed.", cmd); + return -1; + } + + status = -1; + + if (0xFFFFFFFFUL != WaitForSingleObject (process_info.hProcess, INFINITE)) + { + DWORD exit_code; + + if (TRUE == GetExitCodeProcess (process_info.hProcess, &exit_code)) + status = (int) exit_code; + } + + CloseHandle (process_info.hThread); + CloseHandle (process_info.hProcess); + + return status; +} +#endif diff --git a/slang/slsmg.c b/slang/slsmg.c index d548c0bc9..05f99ec9c 100644 --- a/slang/slsmg.c +++ b/slang/slsmg.c @@ -1,24 +1,22 @@ /* SLang Screen management routines */ -/* Copyright (c) 1992, 1995 John E. Davis - * All rights reserved. - * +/* Copyright (c) 1992, 1999, 2001, 2002 John E. Davis + * This file is part of the S-Lang library. + * * You may distribute under the terms of either the GNU General Public * License or the Perl Artistic License. */ -#include "config.h" - -#include -#include +#include "slinclud.h" +#include "slang.h" #include "_slang.h" typedef struct Screen_Type { int n; /* number of chars written last time */ int flags; /* line untouched, etc... */ - unsigned short *old, *neew; -#ifndef pc_system + SLsmg_Char_Type *old, *neew; +#ifndef IBMPC_SYSTEM unsigned long old_hash, new_hash; #endif } @@ -26,11 +24,12 @@ Screen_Type; #define TOUCHED 0x1 #define TRASHED 0x2 +static int Screen_Trashed; -#ifndef pc_system -#define MAX_SCREEN_SIZE 120 +#if !defined(__MSDOS_16BIT__) +# define MAX_SCREEN_SIZE 256 #else -#define MAX_SCREEN_SIZE 75 +# define MAX_SCREEN_SIZE 75 #endif Screen_Type SL_Screen[MAX_SCREEN_SIZE]; @@ -44,34 +43,67 @@ static int This_Color; /* only the first 8 bits of this * color combination. */ -#ifndef pc_system +#ifndef IBMPC_SYSTEM #define ALT_CHAR_FLAG 0x80 #else #define ALT_CHAR_FLAG 0x00 #endif -int SLsmg_Newline_Moves = 0; +#if SLTT_HAS_NON_BCE_SUPPORT && !defined(IBMPC_SYSTEM) +#define REQUIRES_NON_BCE_SUPPORT 1 +static int Bce_Color_Offset; +#endif + +int SLsmg_Newline_Behavior = 0; int SLsmg_Backspace_Moves = 0; +/* Backward compatibility. Not used. */ +/* int SLsmg_Newline_Moves; */ -static void blank_line (unsigned short *p, int n, unsigned char ch) +static void (*tt_normal_video)(void) = SLtt_normal_video; +static void (*tt_goto_rc)(int, int) = SLtt_goto_rc; +static void (*tt_cls) (void) = SLtt_cls; +static void (*tt_del_eol) (void) = SLtt_del_eol; +static void (*tt_smart_puts) (SLsmg_Char_Type *, SLsmg_Char_Type *, int, int) = SLtt_smart_puts; +static int (*tt_flush_output) (void) = SLtt_flush_output; +static int (*tt_reset_video) (void) = SLtt_reset_video; +static int (*tt_init_video) (void) = SLtt_init_video; +static int *tt_Screen_Rows = &SLtt_Screen_Rows; +static int *tt_Screen_Cols = &SLtt_Screen_Cols; + +#ifndef IBMPC_SYSTEM +static void (*tt_set_scroll_region)(int, int) = SLtt_set_scroll_region; +static void (*tt_reverse_index)(int) = SLtt_reverse_index; +static void (*tt_reset_scroll_region)(void) = SLtt_reset_scroll_region; +static void (*tt_delete_nlines)(int) = SLtt_delete_nlines; +#endif + +#ifndef IBMPC_SYSTEM +static int *tt_Term_Cannot_Scroll = &SLtt_Term_Cannot_Scroll; +static int *tt_Has_Alt_Charset = &SLtt_Has_Alt_Charset; +static char **tt_Graphics_Char_Pairs = &SLtt_Graphics_Char_Pairs; +static int *tt_Use_Blink_For_ACS = &SLtt_Use_Blink_For_ACS; +#endif + +static int Smg_Inited; + +static void blank_line (SLsmg_Char_Type *p, int n, unsigned char ch) { - register unsigned short *pmax = p + n; - register unsigned short color_ch; + register SLsmg_Char_Type *pmax = p + n; + register SLsmg_Char_Type color_ch; + + color_ch = SLSMG_BUILD_CHAR(ch,This_Color); - color_ch = (This_Color << 8) | (unsigned short) ch; - while (p < pmax) { *p++ = color_ch; } } - static void clear_region (int row, int n) { int i; int imax = row + n; - + if (imax > Screen_Rows) imax = Screen_Rows; for (i = row; i < imax; i++) { @@ -86,10 +118,12 @@ static void clear_region (int row, int n) void SLsmg_erase_eol (void) { int r, c; - + + if (Smg_Inited == 0) return; + c = This_Col - Start_Col; r = This_Row - Start_Row; - + if ((r < 0) || (r >= Screen_Rows)) return; if (c < 0) c = 0; else if (c >= Screen_Cols) return; blank_line (SL_Screen[This_Row].neew + c , Screen_Cols - c, ' '); @@ -99,7 +133,7 @@ void SLsmg_erase_eol (void) static void scroll_up (void) { unsigned int i, imax; - unsigned short *neew; + SLsmg_Char_Type *neew; neew = SL_Screen[0].neew; imax = Screen_Rows - 1; @@ -114,9 +148,6 @@ static void scroll_up (void) This_Row--; } - - - void SLsmg_gotorc (int r, int c) { This_Row = r; @@ -135,76 +166,76 @@ int SLsmg_get_column (void) void SLsmg_erase_eos (void) { + if (Smg_Inited == 0) return; + SLsmg_erase_eol (); clear_region (This_Row + 1, Screen_Rows); } static int This_Alt_Char; -#ifndef pc_system void SLsmg_set_char_set (int i) { - if (SLtt_Use_Blink_For_ACS) return; /* alt chars not used and the alt bit - * is used to indicate a blink. - */ +#ifdef IBMPC_SYSTEM + (void) i; +#else + if ((tt_Use_Blink_For_ACS != NULL) + && (*tt_Use_Blink_For_ACS != 0)) + return;/* alt chars not used and the alt bit + * is used to indicate a blink. + */ + if (i) This_Alt_Char = ALT_CHAR_FLAG; else This_Alt_Char = 0; - + This_Color &= 0x7F; This_Color |= This_Alt_Char; -} #endif +} void SLsmg_set_color (int color) { if (color < 0) return; +#ifdef REQUIRES_NON_BCE_SUPPORT + color += Bce_Color_Offset; +#endif This_Color = color | This_Alt_Char; } - void SLsmg_reverse_video (void) { SLsmg_set_color (1); } - void SLsmg_normal_video (void) { - This_Color = This_Alt_Char; /* reset video but NOT char set. */ + SLsmg_set_color (0); } - static int point_visible (int col_too) { return ((This_Row >= Start_Row) && (This_Row < Start_Row + Screen_Rows) && ((col_too == 0) - || ((This_Col >= Start_Col) + || ((This_Col >= Start_Col) && (This_Col < Start_Col + Screen_Cols)))); } - -void SLsmg_printf (char *fmt, ...) -{ - char p[1000]; - va_list ap; - - va_start(ap, fmt); - (void) g_vsnprintf(p, sizeof (p), fmt, ap); - va_end(ap); - - SLsmg_write_string (p); -} void SLsmg_write_string (char *str) { SLsmg_write_nchars (str, strlen (str)); } -void SLsmg_write_nstring (char *str, int n) +void SLsmg_write_nstring (char *str, unsigned int n) { - int width; + unsigned int width; char blank = ' '; + + /* Avoid a problem if a user accidently passes a negative value */ + if ((int) n < 0) + return; + if (str == NULL) width = 0; - else + else { width = strlen (str); if (width > n) width = n; @@ -213,11 +244,13 @@ void SLsmg_write_nstring (char *str, int n) while (width++ < n) SLsmg_write_nchars (&blank, 1); } -void SLsmg_write_wrapped_string (char *s, int r, int c, int dr, int dc, int fill) +void SLsmg_write_wrapped_string (char *s, int r, int c, + unsigned int dr, unsigned int dc, + int fill) { register char ch, *p; - int maxc = dc; - + int maxc = (int) dc; + if ((dr == 0) || (dc == 0)) return; p = s; dc = 0; @@ -227,9 +260,9 @@ void SLsmg_write_wrapped_string (char *s, int r, int c, int dr, int dc, int fill if ((ch == 0) || (ch == '\n')) { int diff; - - diff = maxc - dc; - + + diff = maxc - (int) dc; + SLsmg_gotorc (r, c); SLsmg_write_nchars (s, dc); if (fill && (diff > 0)) @@ -237,13 +270,13 @@ void SLsmg_write_wrapped_string (char *s, int r, int c, int dr, int dc, int fill while (diff--) SLsmg_write_char (' '); } if ((ch == 0) || (dr == 1)) break; - + r++; dc = 0; dr--; s = p; } - else if (dc == maxc) + else if ((int) dc == maxc) { SLsmg_gotorc (r, c); SLsmg_write_nchars (s, dc + 1); @@ -258,62 +291,63 @@ void SLsmg_write_wrapped_string (char *s, int r, int c, int dr, int dc, int fill } } - - int SLsmg_Tab_Width = 8; /* Minimum value for which eight bit char is displayed as is. */ -#ifndef pc_system +#ifndef IBMPC_SYSTEM int SLsmg_Display_Eight_Bit = 160; static unsigned char Alt_Char_Set[129];/* 129th is used as a flag */ #else int SLsmg_Display_Eight_Bit = 128; #endif -void SLsmg_write_nchars (char *str, int n) +void SLsmg_write_nchars (char *str, unsigned int n) { - register unsigned short *p, old, neew, color; + register SLsmg_Char_Type *p, old, neew, color; unsigned char ch; unsigned int flags; int len, start_len, max_len; char *str_max; int newline_flag; -#ifndef pc_system +#ifndef IBMPC_SYSTEM int alt_char_set_flag; - - alt_char_set_flag = ((SLtt_Use_Blink_For_ACS == 0) - && (This_Color & ALT_CHAR_FLAG)); + + alt_char_set_flag = ((This_Color & ALT_CHAR_FLAG) + && ((tt_Use_Blink_For_ACS == NULL) + || (*tt_Use_Blink_For_ACS == 0))); #endif + if (Smg_Inited == 0) return; + str_max = str + n; - color = This_Color << 8; - + color = This_Color; + top: /* get here only on newline */ - + newline_flag = 0; start_len = Start_Col; - + if (point_visible (0) == 0) return; - + len = This_Col; max_len = start_len + Screen_Cols; - p = SL_Screen[This_Row].neew; + p = SL_Screen[This_Row - Start_Row].neew; if (len > start_len) p += (len - start_len); - - flags = SL_Screen[This_Row].flags; + + flags = SL_Screen[This_Row - Start_Row].flags; while ((len < max_len) && (str < str_max)) - { + { ch = (unsigned char) *str++; -#ifndef pc_system +#ifndef IBMPC_SYSTEM if (alt_char_set_flag) ch = Alt_Char_Set [ch & 0x7F]; #endif if (((ch >= ' ') && (ch < 127)) || (ch >= (unsigned char) SLsmg_Display_Eight_Bit) -#ifndef pc_system +#ifndef IBMPC_SYSTEM || alt_char_set_flag #endif ) @@ -322,7 +356,7 @@ void SLsmg_write_nchars (char *str, int n) if (len > start_len) { old = *p; - neew = color | (unsigned short) ch; + neew = SLSMG_BUILD_CHAR(ch,color); if (old != neew) { flags |= TOUCHED; @@ -331,20 +365,21 @@ void SLsmg_write_nchars (char *str, int n) p++; } } - + else if ((ch == '\t') && (SLsmg_Tab_Width > 0)) { n = len; n += SLsmg_Tab_Width; n = SLsmg_Tab_Width - (n % SLsmg_Tab_Width); - if (len + n > max_len) n = max_len - len; - neew = color | (unsigned short) ' '; + if ((unsigned int) len + n > (unsigned int) max_len) + n = (unsigned int) (max_len - len); + neew = SLSMG_BUILD_CHAR(' ',color); while (n--) { len += 1; if (len > start_len) { - if (*p != neew) + if (*p != neew) { flags |= TOUCHED; *p = neew; @@ -353,7 +388,8 @@ void SLsmg_write_nchars (char *str, int n) } } } - else if (ch == '\n') + else if ((ch == '\n') + && (SLsmg_Newline_Behavior != SLSMG_NEWLINE_PRINTABLE)) { newline_flag = 1; break; @@ -366,7 +402,7 @@ void SLsmg_write_nchars (char *str, int n) { if (ch & 0x80) { - neew = color | (unsigned short) '~'; + neew = SLSMG_BUILD_CHAR('~',color); len += 1; if (len > start_len) { @@ -380,11 +416,11 @@ void SLsmg_write_nchars (char *str, int n) ch &= 0x7F; } } - + len += 1; if (len > start_len) { - neew = color | (unsigned short) '^'; + neew = SLSMG_BUILD_CHAR('^',color); if (*p != neew) { *p = neew; @@ -393,12 +429,12 @@ void SLsmg_write_nchars (char *str, int n) p++; if (len == max_len) break; } - + if (ch == 127) ch = '?'; else ch = ch + '@'; len++; if (len > start_len) { - neew = color | (unsigned short) ch; + neew = SLSMG_BUILD_CHAR(ch,color); if (*p != neew) { *p = neew; @@ -408,13 +444,13 @@ void SLsmg_write_nchars (char *str, int n) } } } - - SL_Screen[This_Row].flags = flags; + + SL_Screen[This_Row - Start_Row].flags = flags; This_Col = len; - - if (SLsmg_Newline_Moves == 0) + + if (SLsmg_Newline_Behavior == 0) return; - + if (newline_flag == 0) { while (str < str_max) @@ -425,17 +461,16 @@ void SLsmg_write_nchars (char *str, int n) if (str == str_max) return; str++; } - + This_Row++; This_Col = 0; if (This_Row == Start_Row + Screen_Rows) { - if (SLsmg_Newline_Moves > 0) scroll_up (); + if (SLsmg_Newline_Behavior == SLSMG_NEWLINE_SCROLLS) scroll_up (); } goto top; } - void SLsmg_write_char (char ch) { SLsmg_write_nchars (&ch, 1); @@ -443,41 +478,45 @@ void SLsmg_write_char (char ch) static int Cls_Flag; - void SLsmg_cls (void) { - This_Color = 0; + int tac; + if (Smg_Inited == 0) return; + + tac = This_Alt_Char; This_Alt_Char = 0; + SLsmg_set_color (0); clear_region (0, Screen_Rows); - This_Color = This_Alt_Char; + This_Alt_Char = tac; + SLsmg_set_color (0); Cls_Flag = 1; } #if 0 -static void do_copy (unsigned short *a, unsigned short *b) +static void do_copy (SLsmg_Char_Type *a, SLsmg_Char_Type *b) { - unsigned short *amax = a + Screen_Cols; - + SLsmg_Char_Type *amax = a + Screen_Cols; + while (a < amax) *a++ = *b++; } #endif -#ifndef pc_system +#ifndef IBMPC_SYSTEM int SLsmg_Scroll_Hash_Border = 0; -static unsigned long compute_hash (unsigned short *s, int n) +static unsigned long compute_hash (SLsmg_Char_Type *s, int n) { register unsigned long h = 0, g; register unsigned long sum = 0; - register unsigned short *smax, ch; + register SLsmg_Char_Type *smax, ch; int is_blank = 2; - + s += SLsmg_Scroll_Hash_Border; smax = s + (n - SLsmg_Scroll_Hash_Border); - while (s < smax) + while (s < smax) { ch = *s++; - if (is_blank && ((ch & 0xFF) != 32)) is_blank--; - + if (is_blank && (SLSMG_EXTRACT_CHAR(ch) != 32)) is_blank--; + sum += ch; - + h = sum + (h << 3); if ((g = h & 0xE0000000UL) != 0) { @@ -491,61 +530,37 @@ static unsigned long compute_hash (unsigned short *s, int n) static unsigned long Blank_Hash; -static void try_scroll (void) +static int try_scroll_down (int rmin, int rmax) { - int i, j, di, r1, r2, rmin, rmax; + int i, r1, r2, di, j; unsigned long hash; - int color, did_scroll = 0; - unsigned short *tmp; + int did_scroll; + int color; + SLsmg_Char_Type *tmp; int ignore; - - /* find region limits. */ - - for (rmax = Screen_Rows - 1; rmax > 0; rmax--) - { - if (SL_Screen[rmax].new_hash != SL_Screen[rmax].old_hash) - { - r1 = rmax - 1; - if ((r1 == 0) - || (SL_Screen[r1].new_hash != SL_Screen[r1].old_hash)) - break; - - rmax = r1; - } - } - - for (rmin = 0; rmin < rmax; rmin++) - { - if (SL_Screen[rmin].new_hash != SL_Screen[rmin].old_hash) - { - r1 = rmin + 1; - if ((r1 == rmax) - || (SL_Screen[r1].new_hash != SL_Screen[r1].old_hash)) - break; - - rmin = r1; - } - } - + did_scroll = 0; for (i = rmax; i > rmin; i--) { hash = SL_Screen[i].new_hash; if (hash == Blank_Hash) continue; - - if ((hash == SL_Screen[i].old_hash) + + if ((hash == SL_Screen[i].old_hash) +#if 0 || ((i + 1 < Screen_Rows) && (hash == SL_Screen[i + 1].old_hash)) - || ((i - 1 > rmin) && (SL_Screen[i].old_hash == SL_Screen[i - 1].new_hash))) + || ((i - 1 > rmin) && (SL_Screen[i].old_hash == SL_Screen[i - 1].new_hash)) +#endif + ) continue; - + for (j = i - 1; j >= rmin; j--) { if (hash == SL_Screen[j].old_hash) break; } if (j < rmin) continue; - + r2 = i; /* end scroll region */ - + di = i - j; j--; ignore = 0; @@ -555,12 +570,12 @@ static void try_scroll (void) j--; } r1 = j + 1; - + /* If this scroll only scrolls this line into place, don't do it. */ if ((di > 1) && (r1 + di + ignore == r2)) continue; - - /* If there is anything in the scrolling region that is ok, abort the + + /* If there is anything in the scrolling region that is ok, abort the * scroll. */ @@ -575,19 +590,25 @@ static void try_scroll (void) } } if (j <= r2) continue; - + color = This_Color; This_Color = 0; did_scroll = 1; - SLtt_normal_video (); - SLtt_set_scroll_region (r1, r2); - SLtt_goto_rc (0, 0); - SLtt_reverse_index (di); - SLtt_reset_scroll_region (); - /* Now we have a hole in the screen. Make the virtual screen look - * like it. + (*tt_normal_video) (); + (*tt_set_scroll_region) (r1, r2); + (*tt_goto_rc) (0, 0); + (*tt_reverse_index) (di); + (*tt_reset_scroll_region) (); + /* Now we have a hole in the screen. + * Make the virtual screen look like it. + * + * Note that if the terminal does not support BCE, then we have + * no idea what color the hole is. So, for this case, we do not + * want to add Bce_Color_Offset to This_Color since if Bce_Color_Offset + * is non-zero, then This_Color = 0 does not match any valid color + * obtained by adding Bce_Color_Offset. */ for (j = r1; j <= r2; j++) SL_Screen[j].flags = TOUCHED; - + while (di--) { tmp = SL_Screen[r2].old; @@ -603,27 +624,37 @@ static void try_scroll (void) } This_Color = color; } - if (did_scroll) return; - - /* Try other direction */ + return did_scroll; +} + +static int try_scroll_up (int rmin, int rmax) +{ + int i, r1, r2, di, j; + unsigned long hash; + int did_scroll; + int color; + SLsmg_Char_Type *tmp; + int ignore; + + did_scroll = 0; for (i = rmin; i < rmax; i++) { hash = SL_Screen[i].new_hash; if (hash == Blank_Hash) continue; - if (hash == SL_Screen[i].old_hash) continue; - + if (hash == SL_Screen[i].old_hash) + continue; /* find a match further down screen */ for (j = i + 1; j <= rmax; j++) { if (hash == SL_Screen[j].old_hash) break; } if (j > rmax) continue; - + r1 = i; /* beg scroll region */ di = j - i; /* number of lines to scroll */ j++; /* since we know this is a match */ - + /* find end of scroll region */ ignore = 0; while ((j <= rmax) && (SL_Screen[j].old_hash == SL_Screen[j - di].new_hash)) @@ -632,15 +663,15 @@ static void try_scroll (void) j++; } r2 = j - 1; /* end of scroll region */ - + /* If this scroll only scrolls this line into place, don't do it. */ if ((di > 1) && (r1 + di + ignore == r2)) continue; - /* If there is anything in the scrolling region that is ok, abort the + /* If there is anything in the scrolling region that is ok, abort the * scroll. */ - + for (j = r1; j <= r2; j++) { if ((SL_Screen[j].old_hash != Blank_Hash) @@ -649,21 +680,24 @@ static void try_scroll (void) if ((j - di < r1) || (SL_Screen[j].old_hash != SL_Screen[j - di].new_hash)) break; } - + } if (j <= r2) continue; - + + did_scroll = 1; + + /* See the above comments about BCE */ color = This_Color; This_Color = 0; - SLtt_normal_video (); - SLtt_set_scroll_region (r1, r2); - SLtt_goto_rc (0, 0); /* relative to scroll region */ - SLtt_delete_nlines (di); - SLtt_reset_scroll_region (); - /* Now we have a hole in the screen. Make the virtual screen look + (*tt_normal_video) (); + (*tt_set_scroll_region) (r1, r2); + (*tt_goto_rc) (0, 0); /* relative to scroll region */ + (*tt_delete_nlines) (di); + (*tt_reset_scroll_region) (); + /* Now we have a hole in the screen. Make the virtual screen look * like it. */ for (j = r1; j <= r2; j++) SL_Screen[j].flags = TOUCHED; - + while (di--) { tmp = SL_Screen[r1].old; @@ -679,87 +713,214 @@ static void try_scroll (void) } This_Color = color; } + return did_scroll; } -#endif /* NOT pc_system */ - +static void try_scroll (void) +{ + int r1, rmin, rmax; + int num_up, num_down; + /* find region limits. */ + + for (rmax = Screen_Rows - 1; rmax > 0; rmax--) + { + if (SL_Screen[rmax].new_hash != SL_Screen[rmax].old_hash) + { + r1 = rmax - 1; + if ((r1 == 0) + || (SL_Screen[r1].new_hash != SL_Screen[r1].old_hash)) + break; + + rmax = r1; + } + } + + for (rmin = 0; rmin < rmax; rmin++) + { + if (SL_Screen[rmin].new_hash != SL_Screen[rmin].old_hash) + { + r1 = rmin + 1; + if ((r1 == rmax) + || (SL_Screen[r1].new_hash != SL_Screen[r1].old_hash)) + break; + + rmin = r1; + } + } + + /* Below, we have two scrolling algorithms. The first has the effect of + * scrolling lines down. This is usually appropriate when one moves + * up the display, e.g., with the UP arrow. The second algorithm is + * appropriate for going the other way. It is important to choose the + * correct one. + */ + + num_up = 0; + for (r1 = rmin; r1 < rmax; r1++) + { + if (SL_Screen[r1].new_hash == SL_Screen[r1 + 1].old_hash) + num_up++; + } + + num_down = 0; + for (r1 = rmax; r1 > rmin; r1--) + { + if (SL_Screen[r1 - 1].old_hash == SL_Screen[r1].new_hash) + num_down++; + } + + if (num_up > num_down) + { + if (try_scroll_up (rmin, rmax)) + return; + + (void) try_scroll_down (rmin, rmax); + } + else + { + if (try_scroll_down (rmin, rmax)) + return; + + (void) try_scroll_up (rmin, rmax); + } +} +#endif /* NOT IBMPC_SYSTEM */ + + +#ifdef REQUIRES_NON_BCE_SUPPORT +static void adjust_colors (void) +{ + int bce; + int i; + + bce = Bce_Color_Offset; + Bce_Color_Offset = _SLtt_get_bce_color_offset (); + if (bce == Bce_Color_Offset) + return; + + if ((tt_Use_Blink_For_ACS != NULL) + && (*tt_Use_Blink_For_ACS != 0)) + return; /* this mode does not support non-BCE + * terminals. + */ + + for (i = 0; i < Screen_Rows; i++) + { + SLsmg_Char_Type *s, *smax; + + SL_Screen[i].flags |= TRASHED; + s = SL_Screen[i].neew; + smax = s + Screen_Cols; - -static int Smg_Inited; + while (s < smax) + { + int color = (int) SLSMG_EXTRACT_COLOR(*s); + int acs; + + if (color < 0) + { + s++; + continue; + } + + acs = color & 0x80; + color = (color & 0x7F) - bce; + color += Bce_Color_Offset; + if (color >= 0) + { + unsigned char ch = SLSMG_EXTRACT_CHAR(*s); + *s = SLSMG_BUILD_CHAR(ch, ((color&0x7F)|acs)); + } + s++; + } + } +} +#endif void SLsmg_refresh (void) { int i; - +#ifndef IBMPC_SYSTEM + int trashed = 0; +#endif + if (Smg_Inited == 0) return; -#ifndef pc_system + + if (Screen_Trashed) + { + Cls_Flag = 1; + for (i = 0; i < Screen_Rows; i++) + SL_Screen[i].flags |= TRASHED; +#ifdef REQUIRES_NON_BCE_SUPPORT + adjust_colors (); +#endif + } + +#ifndef IBMPC_SYSTEM for (i = 0; i < Screen_Rows; i++) { if (SL_Screen[i].flags == 0) continue; SL_Screen[i].new_hash = compute_hash (SL_Screen[i].neew, Screen_Cols); + trashed = 1; } #endif - - if (Cls_Flag) + + if (Cls_Flag) { - SLtt_normal_video (); SLtt_cls (); + (*tt_normal_video) (); (*tt_cls) (); } -#ifndef pc_system - else if (SLtt_Term_Cannot_Scroll == 0) try_scroll (); +#ifndef IBMPC_SYSTEM + else if (trashed && (*tt_Term_Cannot_Scroll == 0)) try_scroll (); #endif for (i = 0; i < Screen_Rows; i++) { - int trashed; - if (SL_Screen[i].flags == 0) continue; - - if (SL_Screen[i].flags & TRASHED) - { - SLtt_goto_rc (i, -1); /* Force cursor to move */ - SLtt_goto_rc (i, 0); - if (Cls_Flag == 0) SLtt_del_eol (); - trashed = 1; - } - else trashed = 0; - - if (Cls_Flag || trashed) + + if (Cls_Flag || SL_Screen[i].flags & TRASHED) { int color = This_Color; + + if (Cls_Flag == 0) + { + (*tt_goto_rc) (i, 0); + (*tt_del_eol) (); + } This_Color = 0; blank_line (SL_Screen[i].old, Screen_Cols, ' '); This_Color = color; } - + SL_Screen[i].old[Screen_Cols] = 0; SL_Screen[i].neew[Screen_Cols] = 0; - - SLtt_smart_puts (SL_Screen[i].neew, SL_Screen[i].old, Screen_Cols, i); - SLMEMCPY ((char *) SL_Screen[i].old, (char *) SL_Screen[i].neew, - Screen_Cols * sizeof (short)); + (*tt_smart_puts) (SL_Screen[i].neew, SL_Screen[i].old, Screen_Cols, i); + + SLMEMCPY ((char *) SL_Screen[i].old, (char *) SL_Screen[i].neew, + Screen_Cols * sizeof (SLsmg_Char_Type)); SL_Screen[i].flags = 0; -#ifndef pc_system +#ifndef IBMPC_SYSTEM SL_Screen[i].old_hash = SL_Screen[i].new_hash; #endif } - - if (point_visible (1)) SLtt_goto_rc (This_Row - Start_Row, This_Col - Start_Col); - SLtt_flush_output (); + + if (point_visible (1)) (*tt_goto_rc) (This_Row - Start_Row, This_Col - Start_Col); + (*tt_flush_output) (); Cls_Flag = 0; + Screen_Trashed = 0; } static int compute_clip (int row, int n, int box_start, int box_end, int *rmin, int *rmax) { int row_max; - + if (n < 0) return 0; if (row >= box_end) return 0; row_max = row + n; if (row_max <= box_start) return 0; - + if (row < box_start) row = box_start; if (row_max >= box_end) row_max = box_end; *rmin = row; @@ -767,14 +928,22 @@ static int compute_clip (int row, int n, int box_start, int box_end, return 1; } -void SLsmg_touch_lines (int row, int n) +void SLsmg_touch_lines (int row, unsigned int n) { int i; int r1, r2; - - if (0 == compute_clip (row, n, Start_Row, Start_Row + Screen_Rows, &r1, &r2)) + + /* Allow this function to be called even when we are not initialied. + * Calling this function is useful after calling SLtt_set_color + * to force the display to be redrawn + */ + + if (Smg_Inited == 0) return; - + + if (0 == compute_clip (row, (int) n, Start_Row, Start_Row + Screen_Rows, &r1, &r2)) + return; + r1 -= Start_Row; r2 -= Start_Row; for (i = r1; i < r2; i++) @@ -783,34 +952,40 @@ void SLsmg_touch_lines (int row, int n) } } -#ifndef pc_system -static const char Fake_Alt_Char_Pairs [] = "a:j+k+l+m+q-t+u+v+w+x|n+`+f\\g#~o,<+>.v-^h#0#"; +void SLsmg_touch_screen (void) +{ + Screen_Trashed = 1; +} + + +#ifndef IBMPC_SYSTEM +static char Fake_Alt_Char_Pairs [] = "a:j+k+l+m+q-t+u+v+w+x|n+`+f\\g#~o,<+>.v-^h#0#"; static void init_alt_char_set (void) { int i; - const unsigned char *p, *pmax; - unsigned char ch; + unsigned char *p, *pmax, ch; if (Alt_Char_Set[128] == 128) return; i = 32; memset ((char *)Alt_Char_Set, ' ', i); - while (i <= 128) + while (i <= 128) { Alt_Char_Set [i] = i; i++; } - + /* Map to VT100 */ - if (SLtt_Has_Alt_Charset) + if (*tt_Has_Alt_Charset) { - p = (unsigned char *) SLtt_Graphics_Char_Pairs; + if (tt_Graphics_Char_Pairs == NULL) p = NULL; + else p = (unsigned char *) *tt_Graphics_Char_Pairs; if (p == NULL) return; } else p = (unsigned char *) Fake_Alt_Char_Pairs; pmax = p + strlen ((char *) p); - + /* Some systems have messed up entries for this */ while (p < pmax) { @@ -822,119 +997,178 @@ static void init_alt_char_set (void) } #endif -#ifndef pc_system -# define BLOCK_SIGNALS SLsig_block_signals (); -# define UNBLOCK_SIGNALS SLsig_unblock_signals (); +#ifndef IBMPC_SYSTEM +# define BLOCK_SIGNALS SLsig_block_signals () +# define UNBLOCK_SIGNALS SLsig_unblock_signals () #else -# define BLOCK_SIGNALS -# define UNBLOCK_SIGNALS +# define BLOCK_SIGNALS (void)0 +# define UNBLOCK_SIGNALS (void)0 #endif static int Smg_Suspended; -void SLsmg_suspend_smg (void) +int SLsmg_suspend_smg (void) { - BLOCK_SIGNALS + BLOCK_SIGNALS; if (Smg_Suspended == 0) { - SLtt_reset_video (); + (*tt_reset_video) (); Smg_Suspended = 1; } - - UNBLOCK_SIGNALS + + UNBLOCK_SIGNALS; + return 0; } -void SLsmg_resume_smg (void) +int SLsmg_resume_smg (void) +{ + BLOCK_SIGNALS; + + if (Smg_Suspended == 0) + { + UNBLOCK_SIGNALS; + return 0; + } + + Smg_Suspended = 0; + + if (-1 == (*tt_init_video) ()) + { + UNBLOCK_SIGNALS; + return -1; + } + + Cls_Flag = 1; + SLsmg_touch_screen (); + SLsmg_refresh (); + + UNBLOCK_SIGNALS; + return 0; +} + + +static void reset_smg (void) { int i; - BLOCK_SIGNALS + if (Smg_Inited == 0) + return; - if (Smg_Suspended == 0) - { - UNBLOCK_SIGNALS - return; - } - - Smg_Suspended = 0; - SLtt_init_video (); - Cls_Flag = 1; for (i = 0; i < Screen_Rows; i++) - SL_Screen[i].flags |= TRASHED; - SLsmg_refresh (); - - UNBLOCK_SIGNALS + { + SLfree ((char *)SL_Screen[i].old); + SLfree ((char *)SL_Screen[i].neew); + SL_Screen[i].old = SL_Screen[i].neew = NULL; + } + This_Alt_Char = This_Color = 0; + Smg_Inited = 0; } -int SLsmg_init_smg (void) + +static int init_smg (void) { int i, len; - unsigned short *old, *neew; - BLOCK_SIGNALS - - if (Smg_Inited) SLsmg_reset_smg (); - SLtt_init_video (); - Screen_Cols = SLtt_Screen_Cols; - Screen_Rows = SLtt_Screen_Rows; + SLsmg_Char_Type *old, *neew; + + Smg_Inited = 0; + +#ifdef REQUIRES_NON_BCE_SUPPORT + Bce_Color_Offset = _SLtt_get_bce_color_offset (); +#endif + + Screen_Rows = *tt_Screen_Rows; + if (Screen_Rows > MAX_SCREEN_SIZE) + Screen_Rows = MAX_SCREEN_SIZE; + + Screen_Cols = *tt_Screen_Cols; + This_Col = This_Row = Start_Col = Start_Row = 0; - This_Color = 0; This_Alt_Char = 0; + SLsmg_set_color (0); Cls_Flag = 1; -#ifndef pc_system +#ifndef IBMPC_SYSTEM init_alt_char_set (); #endif len = Screen_Cols + 3; for (i = 0; i < Screen_Rows; i++) { - if ((NULL == (old = (unsigned short *) SLMALLOC (sizeof(short) * len))) - || ((NULL == (neew = (unsigned short *) SLMALLOC (sizeof(short) * len))))) + if ((NULL == (old = (SLsmg_Char_Type *) SLmalloc (sizeof(SLsmg_Char_Type) * len))) + || ((NULL == (neew = (SLsmg_Char_Type *) SLmalloc (sizeof(SLsmg_Char_Type) * len))))) { - SLang_Error = SL_MALLOC_ERROR; - UNBLOCK_SIGNALS - return 0; + SLfree ((char *) old); + return -1; } blank_line (old, len, ' '); blank_line (neew, len, ' '); SL_Screen[i].old = old; SL_Screen[i].neew = neew; SL_Screen[i].flags = 0; -#ifndef pc_system +#ifndef IBMPC_SYSTEM Blank_Hash = compute_hash (old, Screen_Cols); SL_Screen[i].new_hash = SL_Screen[i].old_hash = Blank_Hash; #endif } + + _SLtt_color_changed_hook = SLsmg_touch_screen; + Screen_Trashed = 1; Smg_Inited = 1; - UNBLOCK_SIGNALS - return 1; + return 0; } +int SLsmg_init_smg (void) +{ + int ret; + + BLOCK_SIGNALS; + + if (Smg_Inited) + SLsmg_reset_smg (); + + if (-1 == (*tt_init_video) ()) + { + UNBLOCK_SIGNALS; + return -1; + } + + if (-1 == (ret = init_smg ())) + (void) (*tt_reset_video)(); + + UNBLOCK_SIGNALS; + return ret; +} + +int SLsmg_reinit_smg (void) +{ + int ret; + + if (Smg_Inited == 0) + return SLsmg_init_smg (); + + BLOCK_SIGNALS; + reset_smg (); + ret = init_smg (); + UNBLOCK_SIGNALS; + return ret; +} + void SLsmg_reset_smg (void) -{ - int i; - BLOCK_SIGNALS - - if (Smg_Inited == 0) - { - UNBLOCK_SIGNALS - return; - } - for (i = 0; i < Screen_Rows; i++) - { - if (SL_Screen[i].old != NULL) SLFREE (SL_Screen[i].old); - if (SL_Screen[i].neew != NULL) SLFREE (SL_Screen[i].neew); - SL_Screen[i].old = SL_Screen[i].neew = NULL; - } - SLtt_reset_video (); - This_Alt_Char = This_Color = 0; - Smg_Inited = 0; +{ + if (Smg_Inited == 0) + return; - UNBLOCK_SIGNALS + BLOCK_SIGNALS; + + reset_smg (); + (*tt_reset_video)(); + + UNBLOCK_SIGNALS; } - -unsigned short SLsmg_char_at (void) +SLsmg_Char_Type SLsmg_char_at (void) { + if (Smg_Inited == 0) return 0; + if (point_visible (1)) { return SL_Screen[This_Row - Start_Row].neew[This_Col - Start_Col]; @@ -942,20 +1176,44 @@ unsigned short SLsmg_char_at (void) return 0; } - void SLsmg_vprintf (char *fmt, va_list ap) { - char p[1000]; - - (void) g_vsnprintf(p, sizeof (p), fmt, ap); - - SLsmg_write_string (p); + char buf[1024]; + + if (Smg_Inited == 0) return; + + (void) _SLvsnprintf (buf, sizeof (buf), fmt, ap); + SLsmg_write_string (buf); +} + +void SLsmg_printf (char *fmt, ...) +{ + va_list ap; + unsigned int len; + char *f; + + if (Smg_Inited == 0) return; + + va_start(ap, fmt); + + f = fmt; + while (*f && (*f != '%')) + f++; + len = (unsigned int) (f - fmt); + if (len) SLsmg_write_nchars (fmt, len); + + if (*f != 0) + SLsmg_vprintf (f, ap); + + va_end (ap); } void SLsmg_set_screen_start (int *r, int *c) { - int or = Start_Row, oc = Start_Col; - + int orow = Start_Row, oc = Start_Col; + + if (Smg_Inited == 0) return; + if (c == NULL) Start_Col = 0; else { @@ -966,14 +1224,16 @@ void SLsmg_set_screen_start (int *r, int *c) else { Start_Row = *r; - *r = or; + *r = orow; } } void SLsmg_draw_object (int r, int c, unsigned char object) { This_Row = r; This_Col = c; - + + if (Smg_Inited == 0) return; + if (point_visible (1)) { int color = This_Color; @@ -985,40 +1245,42 @@ void SLsmg_draw_object (int r, int c, unsigned char object) This_Col = c + 1; } -void SLsmg_draw_hline (int n) +void SLsmg_draw_hline (unsigned int n) { static unsigned char hbuf[16]; int count; int cmin, cmax; - int final_col = This_Col + n; + int final_col = This_Col + (int) n; int save_color; - - if ((This_Row < Start_Row) || (This_Row >= Start_Row + Screen_Rows) + + if (Smg_Inited == 0) return; + + if ((This_Row < Start_Row) || (This_Row >= Start_Row + Screen_Rows) || (0 == compute_clip (This_Col, n, Start_Col, Start_Col + Screen_Cols, &cmin, &cmax))) { This_Col = final_col; return; } - + if (hbuf[0] == 0) { SLMEMSET ((char *) hbuf, SLSMG_HLINE_CHAR, 16); } - - n = cmax - cmin; + + n = (unsigned int)(cmax - cmin); count = n / 16; - + save_color = This_Color; This_Color |= ALT_CHAR_FLAG; This_Col = cmin; - + SLsmg_write_nchars ((char *) hbuf, n % 16); while (count-- > 0) { SLsmg_write_nchars ((char *) hbuf, 16); } - + This_Color = save_color; This_Col = final_col; } @@ -1029,7 +1291,9 @@ void SLsmg_draw_vline (int n) int c = This_Col, rmin, rmax; int final_row = This_Row + n; int save_color; - + + if (Smg_Inited == 0) return; + if (((c < Start_Col) || (c >= Start_Col + Screen_Cols)) || (0 == compute_clip (This_Row, n, Start_Row, Start_Row + Screen_Rows, &rmin, &rmax))) @@ -1037,52 +1301,56 @@ void SLsmg_draw_vline (int n) This_Row = final_row; return; } - + save_color = This_Color; This_Color |= ALT_CHAR_FLAG; - + for (This_Row = rmin; This_Row < rmax; This_Row++) { This_Col = c; SLsmg_write_nchars ((char *) &ch, 1); } - + This_Col = c; This_Row = final_row; This_Color = save_color; } -void SLsmg_draw_box (int r, int c, int dr, int dc) +void SLsmg_draw_box (int r, int c, unsigned int dr, unsigned int dc) { - if (!dr || !dc) return; + if (Smg_Inited == 0) return; + + if (!dr || !dc) return; This_Row = r; This_Col = c; dr--; dc--; - SLsmg_draw_hline (dc); + SLsmg_draw_hline (dc); SLsmg_draw_vline (dr); This_Row = r; This_Col = c; SLsmg_draw_vline (dr); - SLsmg_draw_hline (dc); + SLsmg_draw_hline (dc); SLsmg_draw_object (r, c, SLSMG_ULCORN_CHAR); - SLsmg_draw_object (r, c + dc, SLSMG_URCORN_CHAR); - SLsmg_draw_object (r + dr, c, SLSMG_LLCORN_CHAR); - SLsmg_draw_object (r + dr, c + dc, SLSMG_LRCORN_CHAR); + SLsmg_draw_object (r, c + (int) dc, SLSMG_URCORN_CHAR); + SLsmg_draw_object (r + (int) dr, c, SLSMG_LLCORN_CHAR); + SLsmg_draw_object (r + (int) dr, c + (int) dc, SLSMG_LRCORN_CHAR); This_Row = r; This_Col = c; } - -void SLsmg_fill_region (int r, int c, int dr, int dc, unsigned char ch) + +void SLsmg_fill_region (int r, int c, unsigned int dr, unsigned int dc, unsigned char ch) { static unsigned char hbuf[16]; int count; int dcmax, rmax; - - - if ((dc < 0) || (dr < 0)) return; - + + if (Smg_Inited == 0) return; + SLsmg_gotorc (r, c); r = This_Row; c = This_Col; - + dcmax = Screen_Cols - This_Col; - if (dc > dcmax) dc = dcmax; - + if (dcmax < 0) + return; + + if (dc > (unsigned int) dcmax) dc = (unsigned int) dcmax; + rmax = This_Row + dr; if (rmax > Screen_Rows) rmax = Screen_Rows; @@ -1090,7 +1358,7 @@ void SLsmg_fill_region (int r, int c, int dr, int dc, unsigned char ch) ch = Alt_Char_Set[ch]; #endif if (ch != hbuf[0]) SLMEMSET ((char *) hbuf, (char) ch, 16); - + for (This_Row = r; This_Row < rmax; This_Row++) { This_Col = c; @@ -1101,7 +1369,7 @@ void SLsmg_fill_region (int r, int c, int dr, int dc, unsigned char ch) SLsmg_write_nchars ((char *) hbuf, 16); } } - + This_Row = r; } @@ -1110,76 +1378,207 @@ void SLsmg_forward (int n) This_Col += n; } -void SLsmg_write_color_chars (unsigned short *s, unsigned int len) +void SLsmg_write_color_chars (SLsmg_Char_Type *s, unsigned int len) { - unsigned short *smax, sh; + SLsmg_Char_Type *smax, sh; char buf[32], *b, *bmax; int color, save_color; - + + if (Smg_Inited == 0) return; + smax = s + len; b = buf; bmax = b + sizeof (buf); - + save_color = This_Color; while (s < smax) { sh = *s++; - - color = sh >> 8; + + color = SLSMG_EXTRACT_COLOR(sh); + +#if REQUIRES_NON_BCE_SUPPORT + if (Bce_Color_Offset) + { + if (color & 0x80) + color = ((color & 0x7F) + Bce_Color_Offset) | 0x80; + else + color = ((color & 0x7F) + Bce_Color_Offset) & 0x7F; + } +#endif + if ((color != This_Color) || (b == bmax)) { - if (b != buf) + if (b != buf) { SLsmg_write_nchars (buf, (int) (b - buf)); b = buf; } This_Color = color; } - *b++ = (char) (sh & 0xFF); + *b++ = (char) SLSMG_EXTRACT_CHAR(sh); } - + if (b != buf) - SLsmg_write_nchars (buf, (int) (b - buf)); - + SLsmg_write_nchars (buf, (unsigned int) (b - buf)); + This_Color = save_color; } -unsigned int SLsmg_read_raw (unsigned short *buf, unsigned int len) +unsigned int SLsmg_read_raw (SLsmg_Char_Type *buf, unsigned int len) { unsigned int r, c; + if (Smg_Inited == 0) return 0; + if (0 == point_visible (1)) return 0; - + r = (unsigned int) (This_Row - Start_Row); c = (unsigned int) (This_Col - Start_Col); - + if (c + len > (unsigned int) Screen_Cols) len = (unsigned int) Screen_Cols - c; - - memcpy ((char *) buf, (char *) (SL_Screen[r].neew + c), len * sizeof (short)); + + memcpy ((char *) buf, (char *) (SL_Screen[r].neew + c), len * sizeof (SLsmg_Char_Type)); return len; } -unsigned int SLsmg_write_raw (unsigned short *buf, unsigned int len) +unsigned int SLsmg_write_raw (SLsmg_Char_Type *buf, unsigned int len) { unsigned int r, c; - unsigned short *dest; - + SLsmg_Char_Type *dest; + + if (Smg_Inited == 0) return 0; + if (0 == point_visible (1)) return 0; - + r = (unsigned int) (This_Row - Start_Row); c = (unsigned int) (This_Col - Start_Col); - + if (c + len > (unsigned int) Screen_Cols) len = (unsigned int) Screen_Cols - c; - + dest = SL_Screen[r].neew + c; - - if (0 != memcmp ((char *) dest, (char *) buf, len * sizeof (short))) - { - memcpy ((char *) dest, (char *) buf, len * sizeof (short)); + + if (0 != memcmp ((char *) dest, (char *) buf, len * sizeof (SLsmg_Char_Type))) + { + memcpy ((char *) dest, (char *) buf, len * sizeof (SLsmg_Char_Type)); SL_Screen[r].flags |= TOUCHED; } return len; } + +void +SLsmg_set_color_in_region (int color, int r, int c, unsigned int dr, unsigned int dc) +{ + int cmax, rmax; + SLsmg_Char_Type char_mask; + + if (Smg_Inited == 0) return; + + c -= Start_Col; + r -= Start_Row; + + cmax = c + (int) dc; + rmax = r + (int) dr; + + if (cmax > Screen_Cols) cmax = Screen_Cols; + if (rmax > Screen_Rows) rmax = Screen_Rows; + + if (c < 0) c = 0; + if (r < 0) r = 0; + +#if REQUIRES_NON_BCE_SUPPORT + if (Bce_Color_Offset) + { + if (color & 0x80) + color = ((color & 0x7F) + Bce_Color_Offset) | 0x80; + else + color = ((color & 0x7F) + Bce_Color_Offset) & 0x7F; + } +#endif + color = color << 8; + + char_mask = 0xFF; + +#ifndef IBMPC_SYSTEM + if ((tt_Use_Blink_For_ACS == NULL) + || (0 == *tt_Use_Blink_For_ACS)) + char_mask = 0x80FF; +#endif + + while (r < rmax) + { + SLsmg_Char_Type *s, *smax; + + SL_Screen[r].flags |= TOUCHED; + s = SL_Screen[r].neew; + smax = s + cmax; + s += c; + + while (s < smax) + { + *s = (*s & char_mask) | color; + s++; + } + r++; + } +} + +void SLsmg_set_terminal_info (SLsmg_Term_Type *tt) +{ + if (tt == NULL) /* use default */ + return; + + if ((tt->tt_normal_video == NULL) + || (tt->tt_goto_rc == NULL) + || (tt->tt_cls == NULL) + || (tt->tt_del_eol == NULL) + || (tt->tt_smart_puts == NULL) + || (tt->tt_flush_output == NULL) + || (tt->tt_reset_video == NULL) + || (tt->tt_init_video == NULL) +#ifndef IBMPC_SYSTEM + || (tt->tt_set_scroll_region == NULL) + || (tt->tt_reverse_index == NULL) + || (tt->tt_reset_scroll_region == NULL) + || (tt->tt_delete_nlines == NULL) + /* Variables */ + || (tt->tt_term_cannot_scroll == NULL) + || (tt->tt_has_alt_charset == NULL) +#if 0 /* These can be NULL */ + || (tt->tt_use_blink_for_acs == NULL) + || (tt->tt_graphic_char_pairs == NULL) +#endif + || (tt->tt_screen_cols == NULL) + || (tt->tt_screen_rows == NULL) +#endif + ) + SLang_exit_error ("Terminal not powerful enough for SLsmg"); + + tt_normal_video = tt->tt_normal_video; + tt_goto_rc = tt->tt_goto_rc; + tt_cls = tt->tt_cls; + tt_del_eol = tt->tt_del_eol; + tt_smart_puts = tt->tt_smart_puts; + tt_flush_output = tt->tt_flush_output; + tt_reset_video = tt->tt_reset_video; + tt_init_video = tt->tt_init_video; + +#ifndef IBMPC_SYSTEM + tt_set_scroll_region = tt->tt_set_scroll_region; + tt_reverse_index = tt->tt_reverse_index; + tt_reset_scroll_region = tt->tt_reset_scroll_region; + tt_delete_nlines = tt->tt_delete_nlines; + + tt_Term_Cannot_Scroll = tt->tt_term_cannot_scroll; + tt_Has_Alt_Charset = tt->tt_has_alt_charset; + tt_Use_Blink_For_ACS = tt->tt_use_blink_for_acs; + tt_Graphics_Char_Pairs = tt->tt_graphic_char_pairs; +#endif + + tt_Screen_Cols = tt->tt_screen_cols; + tt_Screen_Rows = tt->tt_screen_rows; +} + diff --git a/slang/sltermin.c b/slang/sltermin.c index 94119fd17..3497eeb36 100644 --- a/slang/sltermin.c +++ b/slang/sltermin.c @@ -2,28 +2,23 @@ * the slang SLtt interface. */ -/* Copyright (c) 1992, 1995 John E. Davis - * All rights reserved. - * +/* Copyright (c) 1992, 1999, 2001, 2002 John E. Davis + * This file is part of the S-Lang library. + * * You may distribute under the terms of either the GNU General Public * License or the Perl Artistic License. */ -#include "config.h" +#include "slinclud.h" -#include -#ifdef HAVE_STDLIB_H -# include -#endif - -#ifndef USE_SETUPTERM +#include "slang.h" #include "_slang.h" /* * The majority of the comments found in the file were taken from the * term(4) man page on an SGI. */ - + /* Short integers are stored in two 8-bit bytes. The first byte contains * the least significant 8 bits of the value, and the second byte contains * the most significant 8 bits. (Thus, the value represented is @@ -52,7 +47,7 @@ static int make_integer (unsigned char *buf) * tic, and read by the routine setupterm [see curses(3X).] The file is * divided into six parts in the following order: the header, terminal * names, boolean flags, numbers, strings, and string table. - * + * * The header section begins the file. This section contains six short * integers in the format described below. These integers are (1) the magic * number (octal 0432); (2) the size, in bytes, of the names section; (3) @@ -64,11 +59,11 @@ static int make_integer (unsigned char *buf) #define MAGIC 0432 -/* In this structure, all char * fields are malloced EXCEPT if the +/* In this structure, all char * fields are malloced EXCEPT if the * structure is SLTERMCAP. In that case, only terminal_names is malloced * and the other fields are pointers into it. */ -typedef struct +struct _SLterminfo_Type { #define SLTERMINFO 1 #define SLTERMCAP 2 @@ -76,34 +71,43 @@ typedef struct unsigned int name_section_size; char *terminal_names; - + unsigned int boolean_section_size; unsigned char *boolean_flags; - + unsigned int num_numbers; unsigned char *numbers; - + unsigned int num_string_offsets; unsigned char *string_offsets; - + unsigned int string_table_size; char *string_table; - -} Terminfo_Type; -static char *tcap_getstr (char *, Terminfo_Type *); -static int tcap_getnum (char *, Terminfo_Type *); -static int tcap_getflag (char *, Terminfo_Type *); -static int tcap_getent (char *, Terminfo_Type *); +}; -static FILE *open_terminfo (char *file, Terminfo_Type *h) +static char *tcap_getstr (char *, SLterminfo_Type *); +static int tcap_getnum (char *, SLterminfo_Type *); +static int tcap_getflag (char *, SLterminfo_Type *); +static int tcap_getent (char *, SLterminfo_Type *); + +static FILE *open_terminfo (char *file, SLterminfo_Type *h) { FILE *fp; unsigned char buf[12]; - + + /* Alan Cox reported a security problem here if the application using the + * library is setuid. So, I need to make sure open the file as a normal + * user. Unfortunately, there does not appear to be a portable way of + * doing this, so I am going to use 'setfsgid' and 'setfsuid', which + * are not portable. + * + * I will also look into the use of setreuid, seteuid and setregid, setegid. + * FIXME: Priority=medium + */ fp = fopen (file, "rb"); if (fp == NULL) return NULL; - + if ((12 == fread ((char *) buf, 1, 12, fp) && (MAGIC == make_integer (buf)))) { h->name_section_size = make_integer (buf + 2); @@ -112,15 +116,15 @@ static FILE *open_terminfo (char *file, Terminfo_Type *h) h->num_string_offsets = make_integer (buf + 8); h->string_table_size = make_integer (buf + 10); } - else + else { fclose (fp); fp = NULL; } return fp; } - -/* + +/* * The terminal names section comes next. It contains the first line of the * terminfo description, listing the various names for the terminal, * separated by the bar ( | ) character (see term(5)). The section is @@ -131,17 +135,17 @@ static FILE *open_terminfo (char *file, Terminfo_Type *h) static unsigned char *read_terminfo_section (FILE *fp, unsigned int size) { char *s; - - if (NULL == (s = (char *) SLMALLOC (size))) return NULL; + + if (NULL == (s = (char *) SLmalloc (size))) return NULL; if (size != fread (s, 1, size, fp)) { - SLFREE (s); + SLfree (s); return NULL; } return (unsigned char *) s; } -static char *read_terminal_names (FILE *fp, Terminfo_Type *t) +static char *read_terminal_names (FILE *fp, SLterminfo_Type *t) { return t->terminal_names = (char *) read_terminfo_section (fp, t->name_section_size); } @@ -153,34 +157,31 @@ static char *read_terminal_names (FILE *fp, Terminfo_Type *t) * . */ -static unsigned char *read_boolean_flags (FILE *fp, Terminfo_Type *t) +static unsigned char *read_boolean_flags (FILE *fp, SLterminfo_Type *t) { /* Between the boolean section and the number section, a null byte is * inserted, if necessary, to ensure that the number section begins on an * even byte offset. All short integers are aligned on a short word * boundary. */ - + unsigned int size = (t->name_section_size + t->boolean_section_size) % 2; size += t->boolean_section_size; - + return t->boolean_flags = read_terminfo_section (fp, size); } - - -/* +/* * The numbers section is similar to the boolean flags section. Each * capability takes up two bytes, and is stored as a short integer. If the * value represented is -1 or -2, the capability is taken to be missing. */ -static unsigned char *read_numbers (FILE *fp, Terminfo_Type *t) +static unsigned char *read_numbers (FILE *fp, SLterminfo_Type *t) { return t->numbers = read_terminfo_section (fp, 2 * t->num_numbers); } - /* The strings section is also similar. Each capability is stored as a * short integer, in the format above. A value of -1 or -2 means the * capability is missing. Otherwise, the value is taken as an offset from @@ -190,23 +191,21 @@ static unsigned char *read_numbers (FILE *fp, Terminfo_Type *t) * (%x) are stored intact in uninterpreted form. */ -static unsigned char *read_string_offsets (FILE *fp, Terminfo_Type *t) +static unsigned char *read_string_offsets (FILE *fp, SLterminfo_Type *t) { return t->string_offsets = (unsigned char *) read_terminfo_section (fp, 2 * t->num_string_offsets); } - /* The final section is the string table. It contains all the values of * string capabilities referenced in the string section. Each string is * null terminated. */ -static char *read_string_table (FILE *fp, Terminfo_Type *t) +static char *read_string_table (FILE *fp, SLterminfo_Type *t) { return t->string_table = (char *) read_terminfo_section (fp, t->string_table_size); } - /* * Compiled terminfo(4) descriptions are placed under the directory * /usr/share/lib/terminfo. In order to avoid a linear search of a huge @@ -217,39 +216,44 @@ static char *read_string_table (FILE *fp, Terminfo_Type *t) * are implemented by multiple links to the same compiled file. */ -#define MAX_TI_DIRS 7 -static char *Terminfo_Dirs [MAX_TI_DIRS] = +static char *Terminfo_Dirs [] = { - NULL, + NULL, /* $HOME/.terminfo */ + NULL, /* $TERMINFO */ + "/usr/share/terminfo", "/usr/lib/terminfo", "/usr/share/lib/terminfo", + "/etc/terminfo", "/usr/local/lib/terminfo", - "/lib/terminfo", - "/usr/local/share/terminfo", - "/usr/share/terminfo" +#ifdef MISC_TERMINFO_DIRS + MISC_TERMINFO_DIRS, +#endif + "" }; -char *SLtt_tigetent (char *term) +SLterminfo_Type *_SLtt_tigetent (char *term) { - char *tidir; + char *tidir; int i; FILE *fp = NULL; - char *file; - Terminfo_Type *ti; + char file[1024]; + static char home_ti [1024]; + char *home; + SLterminfo_Type *ti; if ( - (term == NULL) + (term == NULL) #ifdef SLANG_UNTIC && (SLang_Untic_Terminfo_File == NULL) #endif ) return NULL; - - if (NULL == (ti = (Terminfo_Type *) SLMALLOC (sizeof (Terminfo_Type)))) + + if (NULL == (ti = (SLterminfo_Type *) SLmalloc (sizeof (SLterminfo_Type)))) { return NULL; } - + #ifdef SLANG_UNTIC if (SLang_Untic_Terminfo_File != NULL) { @@ -259,31 +263,41 @@ char *SLtt_tigetent (char *term) else #endif /* If we are on a termcap based system, use termcap */ - if (0 == tcap_getent (term, ti)) return (char *) ti; - - Terminfo_Dirs[0] = getenv ("TERMINFO"); + if (0 == tcap_getent (term, ti)) return ti; + + if (NULL != (home = getenv ("HOME"))) + { + strncpy (home_ti, home, sizeof (home_ti) - 11); + home_ti [sizeof(home_ti) - 11] = 0; + strcat (home_ti, "/.terminfo"); + Terminfo_Dirs [0] = home_ti; + } + + Terminfo_Dirs[1] = getenv ("TERMINFO"); i = 0; - while (i < MAX_TI_DIRS) + while (1) { tidir = Terminfo_Dirs[i]; if (tidir != NULL) { - file = SLMALLOC (strlen (tidir) + 3 + strlen (term) + 1); - if (!file) - continue; - sprintf (file, "%s/%c/%s", tidir, *term, term); - fp = open_terminfo (file, ti); - SLFREE (file); - if (fp) - break; + if (*tidir == 0) + break; /* last one */ + + if (sizeof (file) > strlen (tidir) + 2 + strlen (term)) + { + sprintf (file, "%s/%c/%s", tidir, *term, term); + if (NULL != (fp = open_terminfo (file, ti))) + break; + } } i++; } + #ifdef SLANG_UNTIC fp_open_label: #endif - - if (fp != NULL) + + if (fp != NULL) { if (NULL != read_terminal_names (fp, ti)) { @@ -298,20 +312,20 @@ char *SLtt_tigetent (char *term) /* success */ fclose (fp); ti->flags = SLTERMINFO; - return (char *) ti; + return ti; } - SLFREE (ti->string_offsets); + SLfree ((char *)ti->string_offsets); } - SLFREE (ti->numbers); + SLfree ((char *)ti->numbers); } - SLFREE (ti->boolean_flags); + SLfree ((char *)ti->boolean_flags); } - SLFREE (ti->terminal_names); + SLfree ((char *)ti->terminal_names); } fclose (fp); } - - SLFREE (ti); + + SLfree ((char *)ti); return NULL; } @@ -321,7 +335,7 @@ char *SLtt_tigetent (char *term) # define UNTIC_COMMENT(x) #endif -typedef const struct +typedef struct { char name[3]; int offset; @@ -334,91 +348,428 @@ Tgetstr_Map_Type; /* I need to add: K1-5, %0-5(not important), @8, &8... */ static Tgetstr_Map_Type Tgetstr_Map [] = { - {"@7", 164 UNTIC_COMMENT("KEY End")}, - {"AB", 360 UNTIC_COMMENT("set a color background")}, - {"AF", 359 UNTIC_COMMENT("set a color foreground")}, + {"!1", 212 UNTIC_COMMENT("shifted key")}, + {"!2", 213 UNTIC_COMMENT("shifted key")}, + {"!3", 214 UNTIC_COMMENT("shifted key")}, + {"#1", 198 UNTIC_COMMENT("shifted key")}, + {"#2", 199 UNTIC_COMMENT("Key S-Home")}, + {"#3", 200 UNTIC_COMMENT("Key S-Insert")}, + {"#4", 201 UNTIC_COMMENT("Key S-Left")}, + {"%0", 177 UNTIC_COMMENT("redo key")}, + {"%1", 168 UNTIC_COMMENT("help key")}, + {"%2", 169 UNTIC_COMMENT("mark key")}, + {"%3", 170 UNTIC_COMMENT("message key")}, + {"%4", 171 UNTIC_COMMENT("move key")}, + {"%5", 172 UNTIC_COMMENT("next key")}, + {"%6", 173 UNTIC_COMMENT("open key")}, + {"%7", 174 UNTIC_COMMENT("options key")}, + {"%8", 175 UNTIC_COMMENT("previous key")}, + {"%9", 176 UNTIC_COMMENT("print key")}, + {"%a", 202 UNTIC_COMMENT("shifted key")}, + {"%b", 203 UNTIC_COMMENT("shifted key")}, + {"%c", 204 UNTIC_COMMENT("Key S-Next")}, + {"%d", 205 UNTIC_COMMENT("shifted key")}, + {"%e", 206 UNTIC_COMMENT("Key S-Previous")}, + {"%f", 207 UNTIC_COMMENT("shifted key")}, + {"%g", 208 UNTIC_COMMENT("shifted key")}, + {"%h", 209 UNTIC_COMMENT("shifted key")}, + {"%i", 210 UNTIC_COMMENT("Key S-Right")}, + {"%j", 211 UNTIC_COMMENT("shifted key")}, + {"&0", 187 UNTIC_COMMENT("shifted key")}, + {"&1", 178 UNTIC_COMMENT("reference key")}, + {"&2", 179 UNTIC_COMMENT("refresh key")}, + {"&3", 180 UNTIC_COMMENT("replace key")}, + {"&4", 181 UNTIC_COMMENT("restart key")}, + {"&5", 182 UNTIC_COMMENT("resume key")}, + {"&6", 183 UNTIC_COMMENT("save key")}, + {"&7", 184 UNTIC_COMMENT("suspend key")}, + {"&8", 185 UNTIC_COMMENT("undo key")}, + {"&9", 186 UNTIC_COMMENT("shifted key")}, + {"*0", 197 UNTIC_COMMENT("shifted key")}, + {"*1", 188 UNTIC_COMMENT("shifted key")}, + {"*2", 189 UNTIC_COMMENT("shifted key")}, + {"*3", 190 UNTIC_COMMENT("shifted key")}, + {"*4", 191 UNTIC_COMMENT("Key S-Delete")}, + {"*5", 192 UNTIC_COMMENT("shifted key")}, + {"*6", 193 UNTIC_COMMENT("select key")}, + {"*7", 194 UNTIC_COMMENT("Key S-End")}, + {"*8", 195 UNTIC_COMMENT("shifted key")}, + {"*9", 196 UNTIC_COMMENT("shifted key")}, + {"@0", 167 UNTIC_COMMENT("find key")}, + {"@1", 158 UNTIC_COMMENT("begin key")}, + {"@2", 159 UNTIC_COMMENT("cancel key")}, + {"@3", 160 UNTIC_COMMENT("close key")}, + {"@4", 161 UNTIC_COMMENT("command key")}, + {"@5", 162 UNTIC_COMMENT("copy key")}, + {"@6", 163 UNTIC_COMMENT("create key")}, + {"@7", 164 UNTIC_COMMENT("Key End")}, + {"@8", 165 UNTIC_COMMENT("enter/send key")}, + {"@9", 166 UNTIC_COMMENT("exit key")}, + {"AB", 360 UNTIC_COMMENT("set ANSI color background")}, + {"AF", 359 UNTIC_COMMENT("set ANSI color foreground")}, {"AL", 110 UNTIC_COMMENT("parm_insert_line")}, + {"CC", 9 UNTIC_COMMENT("terminal settable cmd character in prototype !?")}, + {"CM", 15 UNTIC_COMMENT("memory relative cursor addressing")}, + {"CW", 277 UNTIC_COMMENT("define a window #1 from #2, #3 to #4, #5")}, + {"DC", 105 UNTIC_COMMENT("delete #1 chars")}, + {"DI", 280 UNTIC_COMMENT("dial number #1")}, + {"DK", 275 UNTIC_COMMENT("display clock at (#1,#2)")}, {"DL", 106 UNTIC_COMMENT("parm_delete_line")}, + {"DO", 107 UNTIC_COMMENT("down #1 lines")}, + {"F1", 216 UNTIC_COMMENT("key_f11")}, + {"F2", 217 UNTIC_COMMENT("key_f12")}, + {"F3", 218 UNTIC_COMMENT("key_f13")}, + {"F4", 219 UNTIC_COMMENT("key_f14")}, + {"F5", 220 UNTIC_COMMENT("key_f15")}, + {"F6", 221 UNTIC_COMMENT("key_f16")}, + {"F7", 222 UNTIC_COMMENT("key_f17")}, + {"F8", 223 UNTIC_COMMENT("key_f18")}, + {"F9", 224 UNTIC_COMMENT("key_f19")}, + {"FA", 225 UNTIC_COMMENT("key_f20")}, + {"FB", 226 UNTIC_COMMENT("F21 function key")}, + {"FC", 227 UNTIC_COMMENT("F22 function key")}, + {"FD", 228 UNTIC_COMMENT("F23 function key")}, + {"FE", 229 UNTIC_COMMENT("F24 function key")}, + {"FF", 230 UNTIC_COMMENT("F25 function key")}, + {"FG", 231 UNTIC_COMMENT("F26 function key")}, + {"FH", 232 UNTIC_COMMENT("F27 function key")}, + {"FI", 233 UNTIC_COMMENT("F28 function key")}, + {"FJ", 234 UNTIC_COMMENT("F29 function key")}, + {"FK", 235 UNTIC_COMMENT("F30 function key")}, + {"FL", 236 UNTIC_COMMENT("F31 function key")}, + {"FM", 237 UNTIC_COMMENT("F32 function key")}, + {"FN", 238 UNTIC_COMMENT("F33 function key")}, + {"FO", 239 UNTIC_COMMENT("F34 function key")}, + {"FP", 240 UNTIC_COMMENT("F35 function key")}, + {"FQ", 241 UNTIC_COMMENT("F36 function key")}, + {"FR", 242 UNTIC_COMMENT("F37 function key")}, + {"FS", 243 UNTIC_COMMENT("F38 function key")}, + {"FT", 244 UNTIC_COMMENT("F39 function key")}, + {"FU", 245 UNTIC_COMMENT("F40 function key")}, + {"FV", 246 UNTIC_COMMENT("F41 function key")}, + {"FW", 247 UNTIC_COMMENT("F42 function key")}, + {"FX", 248 UNTIC_COMMENT("F43 function key")}, + {"FY", 249 UNTIC_COMMENT("F44 function key")}, + {"FZ", 250 UNTIC_COMMENT("F45 function key")}, + {"Fa", 251 UNTIC_COMMENT("F46 function key")}, + {"Fb", 252 UNTIC_COMMENT("F47 function key")}, + {"Fc", 253 UNTIC_COMMENT("F48 function key")}, + {"Fd", 254 UNTIC_COMMENT("F49 function key")}, + {"Fe", 255 UNTIC_COMMENT("F50 function key")}, + {"Ff", 256 UNTIC_COMMENT("F51 function key")}, + {"Fg", 257 UNTIC_COMMENT("F52 function key")}, + {"Fh", 258 UNTIC_COMMENT("F53 function key")}, + {"Fi", 259 UNTIC_COMMENT("F54 function key")}, + {"Fj", 260 UNTIC_COMMENT("F55 function key")}, + {"Fk", 261 UNTIC_COMMENT("F56 function key")}, + {"Fl", 262 UNTIC_COMMENT("F57 function key")}, + {"Fm", 263 UNTIC_COMMENT("F58 function key")}, + {"Fn", 264 UNTIC_COMMENT("F59 function key")}, + {"Fo", 265 UNTIC_COMMENT("F60 function key")}, + {"Fp", 266 UNTIC_COMMENT("F61 function key")}, + {"Fq", 267 UNTIC_COMMENT("F62 function key")}, + {"Fr", 268 UNTIC_COMMENT("F63 function key")}, + {"G1", 400 UNTIC_COMMENT("single upper right")}, + {"G2", 398 UNTIC_COMMENT("single upper left")}, + {"G3", 399 UNTIC_COMMENT("single lower left")}, + {"G4", 401 UNTIC_COMMENT("single lower right")}, + {"GC", 408 UNTIC_COMMENT("single intersection")}, + {"GD", 405 UNTIC_COMMENT("tee pointing down")}, + {"GH", 406 UNTIC_COMMENT("single horizontal line")}, + {"GL", 403 UNTIC_COMMENT("tee pointing left")}, + {"GR", 402 UNTIC_COMMENT("tee pointing right")}, + {"GU", 404 UNTIC_COMMENT("tee pointing up")}, + {"GV", 407 UNTIC_COMMENT("single vertical line")}, + {"Gm", 358 UNTIC_COMMENT("Curses should get button events")}, + {"HU", 279 UNTIC_COMMENT("hang-up phone")}, + {"IC", 108 UNTIC_COMMENT("insert #1 chars")}, + {"Ic", 299 UNTIC_COMMENT("initialize color #1 to (#2,#3,#4)")}, + {"Ip", 300 UNTIC_COMMENT("Initialize color pair #1 to fg=(#2,#3,#4), bg=(#5,#6,#7)")}, + {"K1", 139 UNTIC_COMMENT("upper left of keypad")}, + {"K2", 141 UNTIC_COMMENT("center of keypad")}, + {"K3", 140 UNTIC_COMMENT("upper right of keypad")}, + {"K4", 142 UNTIC_COMMENT("lower left of keypad")}, + {"K5", 143 UNTIC_COMMENT("lower right of keypad")}, + {"Km", 355 UNTIC_COMMENT("Mouse event has occurred")}, + {"LE", 111 UNTIC_COMMENT("move #1 chars to the left")}, + {"LF", 157 UNTIC_COMMENT("turn off soft labels")}, + {"LO", 156 UNTIC_COMMENT("turn on soft labels")}, + {"Lf", 273 UNTIC_COMMENT("label format")}, + {"MC", 270 UNTIC_COMMENT("clear right and left soft margins")}, + {"ML", 271 UNTIC_COMMENT("set left soft margin")}, + {"ML", 368 UNTIC_COMMENT("Set both left and right margins to #1, #2")}, + {"MR", 272 UNTIC_COMMENT("set right soft margin")}, + {"MT", 369 UNTIC_COMMENT("Sets both top and bottom margins to #1, #2")}, + {"Mi", 356 UNTIC_COMMENT("Mouse status information")}, + {"PA", 285 UNTIC_COMMENT("pause for 2-3 seconds")}, + {"PU", 283 UNTIC_COMMENT("select pulse dialling")}, + {"QD", 281 UNTIC_COMMENT("dial number #1 without checking")}, + {"RA", 152 UNTIC_COMMENT("turn off automatic margins")}, + {"RC", 276 UNTIC_COMMENT("remove clock")}, + {"RF", 215 UNTIC_COMMENT("send next input char (for ptys)")}, {"RI", 112 UNTIC_COMMENT("parm_right_cursor")}, - {"Sf", 302 UNTIC_COMMENT("set foreground (color)")}, + {"RQ", 357 UNTIC_COMMENT("Request mouse position")}, + {"RX", 150 UNTIC_COMMENT("turn off xon/xoff handshaking")}, + {"S1", 378 UNTIC_COMMENT("Display PC character")}, + {"S2", 379 UNTIC_COMMENT("Enter PC character display mode")}, + {"S3", 380 UNTIC_COMMENT("Exit PC character display mode")}, + {"S4", 381 UNTIC_COMMENT("Enter PC scancode mode")}, + {"S5", 382 UNTIC_COMMENT("Exit PC scancode mode")}, + {"S6", 383 UNTIC_COMMENT("PC terminal options")}, + {"S7", 384 UNTIC_COMMENT("Escape for scancode emulation")}, + {"S8", 385 UNTIC_COMMENT("Alternate escape for scancode emulation")}, + {"SA", 151 UNTIC_COMMENT("turn on automatic margins")}, + {"SC", 274 UNTIC_COMMENT("set clock, #1 hrs #2 mins #3 secs")}, + {"SF", 109 UNTIC_COMMENT("scroll forward #1 lines")}, + {"SR", 113 UNTIC_COMMENT("scroll back #1 lines")}, + {"SX", 149 UNTIC_COMMENT("turn on xon/xoff handshaking")}, {"Sb", 303 UNTIC_COMMENT("set background (color)")}, + {"Sf", 302 UNTIC_COMMENT("set foreground (color)")}, + {"TO", 282 UNTIC_COMMENT("select touch tone dialing")}, + {"UP", 114 UNTIC_COMMENT("up #1 lines")}, + {"WA", 286 UNTIC_COMMENT("wait for dial-tone")}, + {"WG", 278 UNTIC_COMMENT("go to window #1")}, + {"XF", 154 UNTIC_COMMENT("XOFF character")}, + {"XN", 153 UNTIC_COMMENT("XON character")}, + {"Xh", 386 UNTIC_COMMENT("Enter horizontal highlight mode")}, + {"Xl", 387 UNTIC_COMMENT("Enter left highlight mode")}, + {"Xo", 388 UNTIC_COMMENT("Enter low highlight mode")}, + {"Xr", 389 UNTIC_COMMENT("Enter right highlight mode")}, + {"Xt", 390 UNTIC_COMMENT("Enter top highlight mode")}, + {"Xv", 391 UNTIC_COMMENT("Enter vertical highlight mode")}, + {"Xy", 370 UNTIC_COMMENT("Repeat bit image cell #1 #2 times")}, + {"YZ", 377 UNTIC_COMMENT("Set page length to #1 lines")}, + {"Yv", 372 UNTIC_COMMENT("Move to beginning of same row")}, + {"Yw", 373 UNTIC_COMMENT("Give name for color #1")}, + {"Yx", 374 UNTIC_COMMENT("Define rectangualar bit image region")}, + {"Yy", 375 UNTIC_COMMENT("End a bit-image region")}, + {"Yz", 376 UNTIC_COMMENT("Change to ribbon color #1")}, + {"ZA", 304 UNTIC_COMMENT("Change number of characters per inch")}, + {"ZB", 305 UNTIC_COMMENT("Change number of lines per inch")}, + {"ZC", 306 UNTIC_COMMENT("Change horizontal resolution")}, + {"ZD", 307 UNTIC_COMMENT("Change vertical resolution")}, + {"ZE", 308 UNTIC_COMMENT("Define a character")}, + {"ZF", 309 UNTIC_COMMENT("Enter double-wide mode")}, + {"ZG", 310 UNTIC_COMMENT("Enter draft-quality mode")}, + {"ZH", 311 UNTIC_COMMENT("Enter italic mode")}, + {"ZI", 312 UNTIC_COMMENT("Start leftward carriage motion")}, + {"ZJ", 313 UNTIC_COMMENT("Start micro-motion mode")}, + {"ZK", 314 UNTIC_COMMENT("Enter NLQ mode")}, + {"ZL", 315 UNTIC_COMMENT("Wnter normal-quality mode")}, + {"ZM", 316 UNTIC_COMMENT("Enter shadow-print mode")}, + {"ZN", 317 UNTIC_COMMENT("Enter subscript mode")}, + {"ZO", 318 UNTIC_COMMENT("Enter superscript mode")}, + {"ZP", 319 UNTIC_COMMENT("Start upward carriage motion")}, + {"ZQ", 320 UNTIC_COMMENT("End double-wide mode")}, + {"ZR", 321 UNTIC_COMMENT("End italic mode")}, + {"ZS", 322 UNTIC_COMMENT("End left-motion mode")}, + {"ZT", 323 UNTIC_COMMENT("End micro-motion mode")}, + {"ZU", 324 UNTIC_COMMENT("End shadow-print mode")}, + {"ZV", 325 UNTIC_COMMENT("End subscript mode")}, + {"ZW", 326 UNTIC_COMMENT("End superscript mode")}, + {"ZX", 327 UNTIC_COMMENT("End reverse character motion")}, + {"ZY", 328 UNTIC_COMMENT("Like column_address in micro mode")}, + {"ZZ", 329 UNTIC_COMMENT("Like cursor_down in micro mode")}, + {"Za", 330 UNTIC_COMMENT("Like cursor_left in micro mode")}, + {"Zb", 331 UNTIC_COMMENT("Like cursor_right in micro mode")}, + {"Zc", 332 UNTIC_COMMENT("Like row_address in micro mode")}, + {"Zd", 333 UNTIC_COMMENT("Like cursor_up in micro mode")}, + {"Ze", 334 UNTIC_COMMENT("Match software bits to print-head pins")}, + {"Zf", 335 UNTIC_COMMENT("Like parm_down_cursor in micro mode")}, + {"Zg", 336 UNTIC_COMMENT("Like parm_left_cursor in micro mode")}, + {"Zh", 337 UNTIC_COMMENT("Like parm_right_cursor in micro mode")}, + {"Zi", 338 UNTIC_COMMENT("Like parm_up_cursor in micro mode")}, + {"Zj", 339 UNTIC_COMMENT("Select character set")}, + {"Zk", 340 UNTIC_COMMENT("Set bottom margin at current line")}, + {"Zl", 341 UNTIC_COMMENT("Set bottom margin at line #1 or #2 lines from bottom")}, + {"Zm", 342 UNTIC_COMMENT("Set left (right) margin at column #1 (#2)")}, + {"Zn", 343 UNTIC_COMMENT("Set right margin at column #1")}, + {"Zo", 344 UNTIC_COMMENT("Set top margin at current line")}, + {"Zp", 345 UNTIC_COMMENT("Set top (bottom) margin at row #1 (#2)")}, + {"Zq", 346 UNTIC_COMMENT("Start printing bit image braphics")}, + {"Zr", 347 UNTIC_COMMENT("Start character set definition")}, + {"Zs", 348 UNTIC_COMMENT("Stop printing bit image graphics")}, + {"Zt", 349 UNTIC_COMMENT("End definition of character aet")}, + {"Zu", 350 UNTIC_COMMENT("List of subscriptable characters")}, + {"Zv", 351 UNTIC_COMMENT("List of superscriptable characters")}, + {"Zw", 352 UNTIC_COMMENT("Printing any of these chars causes CR")}, + {"Zx", 353 UNTIC_COMMENT("No motion for subsequent character")}, + {"Zy", 354 UNTIC_COMMENT("List of character set names")}, + {"Zz", 371 UNTIC_COMMENT("Move to next row of the bit image")}, {"ac", 146 UNTIC_COMMENT("acs_chars")}, {"ae", 38 UNTIC_COMMENT("exit_alt_charset_mode")}, + {"al", 53 UNTIC_COMMENT("insert line")}, {"as", 25 UNTIC_COMMENT("enter_alt_charset_mode")}, + {"bc", 395 UNTIC_COMMENT("move left, if not ^H")}, + {"bl", 1 UNTIC_COMMENT("audible signal (bell)")}, + {"bt", 0 UNTIC_COMMENT("back tab")}, + {"bx", 411 UNTIC_COMMENT("box chars primary set")}, + {"cb", 269 UNTIC_COMMENT("Clear to beginning of line")}, + {"cd", 7 UNTIC_COMMENT("clear to end of screen")}, {"ce", 6 UNTIC_COMMENT("clr_eol")}, - {"cl", 5 UNTIC_COMMENT("clear_screen")}, - {"cm", 10 UNTIC_COMMENT("cursor_address")}, - {"cs", 3 UNTIC_COMMENT("change_scroll_region")}, - {"dc", 21 UNTIC_COMMENT("delete_character")}, - {"ds", 23 UNTIC_COMMENT("disable status line")}, - {"eA", 155 UNTIC_COMMENT("enable alt char set")}, - {"ei", 42 UNTIC_COMMENT("exit_insert_mode")}, - {"fs", 47 UNTIC_COMMENT("return from status line")}, - {"im", 31 UNTIC_COMMENT("enter_insert_mode")}, - {"k0", 65 UNTIC_COMMENT("key_f0")}, - {"k1", 66 UNTIC_COMMENT("key_f1")}, - {"k2", 68 UNTIC_COMMENT("key_f2")}, - {"k3", 69 UNTIC_COMMENT("key_f3")}, - {"k4", 70 UNTIC_COMMENT("key_f4")}, - {"k5", 71 UNTIC_COMMENT("key_f5")}, - {"k6", 72 UNTIC_COMMENT("key_f6")}, - {"k7", 73 UNTIC_COMMENT("key_f7")}, - {"k8", 74 UNTIC_COMMENT("key_f8")}, - {"k9", 75 UNTIC_COMMENT("key_f9")}, - {"kA", 78 UNTIC_COMMENT("key_il")}, - {"kC", 57 UNTIC_COMMENT("key_clear")}, - {"kD", 59 UNTIC_COMMENT("key_dc")}, - {"kE", 63 UNTIC_COMMENT("key_eol,")}, - {"kF", 84 UNTIC_COMMENT("key_sf")}, - {"kH", 80 UNTIC_COMMENT("key_ll")}, - {"kI", 77 UNTIC_COMMENT("key_ic")}, - {"kL", 60 UNTIC_COMMENT("key_dl")}, - {"kM", 62 UNTIC_COMMENT("key_eic,")}, - {"kN", 81 UNTIC_COMMENT("key_npage")}, - {"kP", 82 UNTIC_COMMENT("key_ppage")}, - {"kR", 85 UNTIC_COMMENT("key_sr")}, - {"kS", 64 UNTIC_COMMENT("key_eos,")}, - {"kT", 86 UNTIC_COMMENT("key_stab")}, - {"ka", 56 UNTIC_COMMENT("key_catab")}, - {"k;", 67 UNTIC_COMMENT("key_f10")}, - {"kb", 55 UNTIC_COMMENT("key_backspace")}, - {"kd", 61 UNTIC_COMMENT("key_down")}, - {"ke", 88 UNTIC_COMMENT("End keypad transmit mode")}, - {"kh", 76 UNTIC_COMMENT("key_home")}, - {"kl", 79 UNTIC_COMMENT("key_left")}, - {"kr", 83 UNTIC_COMMENT("key_right")}, - {"ks", 89 UNTIC_COMMENT("Start keypad transmit mode")}, - {"kt", 58 UNTIC_COMMENT("key_ctab")}, - {"ku", 87 UNTIC_COMMENT("key_up")}, - {"mb", 26 UNTIC_COMMENT("enter_blink_mode")}, - {"md", 27 UNTIC_COMMENT("enter_bold_mode")}, - {"me", 39 UNTIC_COMMENT("exit_attribute_mode")}, - {"mr", 34 UNTIC_COMMENT("enter_reverse_mode")}, - {"op", 297 UNTIC_COMMENT("orig_pair (color)")}, - {"pf", 119 UNTIC_COMMENT("turn OFF printer")}, - {"po", 120 UNTIC_COMMENT("turn ON printer")}, - {"se", 43 UNTIC_COMMENT("exit_standout_mode")}, - {"so", 35 UNTIC_COMMENT("enter_standout_mode")}, - {"sr", 130 UNTIC_COMMENT("scroll_reverse")}, - {"te", 40 UNTIC_COMMENT("end cursor addressing")}, - {"ti", 28 UNTIC_COMMENT("begin cursor addressing")}, - {"ts", 135 UNTIC_COMMENT("goto to status line")}, - {"up", 19 UNTIC_COMMENT("cursor_up")}, - {"us", 36 UNTIC_COMMENT("enter_underline_mode")}, - {"vb", 45 UNTIC_COMMENT("flash_screen")}, - {"ve", 16 UNTIC_COMMENT("make cursor very visible")}, - {"vi", 13 UNTIC_COMMENT("make cursor invisible")}, - {"vs", 20 UNTIC_COMMENT("make cursor very visible")}, - {"", 0 UNTIC_COMMENT(NULL)} + {"ch", 8 UNTIC_COMMENT("horizontal position #1, absolute")}, + {"ci", 363 UNTIC_COMMENT("Init sequence for multiple codesets")}, + {"cl", 5 UNTIC_COMMENT("clear screen and home cursor")}, + {"cm", 10 UNTIC_COMMENT("move to row #1 columns #2")}, + {"cr", 2 UNTIC_COMMENT("carriage return")}, + {"cs", 3 UNTIC_COMMENT("change region to line #1 to line #2")}, + {"ct", 4 UNTIC_COMMENT("clear all tab stops")}, + {"cv", 127 UNTIC_COMMENT("vertical position #1 absolute")}, + {"dc", 21 UNTIC_COMMENT("delete character")}, + {"dl", 22 UNTIC_COMMENT("delete line")}, + {"dm", 29 UNTIC_COMMENT("enter delete mode")}, + {"do", 11 UNTIC_COMMENT("down one line")}, + {"ds", 23 UNTIC_COMMENT("disable status line")}, + {"dv", 362 UNTIC_COMMENT("Indicate language/codeset support")}, + {"eA", 155 UNTIC_COMMENT("enable alternate char set")}, + {"ec", 37 UNTIC_COMMENT("erase #1 characters")}, + {"ed", 41 UNTIC_COMMENT("end delete mode")}, + {"ei", 42 UNTIC_COMMENT("exit insert mode")}, + {"ff", 46 UNTIC_COMMENT("hardcopy terminal page eject")}, + {"fh", 284 UNTIC_COMMENT("flash switch hook")}, + {"fs", 47 UNTIC_COMMENT("return from status line")}, + {"hd", 24 UNTIC_COMMENT("half a line down")}, + {"ho", 12 UNTIC_COMMENT("home cursor (if no cup)")}, + {"hu", 137 UNTIC_COMMENT("half a line up")}, + {"i1", 48 UNTIC_COMMENT("initialization string")}, + {"i2", 392 UNTIC_COMMENT("secondary initialization string")}, + {"i3", 50 UNTIC_COMMENT("initialization string")}, + {"iP", 138 UNTIC_COMMENT("path name of program for initialization")}, + {"ic", 52 UNTIC_COMMENT("insert character")}, + {"if", 51 UNTIC_COMMENT("name of initialization file")}, + {"im", 31 UNTIC_COMMENT("enter insert mode")}, + {"ip", 54 UNTIC_COMMENT("insert padding after inserted character")}, + {"is", 49 UNTIC_COMMENT("initialization string")}, + {"k0", 65 UNTIC_COMMENT("F0 function key")}, + {"k1", 66 UNTIC_COMMENT("F1 function key")}, + {"k2", 68 UNTIC_COMMENT("F2 function key")}, + {"k3", 69 UNTIC_COMMENT("F3 function key")}, + {"k4", 70 UNTIC_COMMENT("F4 function key")}, + {"k5", 71 UNTIC_COMMENT("F5 function key")}, + {"k6", 72 UNTIC_COMMENT("F6 function key")}, + {"k7", 73 UNTIC_COMMENT("F7 function key")}, + {"k8", 74 UNTIC_COMMENT("F8 fucntion key")}, + {"k9", 75 UNTIC_COMMENT("F9 function key")}, + {"k;", 67 UNTIC_COMMENT("F10 function key")}, + {"kA", 78 UNTIC_COMMENT("insert-line key")}, + {"kB", 148 UNTIC_COMMENT("back-tab key")}, + {"kC", 57 UNTIC_COMMENT("clear-screen or erase key")}, + {"kD", 59 UNTIC_COMMENT("delete-character key")}, + {"kE", 63 UNTIC_COMMENT("clear-to-end-of-line key")}, + {"kF", 84 UNTIC_COMMENT("scroll-forward key")}, + {"kH", 80 UNTIC_COMMENT("last-line key")}, + {"kI", 77 UNTIC_COMMENT("insert-character key")}, + {"kL", 60 UNTIC_COMMENT("delete-line key")}, + {"kM", 62 UNTIC_COMMENT("sent by rmir or smir in insert mode")}, + {"kN", 81 UNTIC_COMMENT("next-page key")}, + {"kP", 82 UNTIC_COMMENT("prev-page key")}, + {"kR", 85 UNTIC_COMMENT("scroll-backward key")}, + {"kS", 64 UNTIC_COMMENT("clear-to-end-of-screen key")}, + {"kT", 86 UNTIC_COMMENT("set-tab key")}, + {"ka", 56 UNTIC_COMMENT("clear-all-tabs key")}, + {"kb", 55 UNTIC_COMMENT("backspace key")}, + {"kd", 61 UNTIC_COMMENT("down-arrow key")}, + {"ke", 88 UNTIC_COMMENT("leave 'keyboard_transmit' mode")}, + {"kh", 76 UNTIC_COMMENT("home key")}, + {"kl", 79 UNTIC_COMMENT("left-arrow key")}, + {"ko", 396 UNTIC_COMMENT("list of self-mapped keycaps")}, + {"kr", 83 UNTIC_COMMENT("right-arrow key")}, + {"ks", 89 UNTIC_COMMENT("enter 'keyboard_transmit' mode")}, + {"kt", 58 UNTIC_COMMENT("clear-tab key")}, + {"ku", 87 UNTIC_COMMENT("up-arrow key")}, + {"l0", 90 UNTIC_COMMENT("label on function key f0 if not f0")}, + {"l1", 91 UNTIC_COMMENT("label on function key f1 if not f1")}, + {"l2", 93 UNTIC_COMMENT("label on function key f2 if not f2")}, + {"l3", 94 UNTIC_COMMENT("label on function key f3 if not f3")}, + {"l4", 95 UNTIC_COMMENT("label on function key f4 if not f4")}, + {"l5", 96 UNTIC_COMMENT("lable on function key f5 if not f5")}, + {"l6", 97 UNTIC_COMMENT("label on function key f6 if not f6")}, + {"l7", 98 UNTIC_COMMENT("label on function key f7 if not f7")}, + {"l8", 99 UNTIC_COMMENT("label on function key f8 if not f8")}, + {"l9", 100 UNTIC_COMMENT("label on function key f9 if not f9")}, + {"la", 92 UNTIC_COMMENT("label on function key f10 if not f10")}, + {"le", 14 UNTIC_COMMENT("move left one space")}, + {"ll", 18 UNTIC_COMMENT("last line, first column (if no cup)")}, + {"ma", 397 UNTIC_COMMENT("map arrow keys rogue(1) motion keys")}, + {"mb", 26 UNTIC_COMMENT("turn on blinking")}, + {"md", 27 UNTIC_COMMENT("turn on bold (extra bright) mode")}, + {"me", 39 UNTIC_COMMENT("turn off all attributes")}, + {"mh", 30 UNTIC_COMMENT("turn on half-bright mode")}, + {"mk", 32 UNTIC_COMMENT("turn on blank mode (characters invisible)")}, + {"ml", 409 UNTIC_COMMENT("memory lock above")}, + {"mm", 102 UNTIC_COMMENT("turn on meta mode (8th-bit on)")}, + {"mo", 101 UNTIC_COMMENT("turn off meta mode")}, + {"mp", 33 UNTIC_COMMENT("turn on protected mode")}, + {"mr", 34 UNTIC_COMMENT("turn on reverse video mode")}, + {"mu", 410 UNTIC_COMMENT("memory unlock")}, + {"nd", 17 UNTIC_COMMENT("move right one space")}, + {"nl", 394 UNTIC_COMMENT("use to move down")}, + {"nw", 103 UNTIC_COMMENT("newline (behave like cr followed by lf)")}, + {"oc", 298 UNTIC_COMMENT("Set all color pairs to the original ones")}, + {"op", 297 UNTIC_COMMENT("Set default pair to its original value")}, + {"pO", 144 UNTIC_COMMENT("turn on printer for #1 bytes")}, + {"pc", 104 UNTIC_COMMENT("padding char (instead of null)")}, + {"pf", 119 UNTIC_COMMENT("turn off printer")}, + {"pk", 115 UNTIC_COMMENT("program function key #1 to type string #2")}, + {"pl", 116 UNTIC_COMMENT("program function key #1 to execute string #2")}, + {"pn", 147 UNTIC_COMMENT("program label #1 to show string #2")}, + {"po", 120 UNTIC_COMMENT("turn on printer")}, + {"ps", 118 UNTIC_COMMENT("print contents of screen")}, + {"px", 117 UNTIC_COMMENT("program function key #1 to transmit string #2")}, + {"r1", 122 UNTIC_COMMENT("reset string")}, + {"r2", 123 UNTIC_COMMENT("reset string")}, + {"r3", 124 UNTIC_COMMENT("reset string")}, + {"rP", 145 UNTIC_COMMENT("like ip but when in insert mode")}, + {"rc", 126 UNTIC_COMMENT("restore cursor to last position of sc")}, + {"rf", 125 UNTIC_COMMENT("name of reset file")}, + {"rp", 121 UNTIC_COMMENT("repeat char #1 #2 times")}, + {"rs", 393 UNTIC_COMMENT("terminal reset string")}, + {"s0", 364 UNTIC_COMMENT("Shift to code set 0 (EUC set 0, ASCII)")}, + {"s1", 365 UNTIC_COMMENT("Shift to code set 1")}, + {"s2", 366 UNTIC_COMMENT("Shift to code set 2")}, + {"s3", 367 UNTIC_COMMENT("Shift to code set 3")}, + {"sa", 131 UNTIC_COMMENT("define video attributes #1-#9 (PG9)")}, + {"sc", 128 UNTIC_COMMENT("save current cursor position")}, + {"se", 43 UNTIC_COMMENT("exit standout mode")}, + {"sf", 129 UNTIC_COMMENT("scroll text up")}, + {"so", 35 UNTIC_COMMENT("begin standout mode")}, + {"sp", 301 UNTIC_COMMENT("Set current color pair to #1")}, + {"sr", 130 UNTIC_COMMENT("scroll text down")}, + {"st", 132 UNTIC_COMMENT("set a tab in every row, current columns")}, + {"ta", 134 UNTIC_COMMENT("tab to next 8-space hardware tab stop")}, + {"te", 40 UNTIC_COMMENT("strings to end programs using cup")}, + {"ti", 28 UNTIC_COMMENT("string to start programs using cup")}, + {"ts", 135 UNTIC_COMMENT("move to status line")}, + {"u0", 287 UNTIC_COMMENT("User string #0")}, + {"u1", 288 UNTIC_COMMENT("User string #1")}, + {"u2", 289 UNTIC_COMMENT("User string #2")}, + {"u3", 290 UNTIC_COMMENT("User string #3")}, + {"u4", 291 UNTIC_COMMENT("User string #4")}, + {"u5", 292 UNTIC_COMMENT("User string #5")}, + {"u6", 293 UNTIC_COMMENT("User string #6")}, + {"u7", 294 UNTIC_COMMENT("User string #7")}, + {"u8", 295 UNTIC_COMMENT("User string #8")}, + {"u9", 296 UNTIC_COMMENT("User string #9")}, + {"uc", 136 UNTIC_COMMENT("underline char and move past it")}, + {"ue", 44 UNTIC_COMMENT("exit underline mode")}, + {"up", 19 UNTIC_COMMENT("up one line")}, + {"us", 36 UNTIC_COMMENT("begin underline mode")}, + {"vb", 45 UNTIC_COMMENT("visible bell (may not move cursor)")}, + {"ve", 16 UNTIC_COMMENT("make cursor appear normal (undo civis/cvvis)")}, + {"vi", 13 UNTIC_COMMENT("make cursor invisible")}, + {"vs", 20 UNTIC_COMMENT("make cursor very visible")}, + {"wi", 133 UNTIC_COMMENT("current window is lines #1-#2 cols #3-#4")}, + {"xl", 361 UNTIC_COMMENT("Program function key #1 to type string #2 and show string #3")}, + {"", -1 UNTIC_COMMENT(NULL)} }; -static int compute_cap_offset (char *cap, Terminfo_Type *t, Tgetstr_Map_Type *map, unsigned int max_ofs) +static int compute_cap_offset (char *cap, SLterminfo_Type *t, Tgetstr_Map_Type *map, unsigned int max_ofs) { char cha, chb; (void) t; cha = *cap++; chb = *cap; - + while (*map->name != 0) { if ((cha == *map->name) && (chb == *(map->name + 1))) @@ -431,16 +782,15 @@ static int compute_cap_offset (char *cap, Terminfo_Type *t, Tgetstr_Map_Type *ma return -1; } - -char *SLtt_tigetstr (char *cap, char **pp) +char *_SLtt_tigetstr (SLterminfo_Type *t, char *cap) { int offset; - Terminfo_Type *t; - - if ((pp == NULL) || (NULL == (t = (Terminfo_Type *) *pp))) return NULL; - + + if (t == NULL) + return NULL; + if (t->flags == SLTERMCAP) return tcap_getstr (cap, t); - + offset = compute_cap_offset (cap, t, Tgetstr_Map, t->num_string_offsets); if (offset < 0) return NULL; offset = make_integer (t->string_offsets + 2 * offset); @@ -450,21 +800,54 @@ char *SLtt_tigetstr (char *cap, char **pp) static Tgetstr_Map_Type Tgetnum_Map[] = { - {"co", 0 UNTIC_COMMENT("columns")}, - {"li", 2 UNTIC_COMMENT("lines")}, - {"Co", 13 UNTIC_COMMENT("max colors")}, - {"pa", 14 UNTIC_COMMENT("max pairs")}, - {"sg", 4 UNTIC_COMMENT("magic cookie glitch")}, - {"ws", 7 UNTIC_COMMENT("num columns in status line")}, + {"BT", 30 UNTIC_COMMENT("number of buttons on mouse")}, + {"Co", 13 UNTIC_COMMENT("maximum numbers of colors on screen")}, + {"MW", 12 UNTIC_COMMENT("maxumum number of defineable windows")}, + {"NC", 15 UNTIC_COMMENT("video attributes that can't be used with colors")}, + {"Nl", 8 UNTIC_COMMENT("number of labels on screen")}, + {"Ya", 16 UNTIC_COMMENT("numbers of bytes buffered before printing")}, + {"Yb", 17 UNTIC_COMMENT("spacing of pins vertically in pins per inch")}, + {"Yc", 18 UNTIC_COMMENT("spacing of dots horizontally in dots per inch")}, + {"Yd", 19 UNTIC_COMMENT("maximum value in micro_..._address")}, + {"Ye", 20 UNTIC_COMMENT("maximum value in parm_..._micro")}, + {"Yf", 21 UNTIC_COMMENT("character size when in micro mode")}, + {"Yg", 22 UNTIC_COMMENT("line size when in micro mode")}, + {"Yh", 23 UNTIC_COMMENT("numbers of pins in print-head")}, + {"Yi", 24 UNTIC_COMMENT("horizontal resolution in units per line")}, + {"Yj", 25 UNTIC_COMMENT("vertical resolution in units per line")}, + {"Yk", 26 UNTIC_COMMENT("horizontal resolution in units per inch")}, + {"Yl", 27 UNTIC_COMMENT("vertical resolution in units per inch")}, + {"Ym", 28 UNTIC_COMMENT("print rate in chars per second")}, + {"Yn", 29 UNTIC_COMMENT("character step size when in double wide mode")}, + {"Yo", 31 UNTIC_COMMENT("number of passed for each bit-image row")}, + {"Yp", 32 UNTIC_COMMENT("type of bit-image device")}, + {"co", 0 UNTIC_COMMENT("number of columns in aline")}, + {"dB", 36 UNTIC_COMMENT("padding required for ^H")}, + {"dC", 34 UNTIC_COMMENT("pad needed for CR")}, + {"dN", 35 UNTIC_COMMENT("pad needed for LF")}, + {"dT", 37 UNTIC_COMMENT("padding required for ^I")}, + {"it", 1 UNTIC_COMMENT("tabs initially every # spaces")}, + {"kn", 38 UNTIC_COMMENT("count of function keys")}, + {"lh", 9 UNTIC_COMMENT("rows in each label")}, + {"li", 2 UNTIC_COMMENT("number of lines on screen or page")}, + {"lm", 3 UNTIC_COMMENT("lines of memory if > line. 0 => varies")}, + {"lw", 10 UNTIC_COMMENT("columns in each label")}, + {"ma", 11 UNTIC_COMMENT("maximum combined attributes terminal can handle")}, + {"pa", 14 UNTIC_COMMENT("maximum number of color-pairs on the screen")}, + {"pb", 5 UNTIC_COMMENT("lowest baud rate where padding needed")}, + {"sg", 4 UNTIC_COMMENT("number of blank chars left by smso or rmso")}, + {"ug", 33 UNTIC_COMMENT("number of blanks left by ul")}, + {"vt", 6 UNTIC_COMMENT("virtual terminal number (CB/unix)")}, + {"ws", 7 UNTIC_COMMENT("columns in status line")}, {"", -1 UNTIC_COMMENT(NULL)} }; -int SLtt_tigetnum (char *cap, char **pp) +int _SLtt_tigetnum (SLterminfo_Type *t, char *cap) { int offset; - Terminfo_Type *t; - - if ((pp == NULL) || (NULL == (t = (Terminfo_Type *) *pp))) return -1; + + if (t == NULL) + return -1; if (t->flags == SLTERMCAP) return tcap_getnum (cap, t); @@ -475,42 +858,77 @@ int SLtt_tigetnum (char *cap, char **pp) static Tgetstr_Map_Type Tgetflag_Map[] = { - {"am", 1 UNTIC_COMMENT("auto right margin")}, - {"hs", 9 UNTIC_COMMENT("has status line")}, - {"ms", 14 UNTIC_COMMENT("move standout mode")}, - {"xs", 3 UNTIC_COMMENT("ceol standout glitch")}, - {"xn", 4 UNTIC_COMMENT("NEWLINE ignored after 80 columns")}, - {"es", 16 UNTIC_COMMENT("status line esc ok")}, + {"5i", 22 UNTIC_COMMENT("printer won't echo on screen")}, + {"HC", 23 UNTIC_COMMENT("cursor is hard to see")}, + {"MT", 40 UNTIC_COMMENT("has meta key")}, + {"ND", 26 UNTIC_COMMENT("scrolling region is non-destructive")}, + {"NL", 41 UNTIC_COMMENT("move down with \n")}, + {"NP", 25 UNTIC_COMMENT("pad character does not exist")}, + {"NR", 24 UNTIC_COMMENT("smcup does not reverse rmcup")}, + {"YA", 30 UNTIC_COMMENT("only positive motion for hpa/mhpa caps")}, + {"YB", 31 UNTIC_COMMENT("using cr turns off micro mode")}, + {"YC", 32 UNTIC_COMMENT("printer needs operator to change character set")}, + {"YD", 33 UNTIC_COMMENT("only positive motion for vpa/mvpa caps")}, + {"YE", 34 UNTIC_COMMENT("printing in last column causes cr")}, + {"YF", 35 UNTIC_COMMENT("changing character pitch changes resolution")}, + {"YG", 36 UNTIC_COMMENT("changing line pitch changes resolution")}, + {"am", 1 UNTIC_COMMENT("terminal has automatic margins")}, + {"bs", 37 UNTIC_COMMENT("uses ^H to move left")}, + {"bw", 0 UNTIC_COMMENT("cub1 wraps from column 0 to last column")}, + {"cc", 27 UNTIC_COMMENT("terminal can re-define existing colors")}, + {"da", 11 UNTIC_COMMENT("display may be retained above the screen")}, + {"db", 12 UNTIC_COMMENT("display may be retained below the screen")}, + {"eo", 5 UNTIC_COMMENT("can erase overstrikes with a blank")}, + {"es", 16 UNTIC_COMMENT("escape can be used on the status line")}, + {"gn", 6 UNTIC_COMMENT("generic line type")}, + {"hc", 7 UNTIC_COMMENT("hardcopy terminal")}, + {"hl", 29 UNTIC_COMMENT("terminal uses only HLS color notation (tektronix)")}, + {"hs", 9 UNTIC_COMMENT("has extra status line")}, + {"hz", 18 UNTIC_COMMENT("can't print ~'s (hazeltine)")}, + {"in", 10 UNTIC_COMMENT("insert mode distinguishes nulls")}, + {"km", 8 UNTIC_COMMENT("Has a meta key, sets msb high")}, + {"mi", 13 UNTIC_COMMENT("safe to move while in insert mode")}, + {"ms", 14 UNTIC_COMMENT("safe to move while in standout mode")}, + {"nc", 39 UNTIC_COMMENT("no way to go to start of line")}, + {"ns", 38 UNTIC_COMMENT("crt cannot scroll")}, + {"nx", 21 UNTIC_COMMENT("padding won't work, xon/xoff required")}, + {"os", 15 UNTIC_COMMENT("terminal can overstrike")}, + {"pt", 42 UNTIC_COMMENT("has 8-char tabs invoked with ^I")}, + {"ul", 19 UNTIC_COMMENT("underline character overstrikes")}, + {"ut", 28 UNTIC_COMMENT("screen erased with background color")}, + {"xb", 2 UNTIC_COMMENT("beehive (f1=escape, f2=ctrl C)")}, + {"xn", 4 UNTIC_COMMENT("newline ignored after 80 cols (concept)")}, + {"xo", 20 UNTIC_COMMENT("terminal uses xon/xoff handshaking")}, + {"xr", 43 UNTIC_COMMENT("return clears the line")}, + {"xs", 3 UNTIC_COMMENT("standout not erased by overwriting (hp)")}, + {"xt", 17 UNTIC_COMMENT("tabs destructive, magic so char (t1061)")}, {"", -1 UNTIC_COMMENT(NULL)} }; -int SLtt_tigetflag (char *cap, char **pp) +int _SLtt_tigetflag (SLterminfo_Type *t, char *cap) { int offset; - Terminfo_Type *t; - - if ((pp == NULL) || (NULL == (t = (Terminfo_Type *) *pp))) return -1; + + if (t == NULL) return -1; if (t->flags == SLTERMCAP) return tcap_getflag (cap, t); - + offset = compute_cap_offset (cap, t, Tgetflag_Map, t->boolean_section_size); - + if (offset < 0) return -1; return (int) *(t->boolean_flags + offset); } - - /* These are my termcap routines. They only work with the TERMCAP environment * variable. This variable must contain the termcap entry and NOT the file. */ -static int tcap_getflag (char *cap, Terminfo_Type *t) +static int tcap_getflag (char *cap, SLterminfo_Type *t) { char a, b; char *f = (char *) t->boolean_flags; char *fmax; - + if (f == NULL) return 0; fmax = f + t->boolean_section_size; @@ -529,10 +947,10 @@ static char *tcap_get_cap (unsigned char *cap, unsigned char *caps, unsigned int { unsigned char c0, c1; unsigned char *caps_max; - + c0 = cap[0]; c1 = cap[1]; - + if (caps == NULL) return NULL; caps_max = caps + len; while (caps < caps_max) @@ -546,15 +964,14 @@ static char *tcap_get_cap (unsigned char *cap, unsigned char *caps, unsigned int return NULL; } - -static int tcap_getnum (char *cap, Terminfo_Type *t) +static int tcap_getnum (char *cap, SLterminfo_Type *t) { cap = tcap_get_cap ((unsigned char *) cap, t->numbers, t->num_numbers); if (cap == NULL) return -1; return atoi (cap); } -static char *tcap_getstr (char *cap, Terminfo_Type *t) +static char *tcap_getstr (char *cap, SLterminfo_Type *t) { return tcap_get_cap ((unsigned char *) cap, (unsigned char *) t->string_table, t->string_table_size); } @@ -568,13 +985,13 @@ static int tcap_extract_field (unsigned char *t0) } int SLtt_Try_Termcap = 1; -static int tcap_getent (char *term, Terminfo_Type *ti) +static int tcap_getent (char *term, SLterminfo_Type *ti) { unsigned char *termcap, ch; unsigned char *buf, *b; unsigned char *t; int len; - + if (SLtt_Try_Termcap == 0) return -1; #if 1 /* XFREE86 xterm sets the TERMCAP environment variable to an invalid @@ -585,9 +1002,9 @@ static int tcap_getent (char *term, Terminfo_Type *ti) #endif termcap = (unsigned char *) getenv ("TERMCAP"); if ((termcap == NULL) || (*termcap == '/')) return -1; - - /* We have a termcap so lets use it provided it does not have a reference - * to another terminal via tc=. In that case, user terminfo. The alternative + + /* We have a termcap so lets use it provided it does not have a reference + * to another terminal via tc=. In that case, use terminfo. The alternative * would be to parse the termcap file which I do not want to do right now. * Besides, this is a terminfo based system and if the termcap were parsed * terminfo would almost never get a chance to run. In addition, the tc= @@ -600,37 +1017,35 @@ static int tcap_getent (char *term, Terminfo_Type *ti) return -1; t += (len + 1); } - + /* malloc some extra space just in case it is needed. */ len = strlen ((char *) termcap) + 256; - if (NULL == (buf = (unsigned char *) SLMALLOC ((unsigned int) len))) return -1; + if (NULL == (buf = (unsigned char *) SLmalloc ((unsigned int) len))) return -1; b = buf; - + /* The beginning of the termcap entry contains the names of the entry. - * It is terminated by a colon. + * It is terminated by a colon. */ - + ti->terminal_names = (char *) b; t = termcap; len = tcap_extract_field (t); if (len < 0) { - SLFREE (buf); + SLfree ((char *)buf); return -1; } strncpy ((char *) b, (char *) t, (unsigned int) len); b[len] = 0; b += len + 1; ti->name_section_size = len; - - - /* Now, we are really at the start of the termcap entries. Point the + + /* Now, we are really at the start of the termcap entries. Point the * termcap variable here since we want to refer to this a number of times. */ termcap = t + (len + 1); - - + /* Process strings first. */ ti->string_table = (char *) b; t = termcap; @@ -638,7 +1053,7 @@ static int tcap_getent (char *term, Terminfo_Type *ti) { unsigned char *b1; unsigned char *tmax; - + /* We are looking for: XX=something */ if ((len < 4) || (t[2] != '=') || (*t == '.')) { @@ -647,13 +1062,13 @@ static int tcap_getent (char *term, Terminfo_Type *ti) } tmax = t + len; b1 = b; - + while (t < tmax) { ch = *t++; if ((ch == '\\') && (t < tmax)) { - t = (unsigned char *) SLexpand_escaped_char ((char *) t, (char *) &ch); + t = (unsigned char *) _SLexpand_escaped_char ((char *) t, (char *) &ch); } else if ((ch == '^') && (t < tmax)) { @@ -669,7 +1084,7 @@ static int tcap_getent (char *term, Terminfo_Type *ti) b1[2] = (unsigned char) len; /* replace the = by the length */ /* skip colon to next field. */ t++; - } + } ti->string_table_size = (int) (b - (unsigned char *) ti->string_table); /* Now process the numbers. */ @@ -680,7 +1095,7 @@ static int tcap_getent (char *term, Terminfo_Type *ti) { unsigned char *b1; unsigned char *tmax; - + /* We are looking for: XX#NUMBER */ if ((len < 4) || (t[2] != '#') || (*t == '.')) { @@ -689,7 +1104,7 @@ static int tcap_getent (char *term, Terminfo_Type *ti) } tmax = t + len; b1 = b; - + while (t < tmax) { *b++ = *t++; @@ -699,16 +1114,16 @@ static int tcap_getent (char *term, Terminfo_Type *ti) len = (int) (b - b1); b1[2] = (unsigned char) len; /* replace the # by the length */ t++; - } + } ti->num_numbers = (int) (b - ti->numbers); - + /* Now process the flags. */ t = termcap; ti->boolean_flags = b; while (-1 != (len = tcap_extract_field (t))) { /* We are looking for: XX#NUMBER */ - if ((len != 2) || (*t == '.') || (*t <= ' ')) + if ((len != 2) || (*t == '.') || (*t <= ' ')) { t += len + 1; continue; @@ -717,202 +1132,33 @@ static int tcap_getent (char *term, Terminfo_Type *ti) b[1] = t[1]; t += 3; b += 2; - } + } ti->boolean_section_size = (int) (b - ti->boolean_flags); ti->flags = SLTERMCAP; return 0; } -#else /* USE_SETUPTERM */ -/* Ching Hui fixes so that it will work on AIX and OSF/1 */ -#include -#include - -int SLtt_Try_Termcap = 1; - -char *SLtt_tigetent (char *term) +/* These routines are provided only for backward binary compatability. + * They will vanish in V2.x + */ +char *SLtt_tigetent (char *s) { - int rc; - - setupterm(term, 1, &rc); - if (rc != 1) - return NULL; - return (char *)cur_term; + return (char *) _SLtt_tigetent (s); } -#define MATCH_CHAR(c, variable) \ - do { \ - if (*(cap + 1) == c) \ - return variable; \ - } while (0) - -char *SLtt_tigetstr (char *cap, char **pp) +extern char *SLtt_tigetstr (char *s, char **p) { - if ((pp == NULL) || ((cur_term = (struct term *) *pp) == NULL)) - return NULL; - - switch(*cap) { - case '@': - MATCH_CHAR('7', key_end); - break; - case 'A': - MATCH_CHAR('A', parm_insert_line); - break; - case 'D': - MATCH_CHAR('L', parm_delete_line); - break; - case 'R': - MATCH_CHAR('I', parm_right_cursor); - break; - case 'a': -#ifdef acs_chars - MATCH_CHAR('c', acs_chars); -#elif defined (box_chars_1) - MATCH_CHAR('c', box_chars_1); /* AIX hack */ -#else - MATCH_CHAR('c', NULL); -#endif - MATCH_CHAR('e', exit_alt_charset_mode); - MATCH_CHAR('s', enter_alt_charset_mode); - break; - case 'c': - MATCH_CHAR('e', clr_eol); - MATCH_CHAR('l', clear_screen); - MATCH_CHAR('m', cursor_address); - MATCH_CHAR('s', change_scroll_region); - break; - case 'd': - MATCH_CHAR('c', delete_character); - break; - case 'e': - MATCH_CHAR('i', exit_insert_mode); -#ifdef ena_acs - MATCH_CHAR('A', ena_acs); /* aix hack */ -#else - MATCH_CHAR('A', NULL); -#endif - break; - case 'i': - MATCH_CHAR('m', enter_insert_mode); - break; - case 'k': - MATCH_CHAR('0', key_f0); - MATCH_CHAR('1', key_f1); - MATCH_CHAR('1', key_f1); - MATCH_CHAR('2', key_f2); - MATCH_CHAR('3', key_f3); - MATCH_CHAR('4', key_f4); - MATCH_CHAR('5', key_f5); - MATCH_CHAR('6', key_f6); - MATCH_CHAR('7', key_f7); - MATCH_CHAR('8', key_f8); - MATCH_CHAR('9', key_f9); - MATCH_CHAR('A', key_il); - MATCH_CHAR('C', key_clear); - MATCH_CHAR('D', key_dc); - MATCH_CHAR('E', key_eol); - MATCH_CHAR('F', key_sf); - MATCH_CHAR('H', key_ll); - MATCH_CHAR('I', key_ic); - MATCH_CHAR('L', key_dl); - MATCH_CHAR('M', key_eic); - MATCH_CHAR('N', key_npage); - MATCH_CHAR('P', key_ppage); - MATCH_CHAR('R', key_sr); - MATCH_CHAR('S', key_eos); - MATCH_CHAR('T', key_stab); - MATCH_CHAR('a', key_catab); - MATCH_CHAR(';', key_f10); - MATCH_CHAR('b', key_backspace); - MATCH_CHAR('d', key_down); - MATCH_CHAR('e', keypad_local); - MATCH_CHAR('h', key_home); - MATCH_CHAR('l', key_left); - MATCH_CHAR('r', key_right); - MATCH_CHAR('s', keypad_xmit); - MATCH_CHAR('t', key_ctab); - MATCH_CHAR('u', key_up); - break; - case 'm': - MATCH_CHAR('b', enter_blink_mode); - MATCH_CHAR('d', enter_bold_mode); - MATCH_CHAR('e', exit_attribute_mode); - MATCH_CHAR('r', enter_reverse_mode); - break; - case 's': - MATCH_CHAR('e', exit_standout_mode); - MATCH_CHAR('o', enter_standout_mode); - MATCH_CHAR('r', scroll_reverse); - break; - case 't': - MATCH_CHAR('e', exit_ca_mode); - MATCH_CHAR('i', enter_ca_mode); - break; - case 'u': - MATCH_CHAR('p', cursor_up); - MATCH_CHAR('s', enter_underline_mode); - break; - case 'v': - MATCH_CHAR('b', flash_screen); - MATCH_CHAR('i', cursor_invisible); - MATCH_CHAR('s', cursor_visible); - break; - case 'F': - MATCH_CHAR('1', key_f11); - MATCH_CHAR('2', key_f12); - MATCH_CHAR('3', key_f13); - MATCH_CHAR('4', key_f14); - MATCH_CHAR('5', key_f15); - MATCH_CHAR('6', key_f16); - MATCH_CHAR('7', key_f17); - MATCH_CHAR('8', key_f18); - MATCH_CHAR('9', key_f19); - MATCH_CHAR('A', key_f20); - break; -#ifdef orig_pair - case 'o': - MATCH_CHAR('p', orig_pair); - break; -#endif - } - return NULL; + if (p == NULL) + return NULL; + return _SLtt_tigetstr ((SLterminfo_Type *) *p, s); } -int SLtt_tigetnum (char *cap, char **pp) +extern int SLtt_tigetnum (char *s, char **p) { - if ((pp == NULL) || ((cur_term = (struct term *) *pp) == NULL)) - return (int) NULL; - switch(*cap) { - case 'c': - MATCH_CHAR('o', columns); - break; - case 'l': - MATCH_CHAR('i', lines); - break; - } - return -1; + if (p == NULL) + return -1; + return _SLtt_tigetnum ((SLterminfo_Type *) *p, s); } -int SLtt_tigetflag (char *cap, char **pp) -{ - if ((pp == NULL) || ((cur_term = (struct term *) *pp) == NULL)) - return (int) NULL; - switch(*cap) { - case 'a': - MATCH_CHAR('m', auto_right_margin); - break; - case 'm': - MATCH_CHAR('s', move_standout_mode); - break; - case 'x': - MATCH_CHAR('s', ceol_standout_glitch); - break; - case 's': - MATCH_CHAR('g', magic_cookie_glitch); - break; - } - return -1; -} -#endif /* !USE_SETUPTERM */ diff --git a/slang/sltoken.c b/slang/sltoken.c deleted file mode 100644 index 7b3368a3f..000000000 --- a/slang/sltoken.c +++ /dev/null @@ -1,354 +0,0 @@ -/*--------------------------------*-C-*---------------------------------* - * File: sltoken.c - * - * Descript: --- - * - * Requires: --- - * - * Public: SLexpand_escaped_char (); - * SLexpand_escaped_string (); - * SLang_extract_token (); - * SLang_guess_type (); - * SLatoi (); - * - * Private: --- - * - * Notes: --- - * - * Copyright (c) 1992, 1995 John E. Davis - * All rights reserved. - * - * You may distribute under the terms of either the GNU General Public - * License or the Perl Artistic License. -\*----------------------------------------------------------------------*/ - -#include "config.h" - -#include - - -#ifdef HAVE_STDLIB_H -# include -#endif -#include -#include "_slang.h" - -/* There are non-zeros at positions "\t %()*,/:;[]{}" */ - -static const unsigned char special_chars[256] = -{ - /* 0 */ 0,0,0,0,0,0,0,0, 0,'\t',0,0,0,0,0,0, - /* 16 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, - /* 32 */ ' ',0,0,0,0,'%',0,0, '(',')','*',0,',',0,0,'/', - /* 48 */ 0,0,0,0,0,0,0,0, 0,0,':',';',0,0,0,0, - /* 64 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, - /* 80 */ 0,0,0,0,0,0,0,0, 0,0,0,'[',0,']',0,0, - /* 96 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, - /* 112 */ 0,0,0,0,0,0,0,0, 0,0,0,'{',0,'}',0,0, - /* 8-bit characters */ - /* 128 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, - /* 144 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, - /* 160 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, - /* 176 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, - /* 192 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, - /* 208 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, - /* 224 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, - /* 240 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0 -}; - -char *SLexpand_escaped_char(char *p, char *ch) -{ - int i = 0; - int max = 0, num, base = 0; - char ch1; - - ch1 = *p++; - - switch (ch1) - { - default: num = ch1; break; - case 'n': num = '\n'; break; - case 't': num = '\t'; break; - case 'v': num = '\v'; break; - case 'b': num = '\b'; break; - case 'r': num = '\r'; break; - case 'f': num = '\f'; break; - case 'E': case 'e': num = 27; break; - case 'a': num = 7; - break; - - /* octal */ - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - max = '7'; - base = 8; i = 2; num = ch1 - '0'; - break; - - case 'd': /* decimal -- S-Lang extension */ - base = 10; - i = 3; - max = '9'; - num = 0; - break; - - case 'x': /* hex */ - base = 16; - max = '9'; - i = 2; - num = 0; - break; - } - - while (i--) - { - ch1 = *p; - - if ((ch1 <= max) && (ch1 >= '0')) - { - num = base * num + (ch1 - '0'); - } - else if (base == 16) - { - ch1 |= 0x20; - if ((ch1 < 'a') || ((ch1 > 'f'))) break; - num = base * num + 10 + (ch1 - 'a'); - } - else break; - p++; - } - - *ch = (char) num; - return p; -} - -void SLexpand_escaped_string (register char *s, register char *t, - register char *tmax) -{ - char ch; - - while (t < tmax) - { - ch = *t++; - if (ch == '\\') - { - t = SLexpand_escaped_char (t, &ch); - } - *s++ = ch; - } - *s = 0; -} - - -int SLang_extract_token (char **linep, char *word_parm, int byte_comp) -{ - register char ch, *line, *word = word_parm; - int string; - char ch1; - char *word_max; - - word_max = word + 250; - - line = *linep; - - /* skip white space */ - while (((ch = *line) == ' ') - || (ch == '\t')) line++; - - if ((!ch) || (ch == '\n')) - { - *linep = line; - return(0); - } - - *word++ = ch; - line++; - - /* Look for -something and rule out --something and -= something */ - if ((ch == '-') && - (*line != '-') && (*line != '=') && ((*line > '9') || (*line < '0'))) - { - *word = 0; - *linep = line; - return 1; - } - - - if (ch == '"') string = 1; else string = 0; - if (ch == '\'') - { - if ((ch = *line++) != 0) - { - if (ch == '\\') - { - line = SLexpand_escaped_char(line, &ch1); - ch = ch1; - } - if (*line++ == '\'') - { - --word; - sprintf(word, "%d", (int) ((unsigned char) ch)); - word += strlen (word); ch = '\''; - } - else SLang_Error = SYNTAX_ERROR; - } - else SLang_Error = SYNTAX_ERROR; - } - else if (!special_chars[(unsigned char) ch]) - { - while (ch = *line++, - (ch > '"') || - ((ch != '\n') && (ch != 0) && (ch != '"'))) - { - if (string) - { - if (ch == '\\') - { - ch = *line++; - if ((ch == 0) || (ch == '\n')) break; - if (byte_comp) *word++ = '\\'; - else - { - line = SLexpand_escaped_char(line - 1, &ch1); - ch = ch1; - } - } - } - else if (special_chars[(unsigned char) ch]) - { - line--; - break; - } - - *word++ = ch; - if (word > word_max) - { - SLang_doerror ("Token to large."); - break; - } - } - } - - if ((!ch) || (ch == '\n')) line--; - if ((ch == '"') && string) *word++ = '"'; else if (string) SLang_Error = SYNTAX_ERROR; - *word = 0; - *linep = line; - /* massage variable-- and ++ into --variable, etc... */ - if (((int) (word - word_parm) > 2) - && (ch = *(word - 1), (ch == '+') || (ch == '-')) - && (ch == *(word - 2))) - { - word--; - while (word >= word_parm + 2) - { - *word = *(word - 2); - word--; - } - *word-- = ch; - *word-- = ch; - } - return(1); -} - - -int SLang_guess_type (char *t) -{ - char *p; - register char ch; - - if (*t == '-') t++; - p = t; -#ifdef FLOAT_TYPE - if (*p != '.') - { -#endif - while ((*p >= '0') && (*p <= '9')) p++; - if (t == p) return(STRING_TYPE); - if ((*p == 'x') && (p == t + 1)) /* 0x?? */ - { - p++; - while (ch = *p, - ((ch >= '0') && (ch <= '9')) - || (((ch | 0x20) >= 'a') && ((ch | 0x20) <= 'f'))) p++; - } - if (*p == 0) return(INT_TYPE); -#ifndef FLOAT_TYPE - return(STRING_TYPE); -#else - } - - /* now down to float case */ - if (*p == '.') - { - p++; - while ((*p >= '0') && (*p <= '9')) p++; - } - if (*p == 0) return(FLOAT_TYPE); - if ((*p != 'e') && (*p != 'E')) return(STRING_TYPE); - p++; - if ((*p == '-') || (*p == '+')) p++; - while ((*p >= '0') && (*p <= '9')) p++; - if (*p != 0) return(STRING_TYPE); else return(FLOAT_TYPE); -#endif -} - -int SLatoi (unsigned char *s) -{ - register unsigned char ch; - register unsigned int value; - register int base; - - if (*s != '0') return atoi((char *) s); - - /* look for 'x' which indicates hex */ - s++; - if ((*s | 0x20) == 'x') - { - base = 16; - s++; - if (*s == 0) - { - SLang_Error = SYNTAX_ERROR; - return -1; - } - } - else base = 8; - - - value = 0; - while ((ch = *s++) != 0) - { - char ch1 = ch | 0x20; - switch (ch1) - { - default: - SLang_Error = SYNTAX_ERROR; - break; - case '8': - case '9': - if (base != 16) SLang_Error = SYNTAX_ERROR; - /* drop */ - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - ch1 -= '0'; - break; - - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - if (base != 16) SLang_Error = SYNTAX_ERROR; - ch1 = (ch1 - 'a') + 10; - break; - } - value = value * base + ch1; - } - return (int) value; -} diff --git a/slang/slutty.c b/slang/slutty.c index 5e53faf0b..aebd21d96 100644 --- a/slang/slutty.c +++ b/slang/slutty.c @@ -1,15 +1,13 @@ /* slutty.c --- Unix Low level terminal (tty) functions for S-Lang */ -/* Copyright (c) 1992, 1995 John E. Davis - * All rights reserved. - * +/* Copyright (c) 1992, 1999, 2001, 2002 John E. Davis + * This file is part of the S-Lang library. + * * You may distribute under the terms of either the GNU General Public * License or the Perl Artistic License. */ +#include "slinclud.h" -#include "config.h" - -#include #include /* sequent support thanks to Kenneth Lorber */ /* SYSV (SYSV ISC R3.2 v3.0) provided by iain.lea@erlm.siemens.de */ @@ -18,14 +16,6 @@ # define _ALL_SOURCE /* so NBBY is defined in */ #endif -#ifdef HAVE_STDLIB_H -# include -#endif - -#ifdef HAVE_UNISTD_H -# include -#endif - #include #include @@ -39,7 +29,6 @@ # endif #endif - #ifdef __BEOS__ /* Prototype for select */ # include @@ -66,13 +55,12 @@ # include #endif - +#include "slang.h" #include "_slang.h" int SLang_TT_Read_FD = -1; int SLang_TT_Baud_Rate; - #ifdef HAVE_TERMIOS_H # if !defined(HAVE_TCGETATTR) || !defined(HAVE_TCSETATTR) # undef HAVE_TERMIOS_H @@ -103,39 +91,103 @@ typedef struct termios TTY_Termio_Type; static TTY_Termio_Type Old_TTY; #ifdef HAVE_TERMIOS_H -static const struct +typedef struct { - speed_t key; - int value; -} Baud_Rates[] = + unsigned int key; + unsigned int value; +} Baud_Rate_Type; + +static Baud_Rate_Type Baud_Rates [] = { - {B0, 0}, - {B50, 50}, - {B75, 75}, - {B110, 110}, - {B134, 134}, - {B150, 150}, - {B200, 200}, - {B300, 300}, - {B600, 600}, - {B1200, 1200}, - {B1800, 1800}, - {B2400, 2400}, - {B4800, 4800}, - {B9600, 9600}, - {B19200, 19200}, - {B38400, 38400} +#ifdef B0 + {B0, 0}, +#endif +#ifdef B50 + {B50, 50}, +#endif +#ifdef B75 + {B75, 75}, +#endif +#ifdef B110 + {B110, 110}, +#endif +#ifdef B134 + {B134, 134}, +#endif +#ifdef B150 + {B150, 150}, +#endif +#ifdef B200 + {B200, 200}, +#endif +#ifdef B300 + {B300, 300}, +#endif +#ifdef B600 + {B600, 600}, +#endif +#ifdef B1200 + {B1200, 1200}, +#endif +#ifdef B1800 + {B1800, 1800}, +#endif +#ifdef B2400 + {B2400, 2400}, +#endif +#ifdef B4800 + {B4800, 4800}, +#endif +#ifdef B9600 + {B9600, 9600}, +#endif +#ifdef B19200 + {B19200, 19200}, +#endif +#ifdef B38400 + {B38400, 38400}, +#endif #ifdef B57600 - , {B57600, 57600} + {B57600, 57600}, #endif #ifdef B115200 - , {B115200, 115200} + {B115200, 115200}, #endif #ifdef B230400 - , {B230400, 230400} + {B230400, 230400}, #endif + {0, 0} }; + +static void +set_baud_rate (TTY_Termio_Type *tty) +{ +#ifdef HAVE_CFGETOSPEED + unsigned int speed; + Baud_Rate_Type *b, *bmax; + + if (SLang_TT_Baud_Rate) + return; /* already set */ + + speed = (unsigned int) cfgetospeed (tty); + + b = Baud_Rates; + bmax = b + (sizeof (Baud_Rates)/sizeof(Baud_Rates[0])); + while (b < bmax) + { + if (b->key == speed) + { + SLang_TT_Baud_Rate = b->value; + return; + } + b++; + } +#else + (void) tty; #endif +} + +#endif /* HAVE_TERMIOS_H */ #ifdef HAVE_TERMIOS_H # define GET_TERMIOS(fd, x) tcgetattr(fd, x) @@ -170,58 +222,36 @@ static int TTY_Open = 0; # endif #endif -static int -speed_t2baud_rate (speed_t s) -{ - int i; - - for (i = 0; i < sizeof (Baud_Rates)/sizeof (Baud_Rates[0]); i++) - if (Baud_Rates[i].key == s) - return (Baud_Rates[i].value); - return 0; -} - int SLang_init_tty (int abort_char, int no_flow_control, int opost) { TTY_Termio_Type newtty; - + SLsig_block_signals (); - - if (TTY_Inited) + + if (TTY_Inited) { SLsig_unblock_signals (); return 0; } - + TTY_Open = 0; - + if ((SLang_TT_Read_FD == -1) || (1 != isatty (SLang_TT_Read_FD))) { -#if 0 #ifdef O_RDWR -# ifndef __BEOS__ /* I have been told that BEOS will HANG if passed /dev/tty */ +# if !defined(__BEOS__) && !defined(__APPLE__) + /* I have been told that BEOS will HANG if passed /dev/tty */ if ((SLang_TT_Read_FD = open("/dev/tty", O_RDWR)) >= 0) { TTY_Open = 1; } # endif #endif -#endif /* 0 */ if (TTY_Open == 0) { - -#if 0 -/* In the Midnight Commander we bind stderr sometimes to a pipe. If we - use stderr for terminal input and call SLang_getkey while stderr is - bound to a pipe MC will hang completly in SLsys_input_pending. - NOTE: There's an independent fix for this problem in src/slint.c for - the case that the Midnight Commander is linked against a shared slang - library compiled from different sources. - */ SLang_TT_Read_FD = fileno (stderr); if (1 != isatty (SLang_TT_Read_FD)) -#endif { SLang_TT_Read_FD = fileno (stdin); if (1 != isatty (SLang_TT_Read_FD)) @@ -232,10 +262,10 @@ int SLang_init_tty (int abort_char, int no_flow_control, int opost) } } } - + SLang_Abort_Char = abort_char; - - /* Some systems may not permit signals to be blocked. As a result, the + + /* Some systems may not permit signals to be blocked. As a result, the * return code must be checked. */ while (-1 == GET_TERMIOS(SLang_TT_Read_FD, &Old_TTY)) @@ -246,7 +276,7 @@ int SLang_init_tty (int abort_char, int no_flow_control, int opost) return -1; } } - + while (-1 == GET_TERMIOS(SLang_TT_Read_FD, &newtty)) { if (errno != EINTR) @@ -255,8 +285,10 @@ int SLang_init_tty (int abort_char, int no_flow_control, int opost) return -1; } } - + #ifndef HAVE_TERMIOS_H + (void) opost; + (void) no_flow_control; newtty.s.sg_flags &= ~(ECHO); newtty.s.sg_flags &= ~(CRMOD); /* if (Flow_Control == 0) newtty.s.sg_flags &= ~IXON; */ @@ -269,43 +301,38 @@ int SLang_init_tty (int abort_char, int no_flow_control, int opost) newtty.lt.t_lnextc = 255; newtty.s.sg_flags |= CBREAK; /* do I want cbreak or raw????? */ #else - + /* get baud rate */ - - /* [not only QNX related !?!] - * ECHO(0x08) is a c_lflag bit, it means here PARMRK(0x08) in c_iflag!!! - */ - /*newtty.c_iflag &= ~(ECHO | INLCR | ICRNL);*/ - newtty.c_iflag &= ~(INLCR | ICRNL); + + newtty.c_iflag &= ~(ECHO | INLCR | ICRNL); #ifdef ISTRIP /* newtty.c_iflag &= ~ISTRIP; */ #endif if (opost == 0) newtty.c_oflag &= ~OPOST; - if (SLang_TT_Baud_Rate == 0) - { -/* Note: if this generates an compiler error, simply remove - the statement */ -#ifdef HAVE_CFGETOSPEED - SLang_TT_Baud_Rate = cfgetospeed (&newtty); -#endif - SLang_TT_Baud_Rate = speed_t2baud_rate (SLang_TT_Baud_Rate); - } + set_baud_rate (&newtty); + if (no_flow_control) newtty.c_iflag &= ~IXON; else newtty.c_iflag |= IXON; + newtty.c_cc[VEOF] = 1; newtty.c_cc[VMIN] = 1; newtty.c_cc[VTIME] = 0; - newtty.c_cc[VEOF] = 1; newtty.c_lflag = ISIG | NOFLSH; if (abort_char == -1) SLang_Abort_Char = newtty.c_cc[VINTR]; newtty.c_cc[VINTR] = SLang_Abort_Char; /* ^G */ newtty.c_cc[VQUIT] = NULL_VALUE; newtty.c_cc[VSUSP] = NULL_VALUE; /* to ignore ^Z */ +#ifdef VDSUSP + newtty.c_cc[VDSUSP] = NULL_VALUE; /* to ignore ^Y */ +#endif +#ifdef VLNEXT + newtty.c_cc[VLNEXT] = NULL_VALUE; /* to ignore ^V ? */ +#endif #ifdef VSWTCH newtty.c_cc[VSWTCH] = NULL_VALUE; /* to ignore who knows what */ #endif #endif /* NOT HAVE_TERMIOS_H */ - + while (-1 == SET_TERMIOS(SLang_TT_Read_FD, &newtty)) { if (errno != EINTR) @@ -314,7 +341,7 @@ int SLang_init_tty (int abort_char, int no_flow_control, int opost) return -1; } } - + TTY_Inited = 1; SLsig_unblock_signals (); return 0; @@ -323,27 +350,48 @@ int SLang_init_tty (int abort_char, int no_flow_control, int opost) void SLtty_set_suspend_state (int mode) { TTY_Termio_Type newtty; - + SLsig_block_signals (); - + if (TTY_Inited == 0) { SLsig_unblock_signals (); return; } - + while ((-1 == GET_TERMIOS (SLang_TT_Read_FD, &newtty)) && (errno == EINTR)) ; - + #ifndef HAVE_TERMIOS_H - if (mode == 0) newtty.lt.t_suspc = 255; - else newtty.lt.t_suspc = Old_TTY.lt.t_suspc; + /* I do not know if all systems define the t_dsuspc field */ + if (mode == 0) + { + newtty.lt.t_suspc = 255; + newtty.lt.t_dsuspc = 255; + } + else + { + newtty.lt.t_suspc = Old_TTY.lt.t_suspc; + newtty.lt.t_dsuspc = Old_TTY.lt.t_dsuspc; + } #else - if (mode == 0) newtty.c_cc[VSUSP] = NULL_VALUE; - else newtty.c_cc[VSUSP] = Old_TTY.c_cc[VSUSP]; + if (mode == 0) + { + newtty.c_cc[VSUSP] = NULL_VALUE; +#ifdef VDSUSP + newtty.c_cc[VDSUSP] = NULL_VALUE; #endif - + } + else + { + newtty.c_cc[VSUSP] = Old_TTY.c_cc[VSUSP]; +#ifdef VDSUSP + newtty.c_cc[VDSUSP] = Old_TTY.c_cc[VDSUSP]; +#endif + } +#endif + while ((-1 == SET_TERMIOS (SLang_TT_Read_FD, &newtty)) && (errno == EINTR)) ; @@ -354,27 +402,27 @@ void SLtty_set_suspend_state (int mode) void SLang_reset_tty (void) { SLsig_block_signals (); - + if (TTY_Inited == 0) { SLsig_unblock_signals (); return; } - + while ((-1 == SET_TERMIOS(SLang_TT_Read_FD, &Old_TTY)) && (errno == EINTR)) ; - + if (TTY_Open) { while ((-1 == close (SLang_TT_Read_FD)) && (errno == EINTR)) ; - + TTY_Open = 0; SLang_TT_Read_FD = -1; } - + TTY_Inited = 0; SLsig_unblock_signals (); } @@ -382,21 +430,27 @@ void SLang_reset_tty (void) static void default_sigint (int sig) { sig = errno; /* use parameter */ - + SLKeyBoard_Quit = 1; - if (SLang_Ignore_User_Abort == 0) SLang_Error = USER_BREAK; + if (SLang_Ignore_User_Abort == 0) SLang_Error = SL_USER_BREAK; SLsignal_intr (SIGINT, default_sigint); errno = sig; } -void SLang_set_abort_signal (void (*hand)(int)) +int SLang_set_abort_signal (void (*hand)(int)) { int save_errno = errno; - + SLSig_Fun_Type *f; + if (hand == NULL) hand = default_sigint; - SLsignal_intr (SIGINT, hand); - + f = SLsignal_intr (SIGINT, hand); + errno = save_errno; + + if (f == (SLSig_Fun_Type *) SIG_ERR) + return -1; + + return 0; } #ifndef FD_SET @@ -408,16 +462,20 @@ typedef int fd_set; static fd_set Read_FD_Set; - /* HACK: If > 0, use 1/10 seconds. If < 0, use 1/1000 seconds */ -int SLsys_input_pending(int tsecs) +int _SLsys_input_pending(int tsecs) { struct timeval wait; long usecs, secs; - if (TTY_Inited == 0) return -1; - + if ((TTY_Inited == 0) + || (SLang_TT_Read_FD < 0)) + { + errno = EBADF; + return -1; + } + if (tsecs >= 0) { secs = tsecs / 10; @@ -429,17 +487,16 @@ int SLsys_input_pending(int tsecs) secs = tsecs / 1000; usecs = (tsecs % 1000) * 1000; } - + wait.tv_sec = secs; wait.tv_usec = usecs; FD_ZERO(&Read_FD_Set); FD_SET(SLang_TT_Read_FD, &Read_FD_Set); - + return select(SLang_TT_Read_FD + 1, &Read_FD_Set, NULL, NULL, &wait); } - int (*SLang_getkey_intr_hook) (void); static int handle_interrupt (void) @@ -447,70 +504,80 @@ static int handle_interrupt (void) if (SLang_getkey_intr_hook != NULL) { int save_tty_fd = SLang_TT_Read_FD; - + if (-1 == (*SLang_getkey_intr_hook) ()) return -1; - + if (save_tty_fd != SLang_TT_Read_FD) return -1; } - + return 0; } -unsigned int SLsys_getkey (void) +unsigned int _SLsys_getkey (void) { unsigned char c; - unsigned int i; - + if (TTY_Inited == 0) { int ic = fgetc (stdin); if (ic == EOF) return SLANG_GETKEY_ERROR; return (unsigned int) ic; } - + while (1) { int ret; - - if (SLKeyBoard_Quit) + + if (SLKeyBoard_Quit) return SLang_Abort_Char; - - if (0 == (ret = SLsys_input_pending (100))) + + if (0 == (ret = _SLsys_input_pending (100))) continue; - + if (ret != -1) break; - - if (SLKeyBoard_Quit) + + if (SLKeyBoard_Quit) return SLang_Abort_Char; - + if (errno == EINTR) { if (-1 == handle_interrupt ()) return SLANG_GETKEY_ERROR; - + continue; } - + break; /* let read handle it */ } - - while (-1 == (i = read(SLang_TT_Read_FD, (char *) &c, 1))) + + while (1) { - if (errno == EINTR) + int status = read(SLang_TT_Read_FD, (char *) &c, 1); + + if (status > 0) + break; + + if (status == 0) + { + /* We are at the end of a file. Let application handle it. */ + return SLANG_GETKEY_ERROR; + } + + if (errno == EINTR) { if (-1 == handle_interrupt ()) return SLANG_GETKEY_ERROR; - - if (SLKeyBoard_Quit) + + if (SLKeyBoard_Quit) return SLang_Abort_Char; - + continue; } #ifdef EAGAIN - if (errno == EAGAIN) + if (errno == EAGAIN) { sleep (1); continue; @@ -526,15 +593,12 @@ unsigned int SLsys_getkey (void) #ifdef EIO if (errno == EIO) { - SLang_exit_error ("SLsys_getkey: EIO error."); + SLang_exit_error ("_SLsys_getkey: EIO error."); } #endif return SLANG_GETKEY_ERROR; } - if (i == 0) - return SLANG_GETKEY_ERROR; - return((unsigned int) c); } diff --git a/slang/slvideo.c b/slang/slvideo.c index ead042647..c56534d90 100644 --- a/slang/slvideo.c +++ b/slang/slvideo.c @@ -1,91 +1,50 @@ -/* Copyright (c) 1992, 1995 John E. Davis - * All rights reserved. - * +/* -*- mode: C; mode: fold -*- */ +/* Copyright (c) 1992, 1997, 2001, 2002 John E. Davis + * This file is part of the S-Lang library. + * * You may distribute under the terms of either the GNU General Public * License or the Perl Artistic License. */ -#include "config.h" +/* This file is best edited with a folding editor */ -#include -#include +#include "slinclud.h" -#include - -#ifdef __WIN32__ -# include +#if !defined(__WIN32__) && !defined(__IBMC__) +# include #endif -#ifdef __GO32__ -# undef msdos -#endif - -#if defined (msdos) -# include -# include -# include -#endif -#if defined (__WATCOMC__) -# include -# define int86 int386 /* simplify code writing */ -#endif - -#if defined (__GO32__) -# include -# define GO32_VIDEO -#endif - -#if defined (__os2__) && !defined (EMX_VIDEO) -# define INCL_BASE -# define INCL_NOPM -# define INCL_VIO -# define INCL_KBD -# include -#else -# if defined (__EMX__) /* EMX video does both DOS & OS/2 */ -# ifndef EMX_VIDEO -# define EMX_VIDEO -# endif -# include -# endif -#endif - -#include +#include "slang.h" #include "_slang.h" -#ifdef GO32_VIDEO -# define HAS_SAVE_SCREEN -#endif - -/* ------------------------- global variables ------------------------- */ - -#ifdef WIN32 -extern HANDLE hStdout, hStdin; -extern CONSOLE_SCREEN_BUFFER_INFO csbiInfo; -#endif - - int SLtt_Term_Cannot_Insert; int SLtt_Term_Cannot_Scroll; int SLtt_Ignore_Beep = 3; int SLtt_Use_Ansi_Colors; - +int SLtt_Has_Status_Line = 0; int SLtt_Screen_Rows = 25; int SLtt_Screen_Cols = 80; +int SLtt_Msdos_Cheap_Video = 0; + +void (*_SLtt_color_changed_hook)(void); + +/* This definition will need changing when SLsmg_Char_Type changes. */ +#define SLSMG_CHAR_TO_USHORT(x) ((unsigned short)(x)) + +/*{{{ ------------- static local variables ---------- */ -/* ------------------------- local variables -------------------------- */ static int Attribute_Byte; static int Scroll_r1 = 0, Scroll_r2 = 25; static int Cursor_Row = 1, Cursor_Col = 1; static int Current_Color; static int IsColor = 1; -static int Blink_Killed; /* high intensity background enabled */ +static int Blink_Killed = 1; /* high intensity background enabled */ #define JMAX_COLORS 256 #define JNORMAL_COLOR 0 #define JNO_COLOR -1 -static unsigned char Color_Map [JMAX_COLORS] = +static unsigned char Color_Map [JMAX_COLORS] = { 0x7, 0x70, 0x70, 0x70, 0x70, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, @@ -121,7 +80,6 @@ static unsigned char Color_Map [JMAX_COLORS] = 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7 }; - #define JMAX_COLOR_NAMES 16 static char *Color_Names [JMAX_COLOR_NAMES] = { @@ -131,242 +89,100 @@ static char *Color_Names [JMAX_COLOR_NAMES] = "brightred", "brightmagenta", "yellow", "white" }; -/* - * set_color_from_attribute (int attribute); - * define the correspondence of color to attribute +static void fixup_colors (void); + +/*}}}*/ + +static void goto_rc_abs (int r, int c) +{ + SLtt_goto_rc (r - Scroll_r1, c); +} + +#if defined(__BORLANDC__) && defined(__MSDOS__) +# define IBMPC_ASM_VIDEO 1 +#endif + +#if defined(__WATCOMC__) && !defined(__NT__) && !defined(__os2__) +# define WATCOM_VIDEO 1 +#endif + +#if defined (__GO32__) +# define GO32_VIDEO 1 +#endif + +#if defined (__EMX__) /* EMX video does both DOS & OS/2 */ +# define EMX_VIDEO 1 +#else +# if defined(__os2__) +# define OS2_VIDEO 1 +# endif +#endif + +#if defined (__WIN32__) +# define WIN32_VIDEO 1 +#endif + +/* The functions in these folds contain somewhat video system specific code + * that if merged together into single functions will become a confusing + * mess. */ -#define set_color_from_attribute(a)\ - SLtt_set_color (\ - JNORMAL_COLOR, NULL,\ - Color_Names[(a) & 0xf],\ - Color_Names[(a) >> 4]) -/* this is how to make a space character */ -#define mkSpaceChar() (((Attribute_Byte) << 8) | 0x20) + +#ifdef IBMPC_ASM_VIDEO /*{{{*/ + +# include +# include +# include /* buffer to hold a line of character/attribute pairs */ #define MAXCOLS 256 static unsigned char Line_Buffer [MAXCOLS*2]; -/*----------------------------------------------------------------------*\ - * define various ways and means of writing to the screen -\*----------------------------------------------------------------------*/ -#if defined (__GO32__) || defined (__WATCOMC__) -# if !defined (GO32_VIDEO) -# define HAS_LINEAR_SCREEN -# endif -#else /* __GO32__ or __WATCOMC__ */ -# if defined (msdos) -# define USE_ASM -# endif -#endif /* __GO32__ or __WATCOMC__ */ +#define MK_SPACE_CHAR() (((Attribute_Byte) << 8) | 0x20) -/* define for direct to memory screen writes */ -#if defined (USE_ASM) || defined (HAS_LINEAR_SCREEN) static unsigned char *Video_Base; -# define mkScreenPointer(row,col) ((unsigned short *)\ +# define MK_SCREEN_POINTER(row,col) ((unsigned short *)\ (Video_Base +\ 2 * (SLtt_Screen_Cols * (row)\ + (col)))) -# if defined (USE_ASM) -int SLtt_Msdos_Cheap_Video = 0; static int Video_Status_Port; -# define MONO_STATUS 0x3BA -# define CGA_STATUS 0x3DA -# define CGA_SETMODE 0x3D8 +# define MONO_STATUS 0x3BA +# define CGA_STATUS 0x3DA +# define CGA_SETMODE 0x3D8 -# define SNOW_CHECK \ -if (SLtt_Msdos_Cheap_Video)\ -{ while ((inp (CGA_STATUS) & 0x08)); while (!(inp (CGA_STATUS) & 0x08)); } -# endif /* USE_ASM */ -#endif /* USE_ASM or HAS_LINEAR_SCREEN */ +# define SNOW_CHECK \ + if (SLtt_Msdos_Cheap_Video)\ + { while ((inp (CGA_STATUS) & 0x08)); while (!(inp (CGA_STATUS) & 0x08)); } - -/* -------------------------------------------------------------------- */ -#if defined (__WATCOMC__) -# define ScreenPrimary (0xb800 << 4) -# define ScreenSize (SLtt_Screen_Cols * SLtt_Screen_Rows) -# define ScreenSetCursor (x,y) _settextposition (x+1,y+1) -void ScreenGetCursor (int *x, int *y) -{ - struct rccoord rc = _gettextposition (); - *x = rc.row - 1; - *y = rc.col - 1; -} -void ScreenRetrieve (unsigned char *dest) -{ - memcpy (dest, (unsigned char *) ScreenPrimary, 2 * ScreenSize); -} -void ScreenUpdate (unsigned char *src) -{ - memcpy ((unsigned char *) ScreenPrimary, src, 2 * ScreenSize); -} -#endif /* __WATCOMC__ */ - -#ifdef HAS_SAVE_SCREEN -static void *Saved_Screen_Buffer; -static int Saved_Cursor_Row; - -static void save_screen (void) -{ - int row, col; - - if (Saved_Screen_Buffer != NULL) - { - SLFREE (Saved_Screen_Buffer); - Saved_Screen_Buffer = NULL; - } -#ifdef GO32_VIDEO - Saved_Screen_Buffer = SLMALLOC (sizeof (short) * - ScreenCols () * ScreenRows ()); - - if (Saved_Screen_Buffer == NULL) - return; - - ScreenRetrieve (Saved_Screen_Buffer); - ScreenGetCursor (&row, &col); - Saved_Cursor_Row = row; -#endif - -} - -static void restore_screen (void) -{ - if (Saved_Screen_Buffer == NULL) return; -#ifdef GO32_VIDEO - ScreenUpdate (Saved_Screen_Buffer); - SLtt_goto_rc (Saved_Cursor_Row, 0); -#endif - -} -#endif /* HAS_SAVE_SCREEN */ -/*----------------------------------------------------------------------*\ - * Function: void SLtt_write_string (char *str); - * - * put string STR to 'stdout' -\*----------------------------------------------------------------------*/ void SLtt_write_string (char *str) { -#ifdef WIN32 - int bytes; - - (void) WriteConsole(hStdout, str, strlen(str), &bytes, NULL); -#else + /* FIXME: Priority=medium + * This should not go to stdout. */ fputs (str, stdout); -#endif } -/*----------------------------------------------------------------------*\ - * Function: void SLtt_set_scroll_region (int r1, int r2); - * - * define a scroll region of top_row to bottom_row -\*----------------------------------------------------------------------*/ -void SLtt_set_scroll_region (int top_row, int bottom_row) +/* row is with respect to the scrolling region. */ +void SLtt_goto_rc (int r, int c) { - Scroll_r1 = top_row; - Scroll_r2 = bottom_row; + union REGS regs; + + r += Scroll_r1; + + if (r > SLtt_Screen_Rows - 1) r = SLtt_Screen_Rows - 1; + if (c > SLtt_Screen_Cols - 1) c = SLtt_Screen_Cols - 1; + + Cursor_Row = r; + Cursor_Col = c; + + regs.h.dh = r; + regs.h.dl = c; + regs.h.bh = 0; + regs.h.ah = 2; + int86 (0x10, ®s, ®s); } -/*----------------------------------------------------------------------*\ - * Function: void SLtt_reset_scroll_region (void); - * - * reset the scrol region to be the entire screen, - * ie, SLtt_set_scroll_region (0, SLtt_Screen_Rows); -\*----------------------------------------------------------------------*/ -void SLtt_reset_scroll_region (void) +static void asm_video_getxy (void) { - Scroll_r1 = 0; - Scroll_r2 = SLtt_Screen_Rows; -} - -/*----------------------------------------------------------------------*\ - * Function: void SLtt_goto_rc (int row, int col); - * - * move the terminal cursor to x,y position COL, ROW and record the - * position in Cursor_Row, Cursor_Col -\*----------------------------------------------------------------------*/ -void SLtt_goto_rc (int row, int col) -{ -#ifdef WIN32 - COORD newPosition; - newPosition.X = col; - newPosition.Y = row; -#endif - -#if !defined (USE_ASM) - if (row > SLtt_Screen_Rows) row = SLtt_Screen_Rows; - if (col > SLtt_Screen_Cols) col = SLtt_Screen_Cols; -# if defined (EMX_VIDEO) - v_gotoxy (col, Scroll_r1 + row); -# else /* EMX_VIDEO_ */ -# if defined (__os2__) - VioSetCurPos (Scroll_r1 + row, col, 0); -# elif defined(WIN32) - (void) SetConsoleCursorPosition(hStdout, newPosition); -# else /* __os2__ */ -# if defined (__GO32__) || defined (__WATCOMC__) - ScreenSetCursor(Scroll_r1 + row, col); -# endif /* __GO32__ or __WATCOMC__ */ -# endif /* __os2__ */ -# endif /* EMX_VIDEO_ */ - Cursor_Row = row; - Cursor_Col = col; -#else /* USE_ASM */ - /* if (r > SLtt_Screen_Rows - 1) r = SLtt_Screen_Rows - 1; */ - asm mov ax, row - asm mov bx, SLtt_Screen_Rows - asm dec bx - asm cmp ax, bx - asm jle L1 - asm mov ax, bx - L1: - /* if (c > SLtt_Screen_Cols - 1) c = SLtt_Screen_Cols - 1; */ - asm mov cx, SLtt_Screen_Cols - asm dec cx - asm mov bx, col - asm cmp bx, cx - asm jle L2 - asm mov bx, cx - L2: - asm mov Cursor_Row, ax - asm mov Cursor_Col, bx - asm add ax, Scroll_r1 - asm xor dx, dx - asm mov dh, al - asm mov dl, bl - asm xor bx, bx - asm mov ax, 0x200 - asm int 0x10 -#endif /* USE_ASM */ -} - -/*----------------------------------------------------------------------*\ - * Function: static void slvid_getxy (void); - * - * retrieve the cursor position into Cursor_Row, Cursor_Col -\*----------------------------------------------------------------------*/ -static void slvid_getxy (void) -{ -#if !defined (USE_ASM) -# if defined (EMX_VIDEO) - v_getxy (&Cursor_Col, &Cursor_Row); -# else /* EMX_VIDEO */ -# if defined (__os2__) - VioGetCurPos ((USHORT*) &Cursor_Row, (USHORT*) &Cursor_Col, 0); -# elif defined(WIN32) - CONSOLE_SCREEN_BUFFER_INFO screenInfo; - if (GetConsoleScreenBufferInfo(hStdout, &screenInfo) == TRUE) - { - Cursor_Row = screenInfo.dwCursorPosition.Y; - Cursor_Col = screenInfo.dwCursorPosition.X; - } -# else /* __os2__ */ -# if defined (__GO32__) || defined (__WATCOMC__) - ScreenGetCursor (&Cursor_Row, &Cursor_Col); -# endif /* __GO32__ or __WATCOMC__ */ -# endif /* __os2__ */ -# endif /* EMX_VIDEO */ -#else /* USE_ASM */ asm mov ah, 3 asm mov bh, 0 asm int 10h @@ -376,209 +192,73 @@ static void slvid_getxy (void) asm xor ax, ax asm mov al, dl asm mov Cursor_Col, ax -#endif /* USE_ASM */ } -/*----------------------------------------------------------------------*\ - * static void slvid_deleol (int x); - * - * write space characters from column X of row Cursor_Row through to - * SLtt_Screen_Cols using the current Attribute_Byte -\*----------------------------------------------------------------------*/ -#if defined (GO32_VIDEO) -static void slvid_deleol (int x) -{ - while (x < SLtt_Screen_Cols) - ScreenPutChar (32, Attribute_Byte, x++, Cursor_Row); -} -#endif -#if defined (EMX_VIDEO) -static void slvid_deleol (int x) -{ - unsigned char *p, *pmax; - int w = mkSpaceChar (); - int count = SLtt_Screen_Cols - x; - - p = Line_Buffer; - pmax = p + 2 * count; - - while (p < pmax) - { - *p++ = (unsigned char) w; - *p++ = (unsigned char) (w >> 8); - } - - v_putline (Line_Buffer, x, Cursor_Row, count); -} -#endif /* EMX_VIDEO */ - -/*----------------------------------------------------------------------*\ - * Function: void SLtt_begin_insert (void); - * - * insert a single space, moving everything right 1 character to make room -\*----------------------------------------------------------------------*/ void SLtt_begin_insert (void) { -#if !defined (GO32_VIDEO) -# if defined (HAS_LINEAR_SCREEN) || defined (USE_ASM) unsigned short *p; -# if defined (HAS_LINEAR_SCREEN) - unsigned short *pmin; -# endif -# endif int n; - slvid_getxy (); + + asm_video_getxy (); n = SLtt_Screen_Cols - Cursor_Col; - /* Msdos_Insert_Mode = 1; */ - -# ifndef WIN32 -# if defined (EMX_VIDEO) - v_getline (Line_Buffer, Cursor_Col, Cursor_Row, n); - v_putline (Line_Buffer, Cursor_Col+1, Cursor_Row, n - 1); -# else /* EMX_VIDEO */ -# if defined (__os2__) - n = 2 * (n - 1); - VioReadCellStr ((PCH)Line_Buffer, (USHORT*) &n, Cursor_Row, Cursor_Col, 0); - VioWrtCellStr ((PCH)Line_Buffer, n, Cursor_Row, Cursor_Col + 1, 0); -# else /* __os2__ */ - p = mkScreenPointer (Cursor_Row, SLtt_Screen_Cols - 1); - -# if defined (HAS_LINEAR_SCREEN) - /* pmin = p - (n-1); */ - pmin = mkScreenPointer (Cursor_Row, Cursor_Col); - while (p-- > pmin) *(p + 1) = *p; -# else + p = MK_SCREEN_POINTER (Cursor_Row, SLtt_Screen_Cols - 1); + SNOW_CHECK; asm mov ax, ds asm mov bx, di asm mov dx, si - + asm mov cx, n asm les di, p asm lds si, p asm sub si, 2 asm std asm rep movsw - + asm mov ds, ax asm mov di, bx asm mov si, dx -# endif /* HAS_LINEAR_SCREEN */ -# endif /* __os2__ */ -# endif /* EMX_VIDEO */ - -# endif /* WIN32 */ - -#endif /* not GO32_VIDEO */ } -/*----------------------------------------------------------------------*\ - * Function: void SLtt_end_insert (void); - * - * any cleanup after insert a blank column -\*----------------------------------------------------------------------*/ void SLtt_end_insert (void) { } -/*----------------------------------------------------------------------*\ - * Function: void SLtt_delete_char (void); - * - * delete a single character, moving everything left 1 column to take - * up the room -\*----------------------------------------------------------------------*/ void SLtt_delete_char (void) { -#if !defined (GO32_VIDEO) -# if defined (HAS_LINEAR_SCREEN) || defined (USE_ASM) unsigned short *p; -# if defined (HAS_LINEAR_SCREEN) - register unsigned short *p1; -# endif -# endif int n; - - slvid_getxy (); + + asm_video_getxy (); n = SLtt_Screen_Cols - Cursor_Col - 1; - -# ifndef WIN32 - -# if defined (EMX_VIDEO) - v_getline (Line_Buffer, Cursor_Col+1, Cursor_Row, n); - v_putline (Line_Buffer, Cursor_Col, Cursor_Row, n); -# else /* EMX_VIDEO */ -# if defined (__os2__) - n *= 2; - VioReadCellStr ((PCH)Line_Buffer, (USHORT*)&n, Cursor_Row, Cursor_Col + 1, 0); - VioWrtCellStr ((PCH)Line_Buffer, n, Cursor_Row, Cursor_Col, 0); - return; -# else /* __os2__ */ - p = mkScreenPointer (Cursor_Row, Cursor_Col); - -# if defined (HAS_LINEAR_SCREEN) - while (n--) - { - p1 = p + 1; - *p = *p1; - p++; - } -# else /* HAS_LINEAR_SCREEN */ + p = MK_SCREEN_POINTER (Cursor_Row, Cursor_Col); + SNOW_CHECK; asm mov ax, ds asm mov bx, si asm mov dx, di - + asm mov cx, n asm les di, p asm lds si, p asm add si, 2 asm cld asm rep movsw - + asm mov ds, ax asm mov si, bx asm mov di, dx -# endif /* HAS_LINEAR_SCREEN */ -# endif /* __os2__ */ -# endif /* EMX_VIDEO */ - -# endif /* WIN32 */ - -#endif /* not GO32_VIDEO */ } -/*----------------------------------------------------------------------*\ - * Function: void SLtt_erase_line (void); - * - * This function is *only* called on exit. - * It sets attribute byte to Black & White -\*----------------------------------------------------------------------*/ void SLtt_erase_line (void) { - -#ifndef WIN32 - -# if defined (GO32_VIDEO) || defined (EMX_VIDEO) + unsigned short w, *p; + + p = MK_SCREEN_POINTER (Cursor_Row, 0); Attribute_Byte = 0x07; - slvid_deleol (0); -# else /* GO32_VIDEO or EMX_VIDEO */ -# if defined (__os2__) - USHORT w; - Attribute_Byte = 0x07; - w = mkSpaceChar (); - VioWrtNCell ((BYTE*)&w, SLtt_Screen_Cols, Cursor_Row, 0, 0); -# else /* __os2__ */ - unsigned short w; - unsigned short *p = mkScreenPointer (Cursor_Row, 0); -# if defined (HAS_LINEAR_SCREEN) - register unsigned short *pmax = p + SLtt_Screen_Cols; - - Attribute_Byte = 0x07; - w = mkSpaceChar (); - while (p < pmax) *p++ = w; -# else /* HAS_LINEAR_SCREEN */ - Attribute_Byte = 0x07; - w = mkSpaceChar (); + + w = MK_SPACE_CHAR (); + SNOW_CHECK; asm mov dx, di asm mov ax, w @@ -587,38 +267,14 @@ void SLtt_erase_line (void) asm cld asm rep stosw asm mov di, dx -# endif /* HAS_LINEAR_SCREEN */ -# endif /* __os2__ */ -# endif /* GO32_VIDEO or EMX_VIDEO */ + Current_Color = JNO_COLOR; /* since we messed with attribute byte */ - -#endif /* WIN32 */ - } -/*----------------------------------------------------------------------*\ - * Function: void SLtt_delete_nlines (int nlines); - * - * delete NLINES by scrolling up the region -\*----------------------------------------------------------------------*/ void SLtt_delete_nlines (int nlines) { SLtt_normal_video (); - -#ifndef WIN32 - -# if defined (EMX_VIDEO) - v_attrib (Attribute_Byte); - v_scroll (0, Scroll_r1, SLtt_Screen_Cols-1, Scroll_r2, nlines, V_SCROLL_UP); -# else /* EMX_VIDEO */ -# if defined (__os2__) - { - Line_Buffer[0] = ' '; Line_Buffer[1] = Attribute_Byte; - VioScrollUp (Scroll_r1, 0, Scroll_r2, SLtt_Screen_Cols-1, - nlines, (PCH) Line_Buffer, 0); - } -# else /* __os2__ */ -# if defined (USE_ASM) + /* This has the effect of pulling all lines below it up */ asm mov ax, nlines asm mov ah, 6 /* int 6h */ @@ -629,55 +285,11 @@ void SLtt_delete_nlines (int nlines) asm mov dh, byte ptr Scroll_r2 asm mov bh, byte ptr Attribute_Byte asm int 10h -# else /* USE_ASM */ - { - union REGS r; -# if defined (__WATCOMC__) - r.x.eax = nlines; - r.x.ecx = 0; -# else - r.x.ax = nlines; - r.x.cx = 0; -# endif - r.h.ah = 6; - r.h.ch = Scroll_r1; - r.h.dl = SLtt_Screen_Cols - 1; - r.h.dh = Scroll_r2; - r.h.bh = Attribute_Byte; - int86 (0x10, &r, &r); - } -# endif /* USE_ASM */ -# endif /* __os2__ */ -# endif /* EMX_VIDEO */ - -#endif /* WIN32 */ - } -/*----------------------------------------------------------------------*\ - * Function: void SLtt_reverse_index (int nlines); - * - * scroll down the region by NLINES -\*----------------------------------------------------------------------*/ void SLtt_reverse_index (int nlines) { SLtt_normal_video (); - -#ifndef WIN32 - -# if defined (EMX_VIDEO) - v_attrib (Attribute_Byte); - v_scroll (0, Scroll_r1, SLtt_Screen_Cols-1, Scroll_r2, nlines, - V_SCROLL_DOWN); -# else /* EMX_VIDEO */ -# if defined (__os2__) - { - Line_Buffer[0] = ' '; Line_Buffer[1] = Attribute_Byte; - VioScrollDn (Scroll_r1, 0, Scroll_r2, SLtt_Screen_Cols-1, - nlines, (PCH) Line_Buffer, 0); - } -# else /* __os2__ */ -# if defined (USE_ASM) asm xor cx, cx asm mov ch, byte ptr Scroll_r1 asm mov dx, SLtt_Screen_Cols @@ -687,81 +299,14 @@ void SLtt_reverse_index (int nlines) asm mov ah, 7 asm mov al, byte ptr nlines asm int 10h -# else /* USE_ASM */ - { - union REGS r; - r.h.al = nlines; -# if defined (__WATCOMC__) - r.x.ecx = 0; -# else - r.x.cx = 0; -# endif - r.h.ah = 7; - r.h.ch = Scroll_r1; - r.h.dl = SLtt_Screen_Cols - 1; - r.h.dh = Scroll_r2; - r.h.bh = Attribute_Byte; - int86 (0x10, &r, &r); - } -# endif /* USE_ASM */ -# endif /* __os2__ */ -# endif /* EMX_VIDEO */ - -#endif /* WIN32 */ - } -/*----------------------------------------------------------------------*\ - * Function: static void slvid_invert_region (int top_row, int bot_row); - * - * invert the display in the region, top_row <= row < bot_row -\*----------------------------------------------------------------------*/ -static void slvid_invert_region (int top_row, int bot_row) +static void asm_video_invert_region (int top_row, int bot_row) { - -#ifndef WIN32 - -# if defined (EMX_VIDEO) - int row, col; - - for (row = top_row; row < bot_row; row++) - { - v_getline (Line_Buffer, 0, row, SLtt_Screen_Cols); - for (col = 1; col < SLtt_Screen_Cols * 2; col += 2) - Line_Buffer [col] ^= 0xff; - v_putline (Line_Buffer, 0, row, SLtt_Screen_Cols); - } -# else /* EMX_VIDEO */ -# ifdef __os2__ - int row, col; - USHORT length = SLtt_Screen_Cols * 2; - - for (row = top_row; row < bot_row; row++) - { - VioReadCellStr ((PCH)Line_Buffer, &length, row, 0, 0); - for (col = 1; col < length; col += 2) - Line_Buffer [col] ^= 0xff; - VioWrtCellStr ((PCH)Line_Buffer, length, row, 0, 0); - } -# else /* __os2__ */ -# if defined (__GO32__) || defined (__WATCOMC__) - unsigned char buf [2 * 180 * 80]; /* 180 cols x 80 rows */ - unsigned char *b, *bmax; - - b = buf + 1 + 2 * SLtt_Screen_Cols * top_row; - bmax = buf + 1 + 2 * SLtt_Screen_Cols * bot_row; - ScreenRetrieve (buf); - while (b < bmax) - { - *b ^= 0xFF; - b += 2; - } - ScreenUpdate (buf); -# else /* __GO32__ or __WATCOMC__ */ register unsigned short ch, sh; - register unsigned short *pmin = mkScreenPointer (top_row, 0); - register unsigned short *pmax = mkScreenPointer (bot_row, 0); - + register unsigned short *pmin = MK_SCREEN_POINTER (top_row, 0); + register unsigned short *pmax = MK_SCREEN_POINTER (bot_row, 0); + while (pmin < pmax) { sh = *pmin; @@ -770,97 +315,19 @@ static void slvid_invert_region (int top_row, int bot_row) *pmin = (ch & 0xFF00) | (sh & 0x00FF); pmin++; } -# endif /* __GO32__ or __WATCOMC__ */ -# endif /* __os2__ */ -# endif /* EMX_VIDEO */ - -#endif /* WIN32 */ - } -/*----------------------------------------------------------------------*\ - * Function: void SLtt_beep (void); - * - * signal error by a "bell" condition, the type of signal is governed - * by the value of SLtt_Ignore_Beep: - * - * 0 silent bell - * 1 audible bell - * 2 visual bell - * 4 special visual bell (only flash the bottom status line) - * - * these may be combined: - * eg, 3 = audible visual bell. - * but if both the visual bell and the "special" visual bell are specified, - * only the special bell is used. -\*----------------------------------------------------------------------*/ -void SLtt_beep (void) -{ - int audible; /* audible bell */ - int special = 0; /* first row to invert */ - int visual = 0; /* final row to invert */ - if (!SLtt_Ignore_Beep) return; - - audible = (SLtt_Ignore_Beep & 1); - if ( (SLtt_Ignore_Beep & 4) ) - { - special = SLtt_Screen_Rows - 1; - visual = special--; /* only invert bottom status line */ - } - else if ( (SLtt_Ignore_Beep & 2) ) - { - visual = SLtt_Screen_Rows; - } - - if (visual) slvid_invert_region (special, visual); -#if defined (EMX_VIDEO) - if (audible) /*sound (1500)*/; _sleep2 (100); if (audible) /* nosound () */; -#else -# ifdef __os2__ - if (audible) DosBeep (1500, 100); else DosSleep (100); - -# elif defined(WIN32) - -# else - if (audible) sound (1500); delay (100); if (audible) nosound (); -# endif -#endif - if (visual) slvid_invert_region (special, visual); -} - -/*----------------------------------------------------------------------*\ - * Function: void SLtt_del_eol (void); - * - * delete from the current cursor position to the end of the row -\*----------------------------------------------------------------------*/ void SLtt_del_eol (void) { - -#ifndef WIN32 - -# if defined (GO32_VIDEO) || defined (EMX_VIDEO) - if (Current_Color != JNO_COLOR) SLtt_normal_video (); - slvid_deleol (Cursor_Col); -# else /* GO32_VIDEO or EMX_VIDEO */ -# ifdef __os2__ - USHORT w; - if (Current_Color != JNO_COLOR) SLtt_normal_video (); - w = mkSpaceChar (); - VioWrtNCell ((BYTE*)&w, (SLtt_Screen_Cols - Cursor_Col), - Cursor_Row, Cursor_Col, 0); -# else /* __os2__ */ - unsigned short *p = mkScreenPointer (Cursor_Row, Cursor_Col); - int n = SLtt_Screen_Cols - Cursor_Col; + unsigned short *p; unsigned short w; -# if defined (HAS_LINEAR_SCREEN) - unsigned short *pmax = p + n; - + int n; + + n = SLtt_Screen_Cols - Cursor_Col; + p = MK_SCREEN_POINTER (Cursor_Row, Cursor_Col); if (Current_Color != JNO_COLOR) SLtt_normal_video (); - w = mkSpaceChar (); - while (p < pmax) *p++ = w; -# else /* HAS_LINEAR_SCREEN */ - if (Current_Color != JNO_COLOR) SLtt_normal_video (); - w = mkSpaceChar (); + w = MK_SPACE_CHAR (); + SNOW_CHECK; asm mov dx, di asm les di, p @@ -868,107 +335,66 @@ void SLtt_del_eol (void) asm mov cx, n asm cld asm rep stosw - + asm mov di, dx -# endif /* HAS_LINEAR_SCREEN */ -# endif /* __os2__ */ -# endif /* GO32_VIDEO or EMX_VIDEO */ - -#endif /* WIN32 */ - } -/*----------------------------------------------------------------------*\ - * Function: void SLtt_reverse_video (int color); - * - * set Attribute_Byte corresponding to COLOR. - * Use Current_Color to remember the color which was set. - * convert from the COLOR number to the attribute value. -\*----------------------------------------------------------------------*/ -void SLtt_reverse_video (int color) -{ - Attribute_Byte = Color_Map [color]; - Current_Color = color; -} - -/*----------------------------------------------------------------------*\ - * Function: void SLtt_normal_video (void); - * - * reset the attributes for normal video -\*----------------------------------------------------------------------*/ -void SLtt_normal_video (void) -{ - SLtt_reverse_video (JNORMAL_COLOR); -} - -#if defined (USE_ASM) -/*----------------------------------------------------------------------*\ - * Function: static unsigned short *video_write (register unsigned char *pp, - * register unsigned char *p, - * register unsigned short *pos) - * - * write out (P - PP) characters from the array pointed to by PP - * at position (POS, Cursor_Row) in the current Attribute_Byte - * - * increment POS to reflect the number of characters sent and - * return the it as a pointer -\*----------------------------------------------------------------------*/ -static unsigned short *video_write (register unsigned char *pp, - register unsigned char *p, - register unsigned short *pos) +static unsigned short *asm_video_write (register unsigned char *pp, + register unsigned char *p, + register unsigned short *pos) { int n = (int) (p - pp); /* num of characters of PP to write */ - + asm push si asm push ds asm push di - + /* set up register for BOTH fast and slow */ asm mov bx, SLtt_Msdos_Cheap_Video - + /* These are the registers needed for both fast AND slow */ asm mov ah, byte ptr Attribute_Byte asm mov cx, n asm lds si, dword ptr pp asm les di, dword ptr pos asm cld - + asm cmp bx, 0 /* cheap video test */ asm je L_fast asm mov bx, ax asm mov dx, CGA_STATUS asm jg L_slow_blank - + /* slow video */ asm cli - + /* wait for retrace */ L_slow: asm in al, dx asm test al, 1 asm jnz L_slow - + L_slow1: asm in al, dx asm test al, 1 asm jz L_slow1 - + /* move a character out */ asm mov ah, bh asm lodsb asm stosw asm loop L_slow - + asm sti asm jmp done - + /* -------------- slow video, vertical retace and pump --------------*/ L_slow_blank: L_slow_blank_loop: asm in al, dx asm test al, 8 asm jnz L_slow_blank_loop - + L_slow_blank1: asm in al, dx asm test al, 8 @@ -979,10 +405,10 @@ static unsigned short *video_write (register unsigned char *pp, asm lodsb asm stosw asm loop L_slow_blank2 - + asm jmp done /*-------------- Fast video --------------*/ - + L_fast: asm lodsb asm stosw @@ -993,211 +419,41 @@ static unsigned short *video_write (register unsigned char *pp, asm pop si return (pos + n); } -#endif /* USE_ASM */ -/*----------------------------------------------------------------------*\ - * Function: static void write_attributes (unsigned short *src, - * int count); - * - * Copy COUNT character/color pairs from the array pointed to by - * SRC to the screen at position (0,Cursor_Row). - * NB: SRC contains character/color pairs -- the color must be converted to - * an ansi attribute. - * - * Write out - * 1) a combination of string/attributes - * 2) each string of continuous colour - * - * approach 2) is used for assembler output, while 1) is used when a higher - * level API is available or direct to memory writing is possible: emx video - * routines, os/2, go32, watcom. -\*----------------------------------------------------------------------*/ -static void write_attributes (unsigned short *src, int count) +static void write_attributes (SLsmg_Char_Type *src, unsigned int count) { - register unsigned char *p = Line_Buffer; + register unsigned char *p; register unsigned short pair; -#ifdef WIN32 - register unsigned char * org_src = src; - COORD coord; - long bytes; -#endif -#if !defined (USE_ASM) -# if defined (HAS_LINEAR_SCREEN) - register unsigned short *pos = mkScreenPointer (Cursor_Row, 0); -# endif - int n = count; - - /* write into a character/attribute pair */ - while (n-- > 0) - { - pair = *(src++); /* character/color pair */ - SLtt_reverse_video (pair >> 8); /* color change */ -# if defined (HAS_LINEAR_SCREEN) - *(pos++) = ((unsigned short) Attribute_Byte << 8) | pair & 0xff; -# else -# if defined(EMX_VIDEO) || !defined(WIN32) - *(p++) = pair & 0xff; /* character byte */ - *(p++) = Attribute_Byte; /* attribute byte */ -# else - /* WIN32 for now... */ - *(p++) = pair & 0xff; -# endif -# endif - } - -# if !defined (HAS_LINEAR_SCREEN) -# if defined (EMX_VIDEO) - v_putline (Line_Buffer, Cursor_Col, Cursor_Row, count); -# else /* EMX_VIDEO */ -# if defined (__os2__) - VioWrtCellStr ((PCH)Line_Buffer, (USHORT)(2 * count), - (USHORT)Cursor_Row, (USHORT)Cursor_Col, 0); -# elif defined(WIN32) - /* do color attributes later */ - p = Line_Buffer; - coord.X = Cursor_Col; - coord.Y = Cursor_Row; - WriteConsoleOutputCharacter(hStdout, p, count, coord, &bytes); - - /* write color attributes */ - p = Line_Buffer; - n = count; - src = org_src; /* restart the src pointer */ - - /* write into attributes only */ - while (n-- > 0) - { - pair = *(src++); /* character/color pair */ - SLtt_reverse_video (pair >> 8); /* color change */ - *(p++) = Attribute_Byte; /* attribute byte */ - *(p++) = 0; /* what's this for? */ - } - - WriteConsoleOutputAttribute(hStdout, Line_Buffer, count, coord, &bytes); -# else /* __os2__ */ - /* ScreenUpdateLine (void *virtual_screen_line, int row); */ - p = Line_Buffer; - n = Cursor_Col; - while (count-- > 0) - { - ScreenPutChar ((int)p[0], (int)p[1], n++, Cursor_Row); - p += 2; - } -# endif /* EMX_VIDEO */ -# endif /* __os2__ */ -# endif /* HAS_LINEAR_SCREEN */ -#else /* not USE_ASM */ unsigned char ch, color; - register unsigned short *pos = mkScreenPointer (Cursor_Row, 0); - + register unsigned short *pos; + + p = Line_Buffer; + pos = MK_SCREEN_POINTER (Cursor_Row, 0); + while (count--) { - pair = *(src++); /* character/color pair */ + pair = SLSMG_CHAR_TO_USHORT(*src); /* character/color pair */ + src++; ch = pair & 0xff; /* character value */ color = pair >> 8; /* color value */ if (color != Current_Color) /* need a new color */ { if (p != Line_Buffer) { - pos = video_write (Line_Buffer, p, pos); + pos = asm_video_write (Line_Buffer, p, pos); p = Line_Buffer; } SLtt_reverse_video (color); /* change color */ } *(p++) = ch; } - pos = video_write (Line_Buffer, p, pos); -#endif /* not USE_ASM */ + pos = asm_video_write (Line_Buffer, p, pos); } -/*----------------------------------------------------------------------*\ - * Function: void SLtt_smart_puts (unsigned short *new_string, - * unsigned short *old_string, - * int len, int row); - * - * puts NEW_STRING, which has length LEN, at row ROW. NEW_STRING contains - * characters/colors packed in the form value = ((color << 8) | (ch)); - * - * the puts tries to avoid overwriting the same characters/colors - * - * OLD_STRING is not used, maintained for compatibility with other systems -\*----------------------------------------------------------------------*/ -void SLtt_smart_puts (unsigned short *new_string, - unsigned short *old_string, - int len, int row) -{ - (void) old_string; - Cursor_Row = row; - Cursor_Col = 0; - write_attributes (new_string, len); -} - -/*----------------------------------------------------------------------*\ - * Function: void SLtt_reset_video (void); -\*----------------------------------------------------------------------*/ -void SLtt_reset_video (void) -{ - SLtt_goto_rc (SLtt_Screen_Rows - 1, 0); -#ifdef HAS_SAVE_SCREEN - restore_screen (); -#endif - Attribute_Byte = 0x07; - Current_Color = JNO_COLOR; - SLtt_del_eol (); -} - -#if 0 -void wide_width (void) -{ -} - -void narrow_width (void) -{ -} -#endif - -/*----------------------------------------------------------------------*\ - * Function: void SLtt_cls (void); -\*----------------------------------------------------------------------*/ void SLtt_cls (void) { -#ifdef WIN32 - long bytes; - COORD coord; - char ch; -#endif SLtt_normal_video (); -#if defined (__GO32__) || defined (__WATCOMC__) || defined (EMX_VIDEO) - SLtt_reset_scroll_region (); - SLtt_goto_rc (0, 0); - SLtt_delete_nlines (SLtt_Screen_Rows); -#else /* __GO32__ or __WATCOMC__ or EMX_VIDEO */ -# ifdef __os2__ - { - Line_Buffer [0] = ' '; Line_Buffer [1] = Attribute_Byte; - VioScrollUp (0, 0, -1, -1, -1, (PCH)Line_Buffer, 0); - } -# elif defined(WIN32) - /* clear the WIN32 screen in one shot */ - coord.X = 0; - coord.Y = 0; - - ch = ' '; - - (void) FillConsoleOutputCharacter(hStdout, - ch, - csbiInfo.dwSize.Y * csbiInfo.dwSize.X, - coord, - &bytes); - - /* now set screen to the current attribute */ - ch = Attribute_Byte; - (void) FillConsoleOutputAttribute(hStdout, - ch, - csbiInfo.dwSize.Y * csbiInfo.dwSize.X, - coord, - &bytes); -# else /* __os2__ */ + asm mov dx, SLtt_Screen_Cols asm dec dx asm mov ax, SLtt_Screen_Rows @@ -1208,319 +464,94 @@ void SLtt_cls (void) asm mov ah, 7 asm mov bh, byte ptr Attribute_Byte asm int 10h -# endif /* __os2__ */ -#endif /* __GO32__ or __WATCOMC__ or EMX_VIDEO */ } -/*----------------------------------------------------------------------*\ - * Function: void SLtt_putchar (char ch); - * - * put CH on the screen in the current position. - * this function is called assuming that cursor is in correct position -\*----------------------------------------------------------------------*/ - void SLtt_putchar (char ch) { -#if !defined (GO32_VIDEO) && !defined (EMX_VIDEO) unsigned short p, *pp; -# if defined(WIN32) - long bytes; -# endif -#endif - + if (Current_Color) SLtt_normal_video (); - slvid_getxy (); /* get current position */ + asm_video_getxy (); /* get current position */ switch (ch) { case 7: /* ^G - break */ SLtt_beep (); break; case 8: /* ^H - backspace */ - SLtt_goto_rc (Cursor_Row, Cursor_Col - 1); break; + goto_rc_abs (Cursor_Row, Cursor_Col - 1); break; case 13: /* ^M - carriage return */ - SLtt_goto_rc (Cursor_Row, 0); break; - default: /* write character to screen */ -#if defined (EMX_VIDEO) - v_putn (ch, 1); -#else /* EMX_VIDEO */ -# ifdef __os2__ - VioWrtCharStrAtt (&ch, 1, Cursor_Row, Cursor_Col, - (BYTE*)&Attribute_Byte, 0); -# elif defined(WIN32) - WriteConsole(hStdout, &ch, 1, &bytes, NULL); -# else /* __os2__ */ -# ifdef GO32_VIDEO - ScreenPutChar ((int) ch, Attribute_Byte, Cursor_Col, Cursor_Row); -# else /* GO32_VIDEO */ - pp = mkScreenPointer (Cursor_Row, Cursor_Col); + goto_rc_abs (Cursor_Row, 0); break; + default: + /* write character to screen */ + pp = MK_SCREEN_POINTER (Cursor_Row, Cursor_Col); p = (Attribute_Byte << 8) | (unsigned char) ch; - -# ifdef USE_ASM SNOW_CHECK; -# endif *pp = p; -# endif /* GO32_VIDEO */ -# endif /* __os2__ */ -#endif /* EMX_VIDEO */ - SLtt_goto_rc (Cursor_Row, Cursor_Col + 1); + goto_rc_abs (Cursor_Row, Cursor_Col + 1); } } -/*----------------------------------------------------------------------*\ - * Function: void SLtt_set_color (int obj, char *what, char *fg, char *bg); - * - * set foreground and background colors of OBJ to the attributes which - * correspond to the names FG and BG, respectively. - * - * WHAT is the name corresponding to the object OBJ, but is not used in - * this routine. -\*----------------------------------------------------------------------*/ -void SLtt_set_color (int obj, char *what, char *fg, char *bg) +void SLtt_get_screen_size (void) { - int i, b = -1, f = -1; -#ifdef WIN32 - int newcolor; -#endif - - (void) what; - - if ( !IsColor || (obj < 0) || (obj >= JMAX_COLORS)) - return; - - for (i = 0; i < JMAX_COLOR_NAMES; i++ ) - { - if (!strcmp (fg, Color_Names [i])) - { - f = i; - break; - } - } - - for (i = 0; i < JMAX_COLOR_NAMES; i++) - { - if (!strcmp (bg, Color_Names [i])) - { - if (Blink_Killed) b = i; else b = i & 0x7; - break; - } - } - if ((f == -1) || (b == -1) || (f == b)) return; -#if 1 - Color_Map [obj] = (b << 4) | f; -#else - - /* - 0 1 2 3 - "black", "blue", "green", "cyan", - 4 5 6 7 - "red", "magenta", "brown", "lightgray", - 8 9 10 11 - "gray", "brightblue", "brightgreen", "brightcyan", - 12 13 14 15 - "brightred", "brightmagenta", "yellow", "white" - */ - - /* these aren't all right yet */ - switch (f) - { - case 0: newcolor = 0; break; - case 1: newcolor = FOREGROUND_BLUE; break; - case 2: newcolor = FOREGROUND_GREEN; break; - case 3: newcolor = FOREGROUND_GREEN | FOREGROUND_BLUE; break; - - case 4: newcolor = FOREGROUND_RED; break; - case 5: newcolor = FOREGROUND_RED | FOREGROUND_BLUE; break; - case 6: newcolor = FOREGROUND_GREEN | FOREGROUND_RED; break; - case 7: newcolor = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY; break; - - case 8: newcolor = FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN; break; - case 9: newcolor = FOREGROUND_BLUE | FOREGROUND_INTENSITY; break; - case 10: newcolor = FOREGROUND_GREEN | FOREGROUND_INTENSITY; break; - case 11: newcolor = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY; break; - - case 12: newcolor = FOREGROUND_RED | FOREGROUND_INTENSITY; break; - case 13: newcolor = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY; break; - case 14: newcolor = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY; break; - case 15: newcolor = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY; break; - } - /* switch (f) */ - - /* - 0 1 2 3 - "black", "blue", "green", "cyan", - 4 5 6 7 - "red", "magenta", "brown", "lightgray", - 8 9 10 11 - "gray", "brightblue", "brightgreen", "brightcyan", - 12 13 14 15 - "brightred", "brightmagenta", "yellow", "white" - */ - - switch (b) - { - case 0: newcolor |= 0; break; - case 1: newcolor |= BACKGROUND_BLUE; break; - case 2: newcolor |= BACKGROUND_GREEN; break; - case 3: newcolor |= BACKGROUND_GREEN | BACKGROUND_BLUE; break; - - case 4: newcolor |= BACKGROUND_RED; break; - case 5: newcolor |= BACKGROUND_RED | BACKGROUND_BLUE; break; - case 6: newcolor |= BACKGROUND_GREEN | BACKGROUND_RED; break; - case 7: newcolor |= BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY; break; - - case 8: newcolor |= BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE; break; - case 9: newcolor |= BACKGROUND_BLUE | BACKGROUND_INTENSITY; break; - case 10: newcolor |= BACKGROUND_GREEN | BACKGROUND_INTENSITY; break; - case 11: newcolor |= BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY; break; - - case 12: newcolor |= BACKGROUND_RED | BACKGROUND_INTENSITY; break; - case 13: newcolor |= BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY; break; - case 14: newcolor |= BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY; break; - case 15: newcolor |= BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY; break; - } - /* switch (b) */ - - Color_Map [obj] = newcolor; - -#endif - /* if we're setting the normal color, and the attribute byte hasn't - been set yet, set it to the new color */ - if ((obj == 0) && (Attribute_Byte == 0)) - SLtt_reverse_video (0); + int w, h; + + h = 0; + + /* Get BIOS's screenwidth, this works on ALL displays. */ + w = *((int *)MK_FP(0x40, 0x4a)); + + /* Use Ralf Brown test for EGA or greater */ + asm mov ah, 12h + asm mov bl, 10h + asm mov bh, 0xFF /* EGA or greater will change this */ + asm int 10h + asm cmp bh, 0xFF + asm je L1 + /* if EGA or compatible: Get BIOS's number of rows. */ + h = *(char *)MK_FP(0x40, 0x84) + 1; + /* scan_lines = *(int *) 0x485; */ + + L1: + if (h <= 0) h = 25; + + SLtt_Screen_Rows = h; + SLtt_Screen_Cols = w; } -/*----------------------------------------------------------------------*\ - * Function: void SLtt_get_terminfo (void) -\*----------------------------------------------------------------------*/ void SLtt_get_terminfo (void) { -#ifdef WIN32 - SLtt_Screen_Rows = csbiInfo.dwSize.Y; - SLtt_Screen_Cols = csbiInfo.dwSize.X; -#endif -#ifdef GO32_VIDEO - SLtt_Screen_Rows = ScreenRows (); - SLtt_Screen_Cols = ScreenCols (); -#endif + SLtt_get_screen_size (); } /*----------------------------------------------------------------------*\ - * Function: void SLtt_init_video (void); + * Function: int SLtt_init_video (void); \*----------------------------------------------------------------------*/ -void SLtt_init_video (void) +int SLtt_init_video (void) { -#if defined (EMX_VIDEO) - int OldCol, OldRow; -#endif - + unsigned char *p; + #ifdef HAS_SAVE_SCREEN save_screen (); #endif Cursor_Row = Cursor_Col = 0; - -#if defined (EMX_VIDEO) - - v_init (); - if ( v_hardware () != V_MONOCHROME ) IsColor = 1; else IsColor = 0; + p = (unsigned char far *) 0x00400049L; + if (*p == 7) + { + Video_Status_Port = MONO_STATUS; + Video_Base = (unsigned char *) MK_FP (0xb000,0000); + IsColor = 0; + } + else + { + Video_Status_Port = CGA_STATUS; + Video_Base = (unsigned char *) MK_FP (0xb800,0000); + IsColor = 1; + } - v_getxy(&OldCol,&OldRow); - - v_gotoxy (0, 0); - if (IsColor) - { - if (_osmode == OS2_MODE) - { -# if 0 - /* Enable high-intensity background colors */ - VIOINTENSITY RequestBlock; - RequestBlock.cb = sizeof (RequestBlock); - RequestBlock.type = 2; RequestBlock.fs = 1; - VioSetState (&RequestBlock, 0); /* nop if !fullscreen */ -# endif - Blink_Killed = 1; - } - else - { - Blink_Killed = 1; /* seems to work */ - } - } - - if (!Attribute_Byte) - { - /* find the attribute currently under the cursor */ - v_getline (Line_Buffer, OldCol, OldRow, 1); - Attribute_Byte = Line_Buffer[1]; - set_color_from_attribute (Attribute_Byte); - } - - v_attrib (Attribute_Byte); - /* SLtt_Term_Cannot_Insert = 1; */ -#else /* EMX_VIDEO */ -# ifdef __os2__ - IsColor = 1; /* is it really? */ - { - /* Enable high-intensity background colors */ - VIOINTENSITY RequestBlock; - RequestBlock.cb = sizeof (RequestBlock); - RequestBlock.type = 2; RequestBlock.fs = 1; - VioSetState (&RequestBlock, 0); /* nop if !fullscreen */ - Blink_Killed = 1; - } - - if (!Attribute_Byte) - { - /* find the attribute currently under the cursor */ - USHORT Length = 2, Row, Col; - VioGetCurPos (&Row, &Col, 0); - VioReadCellStr ((PCH)Line_Buffer, &Length, Row, Col, 0); - Attribute_Byte = Line_Buffer[1]; - set_color_from_attribute (Attribute_Byte); - } -# elif defined(WIN32) - /* initialize the WIN32 console */ - IsColor = 1; /* yes, the WIN32 console can do color (on a color monitor) */ -# else -# if defined (__GO32__) || defined (__WATCOMC__) -# ifdef GO32_VIDEO - SLtt_Term_Cannot_Insert = 1; -# else - Video_Base = (unsigned char *) ScreenPrimary; -# endif - if (!Attribute_Byte) Attribute_Byte = 0x17; - IsColor = 1; /* is it really? */ - - if (IsColor) - { - union REGS r; -# ifdef __WATCOMC__ - r.x.eax = 0x1003; r.x.ebx = 0; -# else - r.x.ax = 0x1003; r.x.bx = 0; -# endif - int86 (0x10, &r, &r); - Blink_Killed = 1; - } -# else /* (__GO32__ or __WATCOMC__ */ - { - unsigned char *p = (unsigned char far *) 0x00400049L; - if (*p == 7) - { - Video_Status_Port = MONO_STATUS; - Video_Base = (unsigned char *) MK_FP (0xb000,0000); - IsColor = 0; - } - else - { - Video_Status_Port = CGA_STATUS; - Video_Base = (unsigned char *) MK_FP (0xb800,0000); - IsColor = 1; - } - } - /* test for video adapter type. Of primary interest is whether there is * snow or not. Assume snow if the card is color and not EGA or greater. */ - + /* Use Ralf Brown test for EGA or greater */ asm mov ah, 0x12 asm mov bl, 0x10 @@ -1528,7 +559,7 @@ void SLtt_init_video (void) asm int 10h asm cmp bh, 0xFF asm je L1 - + /* (V)EGA */ asm xor bx, bx asm mov SLtt_Msdos_Cheap_Video, bx @@ -1538,7 +569,7 @@ void SLtt_init_video (void) asm mov ax, 0x17 asm mov Attribute_Byte, ax asm jmp L2 - + L1: /* Not (V)EGA */ asm mov ah, 0x0F @@ -1562,11 +593,1569 @@ void SLtt_init_video (void) asm int 0x10 Blink_Killed = 1; } -# endif /* __GO32__ or __WATCOMC__ */ -# endif /* __os2__ */ -#endif /* EMX_VIDEO */ - SLtt_set_scroll_region (0, SLtt_Screen_Rows); + SLtt_Use_Ansi_Colors = IsColor; + SLtt_get_screen_size (); + SLtt_reset_scroll_region (); + fixup_colors (); + return 0; +} + +void SLtt_beep (void) +{ + int audible; /* audible bell */ + int special = 0; /* first row to invert */ + int visual = 0; /* final row to invert */ + + if (!SLtt_Ignore_Beep) return; + + audible = (SLtt_Ignore_Beep & 1); + if ( (SLtt_Ignore_Beep & 4) ) + { + special = SLtt_Screen_Rows - 1; + visual = special--; /* only invert bottom status line */ + } + else if ( (SLtt_Ignore_Beep & 2) ) + { + visual = SLtt_Screen_Rows; + } + + if (visual) asm_video_invert_region (special, visual); + if (audible) sound (1500); delay (100); if (audible) nosound (); + if (visual) asm_video_invert_region (special, visual); +} + +#endif /* IBMPC_ASM_VIDEO */ + +/*}}}*/ + +#ifdef GO32_VIDEO /*{{{*/ + +# include +# define HAS_SAVE_SCREEN 1 + +# ifdef HAS_SAVE_SCREEN +static void *Saved_Screen_Buffer; +static int Saved_Cursor_Row; + +static void save_screen (void) +{ + int row, col; + + SLfree ((char *) Saved_Screen_Buffer); + Saved_Screen_Buffer = NULL; + + Saved_Screen_Buffer = (short *) SLmalloc (sizeof (short) * + ScreenCols () * ScreenRows ()); + + if (Saved_Screen_Buffer == NULL) + return; + + ScreenRetrieve (Saved_Screen_Buffer); + ScreenGetCursor (&row, &col); + Saved_Cursor_Row = row; +} + +static void restore_screen (void) +{ + if (Saved_Screen_Buffer == NULL) return; + ScreenUpdate (Saved_Screen_Buffer); + goto_rc_abs (Saved_Cursor_Row, 0); +} +#endif /* HAS_SAVE_SCREEN */ + +void SLtt_write_string (char *str) +{ + while (Cursor_Col < SLtt_Screen_Cols) + { + char ch = *str++; + + if (ch == 0) + break; + + ScreenPutChar (ch, Attribute_Byte, Cursor_Col, Cursor_Row); + Cursor_Col++; + } + goto_rc_abs (Cursor_Row, Cursor_Col); +} + +void SLtt_goto_rc (int row, int col) +{ + row += Scroll_r1; + if (row > SLtt_Screen_Rows) row = SLtt_Screen_Rows; + if (col > SLtt_Screen_Cols) col = SLtt_Screen_Cols; + + ScreenSetCursor (row, col); + + Cursor_Row = row; + Cursor_Col = col; +} + +static void go32_video_getxy (void) +{ + ScreenGetCursor (&Cursor_Row, &Cursor_Col); +} + +static void go32_video_deleol (int x) +{ + while (x < SLtt_Screen_Cols) + ScreenPutChar (32, Attribute_Byte, x++, Cursor_Row); +} + +void SLtt_begin_insert (void) +{ +} + +void SLtt_end_insert (void) +{ +} + +void SLtt_delete_char (void) +{ +} + +void SLtt_erase_line (void) +{ + Attribute_Byte = 0x07; + go32_video_deleol (0); + Current_Color = JNO_COLOR; /* since we messed with attribute byte */ +} + +void SLtt_delete_nlines (int nlines) +{ + union REGS r; + + SLtt_normal_video (); + + r.x.ax = nlines; + r.x.cx = 0; + r.h.ah = 6; + r.h.ch = Scroll_r1; + r.h.dl = SLtt_Screen_Cols - 1; + r.h.dh = Scroll_r2; + r.h.bh = Attribute_Byte; + int86 (0x10, &r, &r); +} + +void SLtt_reverse_index (int nlines) +{ + union REGS r; + + SLtt_normal_video (); + + r.h.al = nlines; + r.x.cx = 0; + r.h.ah = 7; + r.h.ch = Scroll_r1; + r.h.dl = SLtt_Screen_Cols - 1; + r.h.dh = Scroll_r2; + r.h.bh = Attribute_Byte; + int86 (0x10, &r, &r); +} + +static void go32_video_invert_region (int top_row, int bot_row) +{ + unsigned char buf [2 * 180 * 80]; /* 180 cols x 80 rows */ + unsigned char *b, *bmax; + + b = buf + 1 + 2 * SLtt_Screen_Cols * top_row; + bmax = buf + 1 + 2 * SLtt_Screen_Cols * bot_row; + + ScreenRetrieve (buf); + while (b < bmax) + { + *b ^= 0xFF; + b += 2; + } + ScreenUpdate (buf); +} + +void SLtt_beep (void) +{ + int audible; /* audible bell */ + int special = 0; /* first row to invert */ + int visual = 0; /* final row to invert */ + + if (!SLtt_Ignore_Beep) return; + + audible = (SLtt_Ignore_Beep & 1); + if ( (SLtt_Ignore_Beep & 4) ) + { + special = SLtt_Screen_Rows - 1; + visual = special--; /* only invert bottom status line */ + } + else if ( (SLtt_Ignore_Beep & 2) ) + { + visual = SLtt_Screen_Rows; + } + + if (visual) go32_video_invert_region (special, visual); + if (audible) sound (1500); delay (100); if (audible) nosound (); + if (visual) go32_video_invert_region (special, visual); +} + +void SLtt_del_eol (void) +{ + if (Current_Color != JNO_COLOR) SLtt_normal_video (); + go32_video_deleol (Cursor_Col); +} + +static void +write_attributes (SLsmg_Char_Type *src, unsigned int count) +{ + register unsigned short pair; + unsigned int n; + + /* write into a character/attribute pair */ + n = Cursor_Col; + while (count) + { + pair = SLSMG_CHAR_TO_USHORT(*src);/* character/color pair */ + src++; + SLtt_reverse_video (pair >> 8); /* color change */ + ScreenPutChar ((int)pair & 0xFF, Attribute_Byte, n, Cursor_Row); + n++; + count--; + } +} + +/*----------------------------------------------------------------------*\ + * Function: void SLtt_cls (void); +\*----------------------------------------------------------------------*/ +void SLtt_cls (void) +{ + SLtt_normal_video (); + SLtt_reset_scroll_region (); + SLtt_goto_rc (0, 0); + SLtt_delete_nlines (SLtt_Screen_Rows); +} + +void SLtt_putchar (char ch) +{ + if (Current_Color) SLtt_normal_video (); + + go32_video_getxy (); /* get current position */ + + switch (ch) + { + case 7: /* ^G - break */ + SLtt_beep (); break; + case 8: /* ^H - backspace */ + goto_rc_abs (Cursor_Row, Cursor_Col - 1); break; + case 13: /* ^M - carriage return */ + goto_rc_abs (Cursor_Row, 0); break; + default: /* write character to screen */ + ScreenPutChar ((int) ch, Attribute_Byte, Cursor_Col, Cursor_Row); + goto_rc_abs (Cursor_Row, Cursor_Col + 1); + } +} + +void SLtt_get_screen_size (void) +{ + SLtt_Screen_Rows = ScreenRows (); + SLtt_Screen_Cols = ScreenCols (); +} + +void SLtt_get_terminfo (void) +{ + SLtt_get_screen_size (); +} + +int SLtt_init_video (void) +{ +#ifdef HAS_SAVE_SCREEN + save_screen (); +#endif + + if (!Attribute_Byte) Attribute_Byte = 0x17; + + IsColor = 1; /* is it really? */ + + if (IsColor) + { + union REGS r; + r.x.ax = 0x1003; r.x.bx = 0; + int86 (0x10, &r, &r); + Blink_Killed = 1; + } + + Cursor_Row = Cursor_Col = 0; + + SLtt_Term_Cannot_Insert = 1; + SLtt_reset_scroll_region (); + SLtt_Use_Ansi_Colors = IsColor; + fixup_colors (); + return 0; +} + +#endif /* GO32_VIDEO */ + +/*}}}*/ + +#ifdef EMX_VIDEO /*{{{*/ + +# define INCL_VIO +# define INCL_DOSPROCESS +# include +# include +# include + +static VIOMODEINFO vioModeInfo; +/* buffer to hold a line of character/attribute pairs */ +#define MAXCOLS 256 +static unsigned char Line_Buffer [MAXCOLS*2]; + +/* this is how to make a space character */ +#define MK_SPACE_CHAR() (((Attribute_Byte) << 8) | 0x20) + +void SLtt_write_string (char *str) +{ + /* FIXME: Priority=medium + * This should not go to stdout. */ + fputs (str, stdout); +} + +void SLtt_goto_rc (int row, int col) +{ + row += Scroll_r1; + if (row > SLtt_Screen_Rows) row = SLtt_Screen_Rows; + if (col > SLtt_Screen_Cols) col = SLtt_Screen_Cols; + v_gotoxy (col, row); + Cursor_Row = row; + Cursor_Col = col; +} + +static void emx_video_getxy (void) +{ + v_getxy (&Cursor_Col, &Cursor_Row); +} + +static void emx_video_deleol (int x) +{ + unsigned char *p, *pmax; + int count = SLtt_Screen_Cols - x; + int w = MK_SPACE_CHAR (); + + p = Line_Buffer; + pmax = p + 2 * count; + + while (p < pmax) + { + *p++ = (unsigned char) w; + *p++ = (unsigned char) (w >> 8); + } + + v_putline (Line_Buffer, x, Cursor_Row, count); +} + +void SLtt_begin_insert (void) +{ + int n; + + emx_video_getxy (); + + n = SLtt_Screen_Cols - Cursor_Col; + v_getline (Line_Buffer, Cursor_Col, Cursor_Row, n); + v_putline (Line_Buffer, Cursor_Col+1, Cursor_Row, n - 1); +} + +void SLtt_end_insert (void) +{ +} + +void SLtt_delete_char (void) +{ + int n; + + emx_video_getxy (); + + n = SLtt_Screen_Cols - Cursor_Col - 1; + v_getline (Line_Buffer, Cursor_Col+1, Cursor_Row, n); + v_putline (Line_Buffer, Cursor_Col, Cursor_Row, n); +} + +void SLtt_erase_line (void) +{ + Attribute_Byte = 0x07; + emx_video_deleol (0); + Current_Color = JNO_COLOR; /* since we messed with attribute byte */ +} + +void SLtt_delete_nlines (int nlines) +{ + SLtt_normal_video (); + v_attrib (Attribute_Byte); + v_scroll (0, Scroll_r1, SLtt_Screen_Cols-1, Scroll_r2, nlines, V_SCROLL_UP); +} + +void SLtt_reverse_index (int nlines) +{ + SLtt_normal_video (); + + v_attrib (Attribute_Byte); + v_scroll (0, Scroll_r1, SLtt_Screen_Cols-1, Scroll_r2, nlines, + V_SCROLL_DOWN); +} + +static void emx_video_invert_region (int top_row, int bot_row) +{ + int row, col; + + for (row = top_row; row < bot_row; row++) + { + v_getline (Line_Buffer, 0, row, SLtt_Screen_Cols); + for (col = 1; col < SLtt_Screen_Cols * 2; col += 2) + Line_Buffer [col] ^= 0xff; + v_putline (Line_Buffer, 0, row, SLtt_Screen_Cols); + } +} + +void SLtt_beep (void) +{ + int audible; /* audible bell */ + int special = 0; /* first row to invert */ + int visual = 0; /* final row to invert */ + + if (!SLtt_Ignore_Beep) return; + + audible = (SLtt_Ignore_Beep & 1); + if ( (SLtt_Ignore_Beep & 4) ) + { + special = SLtt_Screen_Rows - 1; + visual = special--; /* only invert bottom status line */ + } + else if ( (SLtt_Ignore_Beep & 2) ) + { + visual = SLtt_Screen_Rows; + } + + if (visual) emx_video_invert_region (special, visual); + if (audible) /*sound (1500)*/; _sleep2 (100); if (audible) /* nosound () */; + if (visual) emx_video_invert_region (special, visual); +} + +void SLtt_del_eol (void) +{ + if (Current_Color != JNO_COLOR) SLtt_normal_video (); + emx_video_deleol (Cursor_Col); +} + +static void +write_attributes (SLsmg_Char_Type *src, unsigned int count) +{ + register unsigned char *p = Line_Buffer; + register unsigned short pair; + int n = count; + + /* write into a character/attribute pair */ + while (n-- > 0) + { + pair = SLSMG_CHAR_TO_USHORT(*src);/* character/color pair */ + src++; + SLtt_reverse_video (pair >> 8); /* color change */ + *(p++) = pair & 0xff; /* character byte */ + *(p++) = Attribute_Byte; /* attribute byte */ + } + v_putline (Line_Buffer, Cursor_Col, Cursor_Row, count); +} + +void SLtt_cls (void) +{ + SLtt_normal_video (); + SLtt_reset_scroll_region (); + SLtt_goto_rc (0, 0); + SLtt_delete_nlines (SLtt_Screen_Rows); +} + +void SLtt_putchar (char ch) +{ + if (Current_Color) SLtt_normal_video (); + + emx_video_getxy (); /* get current position */ + switch (ch) + { + case 7: /* ^G - break */ + SLtt_beep (); break; + case 8: /* ^H - backspace */ + goto_rc_abs (Cursor_Row, Cursor_Col - 1); break; + case 13: /* ^M - carriage return */ + goto_rc_abs (Cursor_Row, 0); break; + default: /* write character to screen */ + v_putn (ch, 1); + goto_rc_abs (Cursor_Row, Cursor_Col + 1); + } +} + +void SLtt_get_terminfo (void) +{ + SLtt_get_screen_size (); +} + +void SLtt_get_screen_size (void) +{ + vioModeInfo.cb = sizeof(vioModeInfo); + VioGetMode (&vioModeInfo, 0); + SLtt_Screen_Cols = vioModeInfo.col; + SLtt_Screen_Rows = vioModeInfo.row; +} + +int SLtt_init_video (void) +{ + int OldCol, OldRow; + PTIB ptib; + PPIB ppib; + USHORT args[3] = { 6, 2, 1 }; + +#ifdef HAS_SAVE_SCREEN + save_screen (); +#endif + + Cursor_Row = Cursor_Col = 0; + + v_init (); + if ( v_hardware () != V_MONOCHROME ) IsColor = 1; else IsColor = 0; + + v_getxy(&OldCol,&OldRow); + v_gotoxy (0, 0); + if (IsColor) + { + if (_osmode == OS2_MODE) + { +# if 0 + /* Enable high-intensity background colors */ + VIOINTENSITY RequestBlock; + RequestBlock.cb = sizeof (RequestBlock); + RequestBlock.type = 2; RequestBlock.fs = 1; + VioSetState (&RequestBlock, 0); /* nop if !fullscreen */ +# endif + } + } + + DosGetInfoBlocks (&ptib, &ppib); + if ((ppib->pib_ultype) == 2) /* VIO */ + Blink_Killed = 1; + else + { /* Fullscreen */ + if (VioSetState (args, 0) == 0) + Blink_Killed = 1; + else + Blink_Killed = 0; + } + + if (!Attribute_Byte) + { + /* find the attribute currently under the cursor */ + v_getline (Line_Buffer, OldCol, OldRow, 1); + Attribute_Byte = Line_Buffer[1]; + SLtt_set_color (JNORMAL_COLOR, NULL, + Color_Names[(Attribute_Byte) & 0xf], + Color_Names[(Attribute_Byte) >> 4]); + } + + v_attrib (Attribute_Byte); + + fixup_colors (); + + SLtt_get_screen_size (); + SLtt_Use_Ansi_Colors = IsColor; + SLtt_reset_scroll_region (); + return 0; +} + +#endif /* EMX_VIDEO */ + +/*}}}*/ + +#ifdef WIN32_VIDEO /*{{{*/ + +#include + +static HANDLE hStdout = INVALID_HANDLE_VALUE; + +#define MAXCOLS 256 +static CHAR_INFO Line_Buffer [MAXCOLS]; + +void SLtt_write_string (char *str) +{ + DWORD bytes; + int n, c; + if (str == NULL) return; + + n = (int) strlen (str); + c = n + Cursor_Col; + if (c >= SLtt_Screen_Cols) + n = SLtt_Screen_Cols - Cursor_Col; + if (n < 0) n = 0; + + (void) WriteConsole (hStdout, str, (unsigned int) n, &bytes, NULL); + + goto_rc_abs (Cursor_Row, Cursor_Col + n); +} + +void SLtt_goto_rc (int row, int col) +{ + COORD newPosition; + + row += Scroll_r1; + if (row > SLtt_Screen_Rows) row = SLtt_Screen_Rows; + if (col > SLtt_Screen_Cols) col = SLtt_Screen_Cols; + newPosition.X = col; + newPosition.Y = row; + + (void) SetConsoleCursorPosition(hStdout, newPosition); + + Cursor_Row = row; + Cursor_Col = col; +} + +static void win32_video_getxy (void) +{ + CONSOLE_SCREEN_BUFFER_INFO screenInfo; + + if (TRUE == GetConsoleScreenBufferInfo(hStdout, &screenInfo)) + { + Cursor_Row = screenInfo.dwCursorPosition.Y; + Cursor_Col = screenInfo.dwCursorPosition.X; + } +} + +static void win32_video_hscroll (int n) +{ + SMALL_RECT rc; + COORD c; + CHAR_INFO ci; + WORD w = 227; + DWORD d; + + win32_video_getxy (); + + rc.Left = Cursor_Col; + rc.Right = SLtt_Screen_Cols; + rc.Top = rc.Bottom = Cursor_Row; + + c.Y = Cursor_Row; +#if 1 + c.X = SLtt_Screen_Cols - 1; + ReadConsoleOutputAttribute(hStdout, &w, 1, c, &d); +#else + /* New region gets the current color */ + w = Attribute_Byte; +#endif + c.X = Cursor_Col + n; + + ci.Char.AsciiChar = ' '; + ci.Attributes = w; + + ScrollConsoleScreenBuffer(hStdout, &rc, &rc, c, &ci); +} + +static void win32_video_deleol (int x) +{ + DWORD d; + COORD c; + + c.X = x; + c.Y = Cursor_Row; + + x = SLtt_Screen_Cols - x; + FillConsoleOutputCharacter(hStdout, ' ', x, c, &d); + FillConsoleOutputAttribute(hStdout, (char)Attribute_Byte, x, c, &d); +} + +static void win32_video_vscroll (int n) +{ + SMALL_RECT rc, clip_rc; + COORD c; + CHAR_INFO ci; + + SLtt_normal_video(); + + /* ScrollConsoleScreenBuffer appears to have a bug when + * Scroll_r1 == Scroll_r2. Sigh. + */ + if (Scroll_r2 == Scroll_r1) + { + SLtt_goto_rc (0, 0); + win32_video_deleol (0); + return; + } + + rc.Left = clip_rc.Left = 0; + rc.Right = clip_rc.Right = SLtt_Screen_Cols - 1; + rc.Top = clip_rc.Top = Scroll_r1; + rc.Bottom = clip_rc.Bottom = Scroll_r2; + + c.X = 0; + c.Y = Scroll_r1 + n; + + ci.Char.AsciiChar = ' '; + ci.Attributes = Attribute_Byte; + + ScrollConsoleScreenBuffer(hStdout, &rc, &clip_rc, c, &ci); +} + +void SLtt_begin_insert (void) +{ + win32_video_hscroll (1); +} + +void SLtt_end_insert (void) +{ +} + +void SLtt_delete_char (void) +{ + win32_video_hscroll (-1); +} + +void SLtt_erase_line (void) +{ + Attribute_Byte = 0x7; + win32_video_deleol (0); + Current_Color = JNO_COLOR; +} + +void SLtt_delete_nlines (int nlines) +{ + win32_video_vscroll (-nlines); +} + +void SLtt_reverse_index (int nlines) +{ + win32_video_vscroll (nlines); +} + +static void win32_invert_region (int top_row, int bot_row) +{ + (void) top_row; (void) bot_row; +} + +void SLtt_beep (void) +{ + int audible; /* audible bell */ + int special = 0; /* first row to invert */ + int visual = 0; /* final row to invert */ + + if (!SLtt_Ignore_Beep) return; + + audible = (SLtt_Ignore_Beep & 1); + + if ( (SLtt_Ignore_Beep & 4) ) + { + special = SLtt_Screen_Rows - 1; + visual = special--; /* only invert bottom status line */ + } + else if ( (SLtt_Ignore_Beep & 2) ) + { + visual = SLtt_Screen_Rows; + } + + if (visual) win32_invert_region (special, visual); + if (audible) Beep (1500, 100); else Sleep (100); + if (visual) win32_invert_region (special, visual); +} + +void SLtt_del_eol (void) +{ + if (Current_Color != JNO_COLOR) + SLtt_normal_video (); + win32_video_deleol (Cursor_Col); +} + +static void +write_attributes (SLsmg_Char_Type *src, unsigned int count) +{ + unsigned short pair; + COORD coord, c; + CHAR_INFO *p; + unsigned int n; + SMALL_RECT rc; + + /* write into a character/attribute pair */ + n = count; + p = Line_Buffer; + while (n) + { + n--; + pair = SLSMG_CHAR_TO_USHORT(*src);/* character/color pair */ + src++; + SLtt_reverse_video (pair >> 8); /* color change */ + p->Char.AsciiChar = pair & 0xff; + p->Attributes = Attribute_Byte; + p++; + } + + c.X = count; + c.Y = 1; + coord.X = coord.Y = 0; + rc.Left = Cursor_Col; + rc.Right = Cursor_Col + count - 1; + rc.Top = rc.Bottom = Cursor_Row; + WriteConsoleOutput(hStdout, Line_Buffer, c, coord, &rc); +} + +void SLtt_cls (void) +{ + DWORD bytes; + COORD coord; + char ch; + + SLtt_normal_video (); + /* clear the WIN32 screen in one shot */ + coord.X = 0; + coord.Y = 0; + + ch = ' '; + + (void) FillConsoleOutputCharacter(hStdout, + ch, + SLtt_Screen_Cols * SLtt_Screen_Rows, + coord, + &bytes); + + /* now set screen to the current attribute */ + ch = Attribute_Byte; + (void) FillConsoleOutputAttribute(hStdout, + ch, + SLtt_Screen_Cols * SLtt_Screen_Rows, + coord, + &bytes); +} + +void SLtt_putchar (char ch) +{ + DWORD bytes; + WORD attr; + COORD c; + + if (Current_Color) SLtt_normal_video (); + win32_video_getxy (); + switch (ch) + { + case 7: /* ^G - break */ + SLtt_beep (); break; + case 8: /* ^H - backspace */ + goto_rc_abs (Cursor_Row, Cursor_Col - 1); break; + case 13: /* ^M - carriage return */ + goto_rc_abs (Cursor_Row, 0); break; + default: /* write character to screen */ + c.X = Cursor_Col; + c.Y = Cursor_Row; + attr = Attribute_Byte; + WriteConsoleOutputCharacter(hStdout, &ch, 1, c, &bytes); + WriteConsoleOutputAttribute(hStdout, &attr, 1, c, &bytes); + goto_rc_abs (Cursor_Row, Cursor_Col + 1); + } +} + +void SLtt_get_screen_size (void) +{ + CONSOLE_SCREEN_BUFFER_INFO csbi; + HANDLE h; + + h = hStdout; + if (h == INVALID_HANDLE_VALUE) + h = GetStdHandle (STD_OUTPUT_HANDLE); + + if ((h == INVALID_HANDLE_VALUE) + || (FALSE == GetConsoleScreenBufferInfo(h, &csbi))) + { + SLang_exit_error ("Unable to determine the screen size"); + return; + } +#if 0 + SLtt_Screen_Rows = csbi.dwSize.Y; + SLtt_Screen_Cols = csbi.dwSize.X; +#else + SLtt_Screen_Rows = (csbi.srWindow.Bottom - csbi.srWindow.Top) + 1; + SLtt_Screen_Cols = (csbi.srWindow.Right - csbi.srWindow.Left) + 1; +#endif +} + +void SLtt_get_terminfo (void) +{ + SLtt_get_screen_size (); +} + +static int win32_resize (void) +{ + SMALL_RECT windowRect; + + SLtt_get_screen_size (); + + windowRect.Left = 0; + windowRect.Top = 0; + windowRect.Right = SLtt_Screen_Cols - 1; + windowRect.Bottom = SLtt_Screen_Rows - 1; + + if (FALSE == SetConsoleWindowInfo(hStdout, TRUE, &windowRect)) + return -1; + + return 0; +} + +static int win32_init (void) +{ + SECURITY_ATTRIBUTES sec; + + memset ((char *) &sec, 0, sizeof(SECURITY_ATTRIBUTES)); + sec.nLength = sizeof (SECURITY_ATTRIBUTES); + sec.bInheritHandle = FALSE; + + hStdout = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_WRITE, + &sec, + CONSOLE_TEXTMODE_BUFFER, + 0); + + if (hStdout == INVALID_HANDLE_VALUE) + return -1; + + if ((FALSE == SetConsoleActiveScreenBuffer(hStdout)) + || (FALSE == SetConsoleMode(hStdout, 0)) + || (-1 == win32_resize ())) + { + SLtt_reset_video (); + return -1; + } + + return 0; +} + +int SLtt_init_video (void) +{ + SLtt_reset_video (); + + if (-1 == win32_init ()) + return -1; + + /* It is possible for SLtt_init_video to be called after suspension. + * For all I know, the window size may have changed. So, resize it + * now. + */ + + Cursor_Row = Cursor_Col = 0; + SLtt_Use_Ansi_Colors = IsColor = 1; + Blink_Killed = 1; + + SLtt_reset_scroll_region (); + goto_rc_abs (0, 0); + fixup_colors (); + + return 0; +} + +int SLtt_reset_video (void) +{ + if (hStdout == INVALID_HANDLE_VALUE) + return 0; + + SLtt_reset_scroll_region (); + SLtt_goto_rc (SLtt_Screen_Rows - 1, 0); + Attribute_Byte = 0x7; + Current_Color = JNO_COLOR; + SLtt_del_eol (); + (void) CloseHandle (hStdout); + + hStdout = GetStdHandle (STD_OUTPUT_HANDLE); + if (hStdout != INVALID_HANDLE_VALUE) + (void) SetConsoleActiveScreenBuffer(hStdout); + + hStdout = INVALID_HANDLE_VALUE; + return 0; +} + +#endif + +/*}}}*/ + +#ifdef OS2_VIDEO /*{{{*/ + +# define INCL_BASE +# define INCL_NOPM +# define INCL_VIO +# define INCL_KBD + +# define INCL_DOSPROCESS + +# include +# ifndef __IBMC__ +# include +# endif +/* this is how to make a space character */ +#define MK_SPACE_CHAR() (((Attribute_Byte) << 8) | 0x20) + +/* buffer to hold a line of character/attribute pairs */ +#define MAXCOLS 256 +static unsigned char Line_Buffer [MAXCOLS*2]; + +void SLtt_write_string (char *str) +{ + /* FIXME: Priority=medium + * This should not go to stdout. */ + fputs (str, stdout); +} + +void SLtt_goto_rc (int row, int col) +{ + row += Scroll_r1; + VioSetCurPos (row, col, 0); + Cursor_Row = row; + Cursor_Col = col; +} + +static void os2_video_getxy (void) +{ + USHORT r, c; + + VioGetCurPos (&r, &c, 0); + Cursor_Row = r; + Cursor_Col = c; +} + +void SLtt_begin_insert (void) +{ + USHORT n; + + os2_video_getxy (); + n = SLtt_Screen_Cols - Cursor_Col; + + n = 2 * (n - 1); + VioReadCellStr ((PCH)Line_Buffer, &n, Cursor_Row, Cursor_Col, 0); + VioWrtCellStr ((PCH)Line_Buffer, n, Cursor_Row, Cursor_Col + 1, 0); +} + +void SLtt_end_insert (void) +{ +} + +void SLtt_delete_char (void) +{ + USHORT n; + + os2_video_getxy (); + n = SLtt_Screen_Cols - Cursor_Col - 1; + + n *= 2; + VioReadCellStr ((PCH)Line_Buffer, &n, Cursor_Row, Cursor_Col + 1, 0); + VioWrtCellStr ((PCH)Line_Buffer, n, Cursor_Row, Cursor_Col, 0); +} + +void SLtt_erase_line (void) +{ + USHORT w; + + Attribute_Byte = 0x07; + w = MK_SPACE_CHAR (); + + VioWrtNCell ((BYTE*)&w, SLtt_Screen_Cols, Cursor_Row, 0, 0); + + Current_Color = JNO_COLOR; /* since we messed with attribute byte */ +} + +void SLtt_delete_nlines (int nlines) +{ + SLtt_normal_video (); + + Line_Buffer[0] = ' '; Line_Buffer[1] = Attribute_Byte; + VioScrollUp (Scroll_r1, 0, Scroll_r2, SLtt_Screen_Cols-1, + nlines, (PCH) Line_Buffer, 0); +} + +void SLtt_reverse_index (int nlines) +{ + SLtt_normal_video (); + + Line_Buffer[0] = ' '; Line_Buffer[1] = Attribute_Byte; + VioScrollDn (Scroll_r1, 0, Scroll_r2, SLtt_Screen_Cols-1, + nlines, (PCH) Line_Buffer, 0); +} + +static void os2_video_invert_region (int top_row, int bot_row) +{ + int row, col; + USHORT length = SLtt_Screen_Cols * 2; + + for (row = top_row; row < bot_row; row++) + { + VioReadCellStr ((PCH)Line_Buffer, &length, row, 0, 0); + for (col = 1; col < length; col += 2) + Line_Buffer [col] ^= 0xff; + VioWrtCellStr ((PCH)Line_Buffer, length, row, 0, 0); + } +} + +void SLtt_beep (void) +{ + int audible; /* audible bell */ + int special = 0; /* first row to invert */ + int visual = 0; /* final row to invert */ + + if (!SLtt_Ignore_Beep) return; + + audible = (SLtt_Ignore_Beep & 1); + + if ( (SLtt_Ignore_Beep & 4) ) + { + special = SLtt_Screen_Rows - 1; + visual = special--; /* only invert bottom status line */ + } + else if ( (SLtt_Ignore_Beep & 2) ) + { + visual = SLtt_Screen_Rows; + } + + if (visual) os2_video_invert_region (special, visual); + if (audible) DosBeep (1500, 100); else DosSleep (100); + if (visual) os2_video_invert_region (special, visual); +} + +void SLtt_del_eol (void) +{ + USHORT w; + if (Current_Color != JNO_COLOR) SLtt_normal_video (); + + w = MK_SPACE_CHAR (); + + VioWrtNCell ((BYTE*)&w, (SLtt_Screen_Cols - Cursor_Col), + Cursor_Row, Cursor_Col, 0); +} + +static void +write_attributes (SLsmg_Char_Type *src, unsigned int count) +{ + register unsigned char *p = Line_Buffer; + register unsigned short pair; + int n = count; + + /* write into a character/attribute pair */ + while (n-- > 0) + { + pair = SLSMG_CHAR_TO_USHORT(*src);/* character/color pair */ + src++; + SLtt_reverse_video (pair >> 8); /* color change */ + *(p++) = pair & 0xff; /* character byte */ + *(p++) = Attribute_Byte; /* attribute byte */ + } + + VioWrtCellStr ((PCH)Line_Buffer, (USHORT)(2 * count), + (USHORT)Cursor_Row, (USHORT)Cursor_Col, 0); +} + +void SLtt_cls (void) +{ + SLtt_normal_video (); + Line_Buffer [0] = ' '; Line_Buffer [1] = Attribute_Byte; + VioScrollUp (0, 0, -1, -1, -1, (PCH)Line_Buffer, 0); +} + +void SLtt_putchar (char ch) +{ + unsigned short p, *pp; + + if (Current_Color) SLtt_normal_video (); + os2_video_getxy (); /* get current position */ + + switch (ch) + { + case 7: /* ^G - break */ + SLtt_beep (); break; + case 8: /* ^H - backspace */ + goto_rc_abs (Cursor_Row, Cursor_Col - 1); break; + case 13: /* ^M - carriage return */ + goto_rc_abs (Cursor_Row, 0); break; + default: /* write character to screen */ + VioWrtCharStrAtt (&ch, 1, Cursor_Row, Cursor_Col, + (BYTE*)&Attribute_Byte, 0); + goto_rc_abs (Cursor_Row, Cursor_Col + 1); + } +} + +void SLtt_get_screen_size (void) +{ +#ifdef __os2__ +# ifdef __IBMC__ + VIOMODEINFO vioModeInfo; +# endif + vioModeInfo.cb = sizeof(vioModeInfo); + VioGetMode (&vioModeInfo, 0); + SLtt_Screen_Cols = vioModeInfo.col; + SLtt_Screen_Rows = vioModeInfo.row; +#endif +} + +void SLtt_get_terminfo (void) +{ + SLtt_get_screen_size (); +} + +int SLtt_init_video (void) +{ + VIOINTENSITY RequestBlock; + PTIB ptib; + PPIB ppib; + USHORT args[3] = { 6, 2, 1 }; + + Cursor_Row = Cursor_Col = 0; + + IsColor = 1; /* is it really? */ + + /* Enable high-intensity background colors */ + RequestBlock.cb = sizeof (RequestBlock); + RequestBlock.type = 2; RequestBlock.fs = 1; + VioSetState (&RequestBlock, 0); /* nop if !fullscreen */ + + DosGetInfoBlocks (&ptib, &ppib); + if ((ppib->pib_ultype) == 2) /* VIO */ + Blink_Killed = 1; + else + { /* Fullscreen */ + if (VioSetState (args, 0) == 0) + Blink_Killed = 1; + else + Blink_Killed = 0; + } + + if (!Attribute_Byte) + { + /* find the attribute currently under the cursor */ + USHORT len, r, c; + + len = 2; + VioGetCurPos (&r, &c, 0); + VioReadCellStr ((PCH)Line_Buffer, &len, r, c, 0); + Attribute_Byte = Line_Buffer[1]; + + SLtt_set_color (JNORMAL_COLOR, NULL, + Color_Names[(Attribute_Byte) & 0xf], + Color_Names[(Attribute_Byte) >> 4]); + } + + SLtt_Use_Ansi_Colors = IsColor; + SLtt_get_screen_size (); + SLtt_reset_scroll_region (); + fixup_colors (); + + return 0; +} + +#endif /* OS2_VIDEO */ +/*}}}*/ + +#ifdef WATCOM_VIDEO /*{{{*/ + +# include +# define int86 int386 /* simplify code writing */ + +#include + +/* this is how to make a space character */ +#define MK_SPACE_CHAR() (((Attribute_Byte) << 8) | 0x20) + +/* buffer to hold a line of character/attribute pairs */ +#define MAXCOLS 256 +static unsigned char Line_Buffer [MAXCOLS*2]; + +/* define for direct to memory screen writes */ +static unsigned char *Video_Base; +#define MK_SCREEN_POINTER(row,col) \ + ((unsigned short *)(Video_Base + 2 * (SLtt_Screen_Cols * (row) + (col)))) + +#define ScreenPrimary (0xb800 << 4) +#define ScreenSize (SLtt_Screen_Cols * SLtt_Screen_Rows) +#define ScreenSetCursor(x,y) _settextposition (x+1,y+1) + +void ScreenGetCursor (int *x, int *y) +{ + struct rccoord rc = _gettextposition (); + *x = rc.row - 1; + *y = rc.col - 1; +} + +void ScreenRetrieve (unsigned char *dest) +{ + memcpy (dest, (unsigned char *) ScreenPrimary, 2 * ScreenSize); +} + +void ScreenUpdate (unsigned char *src) +{ + memcpy ((unsigned char *) ScreenPrimary, src, 2 * ScreenSize); +} + +void SLtt_write_string (char *str) +{ + /* FIXME: Priority=medium + * This should not go to stdout. */ + fputs (str, stdout); +} + +void SLtt_goto_rc (int row, int col) +{ + row += Scroll_r1; + if (row > SLtt_Screen_Rows) row = SLtt_Screen_Rows; + if (col > SLtt_Screen_Cols) col = SLtt_Screen_Cols; + ScreenSetCursor(row, col); + Cursor_Row = row; + Cursor_Col = col; +} + +static void watcom_video_getxy (void) +{ + ScreenGetCursor (&Cursor_Row, &Cursor_Col); +} + +void SLtt_begin_insert (void) +{ + unsigned short *p; + unsigned short *pmin; + int n; + + watcom_video_getxy (); + n = SLtt_Screen_Cols - Cursor_Col; + + p = MK_SCREEN_POINTER (Cursor_Row, SLtt_Screen_Cols - 1); + pmin = MK_SCREEN_POINTER (Cursor_Row, Cursor_Col); + + while (p-- > pmin) *(p + 1) = *p; +} + +void SLtt_end_insert (void) +{ +} + +void SLtt_delete_char (void) +{ + unsigned short *p; + register unsigned short *p1; + int n; + + watcom_video_getxy (); + n = SLtt_Screen_Cols - Cursor_Col - 1; + + p = MK_SCREEN_POINTER (Cursor_Row, Cursor_Col); + while (n--) + { + p1 = p + 1; + *p = *p1; + p++; + } +} + +void SLtt_erase_line (void) +{ + unsigned short w; + unsigned short *p = MK_SCREEN_POINTER (Cursor_Row, 0); + register unsigned short *pmax = p + SLtt_Screen_Cols; + + Attribute_Byte = 0x07; + w = MK_SPACE_CHAR (); + while (p < pmax) *p++ = w; + Current_Color = JNO_COLOR; /* since we messed with attribute byte */ +} + +void SLtt_delete_nlines (int nlines) +{ + union REGS r; + + SLtt_normal_video (); + r.x.eax = nlines; + r.x.ecx = 0; + r.h.ah = 6; + r.h.ch = Scroll_r1; + r.h.dl = SLtt_Screen_Cols - 1; + r.h.dh = Scroll_r2; + r.h.bh = Attribute_Byte; + int86 (0x10, &r, &r); +} + +void SLtt_reverse_index (int nlines) +{ + union REGS r; + + SLtt_normal_video (); + r.h.al = nlines; + r.x.ecx = 0; + r.h.ah = 7; + r.h.ch = Scroll_r1; + r.h.dl = SLtt_Screen_Cols - 1; + r.h.dh = Scroll_r2; + r.h.bh = Attribute_Byte; + int86 (0x10, &r, &r); +} + +static void watcom_video_invert_region (int top_row, int bot_row) +{ + unsigned char buf [2 * 180 * 80]; /* 180 cols x 80 rows */ + unsigned char *b, *bmax; + + b = buf + 1 + 2 * SLtt_Screen_Cols * top_row; + bmax = buf + 1 + 2 * SLtt_Screen_Cols * bot_row; + ScreenRetrieve (buf); + while (b < bmax) + { + *b ^= 0xFF; + b += 2; + } + ScreenUpdate (buf); +} + +void SLtt_beep (void) +{ + int audible; /* audible bell */ + int special = 0; /* first row to invert */ + int visual = 0; /* final row to invert */ + + if (!SLtt_Ignore_Beep) return; + + audible = (SLtt_Ignore_Beep & 1); + if ( (SLtt_Ignore_Beep & 4) ) + { + special = SLtt_Screen_Rows - 1; + visual = special--; /* only invert bottom status line */ + } + else if ( (SLtt_Ignore_Beep & 2) ) + { + visual = SLtt_Screen_Rows; + } + + if (visual) watcom_video_invert_region (special, visual); + if (audible) sound (1500); delay (100); if (audible) nosound (); + if (visual) watcom_video_invert_region (special, visual); +} + +void SLtt_del_eol (void) +{ + unsigned short *p, *pmax; + unsigned short w; + int n; + + n = SLtt_Screen_Cols - Cursor_Col; + p = MK_SCREEN_POINTER (Cursor_Row, Cursor_Col); + pmax = p + n; + + if (Current_Color != JNO_COLOR) SLtt_normal_video (); + + w = MK_SPACE_CHAR (); + while (p < pmax) *p++ = w; +} + +static void +write_attributes (SLsmg_Char_Type *src, unsigned int count) +{ + register unsigned short pair; + register unsigned short *pos = MK_SCREEN_POINTER (Cursor_Row, 0); + + /* write into a character/attribute pair */ + while (count--) + { + pair = SLSMG_CHAR_TO_USHORT(*src);/* character/color pair */ + src++; + SLtt_reverse_video (pair >> 8); /* color change */ + *(pos++) = ((unsigned short) Attribute_Byte << 8) | (pair & 0xff); + } +} + +void SLtt_cls (void) +{ + SLtt_normal_video (); + SLtt_reset_scroll_region (); + SLtt_goto_rc (0, 0); + SLtt_delete_nlines (SLtt_Screen_Rows); +} + +void SLtt_putchar (char ch) +{ + unsigned short p, *pp; + + if (Current_Color) SLtt_normal_video (); + watcom_video_getxy (); + switch (ch) + { + case 7: /* ^G - break */ + SLtt_beep (); break; + case 8: /* ^H - backspace */ + goto_rc_abs (Cursor_Row, Cursor_Col - 1); break; + case 13: /* ^M - carriage return */ + goto_rc_abs (Cursor_Row, 0); break; + default: /* write character to screen */ + p = (Attribute_Byte << 8) | (unsigned char) ch; + pp = MK_SCREEN_POINTER (Cursor_Row, Cursor_Col); + *pp = p; + goto_rc_abs (Cursor_Row, Cursor_Col + 1); + } +} + +void SLtt_get_screen_size (void) +{ + struct videoconfig vc; + _getvideoconfig(&vc); + + SLtt_Screen_Rows = vc.numtextrows; + SLtt_Screen_Cols = vc.numtextcols; +} + +void SLtt_get_terminfo (void) +{ + SLtt_get_screen_size (); +} + +int SLtt_init_video (void) +{ +#ifdef HAS_SAVE_SCREEN + save_screen (); +#endif + + Cursor_Row = Cursor_Col = 0; + Video_Base = (unsigned char *) ScreenPrimary; + if (!Attribute_Byte) Attribute_Byte = 0x17; + IsColor = 1; /* is it really? */ + + if (IsColor) + { + union REGS r; + r.x.eax = 0x1003; r.x.ebx = 0; + int86 (0x10, &r, &r); + Blink_Killed = 1; + } + + SLtt_Use_Ansi_Colors = IsColor; + SLtt_get_screen_size (); + SLtt_reset_scroll_region (); + fixup_colors (); + + return 0; +} + +#endif /* WATCOM_VIDEO */ + +/*}}}*/ + +/* -------------------------------------------------------------------------*\ + * The rest of the functions are, for the most part, independent of a specific + * video system. +\* ------------------------------------------------------------------------ */ + +/*----------------------------------------------------------------------*\ + * Function: void SLtt_set_scroll_region (int r1, int r2); + * + * define a scroll region of top_row to bottom_row +\*----------------------------------------------------------------------*/ +void SLtt_set_scroll_region (int top_row, int bottom_row) +{ + Scroll_r1 = top_row; + Scroll_r2 = bottom_row; +} + +/*----------------------------------------------------------------------*\ + * Function: void SLtt_reset_scroll_region (void); + * + * reset the scrol region to be the entire screen, + * ie, SLtt_set_scroll_region (0, SLtt_Screen_Rows); +\*----------------------------------------------------------------------*/ +void SLtt_reset_scroll_region (void) +{ + Scroll_r1 = 0; + Scroll_r2 = SLtt_Screen_Rows - 1; } /*----------------------------------------------------------------------*\ @@ -1574,14 +2163,31 @@ void SLtt_init_video (void) \*----------------------------------------------------------------------*/ int SLtt_flush_output (void) { +#if defined(WIN32_VIDEO) + return 0; +#else + /* FIXME: Priority=medium + * This should not go to stdout. */ fflush (stdout); - return -1; + return 0; +#endif } int SLtt_set_cursor_visibility (int show) { +#if defined(WIN32_VIDEO) + CONSOLE_CURSOR_INFO c; + + if (0 == GetConsoleCursorInfo (hStdout, &c)) + return -1; + c.bVisible = (show ? TRUE: FALSE); + if (0 == SetConsoleCursorInfo (hStdout, &c)) + return -1; + return 0; +#else (void) show; return -1; +#endif } void SLtt_set_mono (int obj_unused, char *unused, SLtt_Char_Type c_unused) @@ -1591,4 +2197,130 @@ void SLtt_set_mono (int obj_unused, char *unused, SLtt_Char_Type c_unused) (void) c_unused; } -/* /////////////////////// end of file (c source) ///////////////////// */ +/*----------------------------------------------------------------------*\ + * Function: void SLtt_reverse_video (int color); + * + * set Attribute_Byte corresponding to COLOR. + * Use Current_Color to remember the color which was set. + * convert from the COLOR number to the attribute value. +\*----------------------------------------------------------------------*/ +void SLtt_reverse_video (int color) +{ + if ((color >= JMAX_COLORS) || (color < 0)) + return; + + Attribute_Byte = Color_Map [color]; + Current_Color = color; +} + +/*----------------------------------------------------------------------*\ + * Function: void SLtt_normal_video (void); + * + * reset the attributes for normal video +\*----------------------------------------------------------------------*/ +void SLtt_normal_video (void) +{ + SLtt_reverse_video (JNORMAL_COLOR); +} + +/*----------------------------------------------------------------------*\ + * Function: void SLtt_smart_puts (SLsmg_Char_Type *new_string, + * SLsmg_Char_Type *old_string, + * int len, int row); + * + * puts NEW_STRING, which has length LEN, at row ROW. NEW_STRING contains + * characters/colors packed in the form value = ((color << 8) | (ch)); + * + * the puts tries to avoid overwriting the same characters/colors + * + * OLD_STRING is not used, maintained for compatibility with other systems +\*----------------------------------------------------------------------*/ +void SLtt_smart_puts (SLsmg_Char_Type *new_string, + SLsmg_Char_Type *old_string, + int len, int row) +{ + (void) old_string; + Cursor_Row = row; + Cursor_Col = 0; + write_attributes (new_string, len); +} + +/*----------------------------------------------------------------------*\ + * Function: int SLtt_reset_video (void); +\*----------------------------------------------------------------------*/ +#ifndef WIN32_VIDEO +int SLtt_reset_video (void) +{ + SLtt_reset_scroll_region (); + SLtt_goto_rc (SLtt_Screen_Rows - 1, 0); +#ifdef HAS_SAVE_SCREEN + restore_screen (); +#endif + Attribute_Byte = 0x07; + Current_Color = JNO_COLOR; + SLtt_del_eol (); + return 0; +} +#endif + +/*----------------------------------------------------------------------*\ + * Function: void SLtt_set_color (int obj, char *what, char *fg, char *bg); + * + * set foreground and background colors of OBJ to the attributes which + * correspond to the names FG and BG, respectively. + * + * WHAT is the name corresponding to the object OBJ, but is not used in + * this routine. +\*----------------------------------------------------------------------*/ +void SLtt_set_color (int obj, char *what, char *fg, char *bg) +{ + int i, b = 0, f = 7; + + (void) what; + + if ((obj < 0) || (obj >= JMAX_COLORS)) + return; + + for (i = 0; i < JMAX_COLOR_NAMES; i++ ) + { + if (!strcmp (fg, Color_Names [i])) + { + f = i; + break; + } + } + + for (i = 0; i < JMAX_COLOR_NAMES; i++) + { + if (!strcmp (bg, Color_Names [i])) + { + if (Blink_Killed) b = i; else b = i & 0x7; + break; + } + } + if (f == b) return; + + Color_Map [obj] = (b << 4) | f; + + /* if we're setting the normal color, and the attribute byte hasn't + been set yet, set it to the new color */ + if ((obj == 0) && (Attribute_Byte == 0)) + SLtt_reverse_video (0); + + if (_SLtt_color_changed_hook != NULL) + (*_SLtt_color_changed_hook)(); +} + +static void fixup_colors (void) +{ + unsigned int i; + + if (Blink_Killed) + return; + + for (i = 0; i < JMAX_COLORS; i++) + Color_Map[i] &= 0x7F; + + SLtt_normal_video (); +} + diff --git a/slang/slw32tty.c b/slang/slw32tty.c index db109f099..990e220f4 100644 --- a/slang/slw32tty.c +++ b/slang/slw32tty.c @@ -1,16 +1,16 @@ -/* Copyright (c) 1992, 1995 John E. Davis - * All rights reserved. - * +/* Copyright (c) 1992, 1999, 2001, 2002 John E. Davis + * This file is part of the S-Lang library. + * * You may distribute under the terms of either the GNU General Public * License or the Perl Artistic License. */ -#include "config.h" -#include +#include "slinclud.h" #include #include +#include "slang.h" #include "_slang.h" #ifdef __cplusplus @@ -19,7 +19,7 @@ # define _DOTS_ void #endif - +static int Process_Mouse_Events; /*----------------------------------------------------------------------*\ * Function: static void set_ctrl_break (int state); @@ -30,7 +30,6 @@ static void set_ctrl_break (int state) { } - /*----------------------------------------------------------------------*\ * Function: int SLang_init_tty (int abort_char, int no_flow_control, * int opost); @@ -40,77 +39,40 @@ static void set_ctrl_break (int state) * NO_FLOW_CONTROL and OPOST are only for compatiblity and are ignored. \*----------------------------------------------------------------------*/ -HANDLE hStdout, hStdin; -CONSOLE_SCREEN_BUFFER_INFO csbiInfo; +HANDLE _SLw32_Hstdin = INVALID_HANDLE_VALUE; int SLang_init_tty (int abort_char, int no_flow_control, int opost) { - SMALL_RECT windowRect; - COORD newPosition; - long flags; + (void) opost; + (void) no_flow_control; -#ifndef SLANG_SAVES_CONSOLE - /* first off, create a new console so the old one can be restored on exit */ - HANDLE console = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ |FILE_SHARE_WRITE, - 0, - CONSOLE_TEXTMODE_BUFFER, - 0); - if (SetConsoleActiveScreenBuffer(console) == FALSE) { - return -1; - } -#endif + if (_SLw32_Hstdin != INVALID_HANDLE_VALUE) + return 0; - /* start things off at the origin */ - newPosition.X = 0; - newPosition.Y = 0; - - /* still read in characters from stdin, but output to the new console */ - /* this way, on program exit, the original screen is restored */ - hStdin = GetStdHandle(STD_INPUT_HANDLE); -/* hStdin = console; */ - -#ifndef SLANG_SAVES_CONSOLE - hStdout = GetStdHandle(STD_OUTPUT_HANDLE); +#if 1 + /* stdin may have been redirected. So try this */ + _SLw32_Hstdin = CreateFile ("CONIN$", GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, 0, NULL); + if (_SLw32_Hstdin == INVALID_HANDLE_VALUE) + return -1; #else - hStdout = console; + if (INVALID_HANDLE_VALUE == (_SLw32_Hstdin = GetStdHandle(STD_INPUT_HANDLE))) + return -1; #endif - if (hStdin == INVALID_HANDLE_VALUE || hStdout == INVALID_HANDLE_VALUE) { - return -1; /* failure */ - } + if (FALSE == SetConsoleMode(_SLw32_Hstdin, ENABLE_WINDOW_INPUT|ENABLE_MOUSE_INPUT)) + { + _SLw32_Hstdin = INVALID_HANDLE_VALUE; + return -1; + } + + if (abort_char > 0) + SLang_Abort_Char = abort_char; - if (!GetConsoleScreenBufferInfo(hStdout, &csbiInfo)) { - return -1; /* failure */ - } // if - - windowRect.Left = 0; - windowRect.Top = 0; - windowRect.Right = csbiInfo.dwSize.X - 1; - windowRect.Bottom = csbiInfo.dwSize.Y - 1; - if (!SetConsoleWindowInfo(hStdout, TRUE, &windowRect)) { - return -1; - } - - if (SetConsoleMode(hStdin, 0) == FALSE) { - return -1; /* failure */ - } - - if (SetConsoleMode(hStdout, 0) == FALSE) { - return -1; /* failure */ - } - - if (GetConsoleMode(hStdin, &flags)) { - if (flags & ENABLE_PROCESSED_INPUT) { - return -1; - } - } - - (void) SetConsoleCursorPosition(hStdout, newPosition); - - /* success */ - return 0; -} /* SLang_init_tty */ + return 0; +} +/* SLang_init_tty */ /*----------------------------------------------------------------------*\ * Function: void SLang_reset_tty (void); @@ -119,70 +81,224 @@ int SLang_init_tty (int abort_char, int no_flow_control, int opost) \*----------------------------------------------------------------------*/ void SLang_reset_tty (void) { + _SLw32_Hstdin = INVALID_HANDLE_VALUE; set_ctrl_break (1); } -/*----------------------------------------------------------------------*\ - * Function: int SLsys_input_pending (int tsecs); - * - * sleep for *tsecs tenths of a sec waiting for input -\*----------------------------------------------------------------------*/ -int SLsys_input_pending (int tsecs) +static int process_mouse_event (MOUSE_EVENT_RECORD *m) { - INPUT_RECORD record; - long one = 1; - long bytesRead; + char buf [8]; - while (1) + if (Process_Mouse_Events == 0) + return -1; + + if (m->dwEventFlags) + return -1; /* double click or movement event */ + + /* A button was either pressed or released. Now make sure that + * the shift keys were not also pressed. + */ + if (m->dwControlKeyState + & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED + |LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED + |SHIFT_PRESSED)) + return -1; + + /* We have a simple press or release. Encode it as an escape sequence + * and buffer the result. The encoding is: + * 'ESC [ M b x y' + * where b represents the button state, and x,y represent the coordinates. + * The ESC is handled by the calling routine. + */ + if (m->dwButtonState & 1) buf[3] = ' '; + else if (m->dwButtonState & 2) buf[3] = ' ' + 2; + else if (m->dwButtonState & 4) buf[3] = ' ' + 1; + else return -1; + + buf[0] = 27; + buf[1] = '['; + buf[2] = 'M'; + + + buf[4] = 1 + ' ' + m->dwMousePosition.X; + buf[5] = 1 + ' ' + m->dwMousePosition.Y; + + return SLang_buffer_keystring ((unsigned char *)buf, 6); +} + +static int process_key_event (KEY_EVENT_RECORD *key) +{ + unsigned int key_state = 0; + unsigned int scan; + char c1; + DWORD d = key->dwControlKeyState; + unsigned char buf[4]; + + if (!key->bKeyDown) return 0; + if (d & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) + key_state |= _SLTT_KEY_ALT; + if (d & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) + key_state |= _SLTT_KEY_CTRL; + if (d & SHIFT_PRESSED) + key_state |= _SLTT_KEY_SHIFT; + + scan = key->wVirtualScanCode; + + switch (scan) { - if (PeekConsoleInput(hStdin, &record, 1, &bytesRead)) - { - if (bytesRead == 1) - { - if ((record.EventType == KEY_EVENT) - && record.Event.KeyEvent.bKeyDown) - { - /* ok, there is a keypress here */ - return 1; - } - else - { - /* something else is here, so read it and try again */ - (void) ReadConsoleInput(hStdin, &record, 1, &bytesRead); - } - } - else - { - /* no Pending events */ - return 0; - } - } + case 0x00E: /* backspace */ + return SLang_buffer_keystring ((unsigned char *)"\x7F", 1); + + case 0x003: /* 2 key */ + if (key_state & _SLTT_KEY_ALT) + break; + /* Drop */ + case 0x039: /* space */ + if (key_state & _SLTT_KEY_CTRL) + return SLang_buffer_keystring ((unsigned char *)"\x00\x03", 2); + break; + + case 0x007: /* 6 key */ + if (_SLTT_KEY_CTRL == (key_state & (_SLTT_KEY_ALT|_SLTT_KEY_CTRL))) + return SLang_buffer_keystring ((unsigned char *)"\x1E", 1); /* Ctrl-^ */ + break; + + case 0x00C: /* -/_ key */ + if (_SLTT_KEY_CTRL == (key_state & (_SLTT_KEY_ALT|_SLTT_KEY_CTRL))) + return SLang_buffer_keystring ((unsigned char *)"\x1F", 1); + break; + + case 0x00F: /* TAB */ + if (_SLTT_KEY_SHIFT == key_state) + return SLang_buffer_keystring ((unsigned char *)"\x00\x09", 2); + break; + + case 0xE02F: /* KEYPAD SLASH */ + case 0x037: /* KEYPAD STAR */ + case 0x04A: /* KEYPAD MINUS */ + case 0x04E: /* KEYPAD PLUS */ + if (d & NUMLOCK_ON) + break; + case 0x047: /* KEYPAD HOME */ + case 0x048: /* KEYPAD UP */ + case 0x049: /* KEYPAD PGUP */ + case 0x04B: /* KEYPAD LEFT */ + case 0x04C: /* KEYPAD 5 */ + case 0x04D: /* KEYPAD RIGHT */ + case 0x04F: /* KEYPAD END */ + case 0x050: /* KEYPAD DOWN */ + case 0x051: /* KEYPAD PGDN */ + case 0x052: /* KEYPAD INSERT */ + case 0x053: /* KEYPAD DEL */ + if (d & ENHANCED_KEY) + scan |= 0xE000; else { - /* function failed */ - return 0; + if (d & NUMLOCK_ON) + break; } - } -#if 0 - /* no delays yet */ - /* use Sleep */ - /* - int count = tsecs * 5; + (void) _SLpc_convert_scancode (scan, key_state, 0); + return 0; - if (keyWaiting()) return 1; - while (count > 0) - { - delay (20); 20 ms or 1/50 sec - if (keyWaiting()) break; - count--; + case 0x3b: /* F1 */ + case 0x3c: + case 0x3d: + case 0x3e: + case 0x3f: + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x57: + case 0x58: /* F12 */ + (void) _SLpc_convert_scancode (scan, key_state, 0); + } + + c1 = key->uChar.AsciiChar; + if (c1 != 0) + { + if (_SLTT_KEY_ALT == (key_state & (_SLTT_KEY_ALT|_SLTT_KEY_CTRL))) + { + buf[0] = 27; + buf[1] = c1; + return SLang_buffer_keystring (buf, 2); + } + if (c1 == SLang_Abort_Char) + { + if (SLang_Ignore_User_Abort == 0) SLang_Error = USER_BREAK; + SLKeyBoard_Quit = 1; + } + buf[0] = c1; + return SLang_buffer_keystring (buf, 1); + } + return 0; +} + + +static void process_console_records(void) +{ + INPUT_RECORD record; + DWORD bytesRead; + DWORD n = 0; + + if (FALSE == GetNumberOfConsoleInputEvents(_SLw32_Hstdin, &n)) + return; + + while (n > 0) + { + ReadConsoleInput(_SLw32_Hstdin, &record, 1, &bytesRead); + switch (record.EventType) + { + case KEY_EVENT: + (void) process_key_event(&record.Event.KeyEvent); + break; + + case MOUSE_EVENT: + process_mouse_event(&record.Event.MouseEvent); + break; + + case WINDOW_BUFFER_SIZE_EVENT: + /* process_resize_records(&record.Event.WindowBufferSizeEvent); */ + break; + } + n--; } - return (count); - */ -#endif } /*----------------------------------------------------------------------*\ - * Function: unsigned int SLsys_getkey (void); + * Function: int _SLsys_input_pending (int tsecs); + * + * sleep for *tsecs tenths of a sec waiting for input +\*----------------------------------------------------------------------*/ +int _SLsys_input_pending (int tsecs) +{ + long ms; + + if (_SLw32_Hstdin == INVALID_HANDLE_VALUE) + return -1; + + if (tsecs < 0) ms = -tsecs; /* specifies 1/1000 */ + else ms = tsecs * 100L; /* convert 1/10 to 1/1000 secs */ + + process_console_records (); + while ((ms > 0) + && (SLang_Input_Buffer_Len == 0)) + { + long t; + + t = GetTickCount (); + + (void) WaitForSingleObject (_SLw32_Hstdin, ms); + process_console_records (); + ms -= GetTickCount () - t; + } + + return SLang_Input_Buffer_Len; +} + +/*----------------------------------------------------------------------*\ + * Function: unsigned int _SLsys_getkey (void); * * wait for and get the next available keystroke. * Also re-maps some useful keystrokes. @@ -191,33 +307,48 @@ int SLsys_input_pending (int tsecs) * Ctrl-Space => ^@ (^@^3 - a pc NUL char) * extended keys are prefixed by a null character \*----------------------------------------------------------------------*/ -unsigned int SLsys_getkey (void) +unsigned int _SLsys_getkey (void) { - unsigned int scan, ch, shift; - long key, bytesRead; - INPUT_RECORD record; + /* Check the input buffer because _SLsys_input_pending may have been + * called prior to this to stuff the input buffer. + */ + if (SLang_Input_Buffer_Len) + return SLang_getkey (); - while (1) { - if (!ReadConsoleInput(hStdin, &record, 1, &bytesRead)) { - return 0; - } - if (record.EventType == KEY_EVENT && record.Event.KeyEvent.bKeyDown) { -#ifndef __MINGW32__ - return record.Event.KeyEvent.uChar.AsciiChar; -#else - return record.Event.KeyEvent.AsciiChar; -#endif - } - } -/* ReadFile(hStdin, &key, 1, &bytesRead, NULL); */ + if (_SLw32_Hstdin == INVALID_HANDLE_VALUE) + return SLANG_GETKEY_ERROR; -/* return key; */ + while (1) + { + int status; + + if (SLKeyBoard_Quit) + return SLang_Abort_Char; + + status = _SLsys_input_pending (600); + if (status == -1) + return SLANG_GETKEY_ERROR; + + if (status > 0) + return SLang_getkey (); + } } /*----------------------------------------------------------------------*\ - * Function: void SLang_set_abort_signal (void (*handler)(int)); + * Function: int SLang_set_abort_signal (void (*handler)(int)); \*----------------------------------------------------------------------*/ -void SLang_set_abort_signal (void (*handler)(int)) +int SLang_set_abort_signal (void (*handler)(int)) { + if (_SLw32_Hstdin == INVALID_HANDLE_VALUE) + return -1; + return 0; +} + +int SLtt_set_mouse_mode (int mode, int force) +{ + (void) force; + + Process_Mouse_Events = mode; + return 0; }