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