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 <time.h>
38#include <stdlib.h>
39#include <AvailabilityMacros.h>
40
41#include <CoreFoundation/CoreFoundation.h>
42
43#include <IOKit/IOKitLib.h>
44#include <IOKit/serial/IOSerialKeys.h>
45#if defined(MAC_OS_X_VERSION_10_3) && \
46 (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3)
47#include <IOKit/serial/ioss.h>
48#endif
49#include <IOKit/IOBSD.h>
50
51// We need CoreGraphics to read the monitor physical size.
52// In 10.7 CoreGraphics is part of ApplicationServices.
53#include <ApplicationServices/ApplicationServices.h>
54// When we stop building against 10.7 we will probably want to link agains
55// CoreGraphics directly:
56//#include <CoreGraphics/CoreGraphics.h>
57
58#include "config.h"
59
60// Returns an iterator across all known serial ports. Caller is responsible for
61// releasing the iterator when iteration is complete.
62static kern_return_t FindSerialPorts(io_iterator_t* matchingServices) {
63 kern_return_t kernResult;
64 CFMutableDictionaryRef classesToMatch;
65
81 // Serial devices are instances of class IOSerialBSDClient
82 classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue);
83 if (classesToMatch == NULL) {
84 printf("IOServiceMatching returned a NULL dictionary.\n");
85 } else {
108 CFDictionarySetValue(classesToMatch, CFSTR(kIOSerialBSDTypeKey),
109 CFSTR(kIOSerialBSDAllTypes));
110
111 // Each serial device object has a property with key
112 // kIOSerialBSDTypeKey and a value that is one of kIOSerialBSDAllTypes,
113 // kIOSerialBSDModemType, or kIOSerialBSDRS232Type. You can experiment with
114 // the matching by changing the last parameter in the above call to
115 // CFDictionarySetValue.
116
117 // As shipped, this sample is only interested in serial ports,
118 // so add this property to the CFDictionary we're matching on.
119 // This will find devices that advertise themselves as serial ports,
120 // such as built-in and USB serial ports. However, this match won't find
121 // serial serial ports.
122 }
123
141 kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault,
142 classesToMatch, matchingServices);
143 if (KERN_SUCCESS != kernResult) {
144 printf("IOServiceGetMatchingServices returned %d\n", kernResult);
145 goto exit;
146 }
147
148exit:
149 return kernResult;
150}
151
152// Given an iterator across a set of serial ports, return the BSD path to the
153// first one. If no serial ports are found the path name is set to an empty
154// string.
155static int GetSerialPortPath(io_iterator_t serialPortIterator, char** pNames,
156 int iMaxNames, CFIndex maxPathSize) {
157 io_object_t modemService;
158 // kern_return_t kernResult = KERN_FAILURE;
159 Boolean modemFound = false;
160 char bsdPath[maxPathSize];
161 int iCurrentNameIndex = 0;
162 // Initialize the returned path
163 *bsdPath = '\0';
164
165 // Iterate across all serial ports found.
166
167 while ((modemService = IOIteratorNext(serialPortIterator)) && !modemFound) {
168 CFTypeRef bsdPathAsCFString;
169
170 // Get the callout device's path (/dev/cu.xxxxx). The callout device should
171 // almost always be used: the dialin device (/dev/tty.xxxxx) would be used
172 // when monitoring a serial port for incoming calls, e.g. a fax listener.
173
174 bsdPathAsCFString = IORegistryEntryCreateCFProperty(
175 modemService, CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0);
176 if (bsdPathAsCFString) {
177 Boolean result;
178
179 // Convert the path from a CFString to a C (NUL-terminated) string for use
180 // with the POSIX open() call.
181
182 result = CFStringGetCString(bsdPathAsCFString, bsdPath, maxPathSize,
183 kCFStringEncodingUTF8);
184 CFRelease(bsdPathAsCFString);
185
186 if (result) {
187 pNames[iCurrentNameIndex] = calloc(1, strlen(bsdPath) + 1);
188 strncpy(pNames[iCurrentNameIndex], bsdPath, strlen(bsdPath) + 1);
189 iCurrentNameIndex++;
190 }
191 }
192 // Release the io_service_t now that we are done with it.
193 (void)IOObjectRelease(modemService);
194 }
195 return iCurrentNameIndex;
196}
197
198int FindSerialPortNames(char** pNames, int iMaxNames) {
199 int iActiveNameCount = 0;
200 kern_return_t kernResult; // on PowerPC this is an int (4 bytes)
201
202 io_iterator_t serialPortIterator;
203
204 kernResult = FindSerialPorts(&serialPortIterator);
205
206 iActiveNameCount =
207 GetSerialPortPath(serialPortIterator, pNames, iMaxNames, MAXPATHLEN);
208
209 IOObjectRelease(serialPortIterator); // Release the iterator.
210 return iActiveNameCount;
211}
212
213bool ValidateSerialPortName(char* pPortName, int iMaxNamestoSearch) {
214 char* paPortNames[iMaxNamestoSearch];
215 int iPortNameCount;
216 int iPortIndex;
217 bool bPortFound = false;
218 char* pPortSubName = index(pPortName, ':');
219 // name is always valid if opetion is set to 'none'
220 if (0 == strcasecmp(pPortName, "NONE")) return true;
221 // if this name done not have a leading descriptor with a 'serial:', 'GPS:',
222 // etc, use the whole name
223 if (NULL == pPortSubName)
224 pPortSubName = pPortName;
225 else
226 pPortSubName++;
227
228 memset(paPortNames, 0x00, sizeof(paPortNames));
229 iPortNameCount = FindSerialPortNames(&paPortNames[0], iMaxNamestoSearch);
230 for (iPortIndex = 0; iPortIndex < iPortNameCount; iPortIndex++) {
231 // stripoff leading 'serial:', etc based on iColonIndex
232 int iStrCompresult = strcmp(paPortNames[iPortIndex], pPortSubName);
233 if (false == bPortFound) bPortFound = (bool)(0 == iStrCompresult);
234 free(paPortNames[iPortIndex]);
235 }
236 return bPortFound;
237}
238
242int GetMacMonitorSize() {
243 CGSize displayPhysicalSize = CGDisplayScreenSize(CGMainDisplayID()); // mm
244 return displayPhysicalSize.width;
245}
246
247#endif //__WXOSX__