3 * Copyright 2007 Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include "talk/base/common.h"
31 #include "talk/base/logging.h"
32 #include "talk/base/macutils.h"
33 #include "talk/base/scoped_ptr.h"
34 #include "talk/base/stringutils.h"
38 ///////////////////////////////////////////////////////////////////////////////
40 bool ToUtf8(const CFStringRef str16, std::string* str8) {
41 if ((NULL == str16) || (NULL == str8))
43 size_t maxlen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str16),
44 kCFStringEncodingUTF8)
46 scoped_ptr<char[]> buffer(new char[maxlen]);
47 if (!buffer || !CFStringGetCString(str16, buffer.get(), maxlen,
48 kCFStringEncodingUTF8))
50 str8->assign(buffer.get());
54 bool ToUtf16(const std::string& str8, CFStringRef* str16) {
57 *str16 = CFStringCreateWithBytes(kCFAllocatorDefault,
58 reinterpret_cast<const UInt8*>(str8.data()),
59 str8.length(), kCFStringEncodingUTF8,
61 return (NULL != *str16);
65 void DecodeFourChar(UInt32 fc, std::string* out) {
68 bool printable = true;
69 for (int i = 3; i >= 0; --i) {
70 char ch = (fc >> (8 * i)) & 0xFF;
71 if (isprint(static_cast<unsigned char>(ch))) {
82 ss << "0x" << std::hex << fc;
84 out->append(ss.str());
87 static bool GetGestalt(OSType ostype, int* value) {
88 ASSERT(NULL != value);
90 OSStatus result = Gestalt(ostype, &native_value);
91 if (noErr == result) {
92 *value = native_value;
96 DecodeFourChar(ostype, &str);
97 LOG_E(LS_ERROR, OS, result) << "Gestalt(" << str << ")";
101 bool GetOSVersion(int* major, int* minor, int* bugfix) {
102 ASSERT(major && minor && bugfix);
103 if (!GetGestalt(gestaltSystemVersion, major))
105 if (*major < 0x1040) {
106 *bugfix = *major & 0xF;
107 *minor = (*major >> 4) & 0xF;
108 *major = (*major >> 8);
111 return GetGestalt(gestaltSystemVersionMajor, major)
112 && GetGestalt(gestaltSystemVersionMinor, minor)
113 && GetGestalt(gestaltSystemVersionBugFix, bugfix);
116 MacOSVersionName GetOSVersionName() {
117 int major = 0, minor = 0, bugfix = 0;
118 if (!GetOSVersion(&major, &minor, &bugfix))
119 return kMacOSUnknown;
123 if ((major < 10) || (minor < 3)) {
128 return kMacOSPanther;
132 return kMacOSLeopard;
134 return kMacOSSnowLeopard;
138 return kMacOSMountainLion;
143 bool GetQuickTimeVersion(std::string* out) {
145 if (!GetGestalt(gestaltQuickTimeVersion, &ver))
148 std::stringstream ss;
149 ss << std::hex << ver;
154 bool RunAppleScript(const std::string& script) {
155 // TODO(thaloun): Add a .mm file that contains something like this:
156 // NSString source from script
157 // NSAppleScript* appleScript = [[NSAppleScript alloc] initWithSource:&source]
158 // if (appleScript != nil) {
159 // [appleScript executeAndReturnError:nil]
160 // [appleScript release]
161 #ifndef CARBON_DEPRECATED
162 ComponentInstance component = NULL;
166 OSAID script_id, result_id;
168 AECreateDesc(typeNull, NULL, 0, &script_desc);
169 AECreateDesc(typeNull, NULL, 0, &result_data);
170 script_id = kOSANullScript;
171 result_id = kOSANullScript;
173 component = OpenDefaultComponent(kOSAComponentType, typeAppleScript);
174 if (component == NULL) {
175 LOG(LS_ERROR) << "Failed opening Apple Script component";
178 err = AECreateDesc(typeUTF8Text, script.data(), script.size(), &script_desc);
180 CloseComponent(component);
181 LOG(LS_ERROR) << "Failed creating Apple Script description";
185 err = OSACompile(component, &script_desc, kOSAModeCanInteract, &script_id);
187 AEDisposeDesc(&script_desc);
188 if (script_id != kOSANullScript) {
189 OSADispose(component, script_id);
191 CloseComponent(component);
192 LOG(LS_ERROR) << "Error compiling Apple Script";
196 err = OSAExecute(component, script_id, kOSANullScript, kOSAModeCanInteract,
199 if (err == errOSAScriptError) {
200 LOG(LS_ERROR) << "Error when executing Apple Script: " << script;
201 AECreateDesc(typeNull, NULL, 0, &result_data);
202 OSAScriptError(component, kOSAErrorMessage, typeChar, &result_data);
203 int len = AEGetDescDataSize(&result_data);
204 char* data = (char*) malloc(len);
206 err = AEGetDescData(&result_data, data, len);
207 LOG(LS_ERROR) << "Script error: " << data;
209 AEDisposeDesc(&script_desc);
210 AEDisposeDesc(&result_data);
213 AEDisposeDesc(&script_desc);
214 if (script_id != kOSANullScript) {
215 OSADispose(component, script_id);
217 if (result_id != kOSANullScript) {
218 OSADispose(component, result_id);
220 CloseComponent(component);
223 // TODO(thaloun): Support applescripts with the NSAppleScript API.
225 #endif // CARBON_DEPRECATED
229 ///////////////////////////////////////////////////////////////////////////////
231 } // namespace talk_base