diff options
author | Jacek Antonelli | 2008-08-15 23:45:19 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:19 -0500 |
commit | b235c59d60472f818a9142c0886b95a0ff4191d7 (patch) | |
tree | d323c55587584b19cc43a03f58a178823f12d3cd /linden/indra/newview/llappviewermacosx.cpp | |
parent | Second Life viewer sources 1.18.5.3 (diff) | |
download | meta-impy-b235c59d60472f818a9142c0886b95a0ff4191d7.zip meta-impy-b235c59d60472f818a9142c0886b95a0ff4191d7.tar.gz meta-impy-b235c59d60472f818a9142c0886b95a0ff4191d7.tar.bz2 meta-impy-b235c59d60472f818a9142c0886b95a0ff4191d7.tar.xz |
Second Life viewer sources 1.18.6.0-RC
Diffstat (limited to 'linden/indra/newview/llappviewermacosx.cpp')
-rw-r--r-- | linden/indra/newview/llappviewermacosx.cpp | 373 |
1 files changed, 373 insertions, 0 deletions
diff --git a/linden/indra/newview/llappviewermacosx.cpp b/linden/indra/newview/llappviewermacosx.cpp new file mode 100644 index 0000000..e80491e --- /dev/null +++ b/linden/indra/newview/llappviewermacosx.cpp | |||
@@ -0,0 +1,373 @@ | |||
1 | /** | ||
2 | * @file llappviewermacosx.cpp | ||
3 | * @brief The LLAppViewerWin32 class definitions | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2007&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2007, Linden Research, Inc. | ||
8 | * | ||
9 | * Second Life Viewer Source Code | ||
10 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
11 | * to you under the terms of the GNU General Public License, version 2.0 | ||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
15 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
16 | * | ||
17 | * There are special exceptions to the terms and conditions of the GPL as | ||
18 | * it is applied to this Source Code. View the full text of the exception | ||
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
20 | * online at http://secondlife.com/developers/opensource/flossexception | ||
21 | * | ||
22 | * By copying, modifying or distributing this software, you acknowledge | ||
23 | * that you have read and understood your obligations described above, | ||
24 | * and agree to abide by those obligations. | ||
25 | * | ||
26 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
27 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
28 | * COMPLETENESS OR PERFORMANCE. | ||
29 | * $/LicenseInfo$ | ||
30 | */ | ||
31 | |||
32 | #include "llviewerprecompiledheaders.h" | ||
33 | |||
34 | #if !defined LL_DARWIN | ||
35 | #error "Use only with Mac OS X" | ||
36 | #endif | ||
37 | |||
38 | #include "llappviewermacosx.h" | ||
39 | #include "llmemtype.h" | ||
40 | |||
41 | #include "llviewernetwork.h" | ||
42 | #include "llmd5.h" | ||
43 | #include "llurlsimstring.h" | ||
44 | #include "llfloaterworldmap.h" | ||
45 | #include "llurldispatcher.h" | ||
46 | #include <Carbon/Carbon.h> | ||
47 | |||
48 | |||
49 | int main( int argc, char **argv ) | ||
50 | { | ||
51 | LLMemType mt1(LLMemType::MTYPE_STARTUP); | ||
52 | |||
53 | #if LL_SOLARIS && defined(__sparc) | ||
54 | asm ("ta\t6"); // NOTE: Make sure memory alignment is enforced on SPARC | ||
55 | #endif | ||
56 | |||
57 | // Set the working dir to <bundle>/Contents/Resources | ||
58 | (void) chdir(gDirUtilp->getAppRODataDir().c_str()); | ||
59 | |||
60 | LLAppViewerMacOSX* viewer_app_ptr = new LLAppViewerMacOSX(); | ||
61 | |||
62 | viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash); | ||
63 | |||
64 | bool ok = viewer_app_ptr->tempStoreCommandOptions(argc, argv); | ||
65 | if(!ok) | ||
66 | { | ||
67 | llwarns << "Unable to parse command line." << llendl; | ||
68 | return -1; | ||
69 | } | ||
70 | |||
71 | ok = viewer_app_ptr->init(); | ||
72 | if(!ok) | ||
73 | { | ||
74 | llwarns << "Application init failed." << llendl; | ||
75 | return -1; | ||
76 | } | ||
77 | |||
78 | // Run the application main loop | ||
79 | if(!LLApp::isQuitting()) | ||
80 | { | ||
81 | viewer_app_ptr->mainLoop(); | ||
82 | } | ||
83 | |||
84 | if (!LLApp::isError()) | ||
85 | { | ||
86 | // | ||
87 | // We don't want to do cleanup here if the error handler got called - | ||
88 | // the assumption is that the error handler is responsible for doing | ||
89 | // app cleanup if there was a problem. | ||
90 | // | ||
91 | viewer_app_ptr->cleanup(); | ||
92 | } | ||
93 | delete viewer_app_ptr; | ||
94 | viewer_app_ptr = NULL; | ||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | LLAppViewerMacOSX::LLAppViewerMacOSX() | ||
99 | { | ||
100 | } | ||
101 | |||
102 | LLAppViewerMacOSX::~LLAppViewerMacOSX() | ||
103 | { | ||
104 | } | ||
105 | |||
106 | bool LLAppViewerMacOSX::init() | ||
107 | { | ||
108 | return LLAppViewer::init(); | ||
109 | } | ||
110 | |||
111 | void LLAppViewerMacOSX::handleCrashReporting() | ||
112 | { | ||
113 | // Macintosh | ||
114 | LLString command_str; | ||
115 | command_str = "crashreporter.app/Contents/MacOS/crashreporter "; | ||
116 | command_str += "-user "; | ||
117 | command_str += gGridName; | ||
118 | command_str += " &"; // This backgrounds the command so system() doesn't block until the crashreporter exits. | ||
119 | system(command_str.c_str()); /* Flawfinder: ignore */ | ||
120 | |||
121 | // Sometimes signals don't seem to quit the viewer. | ||
122 | // Make sure we exit so as to not totally confuse the user. | ||
123 | exit(1); | ||
124 | } | ||
125 | |||
126 | std::string LLAppViewerMacOSX::generateSerialNumber() | ||
127 | { | ||
128 | char serial_md5[MD5HEX_STR_SIZE]; // Flawfinder: ignore | ||
129 | serial_md5[0] = 0; | ||
130 | |||
131 | // JC: Sample code from http://developer.apple.com/technotes/tn/tn1103.html | ||
132 | CFStringRef serialNumber = NULL; | ||
133 | io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, | ||
134 | IOServiceMatching("IOPlatformExpertDevice")); | ||
135 | if (platformExpert) { | ||
136 | serialNumber = (CFStringRef) IORegistryEntryCreateCFProperty(platformExpert, | ||
137 | CFSTR(kIOPlatformSerialNumberKey), | ||
138 | kCFAllocatorDefault, 0); | ||
139 | IOObjectRelease(platformExpert); | ||
140 | } | ||
141 | |||
142 | if (serialNumber) | ||
143 | { | ||
144 | char buffer[MAX_STRING]; // Flawfinder: ignore | ||
145 | if (CFStringGetCString(serialNumber, buffer, MAX_STRING, kCFStringEncodingASCII)) | ||
146 | { | ||
147 | LLMD5 md5( (unsigned char*)buffer ); | ||
148 | md5.hex_digest(serial_md5); | ||
149 | } | ||
150 | CFRelease(serialNumber); | ||
151 | } | ||
152 | |||
153 | return serial_md5; | ||
154 | } | ||
155 | |||
156 | OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn) | ||
157 | { | ||
158 | OSErr result = noErr; | ||
159 | DescType actualType; | ||
160 | char buffer[1024]; // Flawfinder: ignore | ||
161 | Size size; | ||
162 | |||
163 | result = AEGetParamPtr ( | ||
164 | messagein, | ||
165 | keyDirectObject, | ||
166 | typeCString, | ||
167 | &actualType, | ||
168 | (Ptr)buffer, | ||
169 | sizeof(buffer), | ||
170 | &size); | ||
171 | |||
172 | if(result == noErr) | ||
173 | { | ||
174 | std::string url = buffer; | ||
175 | LLURLDispatcher::dispatch(url); | ||
176 | } | ||
177 | |||
178 | return(result); | ||
179 | } | ||
180 | |||
181 | OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn) | ||
182 | { | ||
183 | OSErr result = noErr; | ||
184 | |||
185 | LLAppViewer::instance()->userQuit(); | ||
186 | |||
187 | return(result); | ||
188 | } | ||
189 | |||
190 | OSStatus simpleDialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata) | ||
191 | { | ||
192 | OSStatus result = eventNotHandledErr; | ||
193 | OSStatus err; | ||
194 | UInt32 evtClass = GetEventClass(event); | ||
195 | UInt32 evtKind = GetEventKind(event); | ||
196 | WindowRef window = (WindowRef)userdata; | ||
197 | |||
198 | if((evtClass == kEventClassCommand) && (evtKind == kEventCommandProcess)) | ||
199 | { | ||
200 | HICommand cmd; | ||
201 | err = GetEventParameter(event, kEventParamDirectObject, typeHICommand, NULL, sizeof(cmd), NULL, &cmd); | ||
202 | |||
203 | if(err == noErr) | ||
204 | { | ||
205 | switch(cmd.commandID) | ||
206 | { | ||
207 | case kHICommandOK: | ||
208 | QuitAppModalLoopForWindow(window); | ||
209 | result = noErr; | ||
210 | break; | ||
211 | |||
212 | case kHICommandCancel: | ||
213 | QuitAppModalLoopForWindow(window); | ||
214 | result = userCanceledErr; | ||
215 | break; | ||
216 | } | ||
217 | } | ||
218 | } | ||
219 | |||
220 | return(result); | ||
221 | } | ||
222 | |||
223 | OSStatus DisplayReleaseNotes(void) | ||
224 | { | ||
225 | OSStatus err; | ||
226 | IBNibRef nib = NULL; | ||
227 | WindowRef window = NULL; | ||
228 | |||
229 | err = CreateNibReference(CFSTR("SecondLife"), &nib); | ||
230 | |||
231 | if(err == noErr) | ||
232 | { | ||
233 | CreateWindowFromNib(nib, CFSTR("Release Notes"), &window); | ||
234 | } | ||
235 | |||
236 | if(err == noErr) | ||
237 | { | ||
238 | // Get the text view control | ||
239 | HIViewRef textView; | ||
240 | ControlID id; | ||
241 | |||
242 | id.signature = 'text'; | ||
243 | id.id = 0; | ||
244 | |||
245 | LLString releaseNotesText; | ||
246 | |||
247 | _read_file_into_string(releaseNotesText, "releasenotes.txt"); // Flawfinder: ignore | ||
248 | |||
249 | err = HIViewFindByID(HIViewGetRoot(window), id, &textView); | ||
250 | |||
251 | if(err == noErr) | ||
252 | { | ||
253 | // Convert from the encoding used in the release notes. | ||
254 | CFStringRef str = CFStringCreateWithBytes( | ||
255 | NULL, | ||
256 | (const UInt8*)releaseNotesText.c_str(), | ||
257 | releaseNotesText.size(), | ||
258 | kCFStringEncodingWindowsLatin1, // This matches the way the Windows version displays the release notes. | ||
259 | FALSE); | ||
260 | |||
261 | if(str != NULL) | ||
262 | { | ||
263 | int size = CFStringGetLength(str); | ||
264 | |||
265 | if(size > 0) | ||
266 | { | ||
267 | UniChar *chars = new UniChar[size + 1]; | ||
268 | CFStringGetCharacters(str, CFRangeMake(0, size), chars); | ||
269 | |||
270 | err = TXNSetData(HITextViewGetTXNObject(textView), kTXNUnicodeTextData, chars, size * sizeof(UniChar), kTXNStartOffset, kTXNStartOffset); | ||
271 | |||
272 | delete[] chars; | ||
273 | } | ||
274 | |||
275 | CFRelease(str); | ||
276 | } | ||
277 | else | ||
278 | { | ||
279 | // Creating the string failed. Probably an encoding problem. Display SOMETHING... | ||
280 | err = TXNSetData(HITextViewGetTXNObject(textView), kTXNTextData, releaseNotesText.c_str(), releaseNotesText.size(), kTXNStartOffset, kTXNStartOffset); | ||
281 | } | ||
282 | } | ||
283 | |||
284 | // Set the selection to the beginning of the text and scroll it into view. | ||
285 | if(err == noErr) | ||
286 | { | ||
287 | err = TXNSetSelection(HITextViewGetTXNObject(textView), kTXNStartOffset, kTXNStartOffset); | ||
288 | } | ||
289 | |||
290 | if(err == noErr) | ||
291 | { | ||
292 | // This function returns void. | ||
293 | TXNShowSelection(HITextViewGetTXNObject(textView), false); | ||
294 | } | ||
295 | } | ||
296 | |||
297 | if(err == noErr) | ||
298 | { | ||
299 | ShowWindow(window); | ||
300 | } | ||
301 | |||
302 | if(err == noErr) | ||
303 | { | ||
304 | // Set up an event handler for the window. | ||
305 | EventHandlerRef handler = NULL; | ||
306 | EventTypeSpec handlerEvents[] = | ||
307 | { | ||
308 | { kEventClassCommand, kEventCommandProcess } | ||
309 | }; | ||
310 | |||
311 | InstallWindowEventHandler( | ||
312 | window, | ||
313 | NewEventHandlerUPP(simpleDialogHandler), | ||
314 | GetEventTypeCount (handlerEvents), | ||
315 | handlerEvents, | ||
316 | (void*)window, | ||
317 | &handler); | ||
318 | } | ||
319 | |||
320 | if(err == noErr) | ||
321 | { | ||
322 | RunAppModalLoopForWindow(window); | ||
323 | } | ||
324 | |||
325 | if(window != NULL) | ||
326 | { | ||
327 | DisposeWindow(window); | ||
328 | } | ||
329 | |||
330 | if(nib != NULL) | ||
331 | { | ||
332 | DisposeNibReference(nib); | ||
333 | } | ||
334 | |||
335 | return(err); | ||
336 | } | ||
337 | |||
338 | void init_apple_menu(const char* product) | ||
339 | { | ||
340 | // Load up a proper menu bar. | ||
341 | { | ||
342 | OSStatus err; | ||
343 | IBNibRef nib = NULL; | ||
344 | // NOTE: DO NOT translate or brand this string. It's an internal name in the .nib file, and MUST match exactly. | ||
345 | err = CreateNibReference(CFSTR("SecondLife"), &nib); | ||
346 | |||
347 | if(err == noErr) | ||
348 | { | ||
349 | // NOTE: DO NOT translate or brand this string. It's an internal name in the .nib file, and MUST match exactly. | ||
350 | SetMenuBarFromNib(nib, CFSTR("MenuBar")); | ||
351 | } | ||
352 | |||
353 | if(nib != NULL) | ||
354 | { | ||
355 | DisposeNibReference(nib); | ||
356 | } | ||
357 | } | ||
358 | |||
359 | // Install a handler for 'gurl' AppleEvents. This is how secondlife:// URLs get passed to the viewer. | ||
360 | |||
361 | if(AEInstallEventHandler('GURL', 'GURL', NewAEEventHandlerUPP(AEGURLHandler),0, false) != noErr) | ||
362 | { | ||
363 | // Couldn't install AppleEvent handler. This error shouldn't be fatal. | ||
364 | llinfos << "Couldn't install 'GURL' AppleEvent handler. Continuing..." << llendl; | ||
365 | } | ||
366 | |||
367 | // Install a handler for 'quit' AppleEvents. This makes quitting the application from the dock work. | ||
368 | if(AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(AEQuitHandler),0, false) != noErr) | ||
369 | { | ||
370 | // Couldn't install AppleEvent handler. This error shouldn't be fatal. | ||
371 | llinfos << "Couldn't install Quit AppleEvent handler. Continuing..." << llendl; | ||
372 | } | ||
373 | } | ||