/* Part of SWI-Prolog Author: Jan Wielemaker and Anjo Anjewierden E-mail: jan@swi.psy.uva.nl WWW: http://www.swi-prolog.org Copyright (c) 2002-2012, University of Amsterdam All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Include file to share stuff inside this library. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /******************************* * HISTORY * *******************************/ typedef struct _history { int size; /* size of the history */ int tail; /* oldest position */ int head; /* newest position */ int current; /* for retrieval */ TCHAR ** lines; /* the lines */ } history, *History; /******************************* * CONSOLE DATA * *******************************/ #define ANSI_MAX_ARGC 10 /* Ansi-escape sequence argv */ #define MAXPROMPT 80 /* max size of prompt */ #define OQSIZE 4096 /* output queue size */ #define MAX_USER_VALUES 10 /* max user data-handles */ typedef struct lqueued { TCHAR * line; /* Lines in queue */ struct lqueued* next; /* Next in queue */ } lqueued, *LQueued; typedef unsigned short text_flags; #define ANSI_COLOR_DEFAULT 31 #define TF_FG(f) ((f)&0x1f) /* foreground */ #define TF_BG(f) (((f)>>5)&0x1f) /* background */ #define TF_BOLD(f) ((f)&(1<<10)) /* bold */ #define TF_UNDERLINE(f) ((f)&(1<<11)) /* underline */ #define TF_DEFAULT (ANSI_COLOR_DEFAULT | ANSI_COLOR_DEFAULT<<5) #define TF_SET_FG(f,c) (((f)&~0x1f)|(c)) #define TF_SET_BG(f,c) (((f)&~(0x1f<<5))|((c)<<5)) #define TF_SET_BOLD(f,v) (((f)&~(1<<10))|((v)<<10)) #define TF_SET_UNDERLINE(f,v) (((f)&~(1<<11))|((v)<<11)) typedef struct { TCHAR code; /* character code */ text_flags flags; /* flags for the text */ } text_char; typedef struct { text_char *text; /* the storage */ unsigned short size; /* #characters in line */ unsigned adjusted : 1; /* line has been adjusted? */ unsigned changed : 1; /* line needs redraw */ unsigned softreturn : 1; /* wrapped line */ } text_line, *TextLine; typedef struct { uintptr_t data; /* the data itself */ RlcFreeDataHook hook; /* call when destroying console */ } user_data; #define RLC_MAGIC 0x3b75df1e /* magic number to verify */ typedef struct { int magic; int height; /* number of lines in buffer */ int width; /* #characters ler line */ int first; /* first line of ring */ int last; /* last line of ring */ int caret_x; /* cursor's x-position */ int caret_y; /* its line */ int window_start; /* start line of the window */ int window_size; /* #lines on the window */ TextLine lines; /* the actual lines */ int sel_unit; /* SEL_CHAR, SEL_WORD, SEL_LINE */ int sel_org_line; /* line origin of the selection */ int sel_org_char; /* char origin of the selection */ int sel_start_line; /* starting line for selection */ int sel_start_char; /* starting char for selection */ int sel_end_line; /* ending line for selection */ int sel_end_char; /* ending char for selection */ int cmdstat; /* for parsing ANSI escape */ int argstat; /* argument status ANSI */ int argc; /* argument count for ANSI */ int argv[ANSI_MAX_ARGC]; /* argument vector for ANSI */ int scaret_x; /* saved-caret X */ int scaret_y; /* saved-caret Y */ HWND window; /* MS-Window window handle */ int has_focus; /* Application has the focus */ HFONT hfont; /* Windows font handle */ int fixedfont; /* Font is fixed */ COLORREF foreground; /* Foreground (text) color */ COLORREF background; /* Background color */ COLORREF sel_foreground; /* Selection foreground */ COLORREF sel_background; /* Selection background */ COLORREF ansi_color[16]; /* ANSI colors (8 normal + 8 bright) */ text_flags sgr_flags; /* Current SGR flags */ int cw; /* character width */ int ch; /* character height */ int cb; /* baseline */ int changed; /* changes to the whole screen */ int sb_lines; /* #lines the scrollbar thinks */ int sb_start; /* start-line scrollbar thinks */ int caret_is_shown; /* is caret in the window? */ TCHAR current_title[RLC_TITLE_MAX]; /* window title */ /* status */ rlc_console_attr * create_attributes; /* Creation attributes */ TCHAR *regkey_name; /* last part of key */ int win_x; /* window top-left corner */ int win_y; /* window top-left corner */ /* output queue */ TCHAR output_queue[OQSIZE]; /* The output queue */ int output_queued; /* # characters in the queue */ struct { TCHAR *line; /* buffered line */ size_t length; /* length of line */ size_t given; /* how much we passed */ } read_buffer; /* input queuing */ int imode; /* input mode */ int imodeswitch; /* switching imode */ RlcQueue queue; /* input stream */ LQueued lhead; /* line-queue head */ LQueued ltail; /* line-queue tail */ TCHAR promptbuf[MAXPROMPT]; /* Buffer for building prompt */ TCHAR prompt[MAXPROMPT]; /* The prompt */ int promptlen; /* length of the prompt */ int closing; /* closing status */ int modified_options; /* OPT_ */ history history; /* history for this console */ /* Thread handles */ HANDLE console_thread; /* I/O thread */ HANDLE application_thread; /* The application I work for */ DWORD console_thread_id; /* I/O thread id */ DWORD application_thread_id; HWND kill_window; /* window in app thread for destroy */ CRITICAL_SECTION lock; /* Serialized actions */ user_data values[MAX_USER_VALUES]; /* associated user data */ } rlc_data, *RlcData; /******************************* * DATA * *******************************/ extern RlcData _rlc_stdio; /* global default console */ /******************************* * FUNCTIONS * *******************************/ extern void rlc_assert(const TCHAR *msg); int rlc_at_head_history(RlcData b); const TCHAR * rlc_bwd_history(RlcData b); const TCHAR * rlc_fwd_history(RlcData b); void rlc_get_mark(rlc_console c, RlcMark mark); void rlc_goto_mark(rlc_console c, RlcMark mark, const TCHAR *data, size_t offset); void rlc_erase_from_caret(rlc_console c); void rlc_putchar(rlc_console c, int chr); TCHAR * rlc_read_screen(rlc_console c, RlcMark from, RlcMark to); void rlc_update(rlc_console c); const TCHAR * rlc_prompt(rlc_console c, const TCHAR *prompt); void rlc_clearprompt(rlc_console c); /******************************* * INLINE FUNCTIONS * *******************************/ #ifdef _DEBUG #define assert(g) if ( !(g) ) rlc_assert(_T(#g)) #else #define assert(g) (void)0 #endif static __inline RlcData rlc_get_data(rlc_console c) { if ( c ) { RlcData b = c; assert(b->magic == RLC_MAGIC); if ( b->magic == RLC_MAGIC ) { return b; } return NULL; } return _rlc_stdio; }