platform.h
author Ryan C. Gordon <icculus@icculus.org>
Fri, 25 Jan 2008 07:08:25 +0000
changeset 466 7ed76bfef8da
parent 444 068c2a42c62a
child 482 d46016ed7d57
permissions -rw-r--r--
Support for launching a web browser.
icculus@249
     1
/**
icculus@249
     2
 * MojoSetup; a portable, flexible installation application.
icculus@249
     3
 *
icculus@249
     4
 * Please see the file LICENSE.txt in the source's root directory.
icculus@249
     5
 *
icculus@249
     6
 *  This file written by Ryan C. Gordon.
icculus@249
     7
 */
icculus@249
     8
icculus@5
     9
#ifndef _INCL_PLATFORM_H_
icculus@5
    10
#define _INCL_PLATFORM_H_
icculus@5
    11
icculus@5
    12
#include "universal.h"
icculus@5
    13
icculus@5
    14
#ifdef __cplusplus
icculus@5
    15
extern "C" {
icculus@5
    16
#endif
icculus@5
    17
icculus@10
    18
// this is called by your mainline.
icculus@8
    19
int MojoSetup_main(int argc, char **argv);
icculus@5
    20
icculus@69
    21
// Caller must free returned string!
icculus@70
    22
char *MojoPlatform_appBinaryPath(void);
icculus@14
    23
icculus@234
    24
// Caller must free returned string!
icculus@299
    25
char *MojoPlatform_currentWorkingDir(void);
icculus@299
    26
icculus@299
    27
// Caller must free returned string!
icculus@234
    28
char *MojoPlatform_homedir(void);
icculus@234
    29
icculus@44
    30
uint32 MojoPlatform_ticks(void);
icculus@44
    31
icculus@64
    32
// Make current process kill itself immediately, without any sort of internal
icculus@64
    33
//  cleanup, like atexit() handlers or static destructors...the OS will have
icculus@64
    34
//  to sort out the freeing of any resources, and no more code in this
icculus@64
    35
//  process than necessary should run. This function does not return. Try to
icculus@64
    36
//  avoid calling this.
icculus@64
    37
void MojoPlatform_die(void);
icculus@64
    38
icculus@189
    39
// Delete a file from the physical filesystem. This should remove empty
icculus@189
    40
//  directories as well as files. Returns true on success, false on failure.
icculus@77
    41
boolean MojoPlatform_unlink(const char *fname);
icculus@77
    42
icculus@104
    43
// Resolve symlinks, relative paths, etc. Caller free()'s buffer. Returns
icculus@104
    44
//  NULL if path couldn't be resolved.
icculus@104
    45
char *MojoPlatform_realpath(const char *path);
icculus@104
    46
icculus@145
    47
// Create a symlink in the physical filesystem. (src) is the NAME OF THE LINK
icculus@145
    48
//  and (dst) is WHAT IT POINTS TO. This is backwards from the unix symlink()
icculus@145
    49
//  syscall! Returns true if link was created, false otherwise.
icculus@145
    50
boolean MojoPlatform_symlink(const char *src, const char *dst);
icculus@145
    51
icculus@330
    52
// Read the destination from symlink (linkname). Returns a pointer
icculus@330
    53
//  allocated with xmalloc() containing the linkdest on success, and NULL
icculus@330
    54
//  on failure. The caller is responsible for freeing the returned pointer!
icculus@330
    55
char *MojoPlatform_readlink(const char *linkname);
icculus@330
    56
icculus@345
    57
// !!! FIXME: we really can't do this in a 16-bit value...non-Unix platforms
icculus@345
    58
// !!! FIXME:  and Extended Attributes need more.
icculus@345
    59
// Create a directory in the physical filesystem, with (perms) permissions.
icculus@345
    60
//  returns true if directory is created, false otherwise.
icculus@283
    61
boolean MojoPlatform_mkdir(const char *path, uint16 perms);
icculus@145
    62
icculus@145
    63
// Move a file to a new name. This has to be a fast (if not atomic) operation,
icculus@145
    64
//  so if it would require a legitimate copy to another filesystem or device,
icculus@145
    65
//  this should fail, as the standard Unix rename() function does.
icculus@145
    66
// Returns true on successful rename, false otherwise.
icculus@145
    67
boolean MojoPlatform_rename(const char *src, const char *dst);
icculus@145
    68
icculus@345
    69
// Determine if dir/fname exists in the native filesystem. It doesn't matter
icculus@345
    70
//  if it's a directory, file, symlink, etc, we're just looking for the
icculus@345
    71
//  existance of the entry itself. (fname) may be NULL, in which case,
icculus@345
    72
//  (dir) contains the whole path, otherwise, the platform layer needs to
icculus@345
    73
//  build the path: (on Unix: dir/path, on Windows: dir\\path, etc).
icculus@345
    74
//  This is a convenience thing for the caller.
icculus@345
    75
// Returns true if path in question exists, false otherwise.
icculus@131
    76
boolean MojoPlatform_exists(const char *dir, const char *fname);
icculus@131
    77
icculus@345
    78
// Returns true if (fname) in the native filesystem is writable. If (fname)
icculus@345
    79
//  is a directory, this means that the contents of the directory can be
icculus@345
    80
//  added to (create files, delete files, etc). If (fname) is a file, this
icculus@345
    81
//  means that this process has write access to the file.
icculus@345
    82
// Returns false if (fname) isn't writable.
icculus@237
    83
boolean MojoPlatform_writable(const char *fname);
icculus@237
    84
icculus@345
    85
// Returns true if (dir) is a directory in the physical filesystem, false
icculus@345
    86
//  otherwise (including if (dir) doesn't exist). Don't follow symlinks.
icculus@237
    87
boolean MojoPlatform_isdir(const char *dir);
icculus@237
    88
icculus@345
    89
// Returns true if (fname) is a symlink in the physical filesystem, false
icculus@345
    90
//  otherwise (including if (fname) doesn't exist). Don't follow symlinks.
icculus@339
    91
boolean MojoPlatform_issymlink(const char *fname);
icculus@339
    92
icculus@369
    93
// Returns true if stdin and stdout are connected to a tty.
icculus@369
    94
boolean MojoPlatform_istty(void);
icculus@369
    95
icculus@345
    96
// Returns true if (fname) is a regular file in the physical filesystem, false
icculus@345
    97
//  otherwise (including if (fname) doesn't exist). Don't follow symlinks.
icculus@339
    98
boolean MojoPlatform_isfile(const char *fname);
icculus@339
    99
icculus@345
   100
// Returns size, in bytes, of the file (fname) in the physical filesystem.
icculus@345
   101
//  Return -1 if file is missing or not a file. Don't follow symlinks.
icculus@339
   102
int64 MojoPlatform_filesize(const char *fname);
icculus@339
   103
icculus@345
   104
// !!! FIXME: we really can't do this in a 16-bit value...non-Unix platforms
icculus@345
   105
// !!! FIXME:  and Extended Attributes need more.
icculus@339
   106
// !!! FIXME: comment me.
icculus@155
   107
boolean MojoPlatform_perms(const char *fname, uint16 *p);
icculus@155
   108
icculus@345
   109
// !!! FIXME: we really can't do this in a 16-bit value...non-Unix platforms
icculus@345
   110
// !!! FIXME:  and Extended Attributes need more.
icculus@155
   111
// !!! FIXME: comment me.
icculus@155
   112
boolean MojoPlatform_chmod(const char *fname, uint16 p);
icculus@155
   113
icculus@345
   114
// Try to locate a specific piece of media (usually an inserted CD or DVD).
icculus@345
   115
//  (uniquefile) is a path that should exist on the media; its presence
icculus@345
   116
//  should uniquely identify the media.
icculus@345
   117
// Returns the path of the media's mount point in the physical filesystem
icculus@345
   118
//  (something like "E:\\" on Windows or "/mnt/cdrom" on Unix), or NULL if
icculus@345
   119
//  the media isn't found (needed disc isn't inserted, etc).
icculus@345
   120
// Caller must free return value!
icculus@131
   121
char *MojoPlatform_findMedia(const char *uniquefile);
icculus@131
   122
icculus@339
   123
// Flag values for MojoPlatform_fopen().
icculus@339
   124
typedef enum
icculus@339
   125
{
icculus@339
   126
    MOJOFILE_READ=(1<<0),
icculus@339
   127
    MOJOFILE_WRITE=(1<<1),
icculus@339
   128
    MOJOFILE_CREATE=(1<<2),
icculus@339
   129
    MOJOFILE_EXCLUSIVE=(1<<3),
icculus@339
   130
    MOJOFILE_TRUNCATE=(1<<4),
icculus@339
   131
    MOJOFILE_APPEND=(1<<5),
icculus@339
   132
} MojoFileFlags;
icculus@339
   133
icculus@339
   134
typedef enum
icculus@339
   135
{
icculus@339
   136
    MOJOSEEK_SET,
icculus@339
   137
    MOJOSEEK_CURRENT,
icculus@339
   138
    MOJOSEEK_END
icculus@339
   139
} MojoFileSeek;
icculus@339
   140
icculus@345
   141
// !!! FIXME: we really can't do this in a 16-bit value...non-Unix platforms
icculus@345
   142
// !!! FIXME:  and Extended Attributes need more.
icculus@345
   143
// Open file (fname). This wraps a subset of the Unix open() syscall. Use
icculus@345
   144
//  MojoFileFlags for (flags). If creating a file, use (mode) for the new
icculus@345
   145
//  file's permissions.
icculus@345
   146
// Returns an opaque handle on success, NULL on error. Caller must free
icculus@345
   147
//  handle with MojoPlatform_close() when done with it.
icculus@339
   148
void *MojoPlatform_open(const char *fname, uint32 flags, uint16 mode);
icculus@345
   149
icculus@411
   150
// Return a handle that's compatible with MojoPlatform_open()'s return values
icculus@411
   151
//  that represents stdout. May return NULL for platforms that don't support
icculus@411
   152
//  this concept. You need to make sure that stdout itself doesn't really
icculus@411
   153
//  close in MojoPlatform_close(), at least for now.
icculus@411
   154
void *MojoPlatform_stdout(void);
icculus@411
   155
icculus@345
   156
// Read (bytes) bytes from (fd) into (buf). This wraps the Unix read() syscall.
icculus@345
   157
//  Returns number of bytes read, -1 on error.
icculus@339
   158
int64 MojoPlatform_read(void *fd, void *buf, uint32 bytes);
icculus@345
   159
icculus@345
   160
// Write (bytes) bytes from (buf) into (fd). This wraps the Unix write()
icculus@345
   161
//  syscall. Returns number of bytes read, -1 on error.
icculus@339
   162
int64 MojoPlatform_write(void *fd, const void *buf, uint32 bytes);
icculus@345
   163
icculus@345
   164
// Reports byte offset of file pointer in (fd), or -1 on error.
icculus@339
   165
int64 MojoPlatform_tell(void *fd);
icculus@345
   166
icculus@345
   167
// Seek to (offset) byte offset of file pointer in (fd), relative to (whence).
icculus@345
   168
//  This wraps the Unix lseek() syscall. Returns byte offset from the start
icculus@345
   169
//  of the file, -1 on error.
icculus@339
   170
int64 MojoPlatform_seek(void *fd, int64 offset, MojoFileSeek whence);
icculus@345
   171
icculus@345
   172
// Get the size, in bytes, of a file, referenced by its opaque handle.
icculus@345
   173
//  (This pulls the data through an fstat() on Unix.) Retuns -1 on error.
icculus@339
   174
int64 MojoPlatform_flen(void *fd);
icculus@345
   175
icculus@345
   176
// Force any pending data to disk, returns true on success, false if there
icculus@345
   177
//  was an i/o error.
icculus@339
   178
boolean MojoPlatform_flush(void *fd);
icculus@345
   179
icculus@345
   180
// Free any resources associated with (fd), flushing any pending data to disk,
icculus@345
   181
//  and closing the file. (fd) becomes invalid after this call returns
icculus@345
   182
//  successfully. This wraps the Unix close() syscall. Returns true on
icculus@345
   183
//  success, false on i/o error.
icculus@339
   184
boolean MojoPlatform_close(void *fd);
icculus@339
   185
icculus@338
   186
// Enumerate a directory. Returns an opaque pointer that can be used with
icculus@338
   187
//  repeated calls to MojoPlatform_readdir() to enumerate the names of
icculus@338
   188
//  directory entries. Returns NULL on error. Non-NULL values should be passed
icculus@338
   189
//  to MojoPlatform_closedir() for cleanup when you are done with them.
icculus@338
   190
void *MojoPlatform_opendir(const char *dirname);
icculus@338
   191
icculus@338
   192
// Get the next entry in the directory. (dirhandle) is an opaque pointer
icculus@338
   193
//  returned by MojoPlatform_opendir(). Returns NULL if we're at the end of
icculus@338
   194
//  the directory, or a null-terminated UTF-8 string otherwise. The order of
icculus@338
   195
//  results are not guaranteed, and may change between two iterations.
icculus@338
   196
// Caller must free returned string!
icculus@338
   197
char *MojoPlatform_readdir(void *dirhandle);
icculus@338
   198
icculus@338
   199
// Clean up resources used by a directory enumeration. (dirhandle) is an
icculus@338
   200
//  opaque pointer returned by MojoPlatform_opendir(), and becomes invalid
icculus@338
   201
//  after this call.
icculus@338
   202
void MojoPlatform_closedir(void *dirhandle);
icculus@338
   203
icculus@283
   204
// Convert a string into a permissions bitmask. On Unix, this is currently
icculus@339
   205
//  expected to be an octal string like "0755", but may expect other forms
icculus@283
   206
//  in the future, and other platforms may need to interpret permissions
icculus@283
   207
//  differently. (str) may be NULL for defaults, and is considered valid.
icculus@283
   208
// If (str) is not valid, return a reasonable default and set (*valid) to
icculus@283
   209
//  false. Otherwise, set (*valid) to true and return the converted value.
icculus@283
   210
uint16 MojoPlatform_makePermissions(const char *str, boolean *valid);
icculus@283
   211
icculus@283
   212
// Return a default, sane set of permissions for a newly-created file.
icculus@283
   213
uint16 MojoPlatform_defaultFilePerms(void);
icculus@283
   214
icculus@283
   215
// Return a default, sane set of permissions for a newly-created directory.
icculus@283
   216
uint16 MojoPlatform_defaultDirPerms(void);
icculus@283
   217
icculus@82
   218
// Wrappers for Unix dlopen/dlsym/dlclose, sort of. Instead of a filename,
icculus@82
   219
//  these take a memory buffer for the library. If you can't load this
icculus@82
   220
//  directly in RAM, the platform should write it to a temporary file first,
icculus@82
   221
//  and deal with cleanup in MojoPlatform_dlclose(). The memory buffer must be
icculus@82
   222
//  dereferenced in MojoPlatform_dlopen(), as the caller may free() it upon
icculus@82
   223
//  return. Everything else works like the usual Unix calls.
icculus@82
   224
void *MojoPlatform_dlopen(const uint8 *img, size_t len);
icculus@77
   225
void *MojoPlatform_dlsym(void *lib, const char *sym);
icculus@77
   226
void MojoPlatform_dlclose(void *lib);
icculus@77
   227
icculus@466
   228
// Launch the user's preferred browser to view the URL (url).
icculus@466
   229
//  Returns true if the browser launched, false otherwise. We can't know
icculus@466
   230
//  if the URL actually loaded, just if the browser launched. The hope is that
icculus@466
   231
//  the browser will inform the user if there's a problem loading the URL.
icculus@466
   232
boolean MojoPlatform_launchBrowser(const char *url);
icculus@466
   233
icculus@299
   234
#if !SUPPORT_MULTIARCH
icculus@299
   235
#define MojoPlatform_switchBin(img, len)
icculus@299
   236
#else
icculus@299
   237
void MojoPlatform_switchBin(const uint8 *img, size_t len);
icculus@299
   238
#endif
icculus@299
   239
icculus@369
   240
// Try to spawn a terminal, and relaunch MojoSetup within it.
icculus@369
   241
//  Does not return on success (process replaces itself).
icculus@369
   242
void MojoPlatform_spawnTerminal(void);
icculus@369
   243
icculus@185
   244
// Put the calling process to sleep for at least (ticks) milliseconds.
icculus@185
   245
//  This is meant to yield the CPU while spinning in a loop that is polling
icculus@185
   246
//  for input, etc. Pumping the GUI event queue happens elsewhere, not here.
icculus@185
   247
void MojoPlatform_sleep(uint32 ticks);
icculus@131
   248
icculus@89
   249
// Put a line of text to the the system log, whatever that might be on a
icculus@89
   250
//  given platform. (str) is a complete line, but won't end with any newline
icculus@89
   251
//  characters. You should supply if needed.
icculus@89
   252
void MojoPlatform_log(const char *str);
icculus@89
   253
icculus@374
   254
// This tries to decode a graphic file in memory into an RGBA framebuffer.
icculus@374
   255
//  Most platforms return NULL here. No one should call this; use decodeImage()
icculus@374
   256
//  instead, which will try included platform-independent code if this fails.
icculus@374
   257
// This function is just here to allow a platform with the appropriate
icculus@374
   258
//  functionality to work without compiling in stb_image.c, or supply more
icculus@374
   259
//  formats over the built-in code.
icculus@374
   260
// (data) points to the compressed data, (size) is the number of bytes
icculus@374
   261
//  of compressed data. (*w) and (*h) will contain the images dimensions on
icculus@374
   262
//  return.
icculus@374
   263
// Returns NULL on failure (unsupported, etc) and a pointer to the
icculus@374
   264
//  uncompressed data on success. Caller must free() the returned pointer!
icculus@374
   265
uint8 *MojoPlatform_decodeImage(const uint8 *data, uint32 size,
icculus@374
   266
                                uint32 *w, uint32 *h);
icculus@374
   267
icculus@39
   268
// Get the current locale, in the format "xx_YY" where "xx" is the language
icculus@39
   269
//  (en, fr, de...) and "_YY" is the country. (_US, _CA, etc). The country
icculus@39
   270
//  can be omitted. Don't include encoding, it's always UTF-8 at this time.
icculus@443
   271
// Returns locale string, or NULL if it couldn't be determined.
icculus@443
   272
//  Caller must free() the returned pointer!
icculus@443
   273
char *MojoPlatform_locale(void);
icculus@39
   274
icculus@443
   275
// !!! FIXME: document me.
icculus@443
   276
// Caller must free() the returned pointer!
icculus@443
   277
char *MojoPlatform_osType(void);
icculus@443
   278
icculus@443
   279
// !!! FIXME: document me.
icculus@443
   280
// Caller must free() the returned pointer!
icculus@443
   281
char *MojoPlatform_osVersion(void);
icculus@443
   282
icculus@444
   283
// !!! FIXME: document me.
icculus@444
   284
uint64 MojoPlatform_getuid(void);
icculus@444
   285
icculus@444
   286
// !!! FIXME: document me.
icculus@444
   287
uint64 MojoPlatform_geteuid(void);
icculus@444
   288
icculus@444
   289
// !!! FIXME: document me.
icculus@444
   290
uint64 MojoPlatform_getgid(void);
icculus@444
   291
icculus@43
   292
icculus@43
   293
// Basic platform detection.
icculus@43
   294
#if PLATFORM_WINDOWS
icculus@43
   295
#define PLATFORM_NAME "windows"
icculus@43
   296
#elif PLATFORM_MACOSX
icculus@43
   297
#define PLATFORM_NAME "macosx"
icculus@43
   298
#elif PLATFORM_UNIX
icculus@43
   299
#define PLATFORM_NAME "unix"
icculus@98
   300
#elif PLATFORM_BEOS
icculus@98
   301
#define PLATFORM_NAME "beos"
icculus@43
   302
#else
icculus@82
   303
#error Unknown platform.
icculus@43
   304
#endif
icculus@43
   305
icculus@43
   306
// Basic architecture detection.
icculus@43
   307
icculus@43
   308
#if defined(__powerpc64__)
icculus@43
   309
#define PLATFORM_ARCH "powerpc64"
icculus@43
   310
#elif defined(__ppc__) || defined(__powerpc__) || defined(__POWERPC__)
icculus@43
   311
#define PLATFORM_ARCH "powerpc"
icculus@43
   312
#elif defined(__x86_64__) || defined(_M_X64)
icculus@43
   313
#define PLATFORM_ARCH "x86-64"
icculus@43
   314
#elif defined(__X86__) || defined(__i386__) || defined(i386) || defined (_M_IX86) || defined(__386__)
icculus@43
   315
#define PLATFORM_ARCH "x86"
icculus@43
   316
#else
icculus@43
   317
#error Unknown processor architecture.
icculus@43
   318
#endif
icculus@43
   319
icculus@339
   320
// Other basic truths...
icculus@339
   321
#if PLATFORM_WINDOWS
icculus@339
   322
#define MOJOPLATFORM_ENDLINE "\r\n"
icculus@339
   323
#else
icculus@339
   324
#define MOJOPLATFORM_ENDLINE "\n"
icculus@339
   325
#endif
icculus@339
   326
icculus@5
   327
#ifdef __cplusplus
icculus@5
   328
}
icculus@5
   329
#endif
icculus@5
   330
icculus@5
   331
#endif
icculus@5
   332
icculus@10
   333
// end of platform.h ...
icculus@5
   334