Code changes to make external python work in windows. Changes credit to WiSo
[vuplus_xbmc] / xbmc / osx / DarwinUtils.mm
1 /*
2  *      Copyright (C) 2010 Team XBMC
3  *      http://www.xbmc.org
4  *
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)
8  *  any later version.
9  *
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.
14  *
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
19  *
20  */
21
22 #define BOOL XBMC_BOOL 
23 #include "system.h"
24 #include "DllPaths.h"
25 #include "utils/log.h"
26 #undef BOOL
27
28 #if defined(__APPLE__)
29 #if defined(__arm__)
30   #import <Foundation/Foundation.h>
31   #import <UIKit/UIKit.h>
32   #import <mach/mach_host.h>
33   #import <sys/sysctl.h>
34 #else
35   #import <Cocoa/Cocoa.h>
36 #endif
37
38 #import "DarwinUtils.h"
39
40 float GetIOSVersion(void)
41 {
42   float version;
43 #if defined(__arm__)
44   version = [[[UIDevice currentDevice] systemVersion] floatValue];
45 #else
46   version = 0.0f;
47 #endif
48
49   return(version);
50 }
51
52 int  GetDarwinFrameworkPath(bool forPython, char* path, uint32_t *pathsize)
53 {
54   // see if we can figure out who we are
55   NSString *pathname;
56
57   path[0] = 0;
58   *pathsize = 0;
59
60   // a) XBMC frappliance running under ATV2
61   Class XBMCfrapp = NSClassFromString(@"XBMCAppliance");
62   if (XBMCfrapp != NULL)
63   {
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);
68     return 0;
69   }
70
71   // b) XBMC application running under IOS
72   pathname = [[NSBundle mainBundle] executablePath];
73   if (pathname && strstr([pathname UTF8String], "XBMC.app/XBMC"))
74   {
75     strcpy(path, [pathname UTF8String]);
76     // Move backwards to last "/"
77     for (int n=strlen(path)-1; path[n] != '/'; n--)
78       path[n] = '\0';
79     strcat(path, "Frameworks");
80     *pathsize = strlen(path);
81     //CLog::Log(LOGDEBUG, "DarwinFrameworkPath(c) -> %s", path);
82     return 0;
83   }
84
85   // d) XBMC application running under OSX
86   pathname = [[NSBundle mainBundle] privateFrameworksPath];
87   if (pathname && strstr([pathname UTF8String], "Contents"))
88   {
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);
93     return 0;
94   }
95
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.
99   if (!forPython)
100   {
101     strcpy(path, PREFIX_USR_PATH);
102     strcat(path, "/lib");
103     *pathsize = strlen(path);
104     //CLog::Log(LOGDEBUG, "DarwinFrameworkPath(e) -> %s", path);
105     return 0;
106   }
107
108   return -1;
109 }
110
111 int  GetDarwinExecutablePath(char* path, uint32_t *pathsize)
112 {
113   // see if we can figure out who we are
114   NSString *pathname;
115
116   // a) XBMC frappliance running under ATV2
117   Class XBMCfrapp = NSClassFromString(@"XBMCAppliance");
118   if (XBMCfrapp != NULL)
119   {
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);
124     return 0;
125   }
126
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);
133
134   return 0;
135 }
136
137 bool DarwinHasVideoToolboxDecoder(void)
138 {
139   bool bDecoderAvailable = false;
140
141   Class XBMCfrapp = NSClassFromString(@"XBMCAppliance");
142   if (XBMCfrapp != NULL)
143   {
144     // atv2 has seatbelt profile key removed so nothing to do here
145     bDecoderAvailable = true;
146   }
147   else
148   {
149     /* Get Application directory */
150     uint32_t path_size = 2*MAXPATHLEN;
151     char     given_path[2*MAXPATHLEN];
152     int      result = -1;
153     
154     memset(given_path, 0x0, path_size);
155     result = GetDarwinExecutablePath(given_path, &path_size);
156     if(result == 0) 
157     {
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) {
161
162         uint64_t proc_enforce = 0;
163         uint64_t vnode_enforce = 0; 
164         size_t size = sizeof(vnode_enforce);
165         
166         sysctlbyname("security.mac.proc_enforce", &proc_enforce, &size, NULL, 0);  
167         sysctlbyname("security.mac.vnode_enforce", &vnode_enforce, &size, NULL, 0);
168         
169         if(vnode_enforce && proc_enforce)
170         {
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__);
174         }
175         else
176         {
177           bDecoderAvailable = true;
178           CLog::Log(LOGINFO, "VideoToolBox decoder available\n");
179           //NSLog(@"%s VideoToolBox decoder available", __PRETTY_FUNCTION__);
180         }  
181       }
182       else
183       {
184         bDecoderAvailable = true;
185       }
186       
187       //NSLog(@"%s Executable path %s", __PRETTY_FUNCTION__, given_path);
188     }
189     else
190     {
191       /* In theory this case can never happen. But who knows. */
192       bDecoderAvailable = true;
193     }
194   }
195
196   return bDecoderAvailable;
197 }
198
199
200 CGImageRef CGImageCreateRotatedByAngle(CGImageRef imgRef, float angle)
201 {
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);
207   
208   CGRect imgRect = CGRectMake(0, 0, width, height);
209   CGAffineTransform transform = CGAffineTransformMakeRotation(angleInRadians);
210   CGRect rotatedRect = CGRectApplyAffineTransform(imgRect, transform);
211   
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);
221   
222   CGImageRef rotatedImage = CGBitmapContextCreateImage(bmContext);
223   CFRelease(bmContext);
224   
225   return rotatedImage;
226 }
227
228 #endif