1/* Metrowerks Standard Library
2 * Copyright � 1995-2002 Metrowerks Corporation.  All rights reserved.
3 *
4 * $Date$
5 * $Revision$
6 */
7
8#include <ansi_parms.h>
9#include <size_t.h>
10#include <console.h>
11#include <unistd.h>
12
13#if __MACH__
14  short InstallConsole(short fd)
15  {
16  #pragma unused (fd)
17
18    return 0;
19  }
20#else
21  #include <Carbon.h>
22
23  typedef int (*ReadPtr)(int, void *, __std(size_t));
24  typedef int (*WritePtr)(int, const void *, __std(size_t));
25
26  static struct
27  {
28    Boolean isLoaded;
29    CFBundleRef theBundle;
30    ReadPtr theRead;
31    WritePtr theWrite;
32  } __msl_os_x;
33
34  static OSErr __msl_CreateFrameworkBundleFromName(CFStringRef theFrameworkName,
35    CFBundleRef *theBundle)
36  {
37    OSErr theErr;
38    FSRef theRef;
39    CFURLRef theFrameworkURL;
40    CFURLRef theBundleURL;
41
42    /* Find the folder containing all the frameworks */
43    theErr = FSFindFolder(kOnAppropriateDisk, kFrameworksFolderType, false, &theRef);
44
45    if (theErr == noErr)
46    {
47      /* Turn the framework folder FSRef into a CFURL */
48      theFrameworkURL = CFURLCreateFromFSRef(kCFAllocatorSystemDefault, &theRef);
49
50      if (theFrameworkURL != NULL)
51      {
52        /* Create a CFURL pointing to the desired framework */
53        theBundleURL = CFURLCreateCopyAppendingPathComponent(kCFAllocatorSystemDefault,
54          theFrameworkURL, theFrameworkName, false);
55
56        CFRelease(theFrameworkURL);
57
58        if (theBundleURL != NULL)
59        {
60          /* Turn the CFURL into a bundle reference */
61          *theBundle = CFBundleCreate(kCFAllocatorSystemDefault, theBundleURL);
62
63          CFRelease(theBundleURL);
64        }
65      }
66    }
67
68    return theErr;
69  }
70
71  short InstallConsole(short fd)
72  {
73  #pragma unused (fd)
74    OSErr theErr;
75    short theResult;
76
77    theResult = -1;
78
79    /* Start with no bundle */
80    __msl_os_x.isLoaded = false;
81    __msl_os_x.theBundle = NULL;
82    __msl_os_x.theRead = NULL;
83    __msl_os_x.theWrite = NULL;
84
85    /* Create a bundle reference based on its name */
86    theErr = __msl_CreateFrameworkBundleFromName(CFSTR("System.framework"),
87      &__msl_os_x.theBundle);
88
89    if ((theErr == noErr) && (__msl_os_x.theBundle != NULL))
90    {
91      theResult = 0;
92
93      __msl_os_x.isLoaded = CFBundleLoadExecutable(__msl_os_x.theBundle);
94
95      if (__msl_os_x.isLoaded)
96      {
97        /* Lookup the functions in the bundle by name */
98        __msl_os_x.theRead = (ReadPtr)
99          CFBundleGetFunctionPointerForName(__msl_os_x.theBundle, CFSTR("read"));
100        __msl_os_x.theWrite = (WritePtr)
101          CFBundleGetFunctionPointerForName(__msl_os_x.theBundle, CFSTR("write"));
102      }
103    }
104
105    return theResult;
106  }
107#endif
108
109void RemoveConsole(void)
110{
111#if !__MACH__
112  if (__msl_os_x.theBundle != NULL)
113  {
114    if (__msl_os_x.isLoaded)
115    {
116      __msl_os_x.theRead = NULL;
117      __msl_os_x.theWrite = NULL;
118
119      CFBundleUnloadExecutable(__msl_os_x.theBundle);
120      __msl_os_x.isLoaded = false;
121    }
122
123    CFRelease(__msl_os_x.theBundle);
124    __msl_os_x.theBundle = NULL;
125  }
126#endif
127}
128
129long WriteCharsToConsole(char *buffer, long n)
130{
131#if __MACH__
132  return write(1, buffer, n);
133#else
134  /* Call the function if it was found */
135  if (__msl_os_x.theWrite == NULL)
136    return -1;
137  else
138    return __msl_os_x.theWrite(1, buffer, n);
139#endif
140}
141
142#if __MACH__
143long WriteCharsToErrorConsole(char *buffer, long n)
144{
145  return write(2, buffer, n);
146}
147#endif
148
149long ReadCharsFromConsole(char *buffer, long n)
150{
151#if __MACH__
152  return read(0, buffer, n);
153#else
154  /* Call the function if it was found */
155  if (__msl_os_x.theRead == NULL)
156    return -1;
157  else
158    return __msl_os_x.theRead(0, buffer, n);
159#endif
160}
161
162/* JWW - This code should never be reached, but it's needed for link purposes */
163char *__ttyname(long fildes)
164{
165#pragma unused (fildes)
166  /* all streams have the same name */
167  static char *__devicename = "Terminal";
168
169  if (fildes >= 0 && fildes <= 2)
170    return (__devicename);
171
172  return (0L);
173}
174
175int kbhit(void)
176{
177  return 0;
178}
179
180int getch(void)
181{
182  return 0;
183}
184
185void clrscr()
186{
187  return;
188}
189
190/* Change record:
191 * JWW 010919 Created Mach-O console stubs file
192 * JWW 020418 Use __std() for all size_t, and #include <size_t.h> to get proper C++ definitions
193 */