1 | //
|
---|
2 | // TxWin, Textmode Windowing Library
|
---|
3 | //
|
---|
4 | // Original code Copyright (c) 1995-2005 Fsys Software and Jan van Wijk
|
---|
5 | //
|
---|
6 | // ==========================================================================
|
---|
7 | //
|
---|
8 | // This file contains Original Code and/or Modifications of Original Code as
|
---|
9 | // defined in and that are subject to the GNU Lesser General Public License.
|
---|
10 | // You may not use this file except in compliance with the License.
|
---|
11 | // BY USING THIS FILE YOU AGREE TO ALL TERMS AND CONDITIONS OF THE LICENSE.
|
---|
12 | // A copy of the License is provided with the Original Code and Modifications,
|
---|
13 | // and is also available at http://www.dfsee.com/txwin/lgpl.htm
|
---|
14 | //
|
---|
15 | // This library is free software; you can redistribute it and/or modify
|
---|
16 | // it under the terms of the GNU Lesser General Public License as published
|
---|
17 | // by the Free Software Foundation; either version 2.1 of the License,
|
---|
18 | // or (at your option) any later version.
|
---|
19 | //
|
---|
20 | // This library is distributed in the hope that it will be useful,
|
---|
21 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
22 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
---|
23 | // See the GNU Lesser General Public License for more details.
|
---|
24 | //
|
---|
25 | // You should have received a copy of the GNU Lesser General Public License
|
---|
26 | // along with this library; (lgpl.htm) if not, write to the Free Software
|
---|
27 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
---|
28 | //
|
---|
29 | // Questions on TxWin licensing can be directed to: txwin@fsys.nl
|
---|
30 | //
|
---|
31 | // ==========================================================================
|
---|
32 | //
|
---|
33 | // Screen output using ANSI X3.64 terminal escape definitions and
|
---|
34 | // file-logging facilities
|
---|
35 | //
|
---|
36 | // Author: J. van Wijk
|
---|
37 | //
|
---|
38 | // JvW 24-01-2003 Removed thread-id from default hex-dump display
|
---|
39 | // JvW 01-02-2002 Added 7 bit ASCII filtering using switch '-7'
|
---|
40 | // JvW 10-12-2001 Added TxStrListAdd
|
---|
41 | // JvW 29-08-2001 Rename to TXCON
|
---|
42 | // JvW 17-01-2000 Added UNICODE modus to FormatMixedStr function
|
---|
43 | // JvW 08-03-1998 Added WIN32 ANSI expansion function (JvD)
|
---|
44 | // JvW 20-04-1997 Ported to WIN32
|
---|
45 | // JvW 27-01-1996 Made more generic, for LPTIO tests
|
---|
46 | // JvW 15-02-1996 Added ddl global debugging variable
|
---|
47 | // JvW 09-03-1996 Added trace macro's and implementation
|
---|
48 | // JvW 26-12-1996 Added RetBool support for 64 threads
|
---|
49 | // JvW 17-06-1995 Initial version, split off from DHPFS.C
|
---|
50 |
|
---|
51 | #include <txlib.h>
|
---|
52 | #include <txwpriv.h> // private window interface
|
---|
53 | #include <txtpriv.h> // private text interface
|
---|
54 |
|
---|
55 | static DEVICE_STATE screen_act = DEVICE_ON;
|
---|
56 | static DEVICE_STATE logfile_act = DEVICE_ON;
|
---|
57 |
|
---|
58 | #if defined (USEWINDOWING)
|
---|
59 | static char txConfirmTitle[] = " Confirmation request ";
|
---|
60 | static char txMsgWarnTitle[] = " Notification or warning message ";
|
---|
61 | #endif
|
---|
62 |
|
---|
63 | // Hook control structures
|
---|
64 | TXH_INFO *txh_clean = NULL; // clean TxPrint handler
|
---|
65 | TXH_INFO *txh_raw = NULL; // raw ansi TxPrint handler
|
---|
66 |
|
---|
67 | static char *txm_buff = NULL; // temporary buffer for TxPrint
|
---|
68 |
|
---|
69 | static BOOL txk_Abort = FALSE; // TX KB-system abort notify
|
---|
70 | static ULONG txkThread = 0; // TX KB-system owning thread
|
---|
71 |
|
---|
72 | #define ANSI_S_TIMEOUT 10000 // 10 seconds timeout on claim
|
---|
73 |
|
---|
74 | static BOOL txc_ascii7 = FALSE; // ASCII filtering off
|
---|
75 | static char txc_ansi = A_ON;
|
---|
76 |
|
---|
77 | //- logfile cycling and size control
|
---|
78 | static ULONG log_written = 0; // bytes written on this file
|
---|
79 | static ULONG log_maxsize = 0; // maximum size per logfile
|
---|
80 | static ULONG log_seq_num = 0; // sequence number 0..n
|
---|
81 | static ULONG log_retain = 0; // log recycle retain count
|
---|
82 |
|
---|
83 | //- Note: 256 color strings sorted in default PC order
|
---|
84 | ANSIDEFS ansi =
|
---|
85 | {
|
---|
86 | "[0;40;30m",
|
---|
87 | "[0;40;34m",
|
---|
88 | "[0;40;32m",
|
---|
89 | "[0;40;36m",
|
---|
90 | "[0;40;31m",
|
---|
91 | "[0;40;35m",
|
---|
92 | "[0;40;33m",
|
---|
93 | "[0;40;37m",
|
---|
94 | "[1;40;30m",
|
---|
95 | "[1;40;34m",
|
---|
96 | "[1;40;32m",
|
---|
97 | "[1;40;36m",
|
---|
98 | "[1;40;31m",
|
---|
99 | "[1;40;35m",
|
---|
100 | "[1;40;33m",
|
---|
101 | "[1;40;37m",
|
---|
102 | "[0;44;30m",
|
---|
103 | "[0;44;34m",
|
---|
104 | "[0;44;32m",
|
---|
105 | "[0;44;36m",
|
---|
106 | "[0;44;31m",
|
---|
107 | "[0;44;35m",
|
---|
108 | "[0;44;33m",
|
---|
109 | "[0;44;37m",
|
---|
110 | "[1;44;30m",
|
---|
111 | "[1;44;34m",
|
---|
112 | "[1;44;32m",
|
---|
113 | "[1;44;36m",
|
---|
114 | "[1;44;31m",
|
---|
115 | "[1;44;35m",
|
---|
116 | "[1;44;33m",
|
---|
117 | "[1;44;37m",
|
---|
118 | "[0;42;30m",
|
---|
119 | "[0;42;34m",
|
---|
120 | "[0;42;32m",
|
---|
121 | "[0;42;36m",
|
---|
122 | "[0;42;31m",
|
---|
123 | "[0;42;35m",
|
---|
124 | "[0;42;33m",
|
---|
125 | "[0;42;37m",
|
---|
126 | "[1;42;30m",
|
---|
127 | "[1;42;34m",
|
---|
128 | "[1;42;32m",
|
---|
129 | "[1;42;36m",
|
---|
130 | "[1;42;31m",
|
---|
131 | "[1;42;35m",
|
---|
132 | "[1;42;33m",
|
---|
133 | "[1;42;37m",
|
---|
134 | "[0;46;30m",
|
---|
135 | "[0;46;34m",
|
---|
136 | "[0;46;32m",
|
---|
137 | "[0;46;36m",
|
---|
138 | "[0;46;31m",
|
---|
139 | "[0;46;35m",
|
---|
140 | "[0;46;33m",
|
---|
141 | "[0;46;37m",
|
---|
142 | "[1;46;30m",
|
---|
143 | "[1;46;34m",
|
---|
144 | "[1;46;32m",
|
---|
145 | "[1;46;36m",
|
---|
146 | "[1;46;31m",
|
---|
147 | "[1;46;35m",
|
---|
148 | "[1;46;33m",
|
---|
149 | "[1;46;37m",
|
---|
150 | "[0;41;30m",
|
---|
151 | "[0;41;34m",
|
---|
152 | "[0;41;32m",
|
---|
153 | "[0;41;36m",
|
---|
154 | "[0;41;31m",
|
---|
155 | "[0;41;35m",
|
---|
156 | "[0;41;33m",
|
---|
157 | "[0;41;37m",
|
---|
158 | "[1;41;30m",
|
---|
159 | "[1;41;34m",
|
---|
160 | "[1;41;32m",
|
---|
161 | "[1;41;36m",
|
---|
162 | "[1;41;31m",
|
---|
163 | "[1;41;35m",
|
---|
164 | "[1;41;33m",
|
---|
165 | "[1;41;37m",
|
---|
166 | "[0;45;30m",
|
---|
167 | "[0;45;34m",
|
---|
168 | "[0;45;32m",
|
---|
169 | "[0;45;36m",
|
---|
170 | "[0;45;31m",
|
---|
171 | "[0;45;35m",
|
---|
172 | "[0;45;33m",
|
---|
173 | "[0;45;37m",
|
---|
174 | "[1;45;30m",
|
---|
175 | "[1;45;34m",
|
---|
176 | "[1;45;32m",
|
---|
177 | "[1;45;36m",
|
---|
178 | "[1;45;31m",
|
---|
179 | "[1;45;35m",
|
---|
180 | "[1;45;33m",
|
---|
181 | "[1;45;37m",
|
---|
182 | "[0;43;30m",
|
---|
183 | "[0;43;34m",
|
---|
184 | "[0;43;32m",
|
---|
185 | "[0;43;36m",
|
---|
186 | "[0;43;31m",
|
---|
187 | "[0;43;35m",
|
---|
188 | "[0;43;33m",
|
---|
189 | "[0;43;37m",
|
---|
190 | "[1;43;30m",
|
---|
191 | "[1;43;34m",
|
---|
192 | "[1;43;32m",
|
---|
193 | "[1;43;36m",
|
---|
194 | "[1;43;31m",
|
---|
195 | "[1;43;35m",
|
---|
196 | "[1;43;33m",
|
---|
197 | "[1;43;37m",
|
---|
198 | "[0;47;30m",
|
---|
199 | "[0;47;34m",
|
---|
200 | "[0;47;32m",
|
---|
201 | "[0;47;36m",
|
---|
202 | "[0;47;31m",
|
---|
203 | "[0;47;35m",
|
---|
204 | "[0;47;33m",
|
---|
205 | "[0;47;37m",
|
---|
206 | "[1;47;30m",
|
---|
207 | "[1;47;34m",
|
---|
208 | "[1;47;32m",
|
---|
209 | "[1;47;36m",
|
---|
210 | "[1;47;31m",
|
---|
211 | "[1;47;35m",
|
---|
212 | "[1;47;33m",
|
---|
213 | "[1;47;37m",
|
---|
214 |
|
---|
215 | "[5;40;30m",
|
---|
216 | "[5;40;34m",
|
---|
217 | "[5;40;32m",
|
---|
218 | "[5;40;36m",
|
---|
219 | "[5;40;31m",
|
---|
220 | "[5;40;35m",
|
---|
221 | "[5;40;33m",
|
---|
222 | "[5;40;37m",
|
---|
223 | "[5;40;1;30m",
|
---|
224 | "[5;40;1;34m",
|
---|
225 | "[5;40;1;32m",
|
---|
226 | "[5;40;1;36m",
|
---|
227 | "[5;40;1;31m",
|
---|
228 | "[5;40;1;35m",
|
---|
229 | "[5;40;1;33m",
|
---|
230 | "[5;40;1;37m",
|
---|
231 | "[5;44;30m",
|
---|
232 | "[5;44;34m",
|
---|
233 | "[5;44;32m",
|
---|
234 | "[5;44;36m",
|
---|
235 | "[5;44;31m",
|
---|
236 | "[5;44;35m",
|
---|
237 | "[5;44;33m",
|
---|
238 | "[5;44;37m",
|
---|
239 | "[5;44;1;30m",
|
---|
240 | "[5;44;1;34m",
|
---|
241 | "[5;44;1;32m",
|
---|
242 | "[5;44;1;36m",
|
---|
243 | "[5;44;1;31m",
|
---|
244 | "[5;44;1;35m",
|
---|
245 | "[5;44;1;33m",
|
---|
246 | "[5;44;1;37m",
|
---|
247 | "[5;42;30m",
|
---|
248 | "[5;42;34m",
|
---|
249 | "[5;42;32m",
|
---|
250 | "[5;42;36m",
|
---|
251 | "[5;42;31m",
|
---|
252 | "[5;42;35m",
|
---|
253 | "[5;42;33m",
|
---|
254 | "[5;42;37m",
|
---|
255 | "[5;42;1;30m",
|
---|
256 | "[5;42;1;34m",
|
---|
257 | "[5;42;1;32m",
|
---|
258 | "[5;42;1;36m",
|
---|
259 | "[5;42;1;31m",
|
---|
260 | "[5;42;1;35m",
|
---|
261 | "[5;42;1;33m",
|
---|
262 | "[5;42;1;37m",
|
---|
263 | "[5;46;30m",
|
---|
264 | "[5;46;34m",
|
---|
265 | "[5;46;32m",
|
---|
266 | "[5;46;36m",
|
---|
267 | "[5;46;31m",
|
---|
268 | "[5;46;35m",
|
---|
269 | "[5;46;33m",
|
---|
270 | "[5;46;37m",
|
---|
271 | "[5;46;1;30m",
|
---|
272 | "[5;46;1;34m",
|
---|
273 | "[5;46;1;32m",
|
---|
274 | "[5;46;1;36m",
|
---|
275 | "[5;46;1;31m",
|
---|
276 | "[5;46;1;35m",
|
---|
277 | "[5;46;1;33m",
|
---|
278 | "[5;46;1;37m",
|
---|
279 | "[5;41;30m",
|
---|
280 | "[5;41;34m",
|
---|
281 | "[5;41;32m",
|
---|
282 | "[5;41;36m",
|
---|
283 | "[5;41;31m",
|
---|
284 | "[5;41;35m",
|
---|
285 | "[5;41;33m",
|
---|
286 | "[5;41;37m",
|
---|
287 | "[5;41;1;30m",
|
---|
288 | "[5;41;1;34m",
|
---|
289 | "[5;41;1;32m",
|
---|
290 | "[5;41;1;36m",
|
---|
291 | "[5;41;1;31m",
|
---|
292 | "[5;41;1;35m",
|
---|
293 | "[5;41;1;33m",
|
---|
294 | "[5;41;1;37m",
|
---|
295 | "[5;45;30m",
|
---|
296 | "[5;45;34m",
|
---|
297 | "[5;45;32m",
|
---|
298 | "[5;45;36m",
|
---|
299 | "[5;45;31m",
|
---|
300 | "[5;45;35m",
|
---|
301 | "[5;45;33m",
|
---|
302 | "[5;45;37m",
|
---|
303 | "[5;45;1;30m",
|
---|
304 | "[5;45;1;34m",
|
---|
305 | "[5;45;1;32m",
|
---|
306 | "[5;45;1;36m",
|
---|
307 | "[5;45;1;31m",
|
---|
308 | "[5;45;1;35m",
|
---|
309 | "[5;45;1;33m",
|
---|
310 | "[5;45;1;37m",
|
---|
311 | "[5;43;30m",
|
---|
312 | "[5;43;34m",
|
---|
313 | "[5;43;32m",
|
---|
314 | "[5;43;36m",
|
---|
315 | "[5;43;31m",
|
---|
316 | "[5;43;35m",
|
---|
317 | "[5;43;33m",
|
---|
318 | "[5;43;37m",
|
---|
319 | "[5;43;1;30m",
|
---|
320 | "[5;43;1;34m",
|
---|
321 | "[5;43;1;32m",
|
---|
322 | "[5;43;1;36m",
|
---|
323 | "[5;43;1;31m",
|
---|
324 | "[5;43;1;35m",
|
---|
325 | "[5;43;1;33m",
|
---|
326 | "[5;43;1;37m",
|
---|
327 | "[5;47;30m",
|
---|
328 | "[5;47;34m",
|
---|
329 | "[5;47;32m",
|
---|
330 | "[5;47;36m",
|
---|
331 | "[5;47;31m",
|
---|
332 | "[5;47;35m",
|
---|
333 | "[5;47;33m",
|
---|
334 | "[5;47;37m",
|
---|
335 | "[5;47;1;30m",
|
---|
336 | "[5;47;1;34m",
|
---|
337 | "[5;47;1;32m",
|
---|
338 | "[5;47;1;36m",
|
---|
339 | "[5;47;1;31m",
|
---|
340 | "[5;47;1;35m",
|
---|
341 | "[5;47;1;33m",
|
---|
342 | "[5;47;1;37m",
|
---|
343 |
|
---|
344 | "[0m", // NORMAL
|
---|
345 | "[1A", // CURSOR_UP1
|
---|
346 | "[2A", // CURSOR_UP2
|
---|
347 | "[4A", // CURSOR_UP4
|
---|
348 | "[8A", // CURSOR_UP8
|
---|
349 | "[1B", // CURSOR_DOWN1
|
---|
350 | "[2B", // CURSOR_DOWN2
|
---|
351 | "[4B", // CURSOR_DOWN4
|
---|
352 | "[8B", // CURSOR_DOWN8
|
---|
353 | "[1C", // CURSOR_RIGHT1
|
---|
354 | "[2C", // CURSOR_RIGHT2
|
---|
355 | "[4C", // CURSOR_RIGHT4
|
---|
356 | "[8C", // CURSOR_RIGHT8
|
---|
357 | "[1D", // CURSOR_LEFT1
|
---|
358 | "[2D", // CURSOR_LEFT2
|
---|
359 | "[4D", // CURSOR_LEFT4
|
---|
360 | "[8D", // CURSOR_LEFT8
|
---|
361 | "[s", // CURSOR_SAVEP
|
---|
362 | "[u", // CURSOR_RESTP
|
---|
363 | "[K", // CLEAR_TO_EOL
|
---|
364 | "[1;70H", // CURS_GO_1_70
|
---|
365 | "[1;75H", // CURS_GO_1_75
|
---|
366 | "[1;1H", // CURS_GO_1_01
|
---|
367 | "[2;1H", // CURS_GO_2_01
|
---|
368 | "[23;1H", // CURS_GO23_01
|
---|
369 | "[24;1H" // CURS_GO24_01
|
---|
370 | };
|
---|
371 |
|
---|
372 |
|
---|
373 | /*****************************************************************************/
|
---|
374 | // Set 7-bit ASCII mode
|
---|
375 | /*****************************************************************************/
|
---|
376 | void TxSetAscii7Mode
|
---|
377 | (
|
---|
378 | BOOL mode // IN ASCII 7-bit mode
|
---|
379 | )
|
---|
380 | {
|
---|
381 | TRACES(( "ASCII7 set 1: %s\n", (mode) ? "TRUE" : "FALSE"));
|
---|
382 | txc_ascii7 = mode;
|
---|
383 | } // end 'TxSetAscii7Mode'
|
---|
384 | /*---------------------------------------------------------------------------*/
|
---|
385 |
|
---|
386 |
|
---|
387 | /*****************************************************************************/
|
---|
388 | // Get ASCII mode, 7-bit or full
|
---|
389 | /*****************************************************************************/
|
---|
390 | BOOL TxGetAscii7Mode // RET ASCII 7-bit in use
|
---|
391 | (
|
---|
392 | void
|
---|
393 | )
|
---|
394 | {
|
---|
395 | return( txc_ascii7);
|
---|
396 | } // end 'TxGetAscii7Mode'
|
---|
397 | /*---------------------------------------------------------------------------*/
|
---|
398 |
|
---|
399 |
|
---|
400 | /*****************************************************************************/
|
---|
401 | // Set ansi string definitions active or inactive
|
---|
402 | /*****************************************************************************/
|
---|
403 | void TxSetAnsiMode
|
---|
404 | (
|
---|
405 | char mode // IN ansi mode
|
---|
406 | )
|
---|
407 | {
|
---|
408 | int i;
|
---|
409 |
|
---|
410 | txc_ansi = mode;
|
---|
411 | for (i = 0; i < NUMBER_ANSIS; i++)
|
---|
412 | {
|
---|
413 | ansi[i][0] = mode;
|
---|
414 | }
|
---|
415 | } // end 'TxSetAnsiMode'
|
---|
416 | /*---------------------------------------------------------------------------*/
|
---|
417 |
|
---|
418 |
|
---|
419 | /*****************************************************************************/
|
---|
420 | // Get ansi string definitions active or inactive
|
---|
421 | /*****************************************************************************/
|
---|
422 | char TxGetAnsiMode // RET ansi mode
|
---|
423 | (
|
---|
424 | void
|
---|
425 | )
|
---|
426 | {
|
---|
427 | return( txc_ansi);
|
---|
428 | } // end 'TxGetAnsiMode'
|
---|
429 | /*---------------------------------------------------------------------------*/
|
---|
430 |
|
---|
431 |
|
---|
432 | /*****************************************************************************/
|
---|
433 | // Test and set TxScreenState
|
---|
434 | /*****************************************************************************/
|
---|
435 | DEVICE_STATE TxScreenState // RET screen active
|
---|
436 | (
|
---|
437 | DEVICE_STATE action // IN screen action
|
---|
438 | )
|
---|
439 | {
|
---|
440 | if (action != DEVICE_TEST)
|
---|
441 | {
|
---|
442 | screen_act = action;
|
---|
443 | }
|
---|
444 | return (screen_act);
|
---|
445 | } // end 'TxScreenState'
|
---|
446 | /*---------------------------------------------------------------------------*/
|
---|
447 |
|
---|
448 |
|
---|
449 | /*****************************************************************************/
|
---|
450 | // Test and set TxLogfileState, logging when state = ON and file opened
|
---|
451 | /*****************************************************************************/
|
---|
452 | DEVICE_STATE TxLogfileState // RET logfile active
|
---|
453 | (
|
---|
454 | DEVICE_STATE action // IN screen action
|
---|
455 | )
|
---|
456 | {
|
---|
457 | if (action != DEVICE_TEST)
|
---|
458 | {
|
---|
459 | logfile_act = action;
|
---|
460 | }
|
---|
461 | return (logfile_act);
|
---|
462 | } // end 'TxLogfileState'
|
---|
463 | /*---------------------------------------------------------------------------*/
|
---|
464 |
|
---|
465 |
|
---|
466 | /*****************************************************************************/
|
---|
467 | // Set logfile maximum size per file
|
---|
468 | /*****************************************************************************/
|
---|
469 | void TxSetLogMaxSize
|
---|
470 | (
|
---|
471 | ULONG size // IN maximum size, bytes
|
---|
472 | )
|
---|
473 | {
|
---|
474 | log_maxsize = size;
|
---|
475 | } // end 'TxSetLogMaxSize'
|
---|
476 | /*---------------------------------------------------------------------------*/
|
---|
477 |
|
---|
478 |
|
---|
479 | /*****************************************************************************/
|
---|
480 | // Set logfile number of files to retain on cycle, #files besides .log itself
|
---|
481 | /*****************************************************************************/
|
---|
482 | void TxSetLogRetain
|
---|
483 | (
|
---|
484 | ULONG retain // IN retain count
|
---|
485 | )
|
---|
486 | {
|
---|
487 | log_retain = retain;
|
---|
488 | } // end 'TxSetLogRetain'
|
---|
489 | /*---------------------------------------------------------------------------*/
|
---|
490 |
|
---|
491 |
|
---|
492 | /*****************************************************************************/
|
---|
493 | // printf-like print on stdout, LOG filehandle and raw/clean copy hooks
|
---|
494 | /*****************************************************************************/
|
---|
495 | void TxPrint
|
---|
496 | (
|
---|
497 | char *fmt, // IN format string (printf)
|
---|
498 | ... // IN variable arguments
|
---|
499 | )
|
---|
500 | {
|
---|
501 | va_list varargs;
|
---|
502 | ULONG size = 0;
|
---|
503 | BOOL log7bit;
|
---|
504 | BOOL logreopen;
|
---|
505 | FILE *log_handle = TxQueryLogFile( &log7bit, &logreopen);
|
---|
506 | TXH_INFO *hinfo; // current hook info
|
---|
507 |
|
---|
508 | va_start(varargs, fmt);
|
---|
509 | if (txm_buff == NULL)
|
---|
510 | {
|
---|
511 | txm_buff = calloc( 1, TXMAX4K);
|
---|
512 | }
|
---|
513 | if (txm_buff != NULL)
|
---|
514 | {
|
---|
515 | size = vsprintf( txm_buff, fmt, varargs); // expanded string in buffer
|
---|
516 |
|
---|
517 | if (txc_ascii7) // filter to 7-bit ASCII
|
---|
518 | {
|
---|
519 | TxAscii827( txm_buff, TXASCII827_TRANS);
|
---|
520 | }
|
---|
521 |
|
---|
522 | if ((screen_act == DEVICE_ON) && // screen output ON
|
---|
523 | (txh_raw == NULL)) // and not redirected to a RAW
|
---|
524 | { // stream (like scrollbuffer)
|
---|
525 | #if defined (WIN32)
|
---|
526 | txNtConsoleDisplay( txm_buff); // ANSI expand and print
|
---|
527 | #else
|
---|
528 | printf( "%s", txm_buff); // just print formatted buffer
|
---|
529 | #endif
|
---|
530 | fflush(stdout);
|
---|
531 | }
|
---|
532 | for (hinfo = txh_raw; hinfo != NULL; hinfo = hinfo->next)
|
---|
533 | {
|
---|
534 | if ((size < hinfo->size) && (hinfo->active) &&
|
---|
535 | ((screen_act == DEVICE_ON) ||
|
---|
536 | (hinfo->follow_screen_toggle == FALSE)))
|
---|
537 | {
|
---|
538 | strcpy( hinfo->cbuf, txm_buff);
|
---|
539 | (hinfo->copy) (hinfo->cbuf, hinfo->user);
|
---|
540 | }
|
---|
541 | }
|
---|
542 | if ((log_handle != 0) || (txh_clean != NULL))
|
---|
543 | {
|
---|
544 | TxStripAnsiCodes( txm_buff);
|
---|
545 | for (hinfo = txh_clean; hinfo != NULL; hinfo = hinfo->next)
|
---|
546 | {
|
---|
547 | if ((size < hinfo->size) && (hinfo->active) &&
|
---|
548 | ((screen_act == DEVICE_ON) ||
|
---|
549 | (hinfo->follow_screen_toggle == FALSE)))
|
---|
550 | {
|
---|
551 | strcpy( hinfo->cbuf, txm_buff);
|
---|
552 | (hinfo->copy) (hinfo->cbuf, hinfo->user);
|
---|
553 | }
|
---|
554 | }
|
---|
555 | if ((log_handle != 0) && (logfile_act == DEVICE_ON))
|
---|
556 | {
|
---|
557 | if (!txc_ascii7 && log7bit) // 7-bit ASCII for log only ?
|
---|
558 | {
|
---|
559 | TxAscii827( txm_buff, TXASCII827_TRANS);
|
---|
560 | }
|
---|
561 |
|
---|
562 | if ((log_maxsize > size) && (log_written > (log_maxsize - size)))
|
---|
563 | {
|
---|
564 | TXLN fname;
|
---|
565 |
|
---|
566 | log_written = 0; // avoid recursive cycling
|
---|
567 | fprintf( log_handle, "\nClosing logfile at size limit\n");
|
---|
568 |
|
---|
569 | TxAppendToLogFile( NULL, FALSE); // close current log, quiet
|
---|
570 | if (log_seq_num >= log_retain) // need to delete one
|
---|
571 | {
|
---|
572 | TxBuildLogName( log_seq_num - log_retain, fname);
|
---|
573 | remove( fname); // delete a logfile (cycle)
|
---|
574 | }
|
---|
575 | TxBuildLogName( (log_retain) ? ++log_seq_num : 0, fname);
|
---|
576 | TxAppendToLogFile( fname, FALSE); // open next logfile, quiet
|
---|
577 | log_handle = TxQueryLogFile( &log7bit, &logreopen);
|
---|
578 | fprintf( log_handle, "Start next logfile: '%s'\n", fname);
|
---|
579 | }
|
---|
580 | else
|
---|
581 | {
|
---|
582 | log_written += size; // maintain total size in log
|
---|
583 | }
|
---|
584 |
|
---|
585 | fprintf( log_handle, "%s", txm_buff);
|
---|
586 | if (logreopen)
|
---|
587 | {
|
---|
588 | TxCloseReopenLogFile(); // close/reopen (force flush)
|
---|
589 | }
|
---|
590 | else
|
---|
591 | {
|
---|
592 | fflush( log_handle); // soft flush
|
---|
593 | }
|
---|
594 | }
|
---|
595 | }
|
---|
596 | }
|
---|
597 | va_end(varargs);
|
---|
598 | } // end 'TxPrint'
|
---|
599 | /*---------------------------------------------------------------------------*/
|
---|
600 |
|
---|
601 |
|
---|
602 | /*****************************************************************************/
|
---|
603 | // Remove ANSI control code from a text-string (in place conversion)
|
---|
604 | /*****************************************************************************/
|
---|
605 | char *TxStripAnsiCodes // RET stripped string
|
---|
606 | (
|
---|
607 | char *text // INOUT ANSI text to strip
|
---|
608 | )
|
---|
609 | {
|
---|
610 | char *rd = text; // read-pointer in string
|
---|
611 | char *wr = text; // write pointer
|
---|
612 |
|
---|
613 | while (*rd)
|
---|
614 | {
|
---|
615 | if ((*rd == TXK_ESCAPE) && (*(rd+1) == '['))
|
---|
616 | {
|
---|
617 | rd += 2;
|
---|
618 | while ((isdigit(*rd)) || (*rd == ';'))
|
---|
619 | {
|
---|
620 | rd++;
|
---|
621 | }
|
---|
622 | }
|
---|
623 | else
|
---|
624 | {
|
---|
625 | *(wr++) = *rd; // copy the character
|
---|
626 | }
|
---|
627 | rd++;
|
---|
628 | }
|
---|
629 | *wr = '\0'; // terminate stripped string
|
---|
630 | return( text);
|
---|
631 | } // end 'TxStripAnsiCodes'
|
---|
632 | /*---------------------------------------------------------------------------*/
|
---|
633 |
|
---|
634 |
|
---|
635 | /*****************************************************************************/
|
---|
636 | // Claim TX keyboard access-functions for current thread (TxAbort etc)
|
---|
637 | /*****************************************************************************/
|
---|
638 | ULONG TxClaimKeyboard // RET previous owner
|
---|
639 | (
|
---|
640 | void
|
---|
641 | )
|
---|
642 | {
|
---|
643 | ULONG rc = txkThread; // function return
|
---|
644 |
|
---|
645 | ENTER();
|
---|
646 |
|
---|
647 | txkThread = TXCURTHREAD;
|
---|
648 |
|
---|
649 | RETURN (rc);
|
---|
650 | } // end 'TxClaimKeyboard'
|
---|
651 | /*---------------------------------------------------------------------------*/
|
---|
652 |
|
---|
653 |
|
---|
654 | /*****************************************************************************/
|
---|
655 | // Cancel any pending abort status (as returned by TxAbort)
|
---|
656 | /*****************************************************************************/
|
---|
657 | void TxCancelAbort
|
---|
658 | (
|
---|
659 | void
|
---|
660 | )
|
---|
661 | {
|
---|
662 | ENTER();
|
---|
663 |
|
---|
664 | txk_Abort = FALSE;
|
---|
665 |
|
---|
666 | VRETURN ();
|
---|
667 | } // end 'TxCancelAbort'
|
---|
668 | /*---------------------------------------------------------------------------*/
|
---|
669 |
|
---|
670 | /*****************************************************************************/
|
---|
671 | // Set abort status to pending, for other threads (as returned by TxAbort)
|
---|
672 | /*****************************************************************************/
|
---|
673 | void TxSetPendingAbort
|
---|
674 | (
|
---|
675 | void
|
---|
676 | )
|
---|
677 | {
|
---|
678 | ENTER();
|
---|
679 |
|
---|
680 | txk_Abort = TRUE;
|
---|
681 |
|
---|
682 | VRETURN ();
|
---|
683 | } // end 'TxSetPendingAbort'
|
---|
684 | /*---------------------------------------------------------------------------*/
|
---|
685 |
|
---|
686 |
|
---|
687 | /*****************************************************************************/
|
---|
688 | // Return kbhit status and latest More ... reply, read away the hit
|
---|
689 | /*****************************************************************************/
|
---|
690 | BOOL TxAbort // RET TRUE when abort wanted
|
---|
691 | (
|
---|
692 | void
|
---|
693 | )
|
---|
694 | {
|
---|
695 | BOOL aborting = FALSE;
|
---|
696 | ULONG key;
|
---|
697 |
|
---|
698 | if ((txk_Abort) || // already aborting
|
---|
699 | (txkThread != TXCURTHREAD)) // or not KB owning thread
|
---|
700 | {
|
---|
701 | aborting = txk_Abort;
|
---|
702 | }
|
---|
703 | else
|
---|
704 | {
|
---|
705 | if (kbhit())
|
---|
706 | {
|
---|
707 | #if defined (USEWINDOWING)
|
---|
708 | key = txwGetInputEvent( NULL);
|
---|
709 | #else
|
---|
710 | key = getch();
|
---|
711 | #endif
|
---|
712 | switch (key)
|
---|
713 | {
|
---|
714 | case TXK_ESCAPE:
|
---|
715 | aborting = TRUE; // abort if <Esc>
|
---|
716 | txk_Abort = TRUE; // remember abort status
|
---|
717 | break;
|
---|
718 |
|
---|
719 | #if defined (DUMP)
|
---|
720 | case TXa_SLASH: // toggle trace value
|
---|
721 | switch (TxTrLevel)
|
---|
722 | {
|
---|
723 | case 0: TxTrLevel = 1; break;
|
---|
724 | case 1: TxTrLevel = 100; break;
|
---|
725 | default: TxTrLevel = 0; break;
|
---|
726 | }
|
---|
727 | break;
|
---|
728 | #endif
|
---|
729 | default: // route some keys to focus-win
|
---|
730 | #if defined (USEWINDOWING)
|
---|
731 | if (txwa->desktop != NULL) // if windowing is active
|
---|
732 | {
|
---|
733 | switch (key) // do not send critical keys
|
---|
734 | {
|
---|
735 | case TXk_ENTER:
|
---|
736 | break;
|
---|
737 |
|
---|
738 | default:
|
---|
739 | txwSendMsg((TXWHANDLE) txwa->focus, TXWM_CHAR, 0, key);
|
---|
740 | break;
|
---|
741 | }
|
---|
742 | }
|
---|
743 | #endif // USEWINDOWING
|
---|
744 | break;
|
---|
745 | }
|
---|
746 | }
|
---|
747 | }
|
---|
748 | return( aborting);
|
---|
749 | } // end 'TxAbort'
|
---|
750 | /*---------------------------------------------------------------------------*/
|
---|
751 |
|
---|
752 |
|
---|
753 | /*****************************************************************************/
|
---|
754 | // Display a message using format string and ask confirmation
|
---|
755 | /*****************************************************************************/
|
---|
756 | BOOL TxConfirm // RET Confirmed
|
---|
757 | (
|
---|
758 | ULONG helpid, // IN helpid confirmation
|
---|
759 | char *fmt, // IN format string (printf)
|
---|
760 | ... // IN variable arguments
|
---|
761 | )
|
---|
762 | {
|
---|
763 | BOOL cf = TRUE; // return value
|
---|
764 | TX1K text;
|
---|
765 | int reply = 'n';
|
---|
766 | va_list varargs;
|
---|
767 | char **mText; // formatted text for display
|
---|
768 | int ll; // real max line length
|
---|
769 | int lines; // nr of lines
|
---|
770 | DEVICE_STATE sa = screen_act;
|
---|
771 |
|
---|
772 | if ((ll = TxScreenCols() -12) < 20) // ScreenCols will be 0 if
|
---|
773 | { // output is redirected!
|
---|
774 | ll = 20;
|
---|
775 | }
|
---|
776 | if ((txwa->desktop != NULL) && (!TxaExeSwitch('p')))
|
---|
777 | {
|
---|
778 | screen_act = DEVICE_OFF; // no regular text if windowed
|
---|
779 | } // and not 'pedantic mode'
|
---|
780 | else
|
---|
781 | {
|
---|
782 | screen_act = DEVICE_ON; // force screen for confirm
|
---|
783 | }
|
---|
784 | va_start(varargs, fmt);
|
---|
785 | vsprintf( text, fmt, varargs); // format the message
|
---|
786 |
|
---|
787 | mText = txString2Text( text, &ll, &lines); // convert to multi-line
|
---|
788 | TxPrint( "\n"); // force empty line before
|
---|
789 | TxShowTxt( mText); // display in scrollbuffer
|
---|
790 | txFreeText( mText); // free the text memory
|
---|
791 |
|
---|
792 | screen_act = sa; // restore screen state
|
---|
793 | // to allow sbView output while
|
---|
794 | // MsgBox is up (other threads!)
|
---|
795 | #if defined (USEWINDOWING)
|
---|
796 | if (txwa->desktop != NULL) // there is a desktop
|
---|
797 | {
|
---|
798 | char *yn;
|
---|
799 |
|
---|
800 | TxStripAnsiCodes( text); // remove colors for popup
|
---|
801 | if ((yn = strstr( text, "[Y/N]")) != NULL)
|
---|
802 | {
|
---|
803 | *yn = '\0'; // remove [y/n] part
|
---|
804 | }
|
---|
805 | switch (txwMessageBox( TXHWND_DESKTOP, TXHWND_DESKTOP,
|
---|
806 | text, txConfirmTitle, helpid,
|
---|
807 | TXMB_YESNOCANCEL | TXMB_MOVEABLE |
|
---|
808 | TXMB_HCENTER | TXMB_VCENTER) )
|
---|
809 | {
|
---|
810 | case TXMBID_OK: // F4=OK
|
---|
811 | case TXMBID_YES:
|
---|
812 | reply = 'y'; // for logging only
|
---|
813 | break;
|
---|
814 |
|
---|
815 | case TXMBID_CANCEL:
|
---|
816 | TxSetPendingAbort();
|
---|
817 | TxPrint( "Abort");
|
---|
818 | reply = '!';
|
---|
819 | default:
|
---|
820 | cf = FALSE; // not confirmed
|
---|
821 | break;
|
---|
822 | }
|
---|
823 | }
|
---|
824 | else // use non-windowed interface
|
---|
825 | #endif // USEWINDOWING
|
---|
826 | {
|
---|
827 | if (TxAbort())
|
---|
828 | {
|
---|
829 | reply = TXK_ESCAPE;
|
---|
830 | }
|
---|
831 | else
|
---|
832 | {
|
---|
833 | reply = getch(); // wait for next keystroke
|
---|
834 | }
|
---|
835 | switch (reply)
|
---|
836 | {
|
---|
837 | case 'y': case 'Y':
|
---|
838 | case 'j': case 'J':
|
---|
839 | break;
|
---|
840 |
|
---|
841 | case TXK_ESCAPE:
|
---|
842 | TxSetPendingAbort();
|
---|
843 | TxPrint( "Abort");
|
---|
844 | reply = '!';
|
---|
845 | default:
|
---|
846 | cf = FALSE; // not confirmed
|
---|
847 | break;
|
---|
848 | }
|
---|
849 | }
|
---|
850 | TxPrint("%c\n", reply);
|
---|
851 |
|
---|
852 | return (cf);
|
---|
853 | } // end 'TxConfirm'
|
---|
854 | /*---------------------------------------------------------------------------*/
|
---|
855 |
|
---|
856 |
|
---|
857 | /*****************************************************************************/
|
---|
858 | // Display a message or warning using format string and wait for OK (or ESC)
|
---|
859 | /*****************************************************************************/
|
---|
860 | BOOL TxMessage // RET OK, not escaped
|
---|
861 | (
|
---|
862 | BOOL acknowledge, // IN wait for acknowledge
|
---|
863 | ULONG helpid, // IN helpid confirmation
|
---|
864 | char *fmt, // IN format string (printf)
|
---|
865 | ... // IN variable arguments
|
---|
866 | )
|
---|
867 | {
|
---|
868 | BOOL rc = TRUE; // return value
|
---|
869 | TX1K text;
|
---|
870 | va_list varargs;
|
---|
871 | char **mText; // formatted text for display
|
---|
872 | int ll; // real max line length
|
---|
873 | int lines; // nr of lines
|
---|
874 | DEVICE_STATE sa = screen_act;
|
---|
875 |
|
---|
876 | if ((ll = TxScreenCols() -4) < 20) // ScreenCols will be 0 if
|
---|
877 | { // output is redirected!
|
---|
878 | ll = 20;
|
---|
879 | }
|
---|
880 | if ((txwa->desktop != NULL) && (acknowledge) && (!TxaExeSwitch('p')))
|
---|
881 | {
|
---|
882 | screen_act = DEVICE_OFF; // no regular text if windowed
|
---|
883 | } // and not 'pedantic mode'
|
---|
884 | else if (acknowledge)
|
---|
885 | {
|
---|
886 | screen_act = DEVICE_ON; // force screen on for confirm
|
---|
887 | }
|
---|
888 | va_start(varargs, fmt);
|
---|
889 | vsprintf( text, fmt, varargs); // format the message
|
---|
890 |
|
---|
891 | mText = txString2Text( text, &ll, &lines); // convert to multi-line
|
---|
892 | TxPrint( "\n"); // force empty line before
|
---|
893 | TxShowTxt( mText); // display in scrollbuffer
|
---|
894 | txFreeText( mText); // free the text memory
|
---|
895 | TxPrint("\n");
|
---|
896 |
|
---|
897 | screen_act = sa; // restore screen state
|
---|
898 | // to allow sbView output while
|
---|
899 | // MsgBox is up (other threads!)
|
---|
900 | if (acknowledge)
|
---|
901 | {
|
---|
902 | #if defined (USEWINDOWING)
|
---|
903 | if (txwa->desktop != NULL) // there is a desktop
|
---|
904 | {
|
---|
905 | TxStripAnsiCodes( text); // remove colors for popup
|
---|
906 | if (txwMessageBox( TXHWND_DESKTOP, TXHWND_DESKTOP,
|
---|
907 | text, txMsgWarnTitle, helpid,
|
---|
908 | TXMB_OK | TXMB_MOVEABLE |
|
---|
909 | TXMB_VCENTER | TXMB_HCENTER) != TXMBID_OK)
|
---|
910 | {
|
---|
911 | rc = FALSE;
|
---|
912 | }
|
---|
913 | TxCancelAbort(); // avoid aborting on Escape ...
|
---|
914 | }
|
---|
915 | else // use non-windowed interface
|
---|
916 | #endif
|
---|
917 | {
|
---|
918 | TxPrint( "Press [Space-bar] to continue ...\n");
|
---|
919 | if (getch() == TXK_ESCAPE) // wait for next keystroke
|
---|
920 | {
|
---|
921 | rc = FALSE;
|
---|
922 | }
|
---|
923 | }
|
---|
924 | }
|
---|
925 | return (rc);
|
---|
926 | } // end 'TxMessage'
|
---|
927 | /*---------------------------------------------------------------------------*/
|
---|
928 |
|
---|