File: macosx_osys_misc.mm

package info (click to toggle)
scummvm 2.9.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 450,268 kB
  • sloc: cpp: 4,297,604; asm: 28,322; python: 12,901; sh: 11,219; java: 8,477; xml: 7,843; perl: 2,633; ansic: 2,465; yacc: 1,670; javascript: 1,020; makefile: 933; lex: 578; awk: 275; objc: 82; sed: 11; php: 1
file content (176 lines) | stat: -rw-r--r-- 6,945 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

// Disable symbol overrides so that we can use system headers.
#define FORBIDDEN_SYMBOL_ALLOW_ALL

// Needs to be included first as system headers redefine NO and YES, which clashes
// with the DisposeAfterUse::Flag enum used in Common stream classes.
#include "common/file.h"

#include "backends/platform/sdl/macosx/macosx.h"
#include "backends/platform/sdl/macosx/macosx-compat.h"
#include "base/version.h"

#include <Foundation/NSBundle.h>
#include <Foundation/NSFileManager.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSPathUtilities.h>
#include <Foundation/NSUserDefaults.h>
#include <AppKit/NSPasteboard.h>

#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
#define NSPasteboardTypeString NSStringPboardType
#endif

#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
// https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Cocoa64BitGuide/64BitChangesCocoa/64BitChangesCocoa.html
#if __LP64__ || NS_BUILD_32_LIKE_64
typedef unsigned long NSUInteger;
#else
typedef unsigned int NSUInteger;
#endif

// Those are not defined in the 10.4 SDK, but they are defined when targeting
// Mac OS X 10.4 or above in the 10.5 SDK, and they do work with 10.4.
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
enum {
	NSUTF32StringEncoding = 0x8c000100,
	NSUTF32BigEndianStringEncoding = 0x98000100,
	NSUTF32LittleEndianStringEncoding = 0x9c000100
};
#endif
#endif

void OSystem_MacOSX::updateStartSettings(const Common::String & executable, Common::String &command, Common::StringMap &settings, Common::StringArray& additionalArgs) {
	NSBundle* bundle = [NSBundle mainBundle];
	// Check if scummvm is running from an app bundle
	if (!bundle || ![bundle bundleIdentifier]) {
		// Use default autostart implementation
		OSystem_POSIX::updateStartSettings(executable, command, settings, additionalArgs);
		return;
	}

	// If the bundle contains a scummvm.ini, use it as initial config
	NSString *iniPath = [bundle pathForResource:@"scummvm" ofType:@"ini"];
	if (iniPath && !settings.contains("initial-cfg"))
		settings["initial-cfg"] = Common::String([iniPath fileSystemRepresentation]);

	// If a command was specified on the command line, do not override it
	if (!command.empty())
		return;

	// Check if we have an autorun file with additional arguments
	NSString *autorunPath = [bundle pathForResource:@"scummvm-autorun" ofType:nil];
	if (autorunPath) {
		Common::File autorun;
		Common::String line;
		if (autorun.open(Common::FSNode([autorunPath fileSystemRepresentation]))) {
			while (!autorun.eos()) {
				line = autorun.readLine();
				if (!line.empty() && line[0] != '#')
					additionalArgs.push_back(line);
			}
		}
		autorun.close();
	}

	// If the bundle contains a game directory, auto-detect it
	NSString *gamePath = [[bundle resourcePath] stringByAppendingPathComponent:@"game"];
	BOOL isDir = false;
	BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:gamePath isDirectory:&isDir];
	if (exists && isDir) {
		// Use auto-detection
		command = "auto-detect";
		settings["path"] = [gamePath fileSystemRepresentation];
		return;
	}

	// The rest of the function has some commands executed only the first time after each version change
	// Check the last version stored in the user settings.
	NSString *versionString = [NSString stringWithUTF8String:gScummVMFullVersion];
	NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
	NSString *lastVersion = [defaults stringForKey:@"lastVersion"];
	if (lastVersion && [lastVersion isEqualToString:versionString])
		return;
	[defaults setObject:versionString forKey:@"lastVersion"];

	// If the bundle contains a games directory, add them to the launcher
	NSString *gamesPath = [[bundle resourcePath] stringByAppendingPathComponent:@"games"];
	isDir = false;
	exists = [[NSFileManager defaultManager] fileExistsAtPath:gamesPath isDirectory:&isDir];
	if (exists && isDir) {
		// Detect and add games
		command = "add";
		settings["path"] = [gamesPath fileSystemRepresentation];
		settings["recursive"] = "true";
		settings["exit"] = "false";
		return;
	}
}

bool OSystem_MacOSX::hasTextInClipboard() {
	return [[NSPasteboard generalPasteboard] availableTypeFromArray:[NSArray arrayWithObject:NSPasteboardTypeString]] != nil;
}

Common::U32String OSystem_MacOSX::getTextFromClipboard() {
	if (!hasTextInClipboard())
		return Common::U32String();

	NSPasteboard *pb = [NSPasteboard generalPasteboard];
	NSString *str = [pb  stringForType:NSPasteboardTypeString];
	if (![str respondsToSelector:@selector(getBytes:maxLength:usedLength:encoding:options:range:remainingRange:)])
		return Common::U32String();

	// If translations are supported, use the current TranslationManager charset and otherwise
	// use ASCII. If the string cannot be represented using the requested encoding we get a null
	// pointer below, which is fine as ScummVM would not know what to do with the string anyway.
#ifdef SCUMM_LITTLE_ENDIAN
	NSStringEncoding stringEncoding = NSUTF32LittleEndianStringEncoding;
#else
	NSStringEncoding stringEncoding = NSUTF32BigEndianStringEncoding;
#endif
	NSUInteger textLength = [str length];
	uint32 *text = new uint32[textLength];
	if (![str getBytes:text maxLength:4*textLength usedLength:NULL encoding: stringEncoding options:0 range:NSMakeRange(0, textLength) remainingRange:NULL]) {
		delete[] text;
		return Common::U32String();
	}
	Common::U32String u32String(text, textLength);
	delete[] text;

	return u32String;
}

bool OSystem_MacOSX::setTextInClipboard(const Common::U32String &text) {
	NSPasteboard *pb = [NSPasteboard generalPasteboard];
	[pb declareTypes:[NSArray arrayWithObject:NSPasteboardTypeString] owner:nil];

#ifdef SCUMM_LITTLE_ENDIAN
	NSStringEncoding stringEncoding = NSUTF32LittleEndianStringEncoding;
#else
	NSStringEncoding stringEncoding = NSUTF32BigEndianStringEncoding;
#endif
	NSString *nsstring = [[NSString alloc] initWithBytes:text.c_str() length:4*text.size() encoding: stringEncoding];
	bool status =  [pb setString:nsstring forType:NSPasteboardTypeString];
	[nsstring release];
	return status;
}