OpenCPN Partial API docs
Loading...
Searching...
No Matches
macutils.c
1/***************************************************************************
2 * Copyright (C) 2007..2010 by David S. Register, Richard M Smith *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************
19 *
20 */
21
22#include "wx/wxprec.h"
23#ifdef __WXOSX__
24
25#include <stdio.h>
26#include <string.h>
27#include <unistd.h>
28#include <fcntl.h>
29#include <sys/ioctl.h>
30#include <errno.h>
31#include <paths.h>
32#include <termios.h>
33#include <sysexits.h>
34#include <sys/param.h>
35#include <sys/select.h>
36#include <sys/time.h>
37#include <sys/sysctl.h>
38#include <time.h>
39#include <stdlib.h>
40#include <AvailabilityMacros.h>
41
42#include <CoreFoundation/CoreFoundation.h>
43
44#include <IOKit/IOKitLib.h>
45#include <IOKit/serial/IOSerialKeys.h>
46#if defined(MAC_OS_X_VERSION_10_3) && \
47 (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3)
48#include <IOKit/serial/ioss.h>
49#endif
50#include <IOKit/IOBSD.h>
51
52// We need CoreGraphics to read the monitor physical size.
53// In 10.7 CoreGraphics is part of ApplicationServices.
54#include <ApplicationServices/ApplicationServices.h>
55// When we stop building against 10.7 we will probably want to link agains
56// CoreGraphics directly:
57//#include <CoreGraphics/CoreGraphics.h>
58
59#include "config.h"
60
61// Returns an iterator across all known serial ports. Caller is responsible for
62// releasing the iterator when iteration is complete.
63static kern_return_t FindSerialPorts(io_iterator_t* matchingServices) {
64 kern_return_t kernResult;
65 CFMutableDictionaryRef classesToMatch;
66
82 // Serial devices are instances of class IOSerialBSDClient
83 classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue);
84 if (classesToMatch == NULL) {
85 printf("IOServiceMatching returned a NULL dictionary.\n");
86 } else {
109 CFDictionarySetValue(classesToMatch, CFSTR(kIOSerialBSDTypeKey),
110 CFSTR(kIOSerialBSDAllTypes));
111
112 // Each serial device object has a property with key
113 // kIOSerialBSDTypeKey and a value that is one of kIOSerialBSDAllTypes,
114 // kIOSerialBSDModemType, or kIOSerialBSDRS232Type. You can experiment with
115 // the matching by changing the last parameter in the above call to
116 // CFDictionarySetValue.
117
118 // As shipped, this sample is only interested in serial ports,
119 // so add this property to the CFDictionary we're matching on.
120 // This will find devices that advertise themselves as serial ports,
121 // such as built-in and USB serial ports. However, this match won't find
122 // serial serial ports.
123 }
124
142 kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault,
143 classesToMatch, matchingServices);
144 if (KERN_SUCCESS != kernResult) {
145 printf("IOServiceGetMatchingServices returned %d\n", kernResult);
146 goto exit;
147 }
148
149exit:
150 return kernResult;
151}
152
153// Given an iterator across a set of serial ports, return the BSD path to the
154// first one. If no serial ports are found the path name is set to an empty
155// string.
156static int GetSerialPortPath(io_iterator_t serialPortIterator, char** pNames,
157 int iMaxNames, CFIndex maxPathSize) {
158 io_object_t modemService;
159 // kern_return_t kernResult = KERN_FAILURE;
160 Boolean modemFound = false;
161 char bsdPath[maxPathSize];
162 int iCurrentNameIndex = 0;
163 // Initialize the returned path
164 *bsdPath = '\0';
165
166 // Iterate across all serial ports found.
167
168 while ((modemService = IOIteratorNext(serialPortIterator)) && !modemFound) {
169 CFTypeRef bsdPathAsCFString;
170
171 // Get the callout device's path (/dev/cu.xxxxx). The callout device should
172 // almost always be used: the dialin device (/dev/tty.xxxxx) would be used
173 // when monitoring a serial port for incoming calls, e.g. a fax listener.
174
175 bsdPathAsCFString = IORegistryEntryCreateCFProperty(
176 modemService, CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0);
177 if (bsdPathAsCFString) {
178 Boolean result;
179
180 // Convert the path from a CFString to a C (NUL-terminated) string for use
181 // with the POSIX open() call.
182
183 result = CFStringGetCString(bsdPathAsCFString, bsdPath, maxPathSize,
184 kCFStringEncodingUTF8);
185 CFRelease(bsdPathAsCFString);
186
187 if (result) {
188 pNames[iCurrentNameIndex] = calloc(1, strlen(bsdPath) + 1);
189 strncpy(pNames[iCurrentNameIndex], bsdPath, strlen(bsdPath) + 1);
190 iCurrentNameIndex++;
191 }
192 }
193 // Release the io_service_t now that we are done with it.
194 (void)IOObjectRelease(modemService);
195 }
196 return iCurrentNameIndex;
197}
198
199int FindSerialPortNames(char** pNames, int iMaxNames) {
200 int iActiveNameCount = 0;
201 kern_return_t kernResult; // on PowerPC this is an int (4 bytes)
202
203 io_iterator_t serialPortIterator;
204
205 kernResult = FindSerialPorts(&serialPortIterator);
206
207 iActiveNameCount =
208 GetSerialPortPath(serialPortIterator, pNames, iMaxNames, MAXPATHLEN);
209
210 IOObjectRelease(serialPortIterator); // Release the iterator.
211 return iActiveNameCount;
212}
213
214bool ValidateSerialPortName(char* pPortName, int iMaxNamestoSearch) {
215 char* paPortNames[iMaxNamestoSearch];
216 int iPortNameCount;
217 int iPortIndex;
218 bool bPortFound = false;
219 char* pPortSubName = index(pPortName, ':');
220 // name is always valid if opetion is set to 'none'
221 if (0 == strcasecmp(pPortName, "NONE")) return true;
222 // if this name done not have a leading descriptor with a 'serial:', 'GPS:',
223 // etc, use the whole name
224 if (NULL == pPortSubName)
225 pPortSubName = pPortName;
226 else
227 pPortSubName++;
228
229 memset(paPortNames, 0x00, sizeof(paPortNames));
230 iPortNameCount = FindSerialPortNames(&paPortNames[0], iMaxNamestoSearch);
231 for (iPortIndex = 0; iPortIndex < iPortNameCount; iPortIndex++) {
232 // stripoff leading 'serial:', etc based on iColonIndex
233 int iStrCompresult = strcmp(paPortNames[iPortIndex], pPortSubName);
234 if (false == bPortFound) bPortFound = (bool)(0 == iStrCompresult);
235 free(paPortNames[iPortIndex]);
236 }
237 return bPortFound;
238}
239
243int GetMacMonitorSize() {
244 CGSize displayPhysicalSize = CGDisplayScreenSize(CGMainDisplayID()); // mm
245 return displayPhysicalSize.width;
246}
247
252int ProcessIsTranslated() {
253 int ret = 0;
254 size_t size = sizeof(ret);
255 if (sysctlbyname("sysctl.proc_translated", &ret, &size, NULL, 0) == -1)
256 {
257 if (errno == ENOENT)
258 return 0;
259 return -1;
260 }
261 return ret;
262}
263
264int IsAppleSilicon() {
265 int ret = 0;
266 size_t size = sizeof(ret);
267
268 if (sysctlbyname("hw.optional.arm64", &ret, &size, NULL, 0) == -1) {
269 return -1;
270 }
271 return ret;
272}
273
274#endif //__WXOSX__