cfad47cfa3/tads2/osifc.h

4b825dc642cb6eb9a060e54bf8d69288fbee4904cfad47cfa334b206c65f22086bcc5d63e6f70944
1
/* $Header: d:/cvsroot/tads/TADS2/osifc.h,v 1.3 1999/07/11 00:46:34 MJRoberts Exp $ */
2
3
/* 
4
 *   Copyright (c) 1997, 2002 Michael J. Roberts.  All Rights Reserved.
5
 *   
6
 *   Please see the accompanying license file, LICENSE.TXT, for information
7
 *   on using and copying this software.  
8
 */
9
/*
10
Name
11
  osifc.h - portable interfaces to OS-specific functions
12
Function
13
  This file defines interfaces to certain functions that must be called
14
  from portable code, but which must have system-specific implementations.
15
Notes
16
  DO NOT MODIFY THIS FILE WITH PLATFORM-SPECIFIC DEFINITIONS.  If you
17
  wish to add definitions for your platform, add them to the osxxx.h
18
  file specific to your platform.  Note that your osxxx.h file is always
19
  included *before* this file, so items in your osxxx.h file are already
20
  defined by the time this file is seen by the compiler.
21
22
  To port TADS to a new platform, you should go through this entire file
23
  and provide a definition for each documented macro, typedef, and
24
  function, and you should provide an implementation for each function
25
  prototype.  Each prototype provides a portable interface, so it is
26
  the same on all platforms, but each platform requires its own custom
27
  implementation.  Put your definitions in your osxxx.h header file; put
28
  your function implementations in your osxxx.c file or files.
29
  
30
  You should not change any macro or typedef that is actually #define'd
31
  in this file.  Those definitions are part of the portable interface,
32
  not part of the platform-specific implementation.
33
34
  Certain functions are merely documented here, but no prototypes are
35
  provided.  For these functions, most platforms use #define macros to
36
  implement the functions in terms of standard C library functions or
37
  OS API functions; we do not provide prototypes for these functions so
38
  that the OS implementation can call the C library or OS API functions
39
  directly through a macro, avoiding an unnecessary extra function call.
40
  However, if you must provide an implementation for these functions,
41
  you can provide your own prototypes for them in your osxxx.h header
42
  file.
43
44
  SEE ALSO osifctyp.h, which contains definitions for some of the
45
  interface datatypes.
46
47
Modified
48
  04/04/99 CNebel     - Improve const-ness; use new appctx.h header.
49
  12/05/97 MJRoberts  - Creation
50
*/
51
52
#ifndef OSIFC_H
53
#define OSIFC_H
54
55
#include <stdlib.h>
56
#include "appctx.h"
57
58
#ifdef __cplusplus
59
extern "C" {
60
#endif
61
62
/* ------------------------------------------------------------------------ */
63
/*
64
 *   A note on character sets:
65
 *   
66
 *   Except where noted, all character strings passed to and from the
67
 *   osxxx functions defined herein use the local operating system
68
 *   representation.  On a Windows machine localized to Eastern Europe,
69
 *   for example, the character strings passed to and from the osxxx
70
 *   functions would use single-byte characters in the Windows code page
71
 *   1250 representation.
72
 *   
73
 *   Callers that use multiple character sets must implement mappings to
74
 *   and from the local character set when calling the osxxx functions.
75
 *   The osxxx implementations are thus free to ignore any issues related
76
 *   to character set conversion or mapping.
77
 *   
78
 *   The osxxx implementations are specifically not permitted to use
79
 *   double-byte Unicode as the native character set, nor any other
80
 *   character set where a null byte could appear as part of a non-null
81
 *   character.  In particular, callers may assume that null-terminated
82
 *   strings passed to and from the osxxx functions contain no embedded
83
 *   null bytes.  Multi-byte character sets (i.e., character sets with
84
 *   mixed single-byte and double-byte characters) may be used as long as
85
 *   a null byte is never part of any multi-byte character, since this
86
 *   would guarantee that a null byte could always be taken as a null
87
 *   character without knowledge of the encoding or context.  
88
 */
89
90
/* ------------------------------------------------------------------------ */
91
/*
92
 *   "Far" Pointers.  Most platforms can ignore this.  For platforms with
93
 *   mixed-mode addressing models, where pointers of different sizes can
94
 *   be used within a single program and hence some pointers require
95
 *   qualification to indicate that they use a non-default addressing
96
 *   model, the keyword OSFAR should be defined to the appropriate
97
 *   compiler-specific extension keyword.
98
 *   
99
 *   If you don't know what I'm talking about here, you should just ignore
100
 *   it, because your platform probably doesn't have anything this
101
 *   sinister.  As of this writing, this applies only to MS-DOS, and then
102
 *   only to 16-bit implementations that must interact with other 16-bit
103
 *   programs via dynamic linking or other mechanisms.  
104
 */
105
106
107
/* ------------------------------------------------------------------------ */
108
/*
109
 *   Hardware Configuration.  Define the following functions appropriately
110
 *   for your hardware.  For efficiency, these functions should be defined
111
 *   as macros if possible.
112
 *   
113
 *   Note that these hardware definitions are independent of the OS, at
114
 *   least to the extent that your OS can run on multiple types of
115
 *   hardware.  So, rather than combining these definitions into your
116
 *   osxxx.h header file, we recommend that you put these definitions in a
117
 *   separate h_yyy.h header file, which can be configured into os.h with
118
 *   an appropriate "_M_yyy" preprocessor symbol.  Refer to os.h for
119
 *   details of configuring the hardware include file.  
120
 */
121
122
/* 
123
 *   Round a size up to worst-case alignment boundary.  For example, on a
124
 *   platform where the largest type must be aligned on a 4-byte boundary,
125
 *   this should round the value up to the next higher mutliple of 4 and
126
 *   return the result.  
127
 */
128
/* size_t osrndsz(size_t siz); */
129
130
/* 
131
 *   Round a pointer up to worst-case alignment boundary. 
132
 */
133
/* void *osrndpt(void *ptr); */
134
135
/* 
136
 *   Read an unaligned portable unsigned 2-byte value, returning an int
137
 *   value.  The portable representation has the least significant byte
138
 *   first, so the value 0x1234 is represented as the byte 0x34, followed
139
 *   by the byte 0x12.
140
 *   
141
 *   The source value must be treated as unsigned, but the result is
142
 *   signed.  This is significant on 32- and 64-bit platforms, because it
143
 *   means that the source value should never be sign-extended to 32-bits.
144
 *   For example, if the source value is 0xffff, the result is 65535, not
145
 *   -1.  
146
 */
147
/* int osrp2(unsigned char *p); */
148
149
/* 
150
 *   Read an unaligned portable signed 2-byte value, returning int.  This
151
 *   differs from osrp2() in that this function treats the source value as
152
 *   signed, and returns a signed result; hence, on 32- and 64-bit
153
 *   platforms, the result must be sign-extended to the int size.  For
154
 *   example, if the source value is 0xffff, the result is -1.  
155
 */
156
/* int osrp2s(unsigned char *p); */
157
158
/* 
159
 *   Write int to unaligned portable 2-byte value.  The portable
160
 *   representation stores the low-order byte first in memory, so
161
 *   oswp2(0x1234) should result in storing a byte value 0x34 in the first
162
 *   byte, and 0x12 in the second byte. 
163
 */
164
/* void oswp2(unsigned char *p, int i); */
165
166
/* 
167
 *   Read an unaligned portable 4-byte value, returning long.  The
168
 *   underlying value should be considered signed, and the result is
169
 *   signed.  The portable representation stores the bytes starting with
170
 *   the least significant: the value 0x12345678 is stored with 0x78 in
171
 *   the first byte, 0x56 in the second byte, 0x34 in the third byte, and
172
 *   0x12 in the fourth byte.  
173
 */
174
/* long osrp4(unsigned char *p); */
175
176
/* 
177
 *   Write a long to an unaligned portable 4-byte value.  The portable
178
 *   representation stores the low-order byte first in memory, so
179
 *   0x12345678 is written to memory as 0x78, 0x56, 0x34, 0x12.  
180
 */
181
/* void oswp4(unsigned char *p, long l); */
182
183
184
185
/* ------------------------------------------------------------------------ */
186
/*
187
 *   Platform Identifiers.  You must define the following macros in your
188
 *   osxxx.h header file:
189
 *   
190
 *   OS_SYSTEM_NAME - a string giving the system identifier.  This string
191
 *   must contain only characters that are valid in a TADS identifier:
192
 *   letters, numbers, and underscores; and must start with a letter or
193
 *   underscore.  For example, on MS-DOS, this string is "MSDOS".
194
 *   
195
 *   OS_SYSTEM_LDESC - a string giving the system descriptive name.  This
196
 *   is used in messages displayed to the user.  For example, on MS-DOS,
197
 *   this string is "MS-DOS".  
198
 */
199
200
201
/* ------------------------------------------------------------------------ */
202
/*
203
 *   Message Linking Configuration.  You should #define ERR_LINK_MESSAGES
204
 *   in your osxxx.h header file if you want error messages linked into
205
 *   the application.  Leave this symbol undefined if you want an external
206
 *   message file. 
207
 */
208
209
210
/* ------------------------------------------------------------------------ */
211
/*
212
 *   Program Exit Codes.  These values are used for the argument to exit()
213
 *   to conform to local conventions.  Define the following values in your
214
 *   OS-specific header:
215
 *   
216
 *   OSEXSUCC - successful completion.  Usually defined to 0.
217
 *.  OSEXFAIL - failure.  Usually defined to 1.  
218
 */
219
220
221
/* ------------------------------------------------------------------------ */
222
/*
223
 *   Basic memory management interface.  These functions are merely
224
 *   documented here, but no prototypes are defined, because most
225
 *   platforms #define macros for these functions and types, mapping them
226
 *   to malloc or other system interfaces.  
227
 */
228
229
/*
230
 *   Theoretical maximum osmalloc() size.  This may be less than the
231
 *   capacity of the argument to osmalloc() on some systems.  For example,
232
 *   on segmented architectures (such as 16-bit x86), memory is divided into
233
 *   segments, so a single memory allocation can allocate only a subset of
234
 *   the total addressable memory in the system.  This value thus specifies
235
 *   the maximum amount of memory that can be allocated in one chunk.
236
 *   
237
 *   Note that this is an architectural maximum for the hardware and
238
 *   operating system.  It doesn't have anything to do with the total amount
239
 *   of memory actually available at run-time.
240
 *   
241
 *   #define OSMALMAX to a constant long value with theoretical maximum
242
 *   osmalloc() argument value.  For a platform with a flat (unsegmented)
243
 *   32-bit memory space, this is usually 0xffffffff; for 16-bit platforms,
244
 *   this is usually 0xffff.  
245
 */
246
/* #define OSMALMAX 0xffffffff */
247
248
/*   
249
 *   Allocate a block of memory of the given size in bytes.  The actual
250
 *   allocation may be larger, but may be no smaller.  The block returned
251
 *   should be worst-case aligned (i.e., suitably aligned for any type).
252
 *   Return null if the given amount of memory is not available.  
253
 */
254
/* void *osmalloc(size_t siz); */
255
256
/*
257
 *   Free memory previously allocated with osmalloc().  
258
 */
259
/* void osfree(void *block); */
260
261
/* 
262
 *   Reallocate memory previously allocated with osmalloc() or
263
 *   osrealloc(), changing the block's size to the given number of bytes.
264
 *   If necessary, a new block at a different address can be allocated, in
265
 *   which case the data from the original block is copied (the lesser of
266
 *   the old block size and the new size is copied) to the new block, and
267
 *   the original block is freed.  If the new size is less than the old
268
 *   size, this need not do anything at all, since the returned block can
269
 *   be larger than the new requested size.  If the block cannot be
270
 *   enlarged to the requested size, return null.  
271
 */
272
/* void *osrealloc(void *block, size_t siz); */
273
274
275
/* ------------------------------------------------------------------------ */
276
/*
277
 *   Basic file I/O interface.  These functions are merely documented here,
278
 *   but no prototypes are defined, because most platforms #define macros for
279
 *   these functions and types, mapping them to stdio or other system I/O
280
 *   interfaces.  
281
 *   
282
 *   When writing a file, writes might or might not be buffered in
283
 *   application memory; this is up to the OS implementation, which can
284
 *   perform buffering according to local conventions and what's most
285
 *   efficient.  However, it shouldn't make any difference to the caller
286
 *   whether writes are buffered or not - the OS implementation must take
287
 *   care that any buffering is invisible to the app.  (Porters: note that
288
 *   the basic C stdio package has the proper behavior here, so you'll get
289
 *   the correct semantics if you use a simple stdio implementation.)
290
 *   
291
 *   Write buffering might be visible to *other* apps, though.  In
292
 *   particular, another process might not see data written to a file (with
293
 *   osfwb(), os_fprint(), etc) immediately, since the write functions might
294
 *   hold the written bytes in an internal memory buffer rather than sending
295
 *   them to the OS.  Any internal buffers are guaranteed to be flushed to
296
 *   the OS upon calling osfcls() or osfflush().  Note that it's never
297
 *   *necessary* to call osfflush(), because buffered data will always be
298
 *   flushed on closing the file with osfcls().  However, if you want other
299
 *   apps to be able to see updates immediately, you can use osfflush() to
300
 *   ensure that buffers are flushed to a file before you close it.
301
 *   
302
 *   You can also use osfflush() to check for buffered write errors.  When
303
 *   you use osfwb() or other write functions to write data, they will return
304
 *   a success indication even if the data was only copied into a buffer.
305
 *   This means that a write that appeared to succeed might actually fail
306
 *   later, when the buffer is flushed.  The only way to know for sure is to
307
 *   explicitly flush buffers using osfflush(), and check the result code.
308
 *   If the original write function and a subsequent osfflush() *both* return
309
 *   success indications, then the write has definitely succeeded.  
310
 */
311
312
313
/*
314
 *   Define the following values in your OS header to indicate local
315
 *   conventions:
316
 *   
317
 *   OSFNMAX - integer indicating maximum length of a filename
318
 *   
319
 *   OSPATHCHAR - character giving the normal path separator character
320
 *.  OSPATHALT - string giving other path separator characters
321
 *.  OSPATHURL - string giving path separator characters for URL conversions
322
 *.  OSPATHSEP - directory separator for PATH-style environment variables
323
 *   
324
 *   For example, on DOS, OSPATHCHAR is '\\', OSPATHALT is "/:", and
325
 *   OSPATHSEP is ';'.  On Unix, OSPATHCHAR is '\', OSPATHALT is "", and
326
 *   OSPATHSEP is ':'.
327
 *   
328
 *   OSPATHURL is a little different: this specifies the characters that
329
 *   should be converted to URL-style separators when converting a path from
330
 *   local notation to URL notation.  This is usually the same as the union
331
 *   of OSPATHCHAR and OSPATHALT, but need not be; for example, on DOS, the
332
 *   colon (':') is a path separator for most purposes, but is NOT a path
333
 *   character for URL conversions.
334
 */
335
336
/*
337
 *   Define the type osfildef as the appropriate file handle structure for
338
 *   your osfxxx functions.  This type is always used as a pointer, but
339
 *   the value is always obtained from an osfopxxx call, and is never
340
 *   synthesized by portable code, so you can use essentially any type
341
 *   here that you want.
342
 *   
343
 *   For platforms that use C stdio functions to implement the osfxxx
344
 *   functions, osfildef can simply be defined as FILE.
345
 */
346
/* typedef FILE osfildef; */
347
348
349
/*
350
 *   File types.
351
 *   
352
 *   These are symbols of the form OSFTxxxx defining various content types,
353
 *   somewhat aking to MIME types.  These were mainly designed for the old
354
 *   Mac OS (versions up to OS 9), where the file system stored a type tag
355
 *   with each file's metadata.  The type tags were used for things like
356
 *   filtering file selector dialogs and setting file-to-app associations in
357
 *   the desktop shell.
358
 *   
359
 *   Our OSFTxxx symbols are abstract file types that we define, for types
360
 *   used within the TADS family of applications.  They give us a common,
361
 *   cross-platform reference point for each type we use.  Each port where
362
 *   file types are meaningful then maps our abstract type IDs to the
363
 *   corresponding port-specific type IDs.  In practice, this has never been
364
 *   used anywhere other than the old Mac OS ports; in fact, it's not even
365
 *   used in the modern Mac OS (OS X and later), since Apple decided to stop
366
 *   fighting the tide and start using filename suffixes for this sort of
367
 *   tagging, like everyone else always has.
368
 *   
369
 *   For the list of file types, see osifctyp.h 
370
 */
371
372
373
/*
374
 *   Local newline convention.
375
 *   
376
 *   Because of the pernicious NIH ("Not Invented Here") cultures of the
377
 *   major technology vendors, basically every platform out there has its own
378
 *   unique way of expressing newlines in text files.  Unix uses LF (ASCII
379
 *   10); Mac uses CR (ASCII 13); DOS and Windows use CR-LF pairs.  In the
380
 *   past there were heaven-only-knows how many other conventions in use, but
381
 *   fortunately these three have the market pretty well locked up at this
382
 *   point.  But we do still have to worry about these three.
383
 *   
384
 *   Our strategy on input is to be open to just about anything whenever
385
 *   possible.  So, when we're reading something that we believe to be a text
386
 *   file, we'll treat all of these as line endings: CR, LF, CR-LF, and
387
 *   LF-CR.  It's pretty safe to do this; if we have a CR and LF occurring
388
 *   adjacently, it's almost certain that they're intended to be taken
389
 *   together as a single newline sequence.  Likewise, if there's a lone CR
390
 *   or LF, it's rare for it to mean anything other than a newline.
391
 *   
392
 *   On output, though, we can't be as loose.  The problem is that other
393
 *   applications on our big three platforms *don't* tend to aim for the same
394
 *   flexibility we do on input: other apps usually expect exactly the local
395
 *   conventions on input, and don't always work well if they don't get it.
396
 *   So it's important that when we're writing a text file, we write newlines
397
 *   in the local convention.  This means that we sometimes need to know what
398
 *   the local convention actually is.  That's where this definition comes
399
 *   in.
400
 *   
401
 *   Each port must define OS_NEWLINE_SEQ as an ASCII string giving the local
402
 *   newline sequence to write on output.  For example, DOS defines it as
403
 *   "\r\n" (CR-LF).  Always define it as a STRING (not a character
404
 *   constant), even if it's only one character long.
405
 *   
406
 *   (Note that some compilers use wacky mappings for \r and \n.  Some older
407
 *   Mac compilers, for example, defined \n as CR and \r as LF, because of
408
 *   the Mac convention where newline is represented as CR in a text file.
409
 *   If there's any such variability on your platform, you can always use the
410
 *   octal codes to be unambiguous: \012 for LF and \015 for CR.)  
411
 */
412
/* #define OS_NEWLINE_SEQ  "\r\n" */
413
414
415
416
/* 
417
 *   Open text file for reading.  This opens the file with read-only access;
418
 *   we're not allowed to write to the file using this handle.  Returns NULL
419
 *   on error.
420
 *   
421
 *   A text file differs from a binary file in that some systems perform
422
 *   translations to map between C conventions and local file system
423
 *   conventions; for example, on DOS, the stdio library maps the DOS CR-LF
424
 *   newline convention to the C-style '\n' newline format.  On many systems
425
 *   (Unix, for example), there is no distinction between text and binary
426
 *   files.
427
 *   
428
 *   On systems that support file sharing and locking, this should open the
429
 *   file in "shared read" mode - this means that other processes are allowed
430
 *   to simultaneously read from the file, but no other processs should be
431
 *   allowed to write to the file as long as we have it open.  If another
432
 *   process already has the file open with write access, this routine should
433
 *   return failure, since we can't take away the write privileges the other
434
 *   process already has and thus we can't guarantee that other processes
435
 *   won't write to the file while we have it open.  
436
 */
437
/* osfildef *osfoprt(const char *fname, os_filetype_t typ); */
438
439
/*
440
 *   Open a text file for "volatile" reading: we open the file with read-only
441
 *   access, and we explicitly accept instability in the file's contents due
442
 *   to other processes simultaneously writing to the file.  On systems that
443
 *   support file sharing and locking, the file should be opened in "deny
444
 *   none" mode, meaning that other processes can simultaneously open the
445
 *   file for reading and/or writing even while have the file open.  
446
 */
447
/* osfildef *osfoprtv(const char *fname, os_filetype_t typ); */
448
449
/* 
450
 *   Open text file for writing; returns NULL on error 
451
 */
452
/* osfildef *osfopwt(const char *fname, os_filetype_t typ); */
453
454
/*
455
 *   Open text file for reading and writing, keeping the file's existing
456
 *   contents if the file already exists or creating a new file if no such
457
 *   file exists.  Returns NULL on error. 
458
 */
459
/* osfildef *osfoprwt(const char *fname, os_filetype_t typ); */
460
461
/* 
462
 *   Open text file for reading/writing.  If the file already exists,
463
 *   truncate the existing contents.  Create a new file if it doesn't
464
 *   already exist.  Return null on error.  
465
 */
466
/* osfildef *osfoprwtt(const char *fname, os_filetype_t typ); */
467
468
/* 
469
 *   Open binary file for writing; returns NULL on error.  
470
 */
471
/* osfildef *osfopwb(const char *fname, os_filetype_t typ); */
472
473
/* 
474
 *   Open source file for reading - use the appropriate text or binary
475
 *   mode.  
476
 */
477
/* osfildef *osfoprs(const char *fname, os_filetype_t typ); */
478
479
/* 
480
 *   Open binary file for reading; returns NULL on error.  
481
 */
482
/* osfildef *osfoprb(const char *fname, os_filetype_t typ); */
483
484
/*
485
 *   Open binary file for 'volatile' reading; returns NULL on error.
486
 *   ("Volatile" means that we'll accept writes from other processes while
487
 *   reading, so the file should be opened in "deny none" mode or the
488
 *   equivalent, to the extent that the local system supports file sharing
489
 *   modes.)  
490
 */
491
/* osfildef *osfoprbv(const char *fname, os_filetype_t typ); */
492
493
/* 
494
 *   Open binary file for random-access reading/writing.  If the file already
495
 *   exists, keep the existing contents; if the file doesn't already exist,
496
 *   create a new empty file.
497
 *   
498
 *   The caller is allowed to perform any mixture of read and write
499
 *   operations on the returned file handle, and can seek around in the file
500
 *   to read and write at random locations.
501
 *   
502
 *   If the local file system supports file sharing or locking controls, this
503
 *   should generally open the file in something equivalent to "exclusive
504
 *   write, shared read" mode ("deny write" in DENY terms), so that other
505
 *   processes can't modify the file at the same time we're modifying it (but
506
 *   it doesn't bother us to have other processes reading from the file while
507
 *   we're working on it, as long as they don't mind that we could change
508
 *   things on the fly).  It's not absolutely necessary to assert these
509
 *   locking semantics, but if there's an option to do so this is preferred.
510
 *   Stricter semantics (such as "exclusive" or "deny all" mode) are better
511
 *   than less strict semantics.  Less strict semantics are dicey, because in
512
 *   that case the caller has no way of knowing that another process could be
513
 *   modifying the file at the same time, and no way (through osifc) of
514
 *   coordinating that activity.  If less strict semantics are implemented,
515
 *   the caller will basically be relying on luck to avoid corruptions due to
516
 *   writing by other processes.
517
 *   
518
 *   Return null on error.  
519
 */
520
/* osfildef *osfoprwb(const char *fname, os_filetype_t typ); */
521
522
/* 
523
 *   Open binary file for random-access reading/writing.  If the file already
524
 *   exists, truncate the existing contents (i.e., delete the contents of the
525
 *   file, resetting it to a zero-length file).  Create a new file if it
526
 *   doesn't already exist.  The caller is allowed to perform any mixture of
527
 *   read and write operations on the returned handle, and can seek around in
528
 *   the file to read and write at random locations.
529
 *   
530
 *   The same comments regarding sharing/locking modes for osfoprwb() apply
531
 *   here as well.
532
 *   
533
 *   Return null on error.  
534
 */
535
/* osfildef *osfoprwtb(const char *fname, os_filetype_t typ); */
536
537
/* 
538
 *   Get a line of text from a text file.  Uses fgets semantics.  
539
 */
540
/* char *osfgets(char *buf, size_t len, osfildef *fp); */
541
542
/* 
543
 *   Write a line of text to a text file.  Uses fputs semantics.  
544
 */
545
/* void osfputs(const char *buf, osfildef *fp); */
546
547
/*
548
 *   Write to a text file.  os_fprintz() takes a null-terminated string,
549
 *   while os_fprint() takes an explicit separate length argument that might
550
 *   not end with a null terminator.  
551
 */
552
void os_fprintz(osfildef *fp, const char *str);
553
void os_fprint(osfildef *fp, const char *str, size_t len);
554
555
/* 
556
 *   Write bytes to file.  Return 0 on success, non-zero on error.
557
 */
558
/* int osfwb(osfildef *fp, const void *buf, int bufl); */
559
560
/*
561
 *   Flush buffered writes to a file.  This ensures that any bytes written to
562
 *   the file (with osfwb(), os_fprint(), etc) are actually sent out to the
563
 *   operating system, rather than being buffered in application memory for
564
 *   later writing.
565
 *   
566
 *   Note that this routine only guarantees that we write through to the
567
 *   operating system.  This does *not* guarantee that the data will actually
568
 *   be committed to the underlying physical storage device.  Such a
569
 *   guarantee is hard to come by in general, since most modern systems use
570
 *   multiple levels of software and hardware buffering - the OS might buffer
571
 *   some data in system memory, and the physical disk drive might itself
572
 *   buffer data in its own internal cache.  This routine thus isn't good
573
 *   enough, for example, to protect transactional data that needs to survive
574
 *   a power failure or a serious system crash.  What this routine *does*
575
 *   ensure is that buffered data are written through to the OS; in
576
 *   particular, this ensures that another process that's reading from the
577
 *   same file will see all updates we've made up to this point.
578
 *   
579
 *   Returns 0 on success, non-zero on error.  Errors can occur for any
580
 *   reason that they'd occur on an ordinary write - a full disk, a hardware
581
 *   failure, etc.  
582
 */
583
/* int osfflush(osfildef *fp); */
584
585
/* 
586
 *   Read bytes from file.  Return 0 on success, non-zero on error.  
587
 */
588
/* int osfrb(osfildef *fp, void *buf, int bufl); */
589
590
/* 
591
 *   Read bytes from file and return the number of bytes read.  0
592
 *   indicates that no bytes could be read. 
593
 */
594
/* size_t osfrbc(osfildef *fp, void *buf, size_t bufl); */
595
596
/* 
597
 *   Get the current seek location in the file.  The first byte of the
598
 *   file has seek position 0.  
599
 */
600
/* long osfpos(osfildef *fp); */
601
602
/* 
603
 *   Seek to a location in the file.  The first byte of the file has seek
604
 *   position 0.  Returns zero on success, non-zero on error.
605
 *   
606
 *   The following constants must be defined in your OS-specific header;
607
 *   these values are used for the "mode" parameter to indicate where to
608
 *   seek in the file:
609
 *   
610
 *   OSFSK_SET - set position relative to the start of the file
611
 *.  OSFSK_CUR - set position relative to the current file position
612
 *.  OSFSK_END - set position relative to the end of the file 
613
 */
614
/* int osfseek(osfildef *fp, long pos, int mode); */
615
616
/* 
617
 *   Close a file.
618
 *   
619
 *   If the OS implementation uses buffered writes, this routine guarantees
620
 *   that any buffered data are flushed to the underlying file.  So, it's not
621
 *   necessary to call osfflush() before calling this routine.  However,
622
 *   since this function doesn't return any error indication, a caller could
623
 *   use osfflush() first to check for errors on any final buffered writes.  
624
 */
625
/* void osfcls(osfildef *fp); */
626
627
/* 
628
 *   Delete a file.  Returns zero on success, non-zero on error. 
629
 */
630
/* int osfdel(const char *fname); */
631
632
/* 
633
 *   Access a file - determine if the file exists.  Returns zero if the
634
 *   file exists, non-zero if not.  (The semantics may seem a little
635
 *   weird, but this is consistent with the conventions used by most of
636
 *   the other osfxxx calls: zero indicates success, non-zero indicates an
637
 *   error.  If the file exists, "accessing" it was successful, so osfacc
638
 *   returns zero; if the file doesn't exist, accessing it gets an error,
639
 *   hence a non-zero return code.)  
640
 */
641
/* int osfacc(const char *fname) */
642
643
/* 
644
 *   Get a character from a file.  Provides the same semantics as fgetc().
645
 */
646
/* int osfgetc(osfildef *fp); */
647
648
/*
649
 *   Write a string to a file 
650
 */
651
652
/* ------------------------------------------------------------------------ */
653
/*
654
 *   File time stamps
655
 */
656
657
/*
658
 *   File timestamp type.  This type must be defined by the
659
 *   system-specific header, and should map to a local type that can be
660
 *   used to obtain information on a file's creation, modification, or
661
 *   access time.  Generic code is not allowed to do anything with data of
662
 *   this type except pass them to the routines defined here that take
663
 *   values of this type as parameters.
664
 *   
665
 *   On Unix, for example, this structure can be defined as having a
666
 *   single member of type time_t.  (We define this as an incomplete
667
 *   structure type here so that we can refer to it in the prototypes
668
 *   below.)  
669
 */
670
typedef struct os_file_time_t os_file_time_t;
671
672
/*
673
 *   Get the creation/modification/access time for a file.  Fills in the
674
 *   os_file_time_t value with the time for the file.  Returns zero on
675
 *   success, non-zero on failure (the file doesn't exist, the program has
676
 *   insufficient privileges to access the file, etc).
677
 */
678
int os_get_file_cre_time(os_file_time_t *t, const char *fname);
679
int os_get_file_mod_time(os_file_time_t *t, const char *fname);
680
int os_get_file_acc_time(os_file_time_t *t, const char *fname);
681
682
/*
683
 *   Compare two file time values.  These values must be obtained with one
684
 *   of the os_get_file_xxx_time() functions.  Returns 1 if the first time
685
 *   is later than the second time; 0 if the two times are the same; and
686
 *   -1 if the first time is earlier than the second time.  
687
 */
688
int os_cmp_file_times(const os_file_time_t *a, const os_file_time_t *b);
689
690
691
/* ------------------------------------------------------------------------ */
692
/*
693
 *   Find the first file matching a given pattern.  The returned context
694
 *   pointer is a pointer to whatever system-dependent context structure
695
 *   is needed to continue the search with the next file, and is opaque to
696
 *   the caller.  The caller must pass the context pointer to the
697
 *   next-file routine.  The caller can optionally cancel a search by
698
 *   calling the close-search routine with the context pointer.  If the
699
 *   return value is null, it indicates that no matching files were found.
700
 *   If a file was found, outbuf will be filled in with its name, and
701
 *   isdir will be set to true if the match is a directory, false if it's
702
 *   a file.  If pattern is null, all files in the given directory should
703
 *   be returned; otherwise, pattern is a string containing '*' and '?' as
704
 *   wildcard characters, but not containing any directory separators, and
705
 *   all files in the given directory matching the pattern should be
706
 *   returned.
707
 *   
708
 *   Important: because this routine may allocate memory for the returned
709
 *   context structure, the caller must either call os_find_next_file
710
 *   until that routine returns null, or call os_find_close() to cancel
711
 *   the search, to ensure that the os code has a chance to release the
712
 *   allocated memory.
713
 *   
714
 *   'outbuf' should be set on output to the name of the matching file,
715
 *   without any path information.
716
 *   
717
 *   'outpathbuf' should be set on output to full path of the matching
718
 *   file.  If possible, 'outpathbuf' should use the same relative or
719
 *   absolute notation that the search criteria used on input.  For
720
 *   example, if dir = "resfiles", and the file found is "MyPic.jpg",
721
 *   outpathbuf should be set to "resfiles/MyPic.jpg" (or appropriate
722
 *   syntax for the local platform).  Similarly, if dir =
723
 *   "/home/tads/resfiles", outpath buf should be
724
 *   "/home/tads/resfiles/MyPic.jpg".  The result should always conform to
725
 *   correct local conventions, which may require some amount of
726
 *   manipulation of the filename; for example, on the Mac, if dir =
727
 *   "resfiles", the result should be ":resfiles:MyPic.jpg" (note the
728
 *   added leading colon) to conform to Macintosh relative path notation.
729
 *   
730
 *   Note that 'outpathbuf' may be null, in which case the caller is not
731
 *   interested in the full path information.  
732
 */
733
/*   
734
 *   Note the following possible ways this function may be called:
735
 *   
736
 *   dir = "", pattern = filename - in this case, pattern is the name of a
737
 *   file or directory in the current directory.  filename *might* be a
738
 *   relative path specified by the user (on a command line, for example);
739
 *   for instance, on Unix, it could be something like "resfiles/jpegs".
740
 *   
741
 *   dir = path, pattern = filname - same as above, but this time the
742
 *   filename or directory pattern is relative to the given path, rather
743
 *   than to the current directory.  For example, we could have dir =
744
 *   "/games/mygame" and pattern = "resfiles/jpegs".
745
 *   
746
 *   dir = path, pattern = 0 (NULL) - this should search for all files in
747
 *   the given path.  The path might be absolute or it might be relative.
748
 *   
749
 *   dir = path, pattern = "*" - this should have the same result as when
750
 *   pattern = 0.
751
 *   
752
 *   dir = path, pattern = "*.ext" - this should search for all files in
753
 *   the given path whose names end with ".ext".
754
 *   
755
 *   dir = path, pattern = "abc*" - this should search for all files in
756
 *   the given path whose names start with "abc".
757
 *   
758
 *   All of these combinations are possible because callers, for
759
 *   portability, must generally not manipulate filenames directly;
760
 *   instead, callers obtain paths and search strings from external
761
 *   sources, such as from the user, and present them to this routine with
762
 *   minimal manipulation.  
763
 */
764
void *os_find_first_file(const char *dir, const char *pattern,
765
                         char *outbuf, size_t outbufsiz, int *isdir,
766
                         char *outpathbuf, size_t outpathbufsiz);
767
768
/*
769
 *   Implementation notes for porting os_find_first_file:
770
 *   
771
 *   The algorithm for this routine should go something like this:
772
 *   
773
 *   - If 'path' is null, create a variable real_path and initialize it
774
 *   with the current directory.  Otherwise, copy path to real_path.
775
 *   
776
 *   - If 'pattern' contains any directory separators ("/" on Unix, for
777
 *   example), change real_path so that it reflects the additional leading
778
 *   subdirectories in the path in 'pattern', and remove the leading path
779
 *   information from 'pattern'.  For example, on Unix, if real_path
780
 *   starts out as "./subdir", and pattern is "resfiles/jpegs", change
781
 *   real_path to "./subdir/resfiles", and change pattern to "jpegs".
782
 *   Take care to add and remove path separators as needed to keep the
783
 *   path strings well-formed.
784
 *   
785
 *   - Begin a search using appropriate OS API's for all files in
786
 *   real_path.
787
 *   
788
 *   - Check each file found.  Skip any files that don't match 'pattern',
789
 *   treating "*" as a wildcard that matches any string of zero or more
790
 *   characters, and "?" as a wildcard that matches any single character
791
 *   (or matches nothing at the end of a string).  For example:
792
 *   
793
 *.  "*" matches anything
794
 *.  "abc?" matches "abc", "abcd", "abce", "abcf", but not "abcde"
795
 *.  "abc???" matches "abc", "abcd", "abcde", "abcdef", but not "abcdefg"
796
 *.  "?xyz" matches "wxyz", "axyz", but not "xyz" or "abcxyz"
797
 *   
798
 *   - Return the first file that matches, if any, by filling in 'outbuf'
799
 *   and 'isdir' with appropriate information.  Before returning, allocate
800
 *   a context structure (which is entirely for your own use, and opaque
801
 *   to the caller) and fill it in with the information necessary for
802
 *   os_find_next_file to get the next matching file.  If no file matches,
803
 *   return null.  
804
 */
805
806
807
/*
808
 *   Find the next matching file, continuing a search started with
809
 *   os_find_first_file().  Returns null if no more files were found, in
810
 *   which case the search will have been automatically closed (i.e.,
811
 *   there's no need to call os_find_close() after this routine returns
812
 *   null).  Returns a non-null context pointer, which is to be passed to
813
 *   this function again to get the next file, if a file was found.
814
 *   
815
 *   'outbuf' and 'outpathbuf' are filled in with the filename (without
816
 *   path) and full path (relative or absolute, as appropriate),
817
 *   respectively, in the same manner as they do for os_find_first_file().
818
 *   
819
 *   Implementation note: if os_find_first_file() allocated memory for the
820
 *   search context, this routine must free the memory if it returs null,
821
 *   because this indicates that the search is finished and the caller
822
 *   need not call os_find_close().  
823
 */
824
void *os_find_next_file(void *ctx, char *outbuf, size_t outbufsiz,
825
                        int *isdir, char *outpathbuf, size_t outpathbufsiz);
826
827
/*
828
 *   Cancel a search.  The context pointer returned by the last call to
829
 *   os_find_first_file() or os_find_next_file() is the parameter.  There
830
 *   is no need to call this function if find-first or find-next returned
831
 *   null, since they will have automatically closed the search.
832
 *   
833
 *   Implementation note: if os_find_first_file() allocated memory for the
834
 *   search context, this routine should release the memory.  
835
 */
836
void os_find_close(void *ctx);
837
838
/*
839
 *   Special filename classification 
840
 */
841
enum os_specfile_t
842
{
843
    /* not a special file */
844
    OS_SPECFILE_NONE,
845
846
    /* 
847
     *   current directory link - this is a file like the "." file on Unix
848
     *   or DOS, which is a special link that simply refers to itself 
849
     */
850
    OS_SPECFILE_SELF,
851
852
    /* 
853
     *   parent directory link - this is a file like the ".." file on Unix
854
     *   or DOS, which is a special link that refers to the parent
855
     *   directory 
856
     */
857
    OS_SPECFILE_PARENT
858
};
859
860
/*
861
 *   Determine if the given filename refers to a special file.  Returns
862
 *   the appropriate enum value if so, or OS_SPECFILE_NONE if not.  The
863
 *   given filename must be a root name - it must not contain a path
864
 *   prefix.  The primary purpose of this function is to classify the
865
 *   'outbuf' results from os_find_first/next_file().  
866
 */
867
enum os_specfile_t os_is_special_file(const char *fname);
868
869
/* ------------------------------------------------------------------------ */
870
/* 
871
 *   Convert string to all-lowercase. 
872
 */
873
char *os_strlwr(char *s);
874
875
876
/* ------------------------------------------------------------------------ */
877
/*
878
 *   Character classifications for quote characters.  os_squote() returns
879
 *   true if its argument is any type of single-quote character;
880
 *   os_dquote() returns true if its argument is any type of double-quote
881
 *   character; and os_qmatch(a, b) returns true if a and b are matching
882
 *   open- and close-quote characters.
883
 *   
884
 *   These functions allow systems with extended character codes with
885
 *   weird quote characters (such as the Mac) to match the weird
886
 *   characters, so that users can use the extended quotes in input.
887
 *   
888
 *   These are usually implemented as macros.  The most common
889
 *   implementation simply returns true for the standard ASCII quote
890
 *   characters:
891
 *   
892
 *   #define os_squote(c) ((c) == '\'')
893
 *.  #define os_dquote(c) ((c) == '"')
894
 *.  #define os_qmatch(a, b) ((a) == (b))
895
 *   
896
 *   These functions take int arguments to allow for the possibility of
897
 *   Unicode input.  
898
 */
899
/* int os_squote(int c); */
900
/* int os_dquote(int c); */
901
/* int os_qmatch(int a, int b); */
902
903
904
/* ------------------------------------------------------------------------ */
905
/*
906
 *   Special file and directory locations
907
 */
908
909
/*
910
 *   Get the full filename (including directory path) to the executable
911
 *   file, given the argv[0] parameter passed into the main program.  This
912
 *   fills in the buffer with a null-terminated string that can be used in
913
 *   osfoprb(), for example, to open the executable file.
914
 *   
915
 *   Returns non-zero on success.  If it is not possible to determine the
916
 *   name of the executable file, returns zero.
917
 *   
918
 *   Some operating systems might not provide access to the executable file
919
 *   information, so non-trivial implementation of this routine is optional;
920
 *   if the necessary information is not available, simply implement this to
921
 *   return zero.  If the information is not available, callers should offer
922
 *   gracefully degraded functionality if possible.  
923
 */
924
int os_get_exe_filename(char *buf, size_t buflen, const char *argv0);
925
926
/*
927
 *   Get a special directory path.  Returns the selected path, in a format
928
 *   suitable for use with os_build_full_path().  The main program's argv[0]
929
 *   parameter is provided so that the system code can choose to make the
930
 *   special paths relative to the program install directory, but this is
931
 *   entirely up to the system implementation, so the argv[0] parameter can
932
 *   be ignored if it is not needed.
933
 *   
934
 *   The 'id' parameter selects which special path is requested; this is one
935
 *   of the constants defined below.  If the id is not understood, there is
936
 *   no way of signalling an error to the caller; this routine can fail with
937
 *   an assert() in such cases, because it indicates that the OS layer code
938
 *   is out of date with respect to the calling code.
939
 *   
940
 *   This routine can be implemented using one of the strategies below, or a
941
 *   combination of these.  These are merely suggestions, though, and
942
 *   systems are free to ignore these and implement this routine using
943
 *   whatever scheme is the best fit to local conventions.
944
 *   
945
 *   - Relative to argv[0].  Some systems use this approach because it keeps
946
 *   all of the TADS files together in a single install directory tree, and
947
 *   doesn't require any extra configuration information to find the install
948
 *   directory.  Since we base the path name on the executable that's
949
 *   actually running, we don't need any environment variables or parameter
950
 *   files or registry entries to know where to look for related files.
951
 *   
952
 *   - Environment variables or local equivalent.  On some systems, it is
953
 *   conventional to set some form of global system parameter (environment
954
 *   variables on Unix, for example) for this sort of install configuration
955
 *   data.  In these cases, this routine can look up the appropriate
956
 *   configuration variables in the system environment.
957
 *   
958
 *   - Hard-coded paths.  Some systems have universal conventions for the
959
 *   installation configuration of compiler-like tools, so the paths to our
960
 *   component files can be hard-coded based on these conventions.  Note
961
 *   that it is common on some systems to use hard-coded paths by default
962
 *   but allow these to be overridden using environment variables or the
963
 *   like - this is often a good option because it makes life easy for most
964
 *   users, who use the default install configuration and thus do not need
965
 *   to set any environment variables, while still allowing for special
966
 *   cases where users cannot use the default configuration for some reason.
967
 *   
968
 *   
969
 */
970
void os_get_special_path(char *buf, size_t buflen,
971
                         const char *argv0, int id);
972
973
/* 
974
 *   TADS 3 system resource path.  This path is used to load system
975
 *   resources, such as character mapping files and error message files.  
976
 */
977
#define OS_GSP_T3_RES       1
978
979
/* 
980
 *   TADS 3 compiler - system headers.  This is the #include path for the
981
 *   header files included with the compiler. 
982
 */
983
#define OS_GSP_T3_INC       2
984
985
/*
986
 *   TADS 3 compiler - system library source code.  This is the path to the
987
 *   library source files that the compiler includes in every compilation by
988
 *   default (such as _main.t). 
989
 */
990
#define OS_GSP_T3_LIB       3
991
992
/*
993
 *   TADS 3 compiler - user library path list.  This is a list of directory
994
 *   paths, separated by the OSPATHSEP character, that should be searched for
995
 *   user library files.  The TADS 3 compiler uses this as an additional set
996
 *   of locations to search after the list of "-Fs" options and before the
997
 *   OS_GSP_T3_LIB directory.
998
 *   
999
 *   This path list is intended for the user's use, so no default value is
1000
 *   needed.  The value should be user-configurable using local conventions;
1001
 *   on Unix, for example, this might be handled with an environment
1002
 *   variable.  
1003
 */
1004
#define OS_GSP_T3_USER_LIBS 4
1005
1006
/*
1007
 *   TADS 3 interpreter - application data path.  This is the directory where
1008
 *   we should store things like option settings: data that we want to store
1009
 *   in a file, global to all games.  Depending on local system conventions,
1010
 *   this can be a global shared directory for all users, or can be a
1011
 *   user-specific directory. 
1012
 */
1013
#define OS_GSP_T3_APP_DATA 5
1014
1015
1016
/* 
1017
 *   Seek to the resource file embedded in the current executable file,
1018
 *   given the main program's argv[0].
1019
 *   
1020
 *   On platforms where the executable file format allows additional
1021
 *   information to be attached to an executable, this function can be used
1022
 *   to find the extra information within the executable.
1023
 *   
1024
 *   The 'typ' argument gives a resource type to find.  This is an arbitrary
1025
 *   string that the caller uses to identify what type of object to find.
1026
 *   The "TGAM" type, for example, is used by convention to indicate a TADS
1027
 *   compiled GAM file.  
1028
 */
1029
osfildef *os_exeseek(const char *argv0, const char *typ);
1030
1031
1032
/* ------------------------------------------------------------------------ */
1033
/*
1034
 *   Load a string resource.  Given a string ID number, load the string
1035
 *   into the given buffer.
1036
 *   
1037
 *   Returns zero on success, non-zero if an error occurs (for example,
1038
 *   the buffer is too small, or the requested resource isn't present).
1039
 *   
1040
 *   Whenever possible, implementations should use an operating system
1041
 *   mechanism for loading the string from a user-modifiable resource
1042
 *   store; this will make localization of these strings easier, since the
1043
 *   resource store can be modified without the need to recompile the
1044
 *   application.  For example, on the Macintosh, the normal system string
1045
 *   resource mechanism should be used to load the string from the
1046
 *   application's resource fork.
1047
 *   
1048
 *   When no operating system mechanism exists, the resources can be
1049
 *   stored as an array of strings in a static variable; this isn't ideal,
1050
 *   because it makes it much more difficult to localize the application.
1051
 *   
1052
 *   Resource ID's are application-defined.  For example, for TADS 2,
1053
 *   "res.h" defines the resource ID's.  
1054
 */
1055
int os_get_str_rsc(int id, char *buf, size_t buflen);
1056
1057
1058
/* ------------------------------------------------------------------------ */
1059
/*
1060
 *   Look for a file in the "standard locations": current directory, program
1061
 *   directory, PATH-like environment variables, etc.  The actual standard
1062
 *   locations are specific to each platform; the implementation is free to
1063
 *   use whatever conventions are appropriate to the local system.  On
1064
 *   systems that have something like Unix environment variables, it might be
1065
 *   desirable to define a TADS-specific variable (TADSPATH, for example)
1066
 *   that provides a list of directories to search for TADS-related files.
1067
 *   
1068
 *   On return, fill in 'buf' with the full filename of the located copy of
1069
 *   the file (if a copy was indeed found), in a format suitable for use with
1070
 *   the osfopxxx() functions; in other words, after this function returns,
1071
 *   the caller should be able to pass the contents of 'buf' to an osfopxxx()
1072
 *   function to open the located file.
1073
 *   
1074
 *   Returns true (non-zero) if a copy of the file was located, false (zero)
1075
 *   if the file could not be found in any of the standard locations.  
1076
 */
1077
int os_locate(const char *fname, int flen, const char *arg0,
1078
              char *buf, size_t bufsiz);
1079
1080
1081
/* ------------------------------------------------------------------------ */
1082
/*
1083
 *   Create and open a temporary file.  The file must be opened to allow
1084
 *   both reading and writing, and must be in "binary" mode rather than
1085
 *   "text" mode, if the system makes such a distinction.  Returns null on
1086
 *   failure.
1087
 *   
1088
 *   If 'fname' is non-null, then this routine should create and open a file
1089
 *   with the given name.  When 'fname' is non-null, this routine does NOT
1090
 *   need to store anything in 'buf'.  Note that the routine shouldn't try
1091
 *   to put the file in a special directory or anything like that; just open
1092
 *   the file with the name exactly as given.
1093
 *   
1094
 *   If 'fname' is null, this routine must choose a file name and fill in
1095
 *   'buf' with the chosen name; if possible, the file should be in the
1096
 *   conventional location for temporary files on this system, and should be
1097
 *   unique (i.e., it shouldn't be the same as any existing file).  The
1098
 *   filename stored in 'buf' is opaque to the caller, and cannot be used by
1099
 *   the caller except to pass to osfdel_temp().  On some systems, it may
1100
 *   not be possible to determine the actual filename of a temporary file;
1101
 *   in such cases, the implementation may simply store an empty string in
1102
 *   the buffer.  (The only way the filename would be unavailable is if the
1103
 *   implementation uses a system API that creates a temporary file, and
1104
 *   that API doesn't return the name of the created temporary file.  In
1105
 *   such cases, we don't need the name; the only reason we need the name is
1106
 *   so we can pass it to osfdel_temp() later, but since the system is going
1107
 *   to delete the file automatically, osfdel_temp() doesn't need to do
1108
 *   anything and thus doesn't need the name.)
1109
 *   
1110
 *   After the caller is done with the file, it should close the file (using
1111
 *   osfcls() as normal), then the caller MUST call osfdel_temp() to delete
1112
 *   the temporary file.
1113
 *   
1114
 *   This interface is intended to take advantage of systems that have
1115
 *   automatic support for temporary files, while allowing implementation on
1116
 *   systems that don't have any special temp file support.  On systems that
1117
 *   do have automatic delete-on-close support, this routine should use that
1118
 *   system-level support, because it helps ensure that temp files will be
1119
 *   deleted even if the caller fails to call osfdel_temp() due to a
1120
 *   programming error or due to a process or system crash.  On systems that
1121
 *   don't have any automatic delete-on-close support, this routine can
1122
 *   simply use the same underlying system API that osfoprwbt() normally
1123
 *   uses (although this routine must also generate a name for the temp file
1124
 *   when the caller doesn't supply one).
1125
 *   
1126
 *   This routine can be implemented using ANSI library functions as
1127
 *   follows: if 'fname' is non-null, return fopen(fname,"w+b"); otherwise,
1128
 *   set buf[0] to '\0' and return tmpfile().  
1129
 */
1130
osfildef *os_create_tempfile(const char *fname, char *buf);
1131
1132
/*
1133
 *   Delete a temporary file - this is used to delete a file created with
1134
 *   os_create_tempfile().  For most platforms, this can simply be defined
1135
 *   the same way as osfdel().  For platforms where the operating system or
1136
 *   file manager will automatically delete a file opened as a temporary
1137
 *   file, this routine should do nothing at all, since the system will take
1138
 *   care of deleting the temp file.
1139
 *   
1140
 *   Callers are REQUIRED to call this routine after closing a file opened
1141
 *   with os_create_tempfile().  When os_create_tempfile() is called with a
1142
 *   non-null 'fname' argument, the same value should be passed as 'fname' to
1143
 *   this function.  When os_create_tempfile() is called with a null 'fname'
1144
 *   argument, then the buffer passed in the 'buf' argument to
1145
 *   os_create_tempfile() must be passed as the 'fname' argument here.  In
1146
 *   other words, if the caller explicitly names the temporary file to be
1147
 *   opened in os_create_tempfile(), then that same filename must be passed
1148
 *   here to delete the named file; if the caller lets os_create_tempfile()
1149
 *   generate a filename, then the generated filename must be passed to this
1150
 *   routine.
1151
 *   
1152
 *   If os_create_tempfile() is implemented using ANSI library functions as
1153
 *   described above, then this routine can also be implemented with ANSI
1154
 *   library calls as follows: if 'fname' is non-null and fname[0] != '\0',
1155
 *   then call remove(fname); otherwise do nothing.  
1156
 */
1157
int osfdel_temp(const char *fname);
1158
1159
1160
/*
1161
 *   Get the temporary file path.  This should fill in the buffer with a
1162
 *   path prefix (suitable for strcat'ing a filename onto) for a good
1163
 *   directory for a temporary file, such as the swap file.  
1164
 */
1165
void os_get_tmp_path(char *buf);
1166
1167
1168
/* ------------------------------------------------------------------------ */
1169
/*
1170
 *   Switch to a new working directory.  
1171
 */
1172
void os_set_pwd(const char *dir);
1173
1174
/*
1175
 *   Switch the working directory to the directory containing the given
1176
 *   file.  Generally, this routine should only need to parse the filename
1177
 *   enough to determine the part that's the directory path, then use
1178
 *   os_set_pwd() to switch to that directory.  
1179
 */
1180
void os_set_pwd_file(const char *filename);
1181
1182
1183
/* ------------------------------------------------------------------------ */
1184
/*
1185
 *   Filename manipulation routines
1186
 */
1187
1188
/* apply a default extension to a filename, if it doesn't already have one */
1189
void os_defext(char *fname, const char *ext);
1190
1191
/* unconditionally add an extention to a filename */
1192
void os_addext(char *fname, const char *ext);
1193
1194
/* remove the extension from a filename */
1195
void os_remext(char *fname);
1196
1197
/*
1198
 *   Get a pointer to the root name portion of a filename.  This is the
1199
 *   part of the filename after any path or directory prefix.  For
1200
 *   example, on Unix, given the string "/home/mjr/deep.gam", this
1201
 *   function should return a pointer to the 'd' in "deep.gam".  If the
1202
 *   filename doesn't appear to have a path prefix, it should simply
1203
 *   return the argument unchanged.  
1204
 */
1205
char *os_get_root_name(char *buf);
1206
1207
/*
1208
 *   Determine whether a filename specifies an absolute or relative path.
1209
 *   This is used to analyze filenames provided by the user (for example,
1210
 *   in a #include directive, or on a command line) to determine if the
1211
 *   filename can be considered relative or absolute.  This can be used,
1212
 *   for example, to determine whether to search a directory path for a
1213
 *   file; if a given filename is absolute, a path search makes no sense.
1214
 *   A filename that doesn't specify an absolute path can be combined with
1215
 *   a path using os_build_full_path().
1216
 *   
1217
 *   Returns true if the filename specifies an absolute path, false if
1218
 *   not.  
1219
 */
1220
int os_is_file_absolute(const char *fname);
1221
1222
/*
1223
 *   Extract the path from a filename.  Fills in pathbuf with the path
1224
 *   portion of the filename.  If the filename has no path, the pathbuf
1225
 *   should be set appropriately for the current directory (on Unix or
1226
 *   DOS, for example, it can be set to an empty string).
1227
 *   
1228
 *   The result can end with a path separator character or not, depending
1229
 *   on local OS conventions.  Paths extracted with this function can only
1230
 *   be used with os_build_full_path(), so the conventions should match
1231
 *   that function's.
1232
 *   
1233
 *   Unix examples:
1234
 *   
1235
 *   "/home/mjr/deep.gam" -> "/home/mjr"
1236
 *.  "deep.gam" -> ""
1237
 *.  "games/deep.gam" -> "games"
1238
 *   
1239
 *   Mac examples:
1240
 *   
1241
 *   ":home:mjr:deep.gam" -> ":home:mjr"
1242
 *.  "Hard Disk:games:deep.gam" -> "Hard Disk:games"
1243
 *.  "Hard Disk:deep.gam" -> "Hard Disk:"
1244
 *   
1245
 *   Note in the last example that we've retained the trailing colon in
1246
 *   the path, whereas we didn't in the others; although the others could
1247
 *   also retain the trailing colon, it's required only for the last case.
1248
 *   The last case requires the colon because it would otherwise be
1249
 *   impossible to determine whether "Hard Disk" was a local subdirectory
1250
 *   or a volume name.  
1251
 */
1252
void os_get_path_name(char *pathbuf, size_t pathbuflen, const char *fname);
1253
1254
/*
1255
 *   Build a full path name, given a path and a filename.  The path may have
1256
 *   been specified by the user, or may have been extracted from another
1257
 *   file via os_get_path_name().  This routine must take care to add path
1258
 *   separators as needed, but also must take care not to add too many path
1259
 *   separators.
1260
 *   
1261
 *   Note that relative path names may require special care on some
1262
 *   platforms.  For example, on the Macintosh, a path of "games" and a
1263
 *   filename "deep.gam" should yield ":games:deep.gam" (note the addition
1264
 *   of the leading colon).
1265
 *   
1266
 *   Note also that the 'filename' argument is not only allowed to be an
1267
 *   ordinary file, possibly qualified with a relative path, but is also
1268
 *   allowed to be a subdirectory.  The result in this case should be a path
1269
 *   that can be used as the 'path' argument to a subsequent call to
1270
 *   os_build_full_path; this allows a path to be built in multiple steps by
1271
 *   descending into subdirectories one at a time.
1272
 *   
1273
 *   Unix examples:
1274
 *   
1275
 *   "/home/mjr", "deep.gam" -> "/home/mjr/deep.gam"
1276
 *.  "/home/mjr/", "deep.gam" -> "/home/mjr/deep.gam"
1277
 *.  "games", "deep.gam" -> "games/deep.gam"
1278
 *.  "games/", "deep.gam" -> "games/deep.gam"
1279
 *.  "/home/mjr", "games/deep.gam" -> "/home/mjr/games/deep.gam"
1280
 *.  "games", "scifi/deep.gam" -> "games/scifi/deep.gam"
1281
 *.  "/home/mjr", "games" -> "/home/mjr/games"
1282
 *   
1283
 *   Mac examples:
1284
 *   
1285
 *   "Hard Disk:", "deep.gam" -> "Hard Disk:deep.gam"
1286
 *.  ":games:", "deep.gam" -> ":games:deep.gam"
1287
 *.  "games", "deep.gam" -> ":games:deep.gam"
1288
 *.  "Hard Disk:", ":games:deep.gam" -> "Hard Disk:games:deep.gam"
1289
 *.  "games", ":scifi:deep.gam" -> ":games:scifi:deep.gam"
1290
 *.  "Hard Disk:", "games" -> "Hard Disk:games"
1291
 *.  "Hard Disk:games", "scifi" -> "Hard Disk:games:scifi"
1292
 *.  "Hard Disk:games:scifi", "deep.gam" -> "Hard Disk:games:scifi:deep.gam"
1293
 *.  "Hard Disk:games", ":scifi:deep.gam" -> "Hard Disk:games:scifi:deep.gam"
1294
 */
1295
void os_build_full_path(char *fullpathbuf, size_t fullpathbuflen,
1296
                        const char *path, const char *filename);
1297
1298
/*
1299
 *   Convert an OS filename path to a relative URL.  Paths provided to
1300
 *   this function should always be relative to the current directory, so
1301
 *   the resulting URL should be relative.  If end_sep is true, it means
1302
 *   that the last character of the result should be a '/', even if the
1303
 *   input path doesn't end with a path separator character.
1304
 *   
1305
 *   This routine should replace all system-specific path separator
1306
 *   characters in the input name with forward slashes ('/').  In
1307
 *   addition, if a relative path on the system starts with a path
1308
 *   separator, that leading path separator should be removed; for
1309
 *   example, on the Macintosh, a path of ":images:rooms:startroom.jpeg"
1310
 *   should be converted to "images/rooms/startroom.jpeg".
1311
 */
1312
void os_cvt_dir_url(char *result_buf, size_t result_buf_size,
1313
                    const char *src_path, int end_sep);
1314
1315
/*
1316
 *   Convert a relative URL into a relative filename path.  Paths provided
1317
 *   to this function should always be relative, so the resulting path
1318
 *   should be relative to the current directory.  This function
1319
 *   essentially reverses the transformation done by os_cvt_dir_url().  If
1320
 *   end_sep is true, the path should end with a path separator character,
1321
 *   so that filenames can be strcat'ed onto the result to form a full
1322
 *   filename.
1323
 */
1324
void os_cvt_url_dir(char *result_buf, size_t result_buf_size,
1325
                    const char *src_url, int end_sep);
1326
1327
1328
/* ------------------------------------------------------------------------ */
1329
/*
1330
 *   get a suitable seed for a random number generator; should use the
1331
 *   system clock or some other source of an unpredictable and changing
1332
 *   seed value 
1333
 */
1334
void os_rand(long *val);
1335
1336
1337
/* ------------------------------------------------------------------------ */
1338
/*
1339
 *   Display routines.
1340
 *   
1341
 *   Our display model is a simple stdio-style character stream.
1342
 *   
1343
 *   In addition, we provide an optional "status line," which is a
1344
 *   non-scrolling area where a line of text can be displayed.  If the status
1345
 *   line is supported, text should only be displayed in this area when
1346
 *   os_status() is used to enter status-line mode (mode 1); while in status
1347
 *   line mode, text is written to the status line area, otherwise (mode 0)
1348
 *   it's written to the normal main text area.  The status line is normally
1349
 *   shown in a different color to set it off from the rest of the text.
1350
 *   
1351
 *   The OS layer can provide its own formatting (word wrapping in
1352
 *   particular) if it wants, in which case it should also provide pagination
1353
 *   using os_more_prompt().  
1354
 */
1355
1356
/*
1357
 *   OS_MAXWIDTH - the maximum width of a line of text.  Most platforms use
1358
 *   135 for this, but you can use more or less as appropriate.  If you use
1359
 *   OS-level line wrapping, then the true width of a text line is
1360
 *   irrelevant, and the portable code will use this merely for setting its
1361
 *   internal buffer sizes.
1362
 *   
1363
 *   This must be defined in the os_xxx.h header file for each platform.
1364
 */
1365
/*#define OS_MAXWIDTH 135 - example only: define for real in os_xxx.h header*/
1366
1367
/*
1368
 *   Print a string on the console.  These routines come in two varieties:
1369
 *   
1370
 *   os_printz - write a NULL-TERMINATED string
1371
 *.  os_print - write a COUNTED-LENGTH string, which may not end with a null
1372
 *   
1373
 *   These two routines are identical except that os_printz() takes a string
1374
 *   which is terminated by a null byte, and os_print() instead takes an
1375
 *   explicit length, and a string that may not end with a null byte.
1376
 *   
1377
 *   os_printz(str) may be implemented as simply os_print(str, strlen(str)).
1378
 *   
1379
 *   The string is written in one of three ways, depending on the status mode
1380
 *   set by os_status():
1381
 *   
1382
 *   status mode == 0 -> write to main text window
1383
 *.  status mode == 1 -> write to status line
1384
 *.  anything else -> do not display the text at all
1385
 *   
1386
 *   Implementations are free to omit any status line support, in which case
1387
 *   they should simply suppress all output when the status mode is anything
1388
 *   other than zero.
1389
 *   
1390
 *   The following special characters must be recognized in the displayed
1391
 *   text:
1392
 *   
1393
 *   '\n' - newline: end the current line and move the cursor to the start of
1394
 *   the next line.  If the status line is supported, and the current status
1395
 *   mode is 1 (i.e., displaying in the status line), then two special rules
1396
 *   apply to newline handling: newlines preceding any other text should be
1397
 *   ignored, and a newline following any other text should set the status
1398
 *   mode to 2, so that all subsequent output is suppressed until the status
1399
 *   mode is changed with an explicit call by the client program to
1400
 *   os_status().
1401
 *   
1402
 *   '\r' - carriage return: end the current line and move the cursor back to
1403
 *   the beginning of the current line.  Subsequent output is expected to
1404
 *   overwrite the text previously on this same line.  The implementation
1405
 *   may, if desired, IMMEDIATELY clear the previous text when the '\r' is
1406
 *   written, rather than waiting for subsequent text to be displayed.
1407
 *   
1408
 *   All other characters may be assumed to be ordinary printing characters.
1409
 *   The routine need not check for any other special characters.
1410
 *   
1411
 */
1412
void os_printz(const char *str);
1413
void os_print(const char *str, size_t len);
1414
1415
1416
/* 
1417
 *   Set the status line mode.  There are three possible settings:
1418
 *   
1419
 *   0 -> main text mode.  In this mode, all subsequent text written with
1420
 *   os_print() and os_printz() is to be displayed to the main text area.
1421
 *   This is the normal mode that should be in effect initially.  This mode
1422
 *   stays in effect until an explicit call to os_status().
1423
 *   
1424
 *   1 -> statusline mode.  In this mode, text written with os_print() and
1425
 *   os_printz() is written to the status line, which is usually rendered as
1426
 *   a one-line area across the top of the terminal screen or application
1427
 *   window.  In statusline mode, leading newlines ('\n' characters) are to
1428
 *   be ignored, and any newline following any other character must change
1429
 *   the mode to 2, as though os_status(2) had been called.
1430
 *   
1431
 *   2 -> suppress mode.  In this mode, all text written with os_print() and
1432
 *   os_printz() must simply be ignored, and not displayed at all.  This mode
1433
 *   stays in effect until an explicit call to os_status().  
1434
 */
1435
void os_status(int stat);
1436
1437
/* get the status line mode */
1438
int os_get_status();
1439
1440
/* 
1441
 *   Set the score value.  This displays the given score and turn counts on
1442
 *   the status line.  In most cases, these values are displayed at the right
1443
 *   edge of the status line, in the format "score/turns", but the format is
1444
 *   up to the implementation to determine.  In most cases, this can simply
1445
 *   be implemented as follows:
1446
 *   
1447
 *.  void os_score(int score, int turncount)
1448
 *.  {
1449
 *.     char buf[40];
1450
 *.     sprintf(buf, "%d/%d", score, turncount);
1451
 *.     os_strsc(buf);
1452
 *.  }
1453
 */
1454
void os_score(int score, int turncount);
1455
1456
/* display a string in the score area in the status line */
1457
void os_strsc(const char *p);
1458
1459
/* clear the screen */
1460
void oscls(void);
1461
1462
/* redraw the screen */
1463
void os_redraw(void);
1464
1465
/* flush any buffered display output */
1466
void os_flush(void);
1467
1468
/*
1469
 *   Update the display - process any pending drawing immediately.  This
1470
 *   only needs to be implemented for operating systems that use
1471
 *   event-driven drawing based on window invalidations; the Windows and
1472
 *   Macintosh GUI's both use this method for drawing window contents.
1473
 *   
1474
 *   The purpose of this routine is to refresh the display prior to a
1475
 *   potentially long-running computation, to avoid the appearance that the
1476
 *   application is frozen during the computation delay.
1477
 *   
1478
 *   Platforms that don't need to process events in the main thread in order
1479
 *   to draw their window contents do not need to do anything here.  In
1480
 *   particular, text-mode implementations generally don't need to implement
1481
 *   this routine.
1482
 *   
1483
 *   This routine doesn't absolutely need a non-empty implementation on any
1484
 *   platform, but it will provide better visual feedback if implemented for
1485
 *   those platforms that do use event-driven drawing.  
1486
 */
1487
void os_update_display();
1488
1489
1490
/* ------------------------------------------------------------------------ */
1491
/*
1492
 *   Set text attributes.  Text subsequently displayed through os_print() and
1493
 *   os_printz() are to be displayed with the given attributes.
1494
 *   
1495
 *   'attr' is a (bitwise-OR'd) combination of OS_ATTR_xxx values.  A value
1496
 *   of zero indicates normal text, with no extra attributes.  
1497
 */
1498
void os_set_text_attr(int attr);
1499
1500
/* attribute code: bold-face */
1501
#define OS_ATTR_BOLD     0x0001
1502
1503
/* attribute code: italic */
1504
#define OS_ATTR_ITALIC   0x0002
1505
1506
/*
1507
 *   Abstract attribute codes.  Each platform can choose a custom rendering
1508
 *   for these by #defining them before this point, in the OS-specific header
1509
 *   (osdos.h, osmac.h, etc).  We provide *default* definitions in case the
1510
 *   platform doesn't define these.
1511
 *   
1512
 *   For compatibility with past versions, we treat HILITE, EM, and BOLD as
1513
 *   equivalent.  Platforms that can display multiple kinds of text
1514
 *   attributes (boldface and italic, say) should feel free to use more
1515
 *   conventional HTML mappings, such as EM->italic and STRONG->bold.  
1516
 */
1517
1518
/* 
1519
 *   "Highlighted" text, as appropriate to the local platform.  On most
1520
 *   text-mode platforms, the only kind of rendering variation possible is a
1521
 *   brighter or intensified color.  If actual bold-face is available, that
1522
 *   can be used instead.  This is the attribute used for text enclosed in a
1523
 *   TADS2 "\( \)" sequence.  
1524
 */
1525
#ifndef OS_ATTR_HILITE
1526
# define OS_ATTR_HILITE  OS_ATTR_BOLD
1527
#endif
1528
1529
/* HTML <em> attribute - by default, map this to bold-face */
1530
#ifndef OS_ATTR_EM
1531
# define OS_ATTR_EM      OS_ATTR_BOLD
1532
#endif
1533
1534
/* HTML <strong> attribute - by default, this has no effect */
1535
#ifndef OS_ATTR_STRONG
1536
# define OS_ATTR_STRONG  0
1537
#endif
1538
1539
1540
/* ------------------------------------------------------------------------ */
1541
/*
1542
 *   Colors.
1543
 *   
1544
 *   There are two ways of encoding a color.  First, a specific color can be
1545
 *   specified as an RGB (red-green-blue) value, with discreet levels for
1546
 *   each component's intensity, ranging from 0 to 255.  Second, a color can
1547
 *   be "parameterized," which doesn't specify a color in absolute terms but
1548
 *   rather specified one of a number of pre-defined *types* of colors;
1549
 *   these pre-defined types can be chosen by the OS implementation, or, on
1550
 *   some systems, selected by the user via a preferences mechanism.
1551
 *   
1552
 *   The os_color_t type encodes a color in 32 bits.  The high-order 8 bits
1553
 *   of a color value give the parameterized color identifier, or are set to
1554
 *   zero to indicate an RGB color.  An RGB color is encoded in the
1555
 *   low-order 24 bits, via the following formula:
1556
 *   
1557
 *   (R << 16) + (G << 8) + B
1558
 *   
1559
 *   R specifies the intensity of the red component of the color, G green,
1560
 *   and B blue.  Each of R, G, and B must be in the range 0-255.  
1561
 */
1562
typedef unsigned long os_color_t;
1563
1564
/* encode an R, G, B triplet into an os_color_t value */
1565
#define os_rgb_color(r, g, b) (((r) << 16) + ((g) << 8) + (b))
1566
1567
/* 
1568
 *   Determine if a color is given as an RGB value or as a parameterized
1569
 *   color value.  Returns true if the color is given as a parameterized
1570
 *   color (one of the OS_COLOR_xxx values), false if it's given as an
1571
 *   absolute RGB value.  
1572
 */
1573
#define os_color_is_param(color) (((color) & 0xFF000000) != 0)
1574
1575
/* get the red/green/blue components of an os_color_t value */
1576
#define os_color_get_r(color) ((int)(((color) >> 16) & 0xFF))
1577
#define os_color_get_g(color) ((int)(((color) >> 8) & 0xFF))
1578
#define os_color_get_b(color) ((int)((color) & 0xFF))
1579
1580
/*
1581
 *   Parameterized color codes.  These are os_color_t values that indicate
1582
 *   colors by type, rather than by absolute RGB values.  
1583
 */
1584
1585
/* 
1586
 *   "transparent" - applicable to backgrounds only, this specifies that the
1587
 *   current screen background color should be used 
1588
 */
1589
#define OS_COLOR_P_TRANSPARENT ((os_color_t)0x01000000)
1590
1591
/* "normal text" color (as set via user preferences, if applicable) */
1592
#define OS_COLOR_P_TEXT        ((os_color_t)0x02000000)
1593
1594
/* normal text background color (from user preferences) */
1595
#define OS_COLOR_P_TEXTBG      ((os_color_t)0x03000000)
1596
1597
/* "status line" text color (as set via user preferences, if applicable) */
1598
#define OS_COLOR_P_STATUSLINE  ((os_color_t)0x04000000)
1599
1600
/* status line background color (from user preferences) */
1601
#define OS_COLOR_P_STATUSBG    ((os_color_t)0x05000000)
1602
1603
/* input text color (as set via user preferences, if applicable) */
1604
#define OS_COLOR_P_INPUT       ((os_color_t)0x06000000)
1605
1606
/*
1607
 *   Set the text foreground and background colors.  This sets the text
1608
 *   color for subsequent os_printf() and os_vprintf() calls.
1609
 *   
1610
 *   The background color can be OS_COLOR_TRANSPARENT, in which case the
1611
 *   background color is "inherited" from the current screen background.
1612
 *   Note that if the platform is capable of keeping old text for
1613
 *   "scrollback," then the transparency should be a permanent attribute of
1614
 *   the character - in other words, it should not be mapped to the current
1615
 *   screen color in the scrollback buffer, because doing so would keep the
1616
 *   current screen color even if the screen color changes in the future. 
1617
 *   
1618
 *   Text color support is optional.  If the platform doesn't support text
1619
 *   colors, this can simply do nothing.  If the platform supports text
1620
 *   colors, but the requested color or attributes cannot be displayed, the
1621
 *   implementation should use the best available approximation.  
1622
 */
1623
void os_set_text_color(os_color_t fg, os_color_t bg);
1624
1625
/*
1626
 *   Set the screen background color.  This sets the text color for the
1627
 *   background of the screen.  If possible, this should immediately redraw
1628
 *   the main text area with this background color.  The color is given as an
1629
 *   OS_COLOR_xxx value.
1630
 *   
1631
 *   If the platform is capable of redisplaying the existing text, then any
1632
 *   existing text that was originally displayed with 'transparent'
1633
 *   background color should be redisplayed with the new screen background
1634
 *   color.  In other words, the 'transparent' background color of previously
1635
 *   drawn text should be a permanent attribute of the character - the color
1636
 *   should not be mapped on display to the then-current background color,
1637
 *   because doing so would lose the transparency and thus retain the old
1638
 *   screen color on a screen color change.  
1639
 */
1640
void os_set_screen_color(os_color_t color);
1641
1642
1643
/* ------------------------------------------------------------------------ */
1644
/* 
1645
 *   os_plain() - Use plain ascii mode for the display.  If possible and
1646
 *   necessary, turn off any text formatting effects, such as cursor
1647
 *   positioning, highlighting, or coloring.  If this routine is called,
1648
 *   the terminal should be treated as a simple text stream; users might
1649
 *   wish to use this mode for things like text-to-speech converters.
1650
 *   
1651
 *   Purely graphical implementations that cannot offer a textual mode
1652
 *   (such as Mac OS or Windows) can ignore this setting.
1653
 *   
1654
 *   If this routine is to be called, it must be called BEFORE os_init().
1655
 *   The implementation should set a flag so that os_init() will know to
1656
 *   set up the terminal for plain text output.  
1657
 */
1658
#ifndef os_plain
1659
/* 
1660
 *   some platforms (e.g. Mac OS) define this to be a null macro, so don't
1661
 *   define a prototype in those cases 
1662
 */
1663
void os_plain(void);
1664
#endif
1665
1666
/*
1667
 *   Set the game title.  The output layer calls this routine when a game
1668
 *   sets its title (via an HTML <title> tag, for example).  If it's
1669
 *   convenient to do so, the OS layer can use this string to set a window
1670
 *   caption, or whatever else makes sense on each system.  Most
1671
 *   character-mode implementations will provide an empty implementation,
1672
 *   since there's not usually any standard way to show the current
1673
 *   application title on a character-mode display.  
1674
 */
1675
void os_set_title(const char *title);
1676
1677
/*
1678
 *   Show the system-specific MORE prompt, and wait for the user to respond.
1679
 *   Before returning, remove the MORE prompt from the screen.
1680
 *   
1681
 *   This routine is only used and only needs to be implemented when the OS
1682
 *   layer takes responsibility for pagination; this will be the case on
1683
 *   most systems that use proportionally-spaced (variable-pitch) fonts or
1684
 *   variable-sized windows, since on such platforms the OS layer must do
1685
 *   most of the formatting work, leaving the standard output layer unable
1686
 *   to guess where pagination should occur.
1687
 *   
1688
 *   If the portable output formatter handles the MORE prompt, which is the
1689
 *   usual case for character-mode or terminal-style implementations, this
1690
 *   routine is not used and you don't need to provide an implementation.
1691
 *   Note that HTML TADS provides an implementation of this routine, because
1692
 *   the HTML renderer handles line breaking and thus must handle
1693
 *   pagination.  
1694
 */
1695
void os_more_prompt();
1696
1697
/*
1698
 *   Interpreter Class Configuration.
1699
 *   
1700
 *   If this is a TEXT-ONLY interpreter: DO NOT define USE_HTML.
1701
 *   
1702
 *   If this is a MULTIMEDIA (HTML TADS) intepreter: #define USE_HTML
1703
 *   
1704
 *   (This really should be called something like OS_USE_HTML - the USE_ name
1705
 *   is for historical reasons.  This purpose of this macro is to configure
1706
 *   the tads 2 VM-level output formatter's line breaking and MORE mode
1707
 *   behavior.  In HTML mode, the VM-level formatter knows that it's feeding
1708
 *   its output to a page layout engine, so the VM-level output is just a
1709
 *   text stream.  In plain-text mode, the VM formatter *is* the page layout
1710
 *   engine, so it needs to do all of the word wrapping and MORE prompting
1711
 *   itself.  The tads 3 output layer does NOT use this macro for its
1712
 *   equivalent configuration, but instead has different .cpp files for the
1713
 *   different modes, and you simply link in the one for the configuration
1714
 *   you want.)  
1715
 */
1716
/* #define USE_HTML */
1717
1718
1719
/*
1720
 *   Enter HTML mode.  This is only used when the run-time is compiled
1721
 *   with the USE_HTML flag defined.  This call instructs the renderer
1722
 *   that HTML sequences should be parsed; until this call is made, the
1723
 *   renderer should not interpret output as HTML.  Non-HTML
1724
 *   implementations do not need to define this routine, since the
1725
 *   run-time will not call it if USE_HTML is not defined.  
1726
 */
1727
void os_start_html(void);
1728
1729
/* exit HTML mode */
1730
void os_end_html(void);
1731
1732
/*
1733
 *   Global variables with the height and width (in character cells - rows
1734
 *   and columns) of the main text display area into which os_printf
1735
 *   displays.  The height and width are given in text lines and character
1736
 *   columns, respectively.  The portable code can use these values to
1737
 *   format text for display via os_printf(); for example, the caller can
1738
 *   use the width to determine where to put line breaks.
1739
 *   
1740
 *   These values are only needed for systems where os_printf() doesn't
1741
 *   perform its own word-wrap formatting.  On systems such as the Mac,
1742
 *   where os_printf() performs word wrapping, these sizes aren't really
1743
 *   important because the portable code doesn't need to perform any real
1744
 *   formatting.
1745
 *   
1746
 *   These variables reflect the size of the "main text area," which is the
1747
 *   area of the screen excluding the status line and any "banner" windows
1748
 *   (as created with the os_banner_xxx() interfaces).
1749
 *   
1750
 *   The OS code must initialize these variables during start-up, and must
1751
 *   adjust them whenever the display size is changed by user action or
1752
 *   other external events (for example, if we're running inside a terminal
1753
 *   window, and the user resizes the window, the OS code must recalculate
1754
 *   the layout and adjust these accordingly).  
1755
 */
1756
extern int G_os_pagelength;
1757
extern int G_os_linewidth;
1758
1759
/*
1760
 *   Global flag that tells the output formatter whether to count lines
1761
 *   that it's displaying against the total on the screen so far.  If this
1762
 *   variable is true, lines are counted, and the screen is paused with a
1763
 *   [More] message when it's full.  When not in MORE mode, lines aren't
1764
 *   counted.  This variable should be set to false when displaying text
1765
 *   that doesn't count against the current page, such as status line
1766
 *   information.
1767
 *   
1768
 *   This flag should not be modified by OS code.  Instead, the output
1769
 *   formatter will set this flag according to its current state; the OS
1770
 *   code can use this flag to determine whether or not to display a MORE
1771
 *   prompt during os_printf()-type operations.  Note that this flag is
1772
 *   normally interesting to the OS code only when the OS code itself is
1773
 *   handling the MORE prompt.  
1774
 */
1775
extern int G_os_moremode;
1776
1777
/*
1778
 *   Global buffer containing the name of the byte-code file (the "game
1779
 *   file") loaded into the VM.  This is used only where applicable, which
1780
 *   generally means in TADS Interpreter builds.  In other application
1781
 *   builds, this is simply left empty.  The application is responsible for
1782
 *   setting this during start-up (or wherever else the byte-code filename
1783
 *   becomes known or changes).  
1784
 */
1785
extern char G_os_gamename[OSFNMAX];
1786
1787
/*
1788
 *   Set non-stop mode.  This tells the OS layer that it should disable any
1789
 *   MORE prompting it would normally do.
1790
 *   
1791
 *   This routine is needed only when the OS layer handles MORE prompting; on
1792
 *   character-mode platforms, where the prompting is handled in the portable
1793
 *   console layer, this can be a dummy implementation.  
1794
 */
1795
void os_nonstop_mode(int flag);
1796
1797
/* 
1798
 *   Update progress display with current info, if appropriate.  This can
1799
 *   be used to provide a status display during compilation.  Most
1800
 *   command-line implementations will just ignore this notification; this
1801
 *   can be used for GUI compiler implementations to provide regular
1802
 *   display updates during compilation to show the progress so far.  
1803
 */
1804
/* void os_progress(const char *fname, unsigned long linenum); */
1805
1806
/* 
1807
 *   Set busy cursor.  If 'flag' is true, provide a visual representation
1808
 *   that the system or application is busy doing work.  If 'flag' is
1809
 *   false, remove any visual "busy" indication and show normal status.
1810
 *   
1811
 *   We provide a prototype here if your osxxx.h header file does not
1812
 *   #define a macro for os_csr_busy.  On many systems, this function has
1813
 *   no effect at all, so the osxxx.h header file simply #define's it to
1814
 *   do an empty macro.  
1815
 */
1816
#ifndef os_csr_busy
1817
void os_csr_busy(int flag);
1818
#endif
1819
1820
1821
/* ------------------------------------------------------------------------ */
1822
/*
1823
 *   User Input Routines
1824
 */
1825
1826
/*
1827
 *   Ask the user for a filename, using a system-dependent dialog or other
1828
 *   mechanism.  Returns one of the OS_AFE_xxx status codes (see below).
1829
 *   
1830
 *   prompt_type is the type of prompt to provide -- this is one of the
1831
 *   OS_AFP_xxx codes (see below).  The OS implementation doesn't need to
1832
 *   pay any attention to this parameter, but it can be used if desired to
1833
 *   determine the type of dialog to present if the system provides
1834
 *   different types of dialogs for different types of operations.
1835
 *   
1836
 *   file_type is one of the OSFTxxx codes for system file type.  The OS
1837
 *   implementation is free to ignore this information, but can use it to
1838
 *   filter the list of files displayed if desired; this can also be used
1839
 *   to apply a default suffix on systems that use suffixes to indicate
1840
 *   file type.  If OSFTUNK is specified, it means that no filtering
1841
 *   should be performed, and no default suffix should be applied.  
1842
 */
1843
int os_askfile(const char *prompt, char *fname_buf, int fname_buf_len,
1844
               int prompt_type, os_filetype_t file_type);
1845
1846
/* 
1847
 *   os_askfile status codes 
1848
 */
1849
1850
/* success */
1851
#define OS_AFE_SUCCESS  0 
1852
1853
/* 
1854
 *   Generic failure - this is largely provided for compatibility with
1855
 *   past versions, in which only zero and non-zero error codes were
1856
 *   meaningful; since TRUE is defined as 1 on most platforms, we assume
1857
 *   that 1 is probably the generic non-zero error code that most OS
1858
 *   implementations have traditionally used.  In addition, this can be
1859
 *   used to indicate any other error for which there is no more specific
1860
 *   error code.  
1861
 */
1862
#define OS_AFE_FAILURE  1
1863
1864
/* user cancelled */
1865
#define OS_AFE_CANCEL   2
1866
1867
/* 
1868
 *   os_askfile prompt types
1869
 *   
1870
 *   Important note: do not change these values when porting TADS.  These
1871
 *   values can be used by games, so they must be the same on all
1872
 *   platforms.  
1873
 */
1874
#define OS_AFP_OPEN    1     /* choose an existing file to open for reading */
1875
#define OS_AFP_SAVE    2          /* choose a filename for saving to a file */
1876
1877
1878
/* 
1879
 *   Read a string of input.  Fills in the buffer with a null-terminated
1880
 *   string containing a line of text read from the standard input.  The
1881
 *   returned string should NOT contain a trailing newline sequence.  On
1882
 *   success, returns 'buf'; on failure, including end of file, returns a
1883
 *   null pointer.  
1884
 */
1885
unsigned char *os_gets(unsigned char *buf, size_t bufl);
1886
1887
/*
1888
 *   Read a string of input with an optional timeout.  This behaves like
1889
 *   os_gets(), in that it allows the user to edit a line of text (ideally
1890
 *   using the same editing keys that os_gets() does), showing the line of
1891
 *   text under construction during editing.  This routine differs from
1892
 *   os_gets() in that it returns if the given timeout interval expires
1893
 *   before the user presses Return (or the local equivalent).
1894
 *   
1895
 *   If the user presses Return before the timeout expires, we store the
1896
 *   command line in the given buffer, just as os_gets() would, and we
1897
 *   return OS_EVT_LINE.  We also update the display in the same manner that
1898
 *   os_gets() would, by moving the cursor to a new line and scrolling the
1899
 *   displayed text as needed.
1900
 *   
1901
 *   If a timeout occurs before the user presses Return, we store the
1902
 *   command line so far in the given buffer, statically store the cursor
1903
 *   position, insert mode, buffer text, and anything else relevant to the
1904
 *   editing state, and we return OS_EVT_TIMEOUT.
1905
 *   
1906
 *   If the implementation does not support the timeout operation, this
1907
 *   routine should simply return OS_EVT_NOTIMEOUT immediately when called;
1908
 *   the routine should not allow the user to perform any editing if the
1909
 *   timeout is not supported.  Callers must use the ordinary os_gets()
1910
 *   routine, which has no timeout capabilities, if the timeout is not
1911
 *   supported.
1912
 *   
1913
 *   When we return OS_EVT_TIMEOUT, the caller is responsible for doing one
1914
 *   of two things.
1915
 *   
1916
 *   The first possibility is that the caller performs some work that
1917
 *   doesn't require any display operations (in other words, the caller
1918
 *   doesn't invoke os_printf, os_getc, or anything else that would update
1919
 *   the display), and then calls os_gets_timeout() again.  In this case, we
1920
 *   will use the editing state that we statically stored before we returned
1921
 *   OS_EVT_TIMEOUT to continue editing where we left off.  This allows the
1922
 *   caller to perform some computation in the middle of user command
1923
 *   editing without interrupting the user - the extra computation is
1924
 *   transparent to the user, because we act as though we were still in the
1925
 *   midst of the original editing.
1926
 *   
1927
 *   The second possibility is that the caller wants to update the display.
1928
 *   In this case, the caller must call os_gets_cancel() BEFORE making any
1929
 *   display changes.  Then, the caller must do any post-input work of its
1930
 *   own, such as updating the display mode (for example, closing HTML font
1931
 *   tags that were opened at the start of the input).  The caller is now
1932
 *   free to do any display work it wants.
1933
 *   
1934
 *   If we have information stored from a previous call that was interrupted
1935
 *   by a timeout, and os_gets_cancel(TRUE) was never called, we will resume
1936
 *   editing where we left off when the cancelled call returned; this means
1937
 *   that we'll restore the cursor position, insertion state, and anything
1938
 *   else relevant.  Note that if os_gets_cancel(FALSE) was called, we must
1939
 *   re-display the command line under construction, but if os_gets_cancel()
1940
 *   was never called, we will not have to make any changes to the display
1941
 *   at all.
1942
 *   
1943
 *   Note that when resuming an interrupted editing session (interrupted via
1944
 *   os_gets_cancel()), the caller must re-display the prompt prior to
1945
 *   invoking this routine.
1946
 *   
1947
 *   Note that we can return OS_EVT_EOF in addition to the other codes
1948
 *   mentioned above.  OS_EVT_EOF indicates that an error occurred reading,
1949
 *   which usually indicates that the application is being terminated or
1950
 *   that some hardware error occurred reading the keyboard.  
1951
 *   
1952
 *   If 'use_timeout' is false, the timeout should be ignored.  Without a
1953
 *   timeout, the function behaves the same as os_gets(), except that it
1954
 *   will resume editing of a previously-interrupted command line if
1955
 *   appropriate.  (This difference is why the timeout is optional: a caller
1956
 *   might not need a timeout, but might still want to resume a previous
1957
 *   input that did time out, in which case the caller would invoke this
1958
 *   routine with use_timeout==FALSE.  The regular os_gets() would not
1959
 *   satisfy this need, because it cannot resume an interrupted input.)  
1960
 */
1961
int os_gets_timeout(unsigned char *buf, size_t bufl,
1962
                    unsigned long timeout_in_milliseconds, int use_timeout);
1963
1964
/*
1965
 *   Cancel an interrupted editing session.  This MUST be called if any
1966
 *   output is to be displayed after a call to os_gets_timeout() returns
1967
 *   OS_EVT_TIMEOUT.
1968
 *   
1969
 *   'reset' indicates whether or not we will forget the input state saved
1970
 *   by os_gets_timeout() when it last returned.  If 'reset' is true, we'll
1971
 *   clear the input state, so that the next call to os_gets_timeout() will
1972
 *   start with an empty input buffer.  If 'reset' is false, we will retain
1973
 *   the previous input state, if any; this means that the next call to
1974
 *   os_gets_timeout() will re-display the same input buffer that was under
1975
 *   construction when it last returned.
1976
 *   
1977
 *   This routine need not be called if os_gets_timeout() is to be called
1978
 *   again with no other output operations between the previous
1979
 *   os_gets_timeout() call and the next one.
1980
 *   
1981
 *   Note that this routine needs only a trivial implementation when
1982
 *   os_gets_timeout() is not supported (i.e., the function always returns
1983
 *   OS_EVT_NOTIMEOUT).  
1984
 */
1985
void os_gets_cancel(int reset);
1986
1987
/* 
1988
 *   Read a character from the keyboard.  For extended keystrokes, this
1989
 *   function returns zero, and then returns the CMD_xxx code for the
1990
 *   extended keystroke on the next call.  For example, if the user presses
1991
 *   the up-arrow key, the first call to os_getc() should return 0, and the
1992
 *   next call should return CMD_UP.  Refer to the CMD_xxx codes below.
1993
 *   
1994
 *   os_getc() should return a high-level, translated command code for
1995
 *   command editing.  This means that, where a functional interpretation of
1996
 *   a key and the raw key-cap interpretation both exist as CMD_xxx codes,
1997
 *   the functional interpretation should be returned.  For example, on Unix,
1998
 *   Ctrl-E is conventionally used in command editing to move to the end of
1999
 *   the line, following Emacs key bindings.  Hence, os_getc() should return
2000
 *   CMD_END for this keystroke, rather than a single 0x05 character (ASCII
2001
 *   Ctrl-E), because CMD_END is the high-level command code for the
2002
 *   operation.
2003
 *   
2004
 *   The translation ability of this function allows for system-dependent key
2005
 *   mappings to functional meanings.  
2006
 */
2007
int os_getc(void);
2008
2009
/*
2010
 *   Read a character from the keyboard, following the same protocol as
2011
 *   os_getc() for CMD_xxx codes (i.e., when an extended keystroke is
2012
 *   encountered, os_getc_raw() returns zero, then returns the CMD_xxx code
2013
 *   on the subsequent call).
2014
 *   
2015
 *   This function differs from os_getc() in that this function returns the
2016
 *   low-level, untranslated key code whenever possible.  This means that,
2017
 *   when a functional interpretation of a key and the raw key-cap
2018
 *   interpretation both exist as CMD_xxx codes, this function returns the
2019
 *   key-cap interpretation.  For the Unix Ctrl-E example in the comments
2020
 *   describing os_getc() above, this function should return 5 (the ASCII
2021
 *   code for Ctrl-E), because the ASCII control character interpretation is
2022
 *   the low-level key code.
2023
 *   
2024
 *   This function should return all control keys using their ASCII control
2025
 *   codes, whenever possible.  Similarly, this function should return ASCII
2026
 *   27 for the Escape key, if possible.  
2027
 *   
2028
 *   For keys for which there is no portable ASCII representation, this
2029
 *   should return the CMD_xxx sequence.  So, this function acts exactly the
2030
 *   same as os_getc() for arrow keys, function keys, and other special keys
2031
 *   that have no ASCII representation.  This function returns a
2032
 *   non-translated version ONLY when an ASCII representation exists - in
2033
 *   practice, this means that this function and os_getc() vary only for CTRL
2034
 *   keys and Escape.  
2035
 */
2036
int os_getc_raw(void);
2037
2038
2039
/* wait for a character to become available from the keyboard */
2040
void os_waitc(void);
2041
2042
/*
2043
 *   Constants for os_getc() when returning commands.  When used for
2044
 *   command line editing, special keys (arrows, END, etc.)  should cause
2045
 *   os_getc() to return 0, and return the appropriate CMD_ value on the
2046
 *   NEXT call.  Hence, os_getc() must keep the appropriate information
2047
 *   around statically for the next call when a command key is issued.
2048
 *   
2049
 *   The comments indicate which CMD_xxx codes are "translated" codes and
2050
 *   which are "raw"; the difference is that, when a particular keystroke
2051
 *   could be interpreted as two different CMD_xxx codes, one translated
2052
 *   and the other raw, os_getc() should always return the translated
2053
 *   version of the key, and os_getc_raw() should return the raw version.
2054
 */
2055
#define CMD_UP    1                        /* move up/up arrow (translated) */
2056
#define CMD_DOWN  2                    /* move down/down arrow (translated) */
2057
#define CMD_RIGHT 3                  /* move right/right arrow (translated) */
2058
#define CMD_LEFT  4                    /* move left/left arrow (translated) */
2059
#define CMD_END   5              /* move cursor to end of line (translated) */
2060
#define CMD_HOME  6            /* move cursor to start of line (translated) */
2061
#define CMD_DEOL  7                   /* delete to end of line (translated) */
2062
#define CMD_KILL  8                      /* delete entire line (translated) */
2063
#define CMD_DEL   9                /* delete current character (translated) */
2064
#define CMD_SCR   10                 /* toggle scrollback mode (translated) */
2065
#define CMD_PGUP  11                                /* page up (translated) */
2066
#define CMD_PGDN  12                              /* page down (translated) */
2067
#define CMD_TOP   13                            /* top of file (translated) */
2068
#define CMD_BOT   14                         /* bottom of file (translated) */
2069
#define CMD_F1    15                               /* function key F1 (raw) */
2070
#define CMD_F2    16                               /* function key F2 (raw) */
2071
#define CMD_F3    17                               /* function key F3 (raw) */
2072
#define CMD_F4    18                               /* function key F4 (raw) */
2073
#define CMD_F5    19                               /* function key F5 (raw) */
2074
#define CMD_F6    20                               /* function key F6 (raw) */
2075
#define CMD_F7    21                               /* function key F7 (raw) */
2076
#define CMD_F8    22                               /* function key F8 (raw) */
2077
#define CMD_F9    23                               /* function key F9 (raw) */
2078
#define CMD_F10   24                              /* function key F10 (raw) */
2079
#define CMD_CHOME 25                                  /* control-home (raw) */
2080
#define CMD_TAB   26                                    /* tab (translated) */
2081
#define CMD_SF2   27                                      /* shift-F2 (raw) */
2082
/* not used (obsolete) - 28 */
2083
#define CMD_WORD_LEFT  29      /* word left (ctrl-left on dos) (translated) */
2084
#define CMD_WORD_RIGHT 30    /* word right (ctrl-right on dos) (translated) */
2085
#define CMD_WORDKILL 31                   /* delete word right (translated) */
2086
#define CMD_EOF   32                                   /* end-of-file (raw) */
2087
#define CMD_BREAK 33     /* break (Ctrl-C or local equivalent) (translated) */
2088
2089
2090
/*
2091
 *   ALT-keys - add alphabetical code to CMD_ALT: ALT-A == CMD_ALT + 0,
2092
 *   ALT-B == CMD_ALT + 1, ALT-C == CMD_ALT + 2, etc
2093
 *   
2094
 *   These keys are all raw (untranslated).  
2095
 */
2096
#define CMD_ALT   128                                  /* start of ALT keys */
2097
2098
2099
/* ------------------------------------------------------------------------ */
2100
/*
2101
 *   Event information structure for os_get_event.  The appropriate union
2102
 *   member should be filled in, depending on the type of event that
2103
 *   occurs. 
2104
 */
2105
union os_event_info_t
2106
{
2107
    /* 
2108
     *   OS_EVT_KEY - this returns the one or two characters of the
2109
     *   keystroke.  If the key is an extended key, so that os_getc() would
2110
     *   return a two-character sequence for the keystroke, the first
2111
     *   character should be zero and the second the extended key code.
2112
     *   Otherwise, the first character should simply be the ASCII key code.
2113
     *   
2114
     *   The key code here is the "raw" keycode, equivalent to the codes
2115
     *   returned by os_getc_raw().  Note in particular that this means that
2116
     *   CTRL and Escape keys are presented as one-byte ASCII control
2117
     *   characters, not as two-byte CMD_xxx sequences.  
2118
     *   
2119
     *   For multi-byte character sets (Shift-JIS, for example), note that
2120
     *   os_get_event() must NOT return a complete two-byte character here.
2121
     *   The two bytes here are exclusively used to represent special
2122
     *   CMD_xxx keys (such as arrow keys and function keys).  For a
2123
     *   keystroke that is represented in a multi-byte character set using
2124
     *   more than one byte, os_get_event() must return a series of events.
2125
     *   Return an ordinary OS_EVT_KEY for the first byte of the sequence,
2126
     *   putting the byte in key[0]; then, return the second byte as a
2127
     *   separate OS_EVT_KEY as the next event; and so on for any additional
2128
     *   bytes.  This will allow callers that are not multibyte-aware to
2129
     *   treat multi-byte characters as though they were sequences of
2130
     *   one-byte characters.  
2131
     */
2132
    int key[2];
2133
2134
    /*
2135
     *   OS_EVT_HREF - this returns the text of the HREF as a
2136
     *   null-terminated string.  
2137
     */
2138
    char href[256];
2139
2140
    /* command ID (for OS_EVT_COMMAND) */
2141
    int cmd_id;
2142
};
2143
typedef union os_event_info_t os_event_info_t;
2144
2145
/*
2146
 *   Event types for os_get_event 
2147
 */
2148
2149
/* OS_EVT_KEY - user typed a key on the keyboard */
2150
#define OS_EVT_KEY       0x0001
2151
2152
/* OS_EVT_TIMEOUT - no event occurred before the timeout elapsed */
2153
#define OS_EVT_TIMEOUT   0x0002
2154
2155
/* 
2156
 *   OS_EVT_HREF - user clicked on a <A HREF> link.  This only applies to
2157
 *   the HTML-enabled run-time. 
2158
 */
2159
#define OS_EVT_HREF      0x0003
2160
2161
/* 
2162
 *   OS_EVT_NOTIMEOUT - caller requested a timeout, but timeout is not
2163
 *   supported by this version of the run-time 
2164
 */
2165
#define OS_EVT_NOTIMEOUT 0x0004
2166
2167
/*
2168
 *   OS_EVT_EOF - an error occurred reading the event.  This generally
2169
 *   means that the application is quitting or we can no longer read from
2170
 *   the keyboard or terminal. 
2171
 */
2172
#define OS_EVT_EOF       0x0005
2173
2174
/* 
2175
 *   OS_EVT_LINE - user entered a line of text on the keyboard.  This event
2176
 *   is not returned from os_get_event(), but rather from os_gets_timeout().
2177
 */
2178
#define OS_EVT_LINE      0x0006
2179
2180
2181
/*
2182
 *   Get an input event.  The event types are shown above.  If use_timeout
2183
 *   is false, this routine should simply wait until one of the events it
2184
 *   recognizes occurs, then return the appropriate information on the
2185
 *   event.  If use_timeout is true, this routine should return
2186
 *   OS_EVT_TIMEOUT after the given number of milliseconds elapses if no
2187
 *   event occurs first.
2188
 *   
2189
 *   This function is not obligated to obey the timeout.  If a timeout is
2190
 *   specified and it is not possible to obey the timeout, the function
2191
 *   should simply return OS_EVT_NOTIMEOUT.  The trivial implementation
2192
 *   thus checks for a timeout, returns an error if specified, and
2193
 *   otherwise simply waits for the user to press a key.  
2194
 */
2195
int os_get_event(unsigned long timeout_in_milliseconds, int use_timeout,
2196
                 os_event_info_t *info);
2197
2198
2199
/* ------------------------------------------------------------------------ */
2200
/*
2201
 *   Extended os_get_event() codes.
2202
 *   
2203
 *   THESE ARE NOT USED in the basic osifc implementation - these are only
2204
 *   used if the interpreter supports the "extended" interface defined in
2205
 *   osifcext.h.  
2206
 */
2207
2208
/*
2209
 *   System menu command event.  Some interpreters (such as HTML TADS for
2210
 *   Windows) provide menu commands for common system-level game verbs -
2211
 *   SAVE, RESTORE, UNDO, QUIT.  By default, these commands are returned as
2212
 *   literal command strings ("save", "restore", etc) via os_gets(), as
2213
 *   though the user had typed the commands at the keyboard.  The extended OS
2214
 *   interface allows the program to receive these commands via
2215
 *   os_get_event().  When a command is enabled for os_get_event() via the
2216
 *   extended OS interface, and the player selects the command via a menu (or
2217
 *   toolbar button, etc) during a call to os_get_event(), os_get_event()
2218
 *   returns this event code, with the menu ID stored in the cmd_id field of
2219
 *   the event structure.  
2220
 */
2221
#define OS_EVT_COMMAND   0x0100
2222
2223
/* command IDs for OS_EVT_COMMAND */
2224
#define OS_CMD_NONE      0x0000     /* invalid command ID, for internal use */
2225
#define OS_CMD_SAVE      0x0001                                /* save game */
2226
#define OS_CMD_RESTORE   0x0002                             /* restore game */
2227
#define OS_CMD_UNDO      0x0003                           /* undo last turn */
2228
#define OS_CMD_QUIT      0x0004                                /* quit game */
2229
#define OS_CMD_CLOSE     0x0005                    /* close the game window */
2230
#define OS_CMD_HELP      0x0006                           /* show game help */
2231
2232
/* highest command ID used in this version of the interface */
2233
#define OS_CMD_LAST      0x0006
2234
2235
2236
/* ------------------------------------------------------------------------ */
2237
/*
2238
 *   Ask for input through a dialog.
2239
 *   
2240
 *   'prompt' is a text string to display as a prompting message.  For
2241
 *   graphical systems, this message should be displayed in the dialog;
2242
 *   for text systems, this should be displayed on the terminal after a
2243
 *   newline.
2244
 *   
2245
 *   'standard_button_set' is one of the OS_INDLG_xxx values defined
2246
 *   below, or zero.  If this value is zero, no standard button set is to
2247
 *   be used; the custom set of buttons defined in 'buttons' is to be used
2248
 *   instead.  If this value is non-zero, the appropriate set of standard
2249
 *   buttons, with labels translated to the local language if possible, is
2250
 *   to be used.
2251
 *   
2252
 *   'buttons' is an array of strings to use as button labels.
2253
 *   'button_count' gives the number of entries in the 'buttons' array.
2254
 *   'buttons' and 'button_count' are ignored if 'standard_button_set' is
2255
 *   non-zero, since a standard set of buttons is used instead.  If
2256
 *   'buttons' and 'button_count' are to be used, each entry contains the
2257
 *   label of a button to show.  
2258
 */
2259
/*   
2260
 *   An ampersand ('&') character in a label string indicates that the
2261
 *   next character after the '&' is to be used as the short-cut key for
2262
 *   the button, if supported.  The '&' should NOT be displayed in the
2263
 *   string; instead, the character should be highlighted according to
2264
 *   local system conventions.  On Windows, for example, the short-cut
2265
 *   character should be shown underlined; on a text display, the response
2266
 *   might be shown with the short-cut character enclosed in parentheses.
2267
 *   If there is no local convention for displaying a short-cut character,
2268
 *   then the '&' should simply be removed from the displayed text.  
2269
 *   
2270
 *   The short-cut key specified by each '&' character should be used in
2271
 *   processing responses.  If the user presses the key corresponding to a
2272
 *   button's short-cut, the effect should be the same as if the user
2273
 *   clicked the button with the mouse.  If local system conventions don't
2274
 *   allow for short-cut keys, any short-cut keys can be ignored.
2275
 *   
2276
 *   'default_index' is the 1-based index of the button to use as the
2277
 *   default.  If this value is zero, there is no default response.  If
2278
 *   the user performs the appropriate system-specific action to select
2279
 *   the default response for the dialog, this is the response that is to
2280
 *   be selected.  On Windows, for example, pressing the "Return" key
2281
 *   should select this item.
2282
 *   
2283
 *   'cancel_index' is the 1-based index of the button to use as the
2284
 *   cancel response.  If this value is zero, there is no cancel response.
2285
 *   This is the response to be used if the user cancels the dialog using
2286
 *   the appropriate system-specific action.  On Windows, for example,
2287
 *   pressing the "Escape" key should select this item.  
2288
 */
2289
/*
2290
 *   icon_id is one of the OS_INDLG_ICON_xxx values defined below.  If
2291
 *   possible, an appropriate icon should be displayed in the dialog.
2292
 *   This can be ignored in text mode, and also in GUI mode if there is no
2293
 *   appropriate system icon.
2294
 *   
2295
 *   The return value is the 1-based index of the response selected.  If
2296
 *   an error occurs, return 0.  
2297
 */
2298
int os_input_dialog(int icon_id, const char *prompt, int standard_button_set,
2299
                    const char **buttons, int button_count,
2300
                    int default_index, int cancel_index);
2301
2302
/*
2303
 *   Standard button set ID's 
2304
 */
2305
2306
/* OK */
2307
#define OS_INDLG_OK            1
2308
2309
/* OK, Cancel */
2310
#define OS_INDLG_OKCANCEL      2
2311
2312
/* Yes, No */
2313
#define OS_INDLG_YESNO         3
2314
2315
/* Yes, No, Cancel */
2316
#define OS_INDLG_YESNOCANCEL   4
2317
2318
/*
2319
 *   Dialog icons 
2320
 */
2321
2322
/* no icon */
2323
#define OS_INDLG_ICON_NONE     0
2324
2325
/* warning */
2326
#define OS_INDLG_ICON_WARNING  1
2327
2328
/* information */
2329
#define OS_INDLG_ICON_INFO     2
2330
2331
/* question */
2332
#define OS_INDLG_ICON_QUESTION 3
2333
2334
/* error */
2335
#define OS_INDLG_ICON_ERROR    4
2336
2337
2338
2339
/* ------------------------------------------------------------------------ */
2340
/*
2341
 *   Get the current system high-precision timer.  This function returns a
2342
 *   value giving the wall-clock ("real") time in milliseconds, relative
2343
 *   to any arbitrary zero point.  It doesn't matter what this value is
2344
 *   relative to -- the only important thing is that the values returned
2345
 *   by two different calls should differ by the number of actual
2346
 *   milliseconds that have elapsed between the two calls.  On most
2347
 *   single-user systems, for example, this will probably return the
2348
 *   number of milliseconds since the user turned on the computer.
2349
 *   
2350
 *   True millisecond precision is NOT required.  Each implementation
2351
 *   should simply use the best precision available on the system.  If
2352
 *   your system doesn't have any kind of high-precision clock, you can
2353
 *   simply use the time() function and multiply the result by 1000 (but
2354
 *   see the note below about exceeding 32-bit precision).
2355
 *   
2356
 *   However, it *is* required that the return value be in *units* of
2357
 *   milliseconds, even if your system clock doesn't have that much
2358
 *   precision; so on a system that uses its own internal clock units,
2359
 *   this routine must multiply the clock units by the appropriate factor
2360
 *   to yield milliseconds for the return value.
2361
 *   
2362
 *   It is also required that the values returned by this function be
2363
 *   monotonically increasing.  In other words, each subsequent call must
2364
 *   return a value that is equal to or greater than the value returned
2365
 *   from the last call.  On some systems, you must be careful of two
2366
 *   special situations.
2367
 *   
2368
 *   First, the system clock may "roll over" to zero at some point; for
2369
 *   example, on some systems, the internal clock is reset to zero at
2370
 *   midnight every night.  If this happens, you should make sure that you
2371
 *   apply a bias after a roll-over to make sure that the value returned
2372
 *   from this return continues to increase despite the reset of the
2373
 *   system clock.
2374
 *   
2375
 *   Second, a 32-bit signed number can only hold about twenty-three days
2376
 *   worth of milliseconds.  While it seems unlikely that a TADS game
2377
 *   would run for 23 days without a break, it's certainly reasonable to
2378
 *   expect that the computer itself may run this long without being
2379
 *   rebooted.  So, if your system uses some large type (a 64-bit number,
2380
 *   for example) for its high-precision timer, you may want to store a
2381
 *   zero point the very first time this function is called, and then
2382
 *   always subtract this zero point from the large value returned by the
2383
 *   system clock.  If you're using time(0)*1000, you should use this
2384
 *   technique, since the result of time(0)*1000 will almost certainly not
2385
 *   fit in 32 bits in most cases.
2386
 */
2387
long os_get_sys_clock_ms(void);
2388
2389
/*
2390
 *   Sleep for a while.  This should simply pause for the given number of
2391
 *   milliseconds, then return.  On multi-tasking systems, this should use
2392
 *   a system API to unschedule the current process for the desired delay;
2393
 *   on single-tasking systems, this can simply sit in a wait loop until
2394
 *   the desired interval has elapsed.  
2395
 */
2396
void os_sleep_ms(long delay_in_milliseconds);
2397
2398
/* 
2399
 *   Set a file's type information.  This is primarily for implementations on
2400
 *   Mac OS 9 and earlier, where the file system keeps file-type metadata
2401
 *   separate from the filename.  On such systems, this can be used to set
2402
 *   the type metadata after a file is created.  The system should map the
2403
 *   os_filetype_t values to the actual metadata values on the local system.
2404
 *   On most systems, there's no such thing as file-type metadata, in which
2405
 *   case this function should simply be stubbed out with an empty function.
2406
 */
2407
void os_settype(const char *f, os_filetype_t typ);
2408
2409
/* open the error message file for reading */
2410
osfildef *oserrop(const char *arg0);
2411
2412
/* ------------------------------------------------------------------------ */
2413
/* 
2414
 *   OS main entrypoint 
2415
 */
2416
int os0main(int oargc, char **oargv,
2417
            int (*mainfn)(int, char **, char *), 
2418
            const char *before, const char *config);
2419
2420
/* 
2421
 *   new-style OS main entrypoint - takes an application container context 
2422
 */
2423
int os0main2(int oargc, char **oargv,
2424
             int (*mainfn)(int, char **, struct appctxdef *, char *),
2425
             const char *before, const char *config,
2426
             struct appctxdef *appctx);
2427
2428
/*
2429
 *   OBSOLETE - Get filename from startup parameter, if possible; returns
2430
 *   true and fills in the buffer with the parameter filename on success,
2431
 *   false if no parameter file could be found.
2432
 *   
2433
 *   (This was used until TADS 2.2.5 for the benefit of the Mac interpreter,
2434
 *   and interpreters on systems with similar desktop shells, to allow the
2435
 *   user to launch the terp by double-clicking on a saved game file.  The
2436
 *   terp would read the launch parameters, discover that a saved game had
2437
 *   been used to invoke it, and would then stash away the saved game info
2438
 *   for later retrieval from this function.  This functionality was replaced
2439
 *   in 2.2.5 with a command-line parameter: the terp now uses the desktop
2440
 *   launch data to synthesize a suitable argv[] vectro to pass to os0main()
2441
 *   or os0main2().  This function should now simply be stubbed out - it
2442
 *   should simply return FALSE.)  
2443
 */
2444
int os_paramfile(char *buf);
2445
2446
/* 
2447
 *   Initialize.  This should be called during program startup to
2448
 *   initialize the OS layer and check OS-specific command-line arguments.
2449
 *   
2450
 *   If 'prompt' and 'buf' are non-null, and there are no arguments on the
2451
 *   given command line, the OS code can use the prompt to ask the user to
2452
 *   supply a filename, then store the filename in 'buf' and set up
2453
 *   argc/argv to give a one-argument command string.  (This mechanism for
2454
 *   prompting for a filename is obsolescent, and is retained for
2455
 *   compatibility with a small number of existing implementations only;
2456
 *   new implementations should ignore this mechanism and leave the
2457
 *   argc/argv values unchanged.)  
2458
 */
2459
int os_init(int *argc, char *argv[], const char *prompt,
2460
            char *buf, int bufsiz);
2461
2462
/*
2463
 *   Termination functions.  There are three main termination functions,
2464
 *   described individually below; here's a brief overview of the
2465
 *   relationship among the functions.  The important thing to realize is
2466
 *   that these functions have completely independent purposes; they should
2467
 *   never call one another, and they should never do any of the work that's
2468
 *   intended for the others.
2469
 *   
2470
 *   os_uninit() is meant to undo the effects of os_init().  On many
2471
 *   systems, os_init() has some global effect, such as setting the terminal
2472
 *   to some special input or output mode.  os_uninit's purpose is to undo
2473
 *   these global effects, returning the terminal mode (and whatever else)
2474
 *   to the conditions they were in at program startup.  Portable callers
2475
 *   are meant to call this routine at some point before terminating if they
2476
 *   ever called os_init().  Note that this routine DOES NOT terminate the
2477
 *   program - it should simply undo anything that os_init() did and return,
2478
 *   to let the caller do any additional termination work of its own.
2479
 *   
2480
 *   os_expause() optionally pauses before termination, to allow the user to
2481
 *   acknowledge any text the program displays just before exiting.  This
2482
 *   doesn't have to do anything at all, but it's useful on systems where
2483
 *   program termination will do something drastic like close the window:
2484
 *   without a pause, the user wouldn't have a chance to read any text the
2485
 *   program displayed after the last interactive input, because the window
2486
 *   would abruptly disappear moments after the text was displayed.  For
2487
 *   systems where termination doesn't have such drastic effects, there's no
2488
 *   need to do anything in this routine.  Because it's up to this routine
2489
 *   whether or not to pause, this routine must display a prompt if it's
2490
 *   going to pause for user input - the portable caller obviously can't do
2491
 *   so, because the caller doesn't know if the routine is going to pause or
2492
 *   not (so if the caller displayed a prompt assuming the routine would
2493
 *   pause, the prompt would show up even on systems where there actually is
2494
 *   no pause, which would be confusing).  This routine DOES NOT terminate
2495
 *   the program; it simply pauses if necessary to allow the user to
2496
 *   acknowledge the last bit of text the program displayed, then returns to
2497
 *   allow the caller to carry on with its own termination work.
2498
 *   
2499
 *   os_term() is meant to perform the same function as the C standard
2500
 *   library routine exit(): this actually terminates the program, exiting
2501
 *   to the operating system.  This routine is not meant to return to its
2502
 *   caller, because it's supposed to exit the program directly.  For many
2503
 *   systems, this routine can simply call exit(); the portable code calls
2504
 *   this routine instead of calling exit() directly, because some systems
2505
 *   have their own OS-specific way of terminating rather than using exit().
2506
 *   This routine MUST NOT undo the effects of os_init(), because callers
2507
 *   might not have ever called os_init(); callers are required to call
2508
 *   os_uninit() if they ever called os_init(), before calling os_term(), so
2509
 *   this routine can simply assume that any global modes set by os_init()
2510
 *   have already been undone by the time this is called.  
2511
 */
2512
2513
/*
2514
 *   Uninitialize.  This is called prior to progam termination to reverse
2515
 *   the effect of any changes made in os_init().  For example, if
2516
 *   os_init() put the terminal in raw mode, this should restore the
2517
 *   previous terminal mode.  This routine should not terminate the
2518
 *   program (so don't call exit() here) - the caller might have more
2519
 *   processing to perform after this routine returns.  
2520
 */
2521
void os_uninit(void);
2522
2523
/* 
2524
 *   Pause prior to exit, if desired.  This is meant to be called by
2525
 *   portable code just before the program is to be terminated; it can be
2526
 *   implemented to show a prompt and wait for user acknowledgment before
2527
 *   proceeding.  This is useful for implementations that are using
2528
 *   something like a character-mode terminal window running on a graphical
2529
 *   operating system: this gives the implementation a chance to pause
2530
 *   before exiting, so that the window doesn't just disappear
2531
 *   unceremoniously.
2532
 *   
2533
 *   This is allowed to do nothing at all.  For regular character-mode
2534
 *   systems, this routine usually doesn't do anything, because when the
2535
 *   program exits, the terminal will simply return to the OS command
2536
 *   prompt; none of the text displayed just before the program exited will
2537
 *   be lost, so there's no need for any interactive pause.  Likewise, for
2538
 *   graphical systems where the window will remain open, even after the
2539
 *   program exits, until the user explicitly closes the window, there's no
2540
 *   need to do anything here.
2541
 *   
2542
 *   If this is implemented to pause, then this routine MUST show some kind
2543
 *   of prompt to let the user know we're waiting.  In the simple case of a
2544
 *   text-mode terminal window on a graphical OS, this should simply print
2545
 *   out some prompt text ("Press a key to exit...") and then wait for the
2546
 *   user to acknowledge the prompt (by pressing a key, for example).  For
2547
 *   graphical systems, the prompt could be placed in the window's title
2548
 *   bar, or status-bar, or wherever is appropriate for the OS.  
2549
 */
2550
void os_expause(void);
2551
2552
/* 
2553
 *   Terminate.  This should exit the program with the given exit status.
2554
 *   In general, this should be equivalent to the standard C library
2555
 *   exit() function, but we define this interface to allow the OS code to
2556
 *   do any necessary pre-termination cleanup.  
2557
 */
2558
void os_term(int status);
2559
2560
/* 
2561
 *   Install/uninstall the break handler.  If possible, the OS code should
2562
 *   set (if 'install' is true) or clear (if 'install' is false) a signal
2563
 *   handler for keyboard break signals (control-C, etc, depending on
2564
 *   local convention).  The OS code should set its own handler routine,
2565
 *   which should note that a break occurred with an internal flag; the
2566
 *   portable code uses os_break() from time to time to poll this flag.  
2567
 */
2568
void os_instbrk(int install);
2569
2570
/*
2571
 *   Check for user break ("control-C", etc) - returns true if a break is
2572
 *   pending, false if not.  If this returns true, it should "consume" the
2573
 *   pending break (probably by simply clearing the OS code's internal
2574
 *   break-pending flag).  
2575
 */
2576
int os_break(void);
2577
2578
/*
2579
 *   Yield CPU; returns TRUE if user requested an interrupt (a "control-C"
2580
 *   type of operation to abort the entire program), FALSE to continue.
2581
 *   Portable code should call this routine from time to time during lengthy
2582
 *   computations that don't involve any UI operations; if practical, this
2583
 *   routine should be invoked roughly every 10 to 100 milliseconds.
2584
 *   
2585
 *   The purpose of this routine is to support "cooperative multitasking"
2586
 *   systems, such as pre-X MacOS, where it's necessary for each running
2587
 *   program to call the operating system explicitly in order to yield the
2588
 *   CPU from time to time to other concurrently running programs.  On
2589
 *   cooperative multitasking systems, a program can only lose control of
2590
 *   the CPU by making specific system calls, usually related to GUI events;
2591
 *   a program can never lose control of the CPU asynchronously.  So, a
2592
 *   program that performs lengthy computations without any UI interaction
2593
 *   can cause the rest of the system to freeze up until the computations
2594
 *   are finished; but if a compute-intensive program explicitly yields the
2595
 *   CPU from time to time, it allows other programs to remain responsive.
2596
 *   Yielding the CPU at least every 100 milliseconds or so will generally
2597
 *   allow the UI to remain responsive; yielding more frequently than every
2598
 *   10 ms or so will probably start adding noticeable overhead.
2599
 *   
2600
 *   On single-tasking systems (such as MS-DOS), there's only one program
2601
 *   running at a time, so there's no need to yield the CPU; on virtually
2602
 *   every modern system, the OS automatically schedules CPU time without
2603
 *   the running programs having any say in the matter, so again there's no
2604
 *   need for a program to yield the CPU.  For systems where this routine
2605
 *   isn't needed, the system header should simply #define os_yield to
2606
 *   something like "((void)0)" - this will allow the compiler to completely
2607
 *   ignore calls to this routine for systems where they aren't needed.
2608
 *   
2609
 *   Note that this routine is NOT meant to provide scheduling hinting to
2610
 *   modern systems with true multitasking, so a trivial implementation is
2611
 *   fine for any modern system.  
2612
 */
2613
#ifndef os_yield
2614
int os_yield(void);
2615
#endif
2616
2617
/*
2618
 *   Initialize the time zone.  This routine is meant to take care of any
2619
 *   work that needs to be done prior to calling localtime() and other
2620
 *   time-zone-dependent routines in the run-time library.  For DOS and
2621
 *   Windows, we need to call the run-time library routine tzset() to set
2622
 *   up the time zone from the environment; most systems shouldn't need to
2623
 *   do anything in this routine.  
2624
 */
2625
#ifndef os_tzset
2626
void os_tzset(void);
2627
#endif
2628
2629
/*
2630
 *   Set the default saved-game extension.  This routine will NOT be
2631
 *   called when we're using the standard saved game extension; this
2632
 *   routine will be invoked only if we're running as a stand-alone game,
2633
 *   and the game author specified a non-standard saved-game extension
2634
 *   when creating the stand-alone game.
2635
 *   
2636
 *   This routine is not required if the system does not use the standard,
2637
 *   semi-portable os0.c implementation.  Even if the system uses the
2638
 *   standard os0.c implementation, it can provide an empty routine here
2639
 *   if the system code doesn't need to do anything special with this
2640
 *   information.
2641
 *   
2642
 *   The extension is specified as a null-terminated string.  The
2643
 *   extension does NOT include the leading period.  
2644
 */
2645
void os_set_save_ext(const char *ext);
2646
2647
2648
/* ------------------------------------------------------------------------*/
2649
/*
2650
 *   Translate a character from the HTML 4 Unicode character set to the
2651
 *   current character set used for display.  Takes an HTML 4 character
2652
 *   code and returns the appropriate local character code.
2653
 *   
2654
 *   The result buffer should be filled in with a null-terminated string
2655
 *   that should be used to represent the character.  Multi-character
2656
 *   results are possible, which may be useful for certain approximations
2657
 *   (such as using "(c)" for the copyright symbol).
2658
 *   
2659
 *   Note that we only define this prototype if this symbol isn't already
2660
 *   defined as a macro, which may be the case on some platforms.
2661
 *   Alternatively, if the function is already defined (for example, as an
2662
 *   inline function), the defining code can define OS_XLAT_HTML4_DEFINED,
2663
 *   in which case we'll also omit this prototype.
2664
 *   
2665
 *   Important: this routine provides the *default* mapping that is used
2666
 *   when no external character mapping file is present, and for any named
2667
 *   entities not defined in the mapping file.  Any entities in the
2668
 *   mapping file, if used, will override this routine.
2669
 *   
2670
 *   A trivial implementation of this routine (that simply returns a
2671
 *   one-character result consisting of the original input character,
2672
 *   truncated to eight bits if necessary) can be used if you want to
2673
 *   require an external mapping file to be used for any game that
2674
 *   includes HTML character entities.  The DOS version implements this
2675
 *   routine so that games will still look reasonable when played with no
2676
 *   mapping file present, but other systems are not required to do this.  
2677
 */
2678
#ifndef os_xlat_html4
2679
# ifndef OS_XLAT_HTML4_DEFINED
2680
void os_xlat_html4(unsigned int html4_char,
2681
                   char *result, size_t result_buf_len);
2682
# endif
2683
#endif
2684
2685
/*
2686
 *   Generate a filename for a character-set mapping file.  This function
2687
 *   should determine the current native character set in use, if
2688
 *   possible, then generate a filename, according to system-specific
2689
 *   conventions, that we should attempt to load to get a mapping between
2690
 *   the current native character set and the internal character set
2691
 *   identified by 'internal_id'.
2692
 *   
2693
 *   The internal character set ID is a string of up to 4 characters.
2694
 *   
2695
 *   On DOS, the native character set is a DOS code page.  DOS code pages
2696
 *   are identified by 3- or 4-digit identifiers; for example, code page
2697
 *   437 is the default US ASCII DOS code page.  We generate the
2698
 *   character-set mapping filename by appending the internal character
2699
 *   set identifier to the DOS code page number, then appending ".TCP" to
2700
 *   the result.  So, to map between ISO Latin-1 (internal ID = "La1") and
2701
 *   DOS code page 437, we would generate the filename "437La1.TCP".
2702
 *   
2703
 *   Note that this function should do only two things.  First, determine
2704
 *   the current native character set that's in use.  Second, generate a
2705
 *   filename based on the current native code page and the internal ID.
2706
 *   This function is NOT responsible for figuring out the mapping or
2707
 *   anything like that -- it's simply where we generate the correct
2708
 *   filename based on local convention.
2709
 *   
2710
 *   'filename' is a buffer of at least OSFNMAX characters.
2711
 *   
2712
 *   'argv0' is the executable filename from the original command line.
2713
 *   This parameter is provided so that the system code can look for
2714
 *   mapping files in the original TADS executables directory, if desired.
2715
 */
2716
void os_gen_charmap_filename(char *filename, char *internal_id,
2717
                             char *argv0);
2718
2719
/*
2720
 *   Receive notification that a character mapping file has been loaded.
2721
 *   The caller doesn't require this routine to do anything at all; this
2722
 *   is purely for the system-dependent code's use so that it can take
2723
 *   care of any initialization that it must do after the caller has
2724
 *   loaded a charater mapping file.  'id' is the character set ID, and
2725
 *   'ldesc' is the display name of the character set.  'sysinfo' is the
2726
 *   extra system information string that is stored in the mapping file;
2727
 *   the interpretation of this information is up to this routine.
2728
 *   
2729
 *   For reference, the Windows version uses the extra information as a
2730
 *   code page identifier, and chooses its default font character set to
2731
 *   match the code page.  On DOS, the run-time requires the player to
2732
 *   activate an appropriate code page using a DOS command (MODE CON CP
2733
 *   SELECT) prior to starting the run-time, so this routine doesn't do
2734
 *   anything at all on DOS. 
2735
 */
2736
void os_advise_load_charmap(char *id, char *ldesc, char *sysinfo);
2737
2738
/*
2739
 *   Generate the name of the character set mapping table for Unicode
2740
 *   characters to and from the given local character set.  Fills in the
2741
 *   buffer with the implementation-dependent name of the desired
2742
 *   character set map.  See below for the character set ID codes.
2743
 *   
2744
 *   For example, on Windows, the implementation would obtain the
2745
 *   appropriate active code page (which is simply a Windows character set
2746
 *   identifier number) from the operating system, and build the name of
2747
 *   the Unicode mapping file for that code page, such as "CP1252".  On
2748
 *   Macintosh, the implementation would look up the current script system
2749
 *   and return the name of the Unicode mapping for that script system,
2750
 *   such as "ROMAN" or "CENTEURO".
2751
 *   
2752
 *   If it is not possible to determine the specific character set that is
2753
 *   in use, this function should return "asc7dflt" (ASCII 7-bit default)
2754
 *   as the character set identifier on an ASCII system, or an appropriate
2755
 *   base character set name on a non-ASCII system.  "asc7dflt" is the
2756
 *   generic character set mapping for plain ASCII characters.
2757
 *   
2758
 *   The given buffer must be at least 32 bytes long; the implementation
2759
 *   must limit the result it stores to 32 bytes.  (We use a fixed-size
2760
 *   buffer in this interface for simplicity, and because there seems no
2761
 *   need for greater flexibility in the interface; a character set name
2762
 *   doesn't carry very much information so shouldn't need to be very
2763
 *   long.  Note that this function doesn't generate a filename, but
2764
 *   simply a mapping name; in practice, a map name will be used to
2765
 *   construct a mapping file name.)
2766
 *   
2767
 *   Because this function obtains the Unicode mapping name, there is no
2768
 *   need to specify the internal character set to be used: the internal
2769
 *   character set is Unicode.  
2770
 */
2771
/*
2772
 *   Implementation note: when porting this routine, the convention that
2773
 *   you use to name your mapping files is up to you.  You should simply
2774
 *   choose a convention for this implementation, and then use the same
2775
 *   convention for packaging the mapping files for your OS release.  In
2776
 *   most cases, the best convention is to use the names that the Unicode
2777
 *   consortium uses in their published cross-mapping listings, since
2778
 *   these listings can be used as the basis of the mapping files that you
2779
 *   include with your release.  For example, on Windows, the convention
2780
 *   is to use the code page number to construct the map name, as in
2781
 *   CP1252 or CP1250.  
2782
 */
2783
void os_get_charmap(char *mapname, int charmap_id);
2784
2785
/*
2786
 *   Character map for the display (i.e., for the user interface).  This
2787
 *   is the character set which is used for input read from the keyboard,
2788
 *   and for output displayed on the monitor or terminal.  
2789
 */
2790
#define OS_CHARMAP_DISPLAY     1
2791
2792
/* 
2793
 *   Character map for mapping filename strings.  This should identify the
2794
 *   character set currently in use on the local system for filenames
2795
 *   (i.e., for strings identifying objects in the local file system),
2796
 *   providing a suitable name for use in opening a mapping file.
2797
 *   
2798
 *   On many platforms, the entire system uses only one character set at
2799
 *   the OS level, so the file system character set is the same as the
2800
 *   display character set.  Some systems define a particular character
2801
 *   set for file system use, though, because different users might be
2802
 *   running applications on terminals that display different character
2803
 *   sets.  
2804
 */
2805
#define OS_CHARMAP_FILENAME    2
2806
2807
/*
2808
 *   Default character map for file contents.  On most systems, this will
2809
 *   be the same as display.  On some systems, it won't be possible to
2810
 *   know in general what character set files use; in fact, this isn't
2811
 *   possible anywhere, since a file might have been copied without
2812
 *   translation from a different type of computer using a different
2813
 *   character set.  So, this isn't meant to provide a reliable choice of
2814
 *   character set for any arbitrary file; it's simply meant to be a good
2815
 *   guess that most files on this system are likely to use.  
2816
 */
2817
#define OS_CHARMAP_FILECONTENTS  3
2818
2819
2820
/* ------------------------------------------------------------------------ */
2821
/*
2822
 *   External Banner Interface.  This interface provides the ability to
2823
 *   divide the display window into multiple sub-windows, each with its own
2824
 *   independent contents.
2825
 *   
2826
 *   To determine where a new banner is displayed, we look at the banners as
2827
 *   a tree, rooted at the "main window," the special banner that the system
2828
 *   automatically creates initially for the main game text.  We start by
2829
 *   allocating the entire display (or the entire application window, if
2830
 *   we're running on a GUI system) to the main window.  We then traverse
2831
 *   the tree, starting with the root window's children.  For each child
2832
 *   window, we allocate space for the child out of the parent window's
2833
 *   area, according to the child's alignment and size settings, and deduct
2834
 *   this space from the parent window's size.  We then lay out the children
2835
 *   of the child.
2836
 *   
2837
 *   For each banner window, we take its requested space out of the parent
2838
 *   window's area by starting at the edge of the parent window rectangle as
2839
 *   indicated by the banner's alignment, and taking the requested `width
2840
 *   (for a left/right banner) or height (for a top/bottom banner), limiting
2841
 *   to the available width/height in the parent window's space.  Give the
2842
 *   banner the full extent of the parent's space in its other dimension (so
2843
 *   a left/right banner gets the full height of the parent space, and a
2844
 *   top/bottom banner gets the full width).
2845
 *   
2846
 *   Note that the layout proceeds exclusively down the tree (i.e., from the
2847
 *   root to children to grandchildren, and so on).  It *appears* that a
2848
 *   child affects its parent, because of the deduction step: a child
2849
 *   acquires screen space by carving out a chunk of its parent.  The right
2850
 *   way to think about this, though, is that the parent's full area is the
2851
 *   union of the parent window and all of its children; when viewed this
2852
 *   way, the parent's full area is fully determined the instant the parent
2853
 *   is laid out, and never changes as its children are laid out.  Note in
2854
 *   particular that a child can never make a parent larger; the only thing
2855
 *   a child can do to a parent is carve out a chunk of the parent for
2856
 *   itself, which doesn't affect the boundaries of the union of the parent
2857
 *   plus its children.
2858
 *   
2859
 *   Note also that if the banner has a border, and the implementation
2860
 *   actually draws borders, the border must be drawn for the *full* area of
2861
 *   the banner, as defined above.  For example, suppose we have two
2862
 *   borders: banner A is a child of the main window, is top-aligned, and
2863
 *   has a border.  Banner B is a child of banner A, right-aligned, with no
2864
 *   border.  Obviously, without considering banner B, banner A's space runs
2865
 *   across the entire width of the main window, so its border (at the
2866
 *   bottom of its area) runs across the entire width of the main window.
2867
 *   Banner B carves out some space from A's right side for itself, so
2868
 *   banner A's actual on-screen area runs from the left edge of the main
2869
 *   window to banner B's left edge.  However, even though banner A itself
2870
 *   no longer runs the full width of the main window, banner A's *full*
2871
 *   area - that is, the union of banner A's on-screen area and all of its
2872
 *   children's full areas - does still run the entire width of the main
2873
 *   window, hence banner A's border must still run the full width of the
2874
 *   main window.  The simple way of looking at this is that a banner's
2875
 *   border is always to be drawn exactly the same way, regardless of
2876
 *   whether or not the banner has children - simply draw the banner as it
2877
 *   would be drawn if the banner had no children.
2878
 *   
2879
 *   Each time a banner is added or removed, we must recalculate the layout
2880
 *   of the remaining banners and main text area.  The os_banner_xxx()
2881
 *   implementation is responsible for this layout refiguring.
2882
 *   
2883
 *   The entire external banner window interface is optional, although the
2884
 *   functions must at least be defined as dummies to avoid linker errors
2885
 *   when building.  If a platform doesn't implement this feature,
2886
 *   os_banner_create() should simply return null, and the other routines
2887
 *   can do nothing.  
2888
 */
2889
2890
/* 
2891
 *   Create a banner window.  'info' gives the desired parameters for the new
2892
 *   banner.
2893
 *   
2894
 *   Note that certain requested parameter settings might or might not be
2895
 *   respected, depending on the capabilities of the platform and user
2896
 *   preferences.  os_banner_getinfo() can be used after creation to
2897
 *   determine which parameter settings are actually used in the new banner.
2898
 *   
2899
 *   'parent' gives the parent of this banner; this is the banner handle of
2900
 *   another banner window, or null.  If 'parent' is null, then the new
2901
 *   banner is a child of the main window, which the system creates
2902
 *   automatically at startup and which contains the main input/output
2903
 *   transcript.  The new banner's on-screen area is carved out of the
2904
 *   parent's space, according to the alignment and size settings of the new
2905
 *   window, so this determines how the window is laid out on the screen.
2906
 *   
2907
 *   'where' is OS_BANNER_FIRST to make the new window the first child of its
2908
 *   parent; OS_BANNER_LAST to make it the last child of its parent;
2909
 *   OS_BANNER_BEFORE to insert it immediately before the existing banner
2910
 *   identified by handle in 'other'; or OS_BANNER_AFTER to insert
2911
 *   immediately after 'other'.  When BEFORE or AFTER is used, 'other' must
2912
 *   be another child of the same parent; if it is not, the routine should
2913
 *   act as though 'where' were given as OS_BANNER_LAST.
2914
 *   
2915
 *   'other' is a banner handle for an existing banner window.  This is used
2916
 *   to specify the relative position among children of the new banner's
2917
 *   parent, if 'where' is either OS_BANNER_BEFORE or OS_BANNER_AFTER.  If
2918
 *   'where' is OS_BANNER_FIRST or OS_BANNER_LAST, 'other' is ignored.
2919
 *   
2920
 *   'wintype' is the type of the window.  This is one of the
2921
 *   OS_BANNER_TYPE_xxx codes indicating what kind of window is desired.
2922
 *   
2923
 *   'align' is the banner's alignment, given as an OS_BANNER_ALIGN_xxx
2924
 *   value.  Top/bottom banners are horizontal: they run across the full
2925
 *   width of the existing main text area.  Left/right banners are vertical:
2926
 *   they run down the full height of the existing main text area.
2927
 *   
2928
 *   'siz' is the requested size of the new banner.  The meaning of 'siz'
2929
 *   depends on the value of 'siz_units', which can be OS_BANNER_SIZE_PCT to
2930
 *   set the size as a percentage of the REMAINING space, or
2931
 *   OS_BANNER_SIZE_ABS to set an absolute size in the "natural" units of the
2932
 *   window.  The natural units vary by window type: for text and text grid
2933
 *   windows, this is in rows/columns of '0' characters in the default font
2934
 *   for the window.  Note that when OS_BANNER_SIZE_ABS is used in a text or
2935
 *   text grid window, the OS implementation MUST add the space needed for
2936
 *   margins and borders when determining the actual pixel size of the
2937
 *   window; in other words, the window should be large enough that it can
2938
 *   actually display the given number or rows or columns.
2939
 *   
2940
 *   The size is interpreted as a width or height according to the window's
2941
 *   orientation.  For a TOP or BOTTOM banner, the size is the height; for a
2942
 *   LEFT or RIGHT banner, the size is the width.  A banner has only one
2943
 *   dimension's size given, since the other dimension's size is determined
2944
 *   automatically by the layout rules.
2945
 *   
2946
 *   Note that the window's size can be changed later using
2947
 *   banner_size_to_contents() or banner_set_size().
2948
 *   
2949
 *   'style' is a combination of OS_BANNER_STYLE_xxx flags - see below.  The
2950
 *   style flags give the REQUESTED style for the banner, which might or
2951
 *   might not be respected, depending on the platform's capabilities, user
2952
 *   preferences, and other factors.  os_banner_getinfo() can be used to
2953
 *   determine which style flags are actually used.
2954
 *   
2955
 *   Returns the "handle" to the new banner window, which is an opaque value
2956
 *   that is used in subsequent os_banner_xxx calls to operate on the window.
2957
 *   Returns null if the window cannot be created.  An implementation is not
2958
 *   required to support this functionality at all, and can subset it if it
2959
 *   does support it (for example, an implementation could support only
2960
 *   top/bottom-aligned banners, but not left/right-aligned), so callers must
2961
 *   be prepared for this routine to return null.  
2962
 */
2963
void *os_banner_create(void *parent, int where, void *other, int wintype,
2964
                       int align, int siz, int siz_units,
2965
                       unsigned long style);
2966
2967
2968
/*
2969
 *   insertion positions 
2970
 */
2971
#define OS_BANNER_FIRST   1
2972
#define OS_BANNER_LAST    2
2973
#define OS_BANNER_BEFORE  3
2974
#define OS_BANNER_AFTER   4
2975
2976
/*
2977
 *   banner types 
2978
 */
2979
2980
/* 
2981
 *   Normal text stream window.  This is a text stream that behaves
2982
 *   essentially like the main text window: text is displayed to this
2983
 *   through os_banner_disp(), always in a stream-like fashion by adding new
2984
 *   text to the end of any exiting text.
2985
 *   
2986
 *   Systems that use proportional fonts should usually simply use the same
2987
 *   font they use by default in the main text window.  However, note that
2988
 *   the OS_BANNER_STYLE_TAB_ALIGN style flag might imply that a fixed-pitch
2989
 *   font should be used even when proportional fonts are available, because
2990
 *   a fixed-pitch font will allow the calling code to rely on using spaces
2991
 *   to align text within the window.  
2992
 */
2993
#define OS_BANNER_TYPE_TEXT       1
2994
2995
/* 
2996
 *   "Text grid" window.  This type of window is similar to an normal text
2997
 *   window (OS_BANNER_TYPE_TEXT), but is guaranteed to arrange its text in
2998
 *   a regular grid of character cells, all of the same size.  This means
2999
 *   that the output position can be moved to an arbitrary point within the
3000
 *   window at any time, so the calling program can precisely control the
3001
 *   layout of the text in the window.
3002
 *   
3003
 *   Because the output position can be moved to arbitrary positions in the
3004
 *   window, it is possible to overwrite text previously displayed.  When
3005
 *   this happens, the old text is completely obliterated by the new text,
3006
 *   leaving no trace of the overwritten text.
3007
 *   
3008
 *   In order to guarantee that character cells are all the same size, this
3009
 *   type of window does not allow any text attributes.  The implementation
3010
 *   should simply ignore any attempts to change text attributes in this
3011
 *   type of window.  However, colors can be used to the same degree they
3012
 *   can be used in an ordinary text window.
3013
 *   
3014
 *   To guarantee the regular spacing of character cells, all
3015
 *   implementations must use fixed-pitch fonts for these windows.  This
3016
 *   applies even to platforms where proportional fonts are available.  
3017
 */
3018
#define OS_BANNER_TYPE_TEXTGRID   2
3019
3020
3021
/* 
3022
 *   banner alignment types 
3023
 */
3024
#define OS_BANNER_ALIGN_TOP       0
3025
#define OS_BANNER_ALIGN_BOTTOM    1
3026
#define OS_BANNER_ALIGN_LEFT      2
3027
#define OS_BANNER_ALIGN_RIGHT     3
3028
3029
/*
3030
 *   size units 
3031
 */
3032
#define OS_BANNER_SIZE_PCT  1
3033
#define OS_BANNER_SIZE_ABS  2
3034
3035
3036
/* 
3037
 *   banner style flags 
3038
 */
3039
3040
/* 
3041
 *   The banner has a visible border; this indicates that a line is to be
3042
 *   drawn to separate the banner from the adjacent window or windows
3043
 *   "inside" the banner.  So, a top-aligned banner will have its border
3044
 *   drawn along its bottom edge; a left-aligned banner will show a border
3045
 *   along its right edge; and so forth.
3046
 *   
3047
 *   Note that character-mode platforms generally do NOT respect the border
3048
 *   style, since doing so takes up too much screen space.  
3049
 */
3050
#define OS_BANNER_STYLE_BORDER     0x00000001
3051
3052
/*
3053
 *   The banner has a vertical/horizontal scrollbar.  Character-mode
3054
 *   platforms generally do not support scrollbars.  
3055
 */
3056
#define OS_BANNER_STYLE_VSCROLL    0x00000002
3057
#define OS_BANNER_STYLE_HSCROLL    0x00000004
3058
3059
/* 
3060
 *   Automatically scroll the banner vertically/horizontally whenever new
3061
 *   text is displayed in the window.  In other words, whenever
3062
 *   os_banner_disp() is called, scroll the window so that the text that the
3063
 *   new cursor position after the new text is displayed is visible in the
3064
 *   window.
3065
 *   
3066
 *   Note that this style is independent of the presence of scrollbars.
3067
 *   Even if there are no scrollbars, we can still scroll the window's
3068
 *   contents programmatically.
3069
 *   
3070
 *   Implementations can, if desired, keep an internal buffer of the
3071
 *   window's contents, so that the contents can be recalled via the
3072
 *   scrollbars if the text displayed in the banner exceeds the space
3073
 *   available in the banner's window on the screen.  If the implementation
3074
 *   does keep such a buffer, we recommend the following method for managing
3075
 *   this buffer.  If the AUTO_VSCROLL flag is not set, then the banner's
3076
 *   contents should be truncated at the bottom when the contents overflow
3077
 *   the buffer; that is, once the banner's internal buffer is full, any new
3078
 *   text that the calling program attempts to add to the banner should
3079
 *   simply be discarded.  If the AUTO_VSCROLL flag is set, then the OLDEST
3080
 *   text should be discarded instead, so that the most recent text is
3081
 *   always retained.  
3082
 */
3083
#define OS_BANNER_STYLE_AUTO_VSCROLL 0x00000008
3084
#define OS_BANNER_STYLE_AUTO_HSCROLL 0x00000010
3085
3086
/*
3087
 *   Tab-based alignment is required/supported.  On creation, this is a hint
3088
 *   to the implementation that is sometimes necessary to determine what
3089
 *   kind of font to use in the new window, for non-HTML platforms.  If this
3090
 *   flag is set on creation, the caller is indicating that it wants to use
3091
 *   <TAB> tags to align text in the window.
3092
 *   
3093
 *   Character-mode implementations that use a single font with fixed pitch
3094
 *   can simply ignore this.  These implementations ALWAYS have a working
3095
 *   <TAB> capability, because the portable output formatter provides <TAB>
3096
 *   interpretation for a fixed-pitch window.
3097
 *   
3098
 *   Full HTML TADS implementations can also ignore this.  HTML TADS
3099
 *   implementations always have full <TAB> support via the HTML
3100
 *   parser/renderer.
3101
 *   
3102
 *   Text-only implementations on GUI platforms (i.e., implementations that
3103
 *   are not based on the HTML parser/renderer engine in HTML TADS, but
3104
 *   which run on GUI platforms with proportionally-spaced text) should use
3105
 *   this flag to determine the font to display.  If this flag is NOT set,
3106
 *   then the caller doesn't care about <TAB>, and the implementation is
3107
 *   free to use a proportionally-spaced font in the window if desired.
3108
 *   
3109
 *   When retrieving information on an existing banner, this flag indicates
3110
 *   that <TAB> alignment is actually supported on the window.  
3111
 */
3112
#define OS_BANNER_STYLE_TAB_ALIGN 0x00000020
3113
3114
/*
3115
 *   Use "MORE" mode in this window.  By default, a banner window should
3116
 *   happily allow text to overflow the vertical limits of the window; the
3117
 *   only special thing that should happen on overflow is that the window
3118
 *   should be srolled down to show the latest text, if the auto-vscroll
3119
 *   style is set.  With this flag, though, a banner window acts just like
3120
 *   the main text window: when the window fills up vertically, we show a
3121
 *   MORE prompt (using appropriate system conventions), and wait for the
3122
 *   user to indicate that they're ready to see more text.  On most systems,
3123
 *   the user acknowledges a MORE prompt by pressing a key or scrolling with
3124
 *   the mouse, but it's up to the system implementor to decide what's
3125
 *   appropriate for the system.
3126
 *   
3127
 *   Note that MORE mode in ANY banner window should generally override all
3128
 *   other user input focus.  In other words, if the game in the main window
3129
 *   would like to read a keystroke from the user, but one of the banner
3130
 *   windows is pausing with a MORE prompt, any keyboard input should be
3131
 *   directed to the banner paused at the MORE prompt, not to the main
3132
 *   window; the main window should not receive any key events until the MORE
3133
 *   prompt has been removed.
3134
 *   
3135
 *   This style requires the auto-vscroll style.  Implementations should
3136
 *   assume auto-vscroll when this style is set.  This style can be ignored
3137
 *   with text grid windows.  
3138
 */
3139
#define OS_BANNER_STYLE_MOREMODE  0x00000040
3140
3141
/*
3142
 *   This banner is a horizontal/vertical "strut" for sizing purposes.  This
3143
 *   means that the banner's content size is taken into account when figuring
3144
 *   the content size of its *parent* banner.  If the banner has the same
3145
 *   orientation as the parent, its content size is added to its parent's
3146
 *   internal content size to determine the parent's overall content size.
3147
 *   If the banner's orientation is orthogonal to the parent's, then the
3148
 *   parent's overall content size is the larger of the parent's internal
3149
 *   content size and this banner's content size.  
3150
 */
3151
#define OS_BANNER_STYLE_HSTRUT    0x00000080
3152
#define OS_BANNER_STYLE_VSTRUT    0x00000100
3153
3154
3155
/* 
3156
 *   Delete a banner.  This removes the banner from the display, which
3157
 *   requires recalculating the entire screen's layout to reallocate this
3158
 *   banner's space to other windows.  When this routine returns, the banner
3159
 *   handle is invalid and can no longer be used in any os_banner_xxx
3160
 *   function calls.  
3161
 *   
3162
 *   If the banner has children, the children will no longer be displayed,
3163
 *   but will remain valid in memory until deleted.  A child window's
3164
 *   display area always comes out of its parent's space, so once the parent
3165
 *   is gone, a child has no way to acquire any display space; resizing the
3166
 *   child won't help, since it simply has no way to obtain any screen space
3167
 *   once its parent has been deleted.  Even though the window's children
3168
 *   will become invisible, their banner handles will remain valid; the
3169
 *   caller is responsible for explicitly deleting the children even after
3170
 *   deleting their parent.  
3171
 */
3172
void os_banner_delete(void *banner_handle);
3173
3174
/*
3175
 *   "Orphan" a banner.  This tells the osifc implementation that the caller
3176
 *   wishes to sever all of its ties with the banner (as part of program
3177
 *   termination, for example), but that the calling program does not
3178
 *   actually require that the banner's on-screen display be immediately
3179
 *   removed.
3180
 *   
3181
 *   The osifc implementation can do one of two things:
3182
 *   
3183
 *   1.  Simply call os_banner_delete().  If the osifc implementation
3184
 *   doesn't want to do anything extra with the banner, it can simply delete
3185
 *   the banner, since the caller has no more use for it.
3186
 *   
3187
 *   2.  Take ownership of the banner.  If the osifc implementation wishes
3188
 *   to continue displaying the final screen configuration after a program
3189
 *   has terminated, it can simply take over the banner and leave it on the
3190
 *   screen.  The osifc subsystem must eventually delete the banner itself
3191
 *   if it takes this routine; for example, if the osifc subsystem allows
3192
 *   another client program to be loaded into the same window after a
3193
 *   previous program has terminated, it would want to delete any orphaned
3194
 *   banners from the previous program when loading a new program.  
3195
 */
3196
void os_banner_orphan(void *banner_handle);
3197
3198
/*
3199
 *   Banner information structure.  This is filled in by the system-specific
3200
 *   implementation in os_banner_getinfo().  
3201
 */
3202
struct os_banner_info_t
3203
{
3204
    /* alignment */
3205
    int align;
3206
3207
    /* style flags - these indicate the style flags actually in use */
3208
    unsigned long style;
3209
3210
    /* 
3211
     *   Actual on-screen size of the banner, in rows and columns.  If the
3212
     *   banner is displayed in a proportional font or can display multiple
3213
     *   fonts of different sizes, this is approximated by the number of "0"
3214
     *   characters in the window's default font that will fit in the
3215
     *   window's display area.  
3216
     */
3217
    int rows;
3218
    int columns;
3219
3220
    /*
3221
     *   Actual on-screen size of the banner in pixels.  This is meaningful
3222
     *   only for full HTML interpreter; for text-only interpreters, these
3223
     *   are always set to zero.
3224
     *   
3225
     *   Note that even if we're running on a GUI operating system, these
3226
     *   aren't meaningful unless this is a full HTML interpreter.  Text-only
3227
     *   interpreters should always set these to zero, even on GUI OS's.  
3228
     */
3229
    int pix_width;
3230
    int pix_height;
3231
3232
    /* 
3233
     *   OS line wrapping flag.  If this is set, the window uses OS-level
3234
     *   line wrapping because the window uses a proportional font, so the
3235
     *   caller does not need to (and should not) perform line breaking in
3236
     *   text displayed in the window.
3237
     *   
3238
     *   Note that OS line wrapping is a PERMANENT feature of the window.
3239
     *   Callers can note this information once and expect it to remain
3240
     *   fixed through the window's lifetime.  
3241
     */
3242
    int os_line_wrap;
3243
};
3244
typedef struct os_banner_info_t os_banner_info_t;
3245
3246
/* 
3247
 *   Get information on the banner - fills in the information structure with
3248
 *   the banner's current settings.  Note that this should indicate the
3249
 *   ACTUAL properties of the banner, not the requested properties; this
3250
 *   allows callers to determine how the banner is actually displayed, which
3251
 *   depends upon the platform's capabilities and user preferences.
3252
 *   
3253
 *   Returns true if the information was successfully obtained, false if
3254
 *   not.  This can return false if the underlying OS window has already
3255
 *   been closed by a user action, for example.  
3256
 */
3257
int os_banner_getinfo(void *banner_handle, os_banner_info_t *info);
3258
3259
/* 
3260
 *   Get the character width/height of the banner, for layout purposes.  This
3261
 *   gives the size of the banner in character cells.
3262
 *   
3263
 *   These are not meaningful when the underlying window uses a proportional
3264
 *   font or varying fonts of different sizes.  When the size of text varies
3265
 *   in the window, the OS layer is responsible for word-wrapping and other
3266
 *   layout, in which case these simply return zero.
3267
 *   
3268
 *   Note that these routines might appear to be redundant with the 'rows'
3269
 *   and 'columns' information returned from os_banner_getinfo(), but these
3270
 *   have two important distinctions.  First, these routines return only the
3271
 *   width and height information, so they can be implemented with less
3272
 *   overhead than os_banner_getinfo(); this is important because formatters
3273
 *   might need to call these routines frequently while formatting text.
3274
 *   Second, these routines are not required to return an approximation for
3275
 *   windows using proportional fonts, as os_banner_getinfo() does; these can
3276
 *   simply return zero when a proportional font is in use.  
3277
 */
3278
int os_banner_get_charwidth(void *banner_handle);
3279
int os_banner_get_charheight(void *banner_handle);
3280
3281
/* clear the contents of a banner */
3282
void os_banner_clear(void *banner_handle);
3283
3284
/* 
3285
 *   Display output on a banner.  Writes the output to the window on the
3286
 *   display at the current output position.
3287
 *   
3288
 *   The following special characters should be recognized and handled:
3289
 *   
3290
 *   '\n' - newline; move output position to the start of the next line.
3291
 *   
3292
 *   '\r' - move output position to start of current line; subsequent text
3293
 *   overwrites any text previously displayed on the current line.  It is
3294
 *   permissible to delete the old text immediately on seeing the '\r',
3295
 *   rather than waiting for additional text to actually overwrite it.
3296
 *   
3297
 *   All other characters should simply be displayed as ordinary printing
3298
 *   text characters.  Note that tab characters should not be passed to this
3299
 *   routine, but if they are, they can simply be treated as ordinary spaces
3300
 *   if desired.  Other control characters (backspace, escape, etc) should
3301
 *   never be passed to this routine; the implementation is free to ignore
3302
 *   any control characters not listed above.
3303
 *   
3304
 *   If any text displayed here overflows the current boundaries of the
3305
 *   window on the screen, the text MUST be "clipped" to the current window
3306
 *   boundaries; in other words, anything this routine tries to display
3307
 *   outside of the window's on-screen rectangle must not actually be shown
3308
 *   on the screen.
3309
 *   
3310
 *   Text overflowing the display boundaries MUST also be retained in an
3311
 *   internal buffer.  This internal buffer can be limited to the actual
3312
 *   maximum display size of the terminal screen or application window, if
3313
 *   desired.  It is necessary to retain clipped text, because this allows a
3314
 *   window to be expanded to the size of its contents AFTER the contents
3315
 *   have already been displayed.
3316
 *   
3317
 *   If the banner does its own line wrapping, it must indicate this via the
3318
 *   os_line_wrap flag in the os_banner_getinfo() return data.  If the
3319
 *   banner doesn't indicate this flag, then it must not do any line
3320
 *   wrapping at all, even if the caller attempts to write text beyond the
3321
 *   right edge of the window - any text overflowing the width of the window
3322
 *   must simply be clipped.
3323
 *   
3324
 *   Text grid banners must ALWAYS clip - these banners should never perform
3325
 *   any line wrapping.  
3326
 */
3327
void os_banner_disp(void *banner_handle, const char *txt, size_t len);
3328
3329
/*
3330
 *   Set the text attributes in a banner, for subsequent text displays.
3331
 *   'attr' is a (bitwise-OR'd) combination of OS_ATTR_xxx values. 
3332
 */
3333
void os_banner_set_attr(void *banner_handle, int attr);
3334
3335
/* 
3336
 *   Set the text color in a banner, for subsequent text displays.  The 'fg'
3337
 *   and 'bg' colors are given as RGB or parameterized colors; see the
3338
 *   definition of os_color_t for details.
3339
 *   
3340
 *   If the underlying renderer is HTML-enabled, then this should not be
3341
 *   used; the appropriate HTML code should simply be displayed to the
3342
 *   banner instead.  
3343
 */
3344
void os_banner_set_color(void *banner_handle, os_color_t fg, os_color_t bg);
3345
3346
/* 
3347
 *   Set the screen color in the banner - this is analogous to the screen
3348
 *   color in the main text area.
3349
 *   
3350
 *   If the underlying renderer is HTML-enabled, then this should not be
3351
 *   used; the HTML <BODY> tag should be used instead.  
3352
 */
3353
void os_banner_set_screen_color(void *banner_handle, os_color_t color);
3354
3355
/* flush output on a banner */
3356
void os_banner_flush(void *banner_handle);
3357
3358
/*
3359
 *   Set the banner's size.  The size has the same meaning as in
3360
 *   os_banner_create().
3361
 *   
3362
 *   'is_advisory' indicates whether the sizing is required or advisory only.
3363
 *   If this flag is false, then the size should be set as requested.  If
3364
 *   this flag is true, it means that the caller intends to call
3365
 *   os_banner_size_to_contents() at some point, and that the size being set
3366
 *   now is for advisory purposes only.  Platforms that support
3367
 *   size-to-contents may simply ignore advisory sizing requests, although
3368
 *   they might want to ensure that they have sufficient off-screen buffer
3369
 *   space to keep track of the requested size of display, so that the
3370
 *   information the caller displays in preparation for calling
3371
 *   size-to-contents will be retained.  Platforms that do not support
3372
 *   size-to-contents should set the requested size even when 'is_advisory'
3373
 *   is true.  
3374
 */
3375
void os_banner_set_size(void *banner_handle, int siz, int siz_units,
3376
                        int is_advisory);
3377
3378
/* 
3379
 *   Set the banner to the size of its current contents.  This can be used
3380
 *   to set the banner's size after some text (or other material) has been
3381
 *   displayed to the banner, so that the size can be set according to the
3382
 *   banner's actual space requirements.
3383
 *   
3384
 *   This changes the banner's "requested size" to match the current size.
3385
 *   Subsequent calls to os_banner_getinfo() will thus indicate a requested
3386
 *   size according to the size set here.  
3387
 */
3388
void os_banner_size_to_contents(void *banner_handle);
3389
3390
/* 
3391
 *   Turn HTML mode on/off in the banner window.  If the underlying renderer
3392
 *   doesn't support HTML, these have no effect.  
3393
 */
3394
void os_banner_start_html(void *banner_handle);
3395
void os_banner_end_html(void *banner_handle);
3396
3397
/*
3398
 *   Set the output coordinates in a text grid window.  The grid window is
3399
 *   arranged into character cells numbered from row zero, column zero for
3400
 *   the upper left cell.  This function can only be used if the window was
3401
 *   created with type OS_BANNER_TYPE_TEXTGRID; the request should simply be
3402
 *   ignored by other window types.
3403
 *   
3404
 *   Moving the output position has no immediate effect on the display, and
3405
 *   does not itself affect the "content size" for the purposes of
3406
 *   os_banner_size_to_contents().  This simply sets the coordinates where
3407
 *   any subsequent text is displayed.  
3408
 */
3409
void os_banner_goto(void *banner_handle, int row, int col);
3410
3411
3412
/* ------------------------------------------------------------------------ */
3413
/*
3414
 *   Get system information.  'code' is a SYSINFO_xxx code, which
3415
 *   specifies what type of information to get.  The 'param' argument's
3416
 *   meaning depends on which code is selected.  'result' is a pointer to
3417
 *   an integer that is to be filled in with the result value.  If the
3418
 *   code is not known, this function should return FALSE.  If the code is
3419
 *   known, the function should fill in *result and return TRUE.
3420
 */
3421
int os_get_sysinfo(int code, void *param, long *result);
3422
3423
/* determine if systemInfo is supported - os_get_sysinfo never gets this */
3424
#define SYSINFO_SYSINFO   1
3425
3426
/* get interpreter version number - os_get_sysinfo never gets this */
3427
#define SYSINFO_VERSION   2
3428
3429
/* get operating system name - os_get_sysinfo never gets this */
3430
#define SYSINFO_OS_NAME   3
3431
3432
/* 
3433
 *   Can the system process HTML directives?  returns 1 if so, 0 if not.
3434
 *   Note that if this returns false, then all of the codes below from
3435
 *   JPEG to LINKS are implicitly false as well, since TADS can only use
3436
 *   images, sounds, and links through HTML. 
3437
 */
3438
#define SYSINFO_HTML      4
3439
3440
/* can the system display JPEG's?  1 if yes, 0 if no */
3441
#define SYSINFO_JPEG      5
3442
3443
/* can the system display PNG's?  1 if yes, 0 if no */
3444
#define SYSINFO_PNG       6
3445
3446
/* can the system play WAV's?  1 if yes, 0 if no */
3447
#define SYSINFO_WAV       7
3448
3449
/* can the system play MIDI's?  1 if yes, 0 if no */
3450
#define SYSINFO_MIDI      8
3451
3452
/* can the system play MIDI and WAV's simultaneously?  yes=1, no=0 */
3453
#define SYSINFO_WAV_MIDI_OVL  9
3454
3455
/* can the system play multiple WAV's simultaneously?  yes=1, no=0 */
3456
#define SYSINFO_WAV_OVL   10
3457
3458
/*
3459
 *   GENERAL NOTES ON PREFERENCE SETTINGS:
3460
 *   
3461
 *   Several of the selectors below refer to the preference settings.  We're
3462
 *   talking about user-settable options to control various aspects of the
3463
 *   interpreter.  The conventional GUI for this kind of thing is a dialog
3464
 *   box reachable through a menu command named something like "Options" or
3465
 *   "Preferences".  A couple of general notes about these:
3466
 *   
3467
 *   1.  The entire existence of a preferences mechanism is optional -
3468
 *   interpreter writers aren't required to implement anything along these
3469
 *   lines.  In some cases the local platforms might not have any suitable
3470
 *   conventions for a preferences UI (e.g., character-mode console
3471
 *   applications), and in other cases the terp developer might just want to
3472
 *   omit a prefs mechanism because of the work involved to implement it, or
3473
 *   to keep the UI simpler.
3474
 *   
3475
 *   2.  If a given SYSINFO_PREF_xxx selector refers to a preference item
3476
 *   that's not implemented in the local interpreter, the terp should simply
3477
 *   return a suitable default result.  For example, if the interpreter
3478
 *   doesn't have a preference item to allow the user to turn sounds off, the
3479
 *   selector SYSINFO_PREF_SOUNDS should return 1 to indicate that the user
3480
 *   has not in fact turned off sounds (because there's no way to do so).
3481
 *   
3482
 *   3.  The various SYSINFO_PREF_xxx selectors are purely queries - they're
3483
 *   NOT a mechanism for enforcing the preferences.  For example, if the
3484
 *   interpreter provides a "Sounds On/Off" option, it's up to the terp to
3485
 *   enforce it the Off setting by ignoring any sound playback requests.  The
3486
 *   game isn't under any obligation to query any of the preferences or to
3487
 *   alter its behavior based on their settings - you should expect that the
3488
 *   game will go on trying to play sounds even when "Sounds Off" is selected
3489
 *   in the preferences.  The purpose of these SYSINFO selectors is to let
3490
 *   the game determine the current presentation status, but *only if it
3491
 *   cares*.  For example, the game might determine whether or not sounds are
3492
 *   actually being heard just before playing a sound effect that's important
3493
 *   to the progress of the game, so that it can provide a visual alternative
3494
 *   if the effect won't be heard.  
3495
 */
3496
3497
/* 
3498
 *   Get image preference setting - 1 = images can be displayed, 0 = images
3499
 *   are not being displayed because the user turned off images in the
3500
 *   preferences.  This is, of course, irrelevant if images can't be
3501
 *   displayed at all.
3502
 *   
3503
 *   See the general notes on preferences queries above.  
3504
 */
3505
#define SYSINFO_PREF_IMAGES  11
3506
3507
/*
3508
 *   Get digitized sound effect (WAV) preference setting - 1 = sounds can be
3509
 *   played, 0 = sounds are not being played because the user turned off
3510
 *   sounds in the preferences.
3511
 *   
3512
 *   See the general notes on preferences queries above.  
3513
 */
3514
#define SYSINFO_PREF_SOUNDS  12
3515
3516
/*
3517
 *   Get music (MIDI) preference setting - 1 = music can be played, 0 = music
3518
 *   is not being played because the user turned off music in the
3519
 *   preferences.
3520
 *   
3521
 *   See the general notes on preferences queries above.  
3522
 */
3523
#define SYSINFO_PREF_MUSIC   13
3524
3525
/*
3526
 *   Get link display preference setting - 0 = links are not being displayed
3527
 *   because the user set a preference item that suppresses all links (which
3528
 *   doesn't actually hide them, but merely displays them and otherwise
3529
 *   treats them as ordinary text).  1 = links are to be displayed normally.
3530
 *   2 = links can be displayed temporarily by the user by pressing a key or
3531
 *   some similar action, but aren't being displayed at all times.  
3532
 *   
3533
 *   See the general note on preferences queries above.  
3534
 */
3535
#define SYSINFO_PREF_LINKS   14
3536
3537
/* can the system play MPEG sounds of any kind? */
3538
#define SYSINFO_MPEG         15
3539
3540
/* can the system play MPEG audio 2.0 layer I/II/III sounds? */
3541
#define SYSINFO_MPEG1        16
3542
#define SYSINFO_MPEG2        17
3543
#define SYSINFO_MPEG3        18
3544
3545
/* 
3546
 *   is the system *currently* in HTML mode?  os_get_sysinfo never gets
3547
 *   this code, since the portable output layer keeps track of this 
3548
 */
3549
#define SYSINFO_HTML_MODE    19
3550
3551
/* 
3552
 *   Does the system allow following external URL links of the various
3553
 *   types?  These return true if the system is capable of following these
3554
 *   types of hypertext links, false if not.  Note that, if the system is
3555
 *   capable of following these links, these should return true regardless
3556
 *   of any current mode settings; in particular, these should not be
3557
 *   sensitive to the current HTML mode or the current link display mode,
3558
 *   since the question is not whether a link now displayed can be
3559
 *   followed by the user, but rather whether the system has the
3560
 *   capability to follow these types of links at all.  
3561
 */
3562
#define SYSINFO_LINKS_HTTP   20
3563
#define SYSINFO_LINKS_FTP    21
3564
#define SYSINFO_LINKS_NEWS   22
3565
#define SYSINFO_LINKS_MAILTO 23
3566
#define SYSINFO_LINKS_TELNET 24
3567
3568
/* is PNG transparency supported? */
3569
#define SYSINFO_PNG_TRANS    25
3570
3571
/* is PNG alpha blending supported? */
3572
#define SYSINFO_PNG_ALPHA    26
3573
3574
/* is the Ogg Vorbis audio format supported? */
3575
#define SYSINFO_OGG          27
3576
3577
/* can the system display MNG's? */
3578
#define SYSINFO_MNG          28
3579
3580
/* can the system display MNG's with transparency? */
3581
#define SYSINFO_MNG_TRANS    29
3582
3583
/* can the system display MNG's with alpha blending? */
3584
#define SYSINFO_MNG_ALPHA    30
3585
3586
/* can we display highlighted text in its own appearance? */
3587
#define SYSINFO_TEXT_HILITE  31
3588
3589
/* 
3590
 *   Can we display text colors?  This returns a SYSINFO_TXC_xxx code
3591
 *   indicating the level of color support.
3592
 *   
3593
 *   The os_xxx interfaces don't presently support anything beyond the ANSI
3594
 *   colors; however, HTML-enabled interpreters generally support full RGB
3595
 *   colors, so we call this out as a separate level.  
3596
 */
3597
#define SYSINFO_TEXT_COLORS  32
3598
3599
/* no text color support */
3600
#define SYSINFO_TXC_NONE      0
3601
3602
/* parameterized color names only (OS_COLOR_P_TEXT, etc) */
3603
#define SYSINFO_TXC_PARAM     1
3604
3605
/* 
3606
 *   we support only the basic ANSI colors, foreground control only (white,
3607
 *   black, blue, red, green, yellow, cyan, magenta) 
3608
 */
3609
#define SYSINFO_TXC_ANSI_FG   2
3610
3611
/* ANSI colors, foreground and background */
3612
#define SYSINFO_TXC_ANSI_FGBG 3
3613
3614
/* full RGB support */
3615
#define SYSINFO_TXC_RGB       4
3616
3617
/* are the os_banner_xxx() interfaces supported? */
3618
#define SYSINFO_BANNERS      33
3619
3620
/* Interpreter Class - this returns one of the SYSINFO_ICLASS_xxx codes */
3621
#define SYSINFO_INTERP_CLASS 34
3622
3623
/* 
3624
 *   Interpreter class: Character-mode Text-Only.  Interpreters of this class
3625
 *   use a single, fixed-pitch font to display all text, and use the
3626
 *   text-only HTML subset, and cannot display graphics.
3627
 */
3628
#define SYSINFO_ICLASS_TEXT    1
3629
3630
/* 
3631
 *   Interpreter class: Text-Only GUI.  Interpreters of this class are
3632
 *   traditional text-only interpreters running on graphical operating
3633
 *   systems.  These interpreters might use multiple fonts (for example, they
3634
 *   might display highlighted text in boldface), and might use
3635
 *   proportionally-spaced text for some windows.  These interpreters support
3636
 *   the text-only HTML subset, and cannot display graphics.
3637
 *   
3638
 *   Text-only GUI interpreters act essentially the same as character-mode
3639
 *   text-only interpreters, from the perspective of the client program.  
3640
 */
3641
#define SYSINFO_ICLASS_TEXTGUI 2
3642
3643
/*
3644
 *   Interpreter class: HTML.  Interpreters of this class can display
3645
 *   graphics and sounds, can display multiple fonts and font sizes, can use
3646
 *   proportional fonts, and support the full HTML TADS markup language for
3647
 *   formatting.  
3648
 */
3649
#define SYSINFO_ICLASS_HTML    3
3650
3651
/*
3652
 *   Audio fade information.
3653
 *   
3654
 *   SYSINFO_AUDIO_FADE: basic fade-in and fade-out support.  Interpreters
3655
 *   that don't support audio fade at all should return 0.  Interpreters that
3656
 *   support fades should return a bitwise OR'd combination of
3657
 *   SYSINFO_AUDIOFADE_xxx flags below indicating which formats can be used
3658
 *   with fades.
3659
 *   
3660
 *   SYSINFO_AUDIO_CROSSFADE: cross-fades are supported (i.e., simultaneous
3661
 *   play of overlapping tracks, one fading out while the other fades in).
3662
 *   If cross-fades aren't supported, return 0.  If they're supported, return
3663
 *   a combination of SYSINFO_AUDIOFADE_xxx flags indicating which formats
3664
 *   can be used with cross-fades.  
3665
 */
3666
#define SYSINFO_AUDIO_FADE       35
3667
#define SYSINFO_AUDIO_CROSSFADE  36
3668
3669
/* 
3670
 *   Specific audio fading features.  These are bit flags that can be
3671
 *   combined to indicate the fading capabilities of the interpreter.  
3672
 */
3673
#define SYSINFO_AUDIOFADE_MPEG  0x0001          /* supported for MPEG audio */
3674
#define SYSINFO_AUDIOFADE_OGG   0x0002          /* supported for Ogg Vorbis */
3675
#define SYSINFO_AUDIOFADE_WAV   0x0004                 /* supported for WAV */
3676
#define SYSINFO_AUDIOFADE_MIDI  0x0008                /* supported for MIDI */
3677
3678
3679
/* ------------------------------------------------------------------------ */
3680
/*
3681
 *   Integer division operators.  For any compiler that follows ANSI C
3682
 *   rules, no definitions are required for these routine, since the
3683
 *   standard definitions below will work properly.  However, if your
3684
 *   compiler does not follow ANSI standards with respect to integer
3685
 *   division of negative numbers, you must provide implementations of
3686
 *   these routines that produce the correct results.
3687
 *   
3688
 *   Division must "truncate towards zero," which means that any
3689
 *   fractional part is dropped from the result.  If the result is
3690
 *   positive, the result must be the largest integer less than the
3691
 *   algebraic result: 11/3 yields 3.  If the result is negative, the
3692
 *   result must be the smallest integer less than the result: (-11)/3
3693
 *   yields -3.
3694
 *   
3695
 *   The remainder must obey the relationship (a/b)*b + a%b == a, for any
3696
 *   integers a and b (b != 0).
3697
 *   
3698
 *   If your compiler does not obey the ANSI rules for the division
3699
 *   operators, make the following changes in your osxxx.h file
3700
 *   
3701
 *   - define the symbol OS_NON_ANSI_DIVIDE in the osxxx.h file
3702
 *   
3703
 *   - either define your own macros for os_divide_long() and
3704
 *   os_remainder_long(), or put actual prototypes for these functions
3705
 *   into your osxxx.h file and write appropriate implementations of these
3706
 *   functions in one of your osxxx.c or .cpp files.
3707
 */
3708
/* long os_divide_long(long a, long b);    // returns (a/b) with ANSI rules */
3709
/* long os_remainder_long(long a, long b); // returns (a%b) with ANSI rules */
3710
3711
/* standard definitions for any ANSI compiler */
3712
#ifndef OS_NON_ANSI_DIVIDE
3713
#define os_divide_long(a, b)     ((a) / (b))
3714
#define os_remainder_long(a, b)  ((a) % (b))
3715
#endif
3716
3717
/* ------------------------------------------------------------------------ */
3718
/*
3719
 *   Special "switch" statement optimization flags.  These definitions are
3720
 *   OPTIONAL - if a platform doesn't provide these definitions, suitable
3721
 *   code that's fully portable will be used.
3722
 *   
3723
 *   On some compilers, the performance of a "switch" statement can be
3724
 *   improved by fully populating the switch with all possible "case"
3725
 *   values.  When the compiler can safely assume that every possible "case"
3726
 *   value is specifically called out in the switch, the compiler can
3727
 *   generate somewhat faster code by omitting any range check for the
3728
 *   controlling expression of the switch: a range check is unnecessary
3729
 *   because the compiler knows that the value can never be outside the
3730
 *   "case" table.
3731
 *   
3732
 *   This type of optimization doesn't apply to all compilers.  When a given
3733
 *   platform's compiler can be coerced to produce faster "switch"
3734
 *   statements, though, there might be some benefit in defining these
3735
 *   symbols according to local platform rules.
3736
 *   
3737
 *   First, #define OS_FILL_OUT_CASE_TABLES if you want this type of switch
3738
 *   optimization at all.  This symbol is merely a flag, so it doesn't need
3739
 *   a value - #defining it is enough to activate the special code.  If you
3740
 *   don't define this symbol, then the code that cares about this will
3741
 *   simply generate ordinary switches, leaving holes in the case table and
3742
 *   using "default:" to cover them.  If the platform's osxxx.h header does
3743
 *   #define OS_FILL_OUT_CASE_TABLES, then the portable code will know to
3744
 *   fill out case tables with all possible alternatives where it's possible
3745
 *   and potentially beneficial to do so.
3746
 *   
3747
 *   Second, if you #define OS_FILL_OUT_CASE_TABLES, you MUST ALSO #define
3748
 *   OS_IMPOSSIBLE_DEFAULT_CASE.  The value for this symbol must be some
3749
 *   code to insert into a "switch" statement at the point where a
3750
 *   "default:" case would normally go.  On some compilers, special
3751
 *   extensions allow the program to explicitly indicate within a switch
3752
 *   that all possible cases are covered, so that the compiler doesn't have
3753
 *   to be relied upon to infer this for itself (which would be impossible
3754
 *   for it to do in many cases anyway).  You can use an empty definition
3755
 *   for this symbol if your compiler doesn't have any special construct for
3756
 *   indicating a fully-populated case table.
3757
 *   
3758
 *   Note that *most* switch statements in portable code won't care one way
3759
 *   or the other about these definitions.  There's a time/space trade-off
3760
 *   in fully populating a switch's case table, so only the most
3761
 *   time-critical code will bother trying.  
3762
 */
3763
3764
3765
3766
/* ------------------------------------------------------------------------ */
3767
/*
3768
 *   TADS 2 swapping configuration.  Define OS_DEFAULT_SWAP_ENABLED to 0
3769
 *   if you want swapping turned off, 1 if you want it turned on.  If we
3770
 *   haven't defined a default swapping mode yet, turn swapping on by
3771
 *   default.  
3772
 */
3773
#ifndef OS_DEFAULT_SWAP_ENABLED
3774
# define OS_DEFAULT_SWAP_ENABLED   1
3775
#endif
3776
3777
/*
3778
 *   If the system "long description" (for the banner) isn't defined, make
3779
 *   it the same as the platform ID string.  
3780
 */
3781
#ifndef OS_SYSTEM_LDESC
3782
# define OS_SYSTEM_LDESC  OS_SYSTEM_NAME
3783
#endif
3784
3785
/*
3786
 *   TADS 2 Usage Lines
3787
 *   
3788
 *   If the "usage" lines (i.e., the descriptive lines of text describing
3789
 *   how to run the various programs) haven't been otherwise defined,
3790
 *   define defaults for them here.  Some platforms use names other than
3791
 *   tc, tr, and tdb for the tools (for example, on Unix they're usually
3792
 *   tadsc, tadsr, and tadsdb), so the usage lines should be adjusted
3793
 *   accordingly; simply define them earlier than this point (in this file
3794
 *   or in one of the files included by this file, such as osunixt.h) for
3795
 *   non-default text.  
3796
 */
3797
#ifndef OS_TC_USAGE
3798
# define OS_TC_USAGE  "usage: tc [options] file"
3799
#endif
3800
#ifndef OS_TR_USAGE
3801
# define OS_TR_USAGE  "usage: tr [options] file"
3802
#endif
3803
#ifndef OS_TDB_USAGE
3804
# define OS_TDB_USAGE  "usage: tdb [options] file"
3805
#endif
3806
3807
/*
3808
 *   Ports can define a special TDB startup message, which is displayed
3809
 *   after the copyright/version banner.  If it's not defined at this
3810
 *   point, define it to an empty string.  
3811
 */
3812
#ifndef OS_TDB_STARTUP_MSG
3813
# define OS_TDB_STARTUP_MSG ""
3814
#endif
3815
3816
/*
3817
 *   If a system patch sub-level isn't defined, define it here as zero.
3818
 *   The patch sub-level is used on some systems where a number of ports
3819
 *   are derived from a base port (for example, a large number of ports
3820
 *   are based on the generic Unix port).  For platforms like the Mac,
3821
 *   where the porting work applies only to that one platform, this
3822
 *   sub-level isn't meaningful.
3823
 */
3824
#ifndef OS_SYSTEM_PATCHSUBLVL
3825
# define OS_SYSTEM_PATCHSUBLVL  "0"
3826
#endif
3827
3828
3829
#ifdef __cplusplus
3830
}
3831
#endif
3832
3833
#endif /* OSIFC_H */
3834