1 /*
2  * This file is part of MPlayer.
3  *
4  * MPlayer is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * MPlayer is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #include <Carbon/Carbon.h>
20 #include <ApplicationServices/ApplicationServices.h>
21 #include <stdio.h>
22 
23 #include "stream/url.h"
24 #include "mp_msg.h"
25 #include "m_option.h"
26 #include "m_config.h"
27 #include "playtree.h"
28 #include "macosx_finder_args.h"
29 
30 static play_tree_t *files=NULL;
31 
add_entry(play_tree_t ** last_parentp,play_tree_t ** last_entryp,play_tree_t * entry)32 static inline void add_entry(play_tree_t **last_parentp, play_tree_t **last_entryp, play_tree_t *entry) {
33 
34 	if(*last_entryp==NULL)
35 		play_tree_set_child(*last_parentp, entry);
36 	else
37 		play_tree_append_entry(*last_entryp, entry);
38 
39 	*last_entryp=entry;
40 }
41 
AppleEventHandlerProc(const AppleEvent * theAppleEvent,AppleEvent * reply,SInt32 handlerRefcon)42 static pascal OSErr AppleEventHandlerProc(const AppleEvent *theAppleEvent, AppleEvent* reply, SInt32 handlerRefcon) {
43 OSErr err=errAEEventNotHandled, res=noErr;
44 AEDescList docList;
45 long itemsInList;
46 
47 	AERemoveEventHandler(kCoreEventClass, kAEOpenDocuments, NULL, FALSE);
48 	if((res=AEGetParamDesc(theAppleEvent, keyDirectObject, typeAEList, &docList))==noErr) {
49 		if((res=AECountItems(&docList, &itemsInList))==noErr) {
50 		Size currentSize=0;
51 		int valid=0,i;
52 		char *parm=NULL;
53 		play_tree_t *last_entry=NULL;
54 
55 			files=play_tree_new();
56 			for(i=1;i<=itemsInList;++i) {
57 
58 				for(;;) {
59 				OSErr e;
60 				Size actualSize=0;
61 				AEKeyword keywd;
62 				DescType returnedType;
63 
64 					if((e=AEGetNthPtr(&docList, i, typeFileURL, &keywd, &returnedType, (Ptr)parm, currentSize, &actualSize))==noErr) {
65 						if(actualSize>=currentSize) {
66 							currentSize=actualSize+1;
67 							parm=realloc(parm, currentSize);
68 						}
69 						else {
70 							parm[actualSize]=0;
71 							valid=1;
72 							break;
73 						}
74 					}
75 					else {
76 						valid=0;
77 						break;
78 					}
79 				}
80 
81 				if(valid) {
82 				URL_t *url=url_new(parm);
83 
84 					if(url && !strcmp(url->protocol,"file") && !strcmp(url->hostname,"localhost")) {
85 					play_tree_t *entry=play_tree_new();
86 
87 						url_unescape_string(url->file, url->file);
88 						play_tree_add_file(entry, url->file);
89 						add_entry(&files, &last_entry, entry);
90 					}
91 
92 					url_free(url);
93 				}
94 			}
95 
96 			free(parm);
97 
98 			err=noErr;
99 		}
100 		else
101 			mp_msg(MSGT_CFGPARSER, MSGL_ERR, "AECountItems() error %d\n", res);
102 
103 		AEDisposeDesc(&docList);
104 	}
105 	else
106 		mp_msg(MSGT_CFGPARSER, MSGL_ERR, "AEGetParamDesc() error %d\n", res);
107 
108 	QuitApplicationEventLoop();
109 	return err;
110 }
111 
macosx_finder_args(m_config_t * config,int argc,char ** argv)112 play_tree_t *macosx_finder_args(m_config_t *config, int argc, char **argv) {
113 ProcessSerialNumber myPsn;
114 char myPsnStr[5+10+1+10+1];
115 
116 	GetCurrentProcess(&myPsn);
117 	snprintf(myPsnStr, 5+10+1+10+1, "-psn_%u_%u", myPsn.highLongOfPSN, myPsn.lowLongOfPSN);
118 	myPsnStr[5+10+1+10]=0;
119 
120 	if((argc==2) && !strcmp(myPsnStr, argv[1])) {
121 		m_config_set_option(config, "quiet", NULL);
122 		InitCursor();
123 		AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, NewAEEventHandlerUPP(AppleEventHandlerProc), 0, FALSE);
124 		RunApplicationEventLoop();
125 	}
126 
127 	return files;
128 }
129