1 /* Part of SWI-Prolog
2
3 Author: Jan Wielemaker and Anjo Anjewierden
4 E-mail: jan@swi.psy.uva.nl
5 WWW: http://www.swi-prolog.org
6 Copyright (c) 2002-2012, University of Amsterdam
7 All rights reserved.
8
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions
11 are met:
12
13 1. Redistributions of source code must retain the above copyright
14 notice, this list of conditions and the following disclaimer.
15
16 2. Redistributions in binary form must reproduce the above copyright
17 notice, this list of conditions and the following disclaimer in
18 the documentation and/or other materials provided with the
19 distribution.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
36 Include file to share stuff inside this library.
37 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
38
39 /*******************************
40 * HISTORY *
41 *******************************/
42
43 typedef struct _history
44 { int size; /* size of the history */
45 int tail; /* oldest position */
46 int head; /* newest position */
47 int current; /* for retrieval */
48 TCHAR ** lines; /* the lines */
49 } history, *History;
50
51
52 /*******************************
53 * CONSOLE DATA *
54 *******************************/
55
56 #define ANSI_MAX_ARGC 10 /* Ansi-escape sequence argv */
57 #define MAXPROMPT 80 /* max size of prompt */
58 #define OQSIZE 4096 /* output queue size */
59 #define MAX_USER_VALUES 10 /* max user data-handles */
60
61 typedef struct lqueued
62 { TCHAR * line; /* Lines in queue */
63 struct lqueued* next; /* Next in queue */
64 } lqueued, *LQueued;
65
66 typedef unsigned short text_flags;
67
68 #define ANSI_COLOR_DEFAULT 31
69
70 #define TF_FG(f) ((f)&0x1f) /* foreground */
71 #define TF_BG(f) (((f)>>5)&0x1f) /* background */
72 #define TF_BOLD(f) ((f)&(1<<10)) /* bold */
73 #define TF_UNDERLINE(f) ((f)&(1<<11)) /* underline */
74
75 #define TF_DEFAULT (ANSI_COLOR_DEFAULT | ANSI_COLOR_DEFAULT<<5)
76
77 #define TF_SET_FG(f,c) (((f)&~0x1f)|(c))
78 #define TF_SET_BG(f,c) (((f)&~(0x1f<<5))|((c)<<5))
79 #define TF_SET_BOLD(f,v) (((f)&~(1<<10))|((v)<<10))
80 #define TF_SET_UNDERLINE(f,v) (((f)&~(1<<11))|((v)<<11))
81
82 typedef struct
83 { TCHAR code; /* character code */
84 text_flags flags; /* flags for the text */
85 } text_char;
86
87 typedef struct
88 { text_char *text; /* the storage */
89 unsigned short size; /* #characters in line */
90 unsigned adjusted : 1; /* line has been adjusted? */
91 unsigned changed : 1; /* line needs redraw */
92 unsigned softreturn : 1; /* wrapped line */
93 } text_line, *TextLine;
94
95 typedef struct
96 { uintptr_t data; /* the data itself */
97 RlcFreeDataHook hook; /* call when destroying console */
98 } user_data;
99
100 #define RLC_MAGIC 0x3b75df1e /* magic number to verify */
101
102 typedef struct
103 { int magic;
104 int height; /* number of lines in buffer */
105 int width; /* #characters ler line */
106 int first; /* first line of ring */
107 int last; /* last line of ring */
108 int caret_x; /* cursor's x-position */
109 int caret_y; /* its line */
110 int window_start; /* start line of the window */
111 int window_size; /* #lines on the window */
112 TextLine lines; /* the actual lines */
113 int sel_unit; /* SEL_CHAR, SEL_WORD, SEL_LINE */
114 int sel_org_line; /* line origin of the selection */
115 int sel_org_char; /* char origin of the selection */
116 int sel_start_line; /* starting line for selection */
117 int sel_start_char; /* starting char for selection */
118 int sel_end_line; /* ending line for selection */
119 int sel_end_char; /* ending char for selection */
120 int cmdstat; /* for parsing ANSI escape */
121 int argstat; /* argument status ANSI */
122 int argc; /* argument count for ANSI */
123 int argv[ANSI_MAX_ARGC]; /* argument vector for ANSI */
124 int scaret_x; /* saved-caret X */
125 int scaret_y; /* saved-caret Y */
126 HWND window; /* MS-Window window handle */
127 int has_focus; /* Application has the focus */
128 HFONT hfont; /* Windows font handle */
129 int fixedfont; /* Font is fixed */
130 COLORREF foreground; /* Foreground (text) color */
131 COLORREF background; /* Background color */
132 COLORREF sel_foreground; /* Selection foreground */
133 COLORREF sel_background; /* Selection background */
134 COLORREF ansi_color[16]; /* ANSI colors (8 normal + 8 bright) */
135 text_flags sgr_flags; /* Current SGR flags */
136 int cw; /* character width */
137 int ch; /* character height */
138 int cb; /* baseline */
139 int changed; /* changes to the whole screen */
140 int sb_lines; /* #lines the scrollbar thinks */
141 int sb_start; /* start-line scrollbar thinks */
142 int caret_is_shown; /* is caret in the window? */
143 TCHAR current_title[RLC_TITLE_MAX]; /* window title */
144 /* status */
145 rlc_console_attr * create_attributes; /* Creation attributes */
146 TCHAR *regkey_name; /* last part of key */
147 int win_x; /* window top-left corner */
148 int win_y; /* window top-left corner */
149 /* output queue */
150 TCHAR output_queue[OQSIZE]; /* The output queue */
151 int output_queued; /* # characters in the queue */
152 struct
153 { TCHAR *line; /* buffered line */
154 size_t length; /* length of line */
155 size_t given; /* how much we passed */
156 } read_buffer;
157 /* input queuing */
158 int imode; /* input mode */
159 int imodeswitch; /* switching imode */
160 RlcQueue queue; /* input stream */
161 LQueued lhead; /* line-queue head */
162 LQueued ltail; /* line-queue tail */
163 TCHAR promptbuf[MAXPROMPT]; /* Buffer for building prompt */
164 TCHAR prompt[MAXPROMPT]; /* The prompt */
165 int promptlen; /* length of the prompt */
166 int closing; /* closing status */
167 int modified_options; /* OPT_ */
168 history history; /* history for this console */
169 /* Thread handles */
170 HANDLE console_thread; /* I/O thread */
171 HANDLE application_thread; /* The application I work for */
172 DWORD console_thread_id; /* I/O thread id */
173 DWORD application_thread_id;
174 HWND kill_window; /* window in app thread for destroy */
175
176 user_data values[MAX_USER_VALUES]; /* associated user data */
177 } rlc_data, *RlcData;
178
179
180 /*******************************
181 * DATA *
182 *******************************/
183
184 extern RlcData _rlc_stdio; /* global default console */
185
186
187 /*******************************
188 * FUNCTIONS *
189 *******************************/
190
191 extern void rlc_assert(const TCHAR *msg);
192 int rlc_at_head_history(RlcData b);
193 const TCHAR * rlc_bwd_history(RlcData b);
194 const TCHAR * rlc_fwd_history(RlcData b);
195 void rlc_get_mark(rlc_console c, RlcMark mark);
196 void rlc_goto_mark(rlc_console c, RlcMark mark,
197 const TCHAR *data, size_t offset);
198 void rlc_erase_from_caret(rlc_console c);
199 void rlc_putchar(rlc_console c, int chr);
200 TCHAR * rlc_read_screen(rlc_console c,
201 RlcMark from, RlcMark to);
202 void rlc_update(rlc_console c);
203 const TCHAR * rlc_prompt(rlc_console c, const TCHAR *prompt);
204 void rlc_clearprompt(rlc_console c);
205
206
207 /*******************************
208 * INLINE FUNCTIONS *
209 *******************************/
210
211 #ifdef _DEBUG
212 #define assert(g) if ( !(g) ) rlc_assert(_T(#g))
213 #else
214 #define assert(g) (void)0
215 #endif
216
217 static __inline RlcData
rlc_get_data(rlc_console c)218 rlc_get_data(rlc_console c)
219 { if ( c )
220 { RlcData b = c;
221
222 assert(b->magic == RLC_MAGIC);
223 if ( b->magic == RLC_MAGIC )
224 { return b;
225 }
226 return NULL;
227 }
228
229 return _rlc_stdio;
230 }
231
232
233