2 * Copyright (C) 2010 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
22 #define BOOL XBMC_BOOL
25 #include "utils/log.h"
28 #if defined(__APPLE__)
30 #import <Foundation/Foundation.h>
31 #import <UIKit/UIKit.h>
32 #import <mach/mach_host.h>
33 #import <sys/sysctl.h>
35 #import <Cocoa/Cocoa.h>
38 #import "DarwinUtils.h"
40 float GetIOSVersion(void)
44 version = [[[UIDevice currentDevice] systemVersion] floatValue];
52 int GetDarwinFrameworkPath(bool forPython, char* path, uint32_t *pathsize)
54 // see if we can figure out who we are
60 // a) XBMC frappliance running under ATV2
61 Class XBMCfrapp = NSClassFromString(@"XBMCAppliance");
62 if (XBMCfrapp != NULL)
64 pathname = [[NSBundle bundleForClass:XBMCfrapp] pathForResource:@"Frameworks" ofType:@""];
65 strcpy(path, [pathname UTF8String]);
66 *pathsize = strlen(path);
67 //CLog::Log(LOGDEBUG, "DarwinFrameworkPath(a) -> %s", path);
71 // b) XBMC application running under IOS
72 pathname = [[NSBundle mainBundle] executablePath];
73 if (pathname && strstr([pathname UTF8String], "XBMC.app/XBMC"))
75 strcpy(path, [pathname UTF8String]);
76 // Move backwards to last "/"
77 for (int n=strlen(path)-1; path[n] != '/'; n--)
79 strcat(path, "Frameworks");
80 *pathsize = strlen(path);
81 //CLog::Log(LOGDEBUG, "DarwinFrameworkPath(c) -> %s", path);
85 // d) XBMC application running under OSX
86 pathname = [[NSBundle mainBundle] privateFrameworksPath];
87 if (pathname && strstr([pathname UTF8String], "Contents"))
89 // check for 'Contents' if we are running as real xbmc.app
90 strcpy(path, [pathname UTF8String]);
91 *pathsize = strlen(path);
92 //CLog::Log(LOGDEBUG, "DarwinFrameworkPath(d) -> %s", path);
96 // e) XBMC OSX binary running under xcode or command-line
97 // but only if it's not for python. In this case, let python
98 // use it's internal compiled paths.
101 strcpy(path, PREFIX_USR_PATH);
102 strcat(path, "/lib");
103 *pathsize = strlen(path);
104 //CLog::Log(LOGDEBUG, "DarwinFrameworkPath(e) -> %s", path);
111 int GetDarwinExecutablePath(char* path, uint32_t *pathsize)
113 // see if we can figure out who we are
116 // a) XBMC frappliance running under ATV2
117 Class XBMCfrapp = NSClassFromString(@"XBMCAppliance");
118 if (XBMCfrapp != NULL)
120 pathname = [[NSBundle bundleForClass:XBMCfrapp] pathForResource:@"XBMC" ofType:@""];
121 strcpy(path, [pathname UTF8String]);
122 *pathsize = strlen(path);
123 //CLog::Log(LOGDEBUG, "DarwinExecutablePath(a) -> %s", path);
127 // b) XBMC application running under IOS
128 // c) XBMC application running under OSX
129 pathname = [[NSBundle mainBundle] executablePath];
130 strcpy(path, [pathname UTF8String]);
131 *pathsize = strlen(path);
132 //CLog::Log(LOGDEBUG, "DarwinExecutablePath(b/c) -> %s", path);
137 bool DarwinHasVideoToolboxDecoder(void)
139 bool bDecoderAvailable = false;
141 Class XBMCfrapp = NSClassFromString(@"XBMCAppliance");
142 if (XBMCfrapp != NULL)
144 // atv2 has seatbelt profile key removed so nothing to do here
145 bDecoderAvailable = true;
149 /* Get Application directory */
150 uint32_t path_size = 2*MAXPATHLEN;
151 char given_path[2*MAXPATHLEN];
154 memset(given_path, 0x0, path_size);
155 result = GetDarwinExecutablePath(given_path, &path_size);
158 /* When XBMC is started from a sandbox directory we have to check the sysctl values */
159 if(strlen("/var/mobile/Applications/") < path_size &&
160 strncmp(given_path, "/var/mobile/Applications/", strlen("/var/mobile/Applications/")) == 0) {
162 uint64_t proc_enforce = 0;
163 uint64_t vnode_enforce = 0;
164 size_t size = sizeof(vnode_enforce);
166 sysctlbyname("security.mac.proc_enforce", &proc_enforce, &size, NULL, 0);
167 sysctlbyname("security.mac.vnode_enforce", &vnode_enforce, &size, NULL, 0);
169 if(vnode_enforce && proc_enforce)
171 bDecoderAvailable = false;
172 CLog::Log(LOGINFO, "VideoToolBox decoder not available. Use : sysctl -w security.mac.proc_enforce=0; sysctl -w security.mac.vnode_enforce=0\n");
173 //NSLog(@"%s VideoToolBox decoder not available. Use : sysctl -w security.mac.proc_enforce=0; sysctl -w security.mac.vnode_enforce=0", __PRETTY_FUNCTION__);
177 bDecoderAvailable = true;
178 CLog::Log(LOGINFO, "VideoToolBox decoder available\n");
179 //NSLog(@"%s VideoToolBox decoder available", __PRETTY_FUNCTION__);
184 bDecoderAvailable = true;
187 //NSLog(@"%s Executable path %s", __PRETTY_FUNCTION__, given_path);
191 /* In theory this case can never happen. But who knows. */
192 bDecoderAvailable = true;
196 return bDecoderAvailable;
200 CGImageRef CGImageCreateRotatedByAngle(CGImageRef imgRef, float angle)
202 // image rotation function taken from
203 // https://gist.github.com/585377
204 float angleInRadians = angle * (M_PI / 180);
205 float width = CGImageGetWidth(imgRef);
206 float height = CGImageGetHeight(imgRef);
208 CGRect imgRect = CGRectMake(0, 0, width, height);
209 CGAffineTransform transform = CGAffineTransformMakeRotation(angleInRadians);
210 CGRect rotatedRect = CGRectApplyAffineTransform(imgRect, transform);
212 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
213 CGContextRef bmContext = CGBitmapContextCreate(NULL,rotatedRect.size.width, rotatedRect.size.height,
214 8, 0, colorSpace, kCGImageAlphaPremultipliedFirst);
215 CGContextSetAllowsAntialiasing(bmContext, 1);
216 CGContextSetInterpolationQuality(bmContext, kCGInterpolationHigh);
217 CGColorSpaceRelease(colorSpace);
218 CGContextTranslateCTM(bmContext, +(rotatedRect.size.width/2), +(rotatedRect.size.height/2));
219 CGContextRotateCTM(bmContext, angleInRadians);
220 CGContextDrawImage(bmContext, CGRectMake(-width/2, -height/2, width, height), imgRef);
222 CGImageRef rotatedImage = CGBitmapContextCreateImage(bmContext);
223 CFRelease(bmContext);