1 package org.herac.tuxguitar.carbon.opendoc;
2 
3 import org.eclipse.swt.internal.C;
4 import org.eclipse.swt.internal.Callback;
5 import org.eclipse.swt.internal.carbon.AEDesc;
6 import org.eclipse.swt.internal.carbon.CFRange;
7 import org.eclipse.swt.internal.carbon.EventRecord;
8 import org.eclipse.swt.internal.carbon.OS;
9 /**
10  * <p>
11  * This registers a handler for opendoc events in OSX</o<
12  *
13  * $Id:$
14  *
15  * @author robin
16  */
17 public class OpenDocListener implements OpenDocCallback{
18 
19 	private static final int typeAEList = ('l' << 24) + ('i' << 16) + ('s' << 8) + 't';
20 
21 	private static final int kCoreEventClass = ('a' << 24) + ('e' << 16) + ('v' << 8) + 't';
22 
23 	private static final int kAEOpenDocuments = ('o' << 24) + ('d' << 16) + ('o' << 8) + 'c';
24 
25 	private static final int kURLEventClass = ('G' << 24) + ('U' << 16) + ('R' << 8) + 'L';
26 
27 	private static final int typeText = ('T' << 24) + ('E' << 16) + ('X' << 8) + 'T';
28 
29 	private boolean enabled;
30 
OpenDocListener()31 	public OpenDocListener() {
32 		super();
33 	}
34 
isEnabled()35 	public boolean isEnabled() {
36 		return this.enabled;
37 	}
38 
setEnabled(boolean enabled)39 	public void setEnabled(boolean enabled) {
40 		this.enabled = enabled;
41 	}
42 
init()43 	public void init() {
44 		Callback openDocCallback = new Callback(this, "openDocProc", 3);
45 		int openDocProc = openDocCallback.getAddress();
46 		if (openDocProc == 0) {
47 			openDocCallback.dispose();
48 			return;
49 		}
50 		if (OS.AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,openDocProc, 0, false) != OS.noErr) {
51 			return;
52 		}
53 		if (OS.AEInstallEventHandler(kURLEventClass, kURLEventClass,openDocProc, 0, false) != OS.noErr) {
54 			return;
55 		}
56 		int appTarget = OS.GetApplicationEventTarget();
57 		Callback appleEventCallback = new Callback(this, "appleEventProc", 3);
58 		int appleEventProc = appleEventCallback.getAddress();
59 		int[] mask3 = new int[] { OS.kEventClassAppleEvent, OS.kEventAppleEvent, kURLEventClass, };
60 		OS.InstallEventHandler(appTarget, appleEventProc,mask3.length / 2, mask3, 0, null);
61 	}
62 
appleEventProc(int nextHandler, int theEvent, int userData)63 	public int appleEventProc(int nextHandler, int theEvent, int userData) {
64 		if(!this.isEnabled()){
65 			return OS.noErr;
66 		}
67 		int eventClass = OS.GetEventClass(theEvent);
68 		if (eventClass == OS.kEventClassAppleEvent) {
69 			int[] aeEventID = new int[1];
70 			if (OS.GetEventParameter(theEvent, OS.kEventParamAEEventID, OS.typeType, null, 4, null, aeEventID) != OS.noErr) {
71 				return OS.eventNotHandledErr;
72 			}
73 
74 			if (aeEventID[0] != kAEOpenDocuments && aeEventID[0] != kURLEventClass) {
75 				return OS.eventNotHandledErr;
76 			}
77 
78 			EventRecord eventRecord = new EventRecord();
79 			OS.ConvertEventRefToEventRecord(theEvent, eventRecord);
80 			OS.AEProcessAppleEvent(eventRecord);
81 
82 			return OS.noErr;
83 		}
84 
85 		return OS.eventNotHandledErr;
86 	}
87 
openDocProc(int theAppleEvent, int reply, int handlerRefcon)88 	public int openDocProc(int theAppleEvent, int reply, int handlerRefcon) {
89 		if(!this.isEnabled()){
90 			return OS.noErr;
91 		}
92 		AEDesc aeDesc = new AEDesc();
93 		EventRecord eventRecord = new EventRecord();
94 		OS.ConvertEventRefToEventRecord(theAppleEvent, eventRecord);
95 		try {
96 			int result = OpenDocJNI.AEGetParamDesc(theAppleEvent,OS.kEventParamDirectObject, typeAEList, aeDesc);
97 			if (result != OS.noErr) {
98 				System.err.println("OSX: Could call AEGetParamDesc. Error: " + result);
99 				return OS.noErr;
100 			}
101 		} catch (java.lang.UnsatisfiedLinkError e) {
102 			System.err.println("OSX: AEGetParamDesc not available.  Can't open sent file");
103 			return OS.noErr;
104 		}
105 		int[] count = new int[1];
106 		OS.AECountItems(aeDesc, count);
107 
108 		if (count[0] > 0) {
109 			String[] fileNames = new String[count[0]];
110 			int maximumSize = 80; // size of FSRef
111 			int dataPtr = OS.NewPtr(maximumSize);
112 			int[] aeKeyword = new int[1];
113 			int[] typeCode = new int[1];
114 			int[] actualSize = new int[1];
115 			for (int i = 0; i < count[0]; i++) {
116 				if (OS.AEGetNthPtr(aeDesc, i + 1, OS.typeFSRef, aeKeyword,typeCode, dataPtr, maximumSize, actualSize) == OS.noErr) {
117 					byte[] fsRef = new byte[actualSize[0]];
118 					C.memmove(fsRef, dataPtr, actualSize[0]);
119 					int dirUrl = OS.CFURLCreateFromFSRef(OS.kCFAllocatorDefault, fsRef);
120 					int dirString = OS.CFURLCopyFileSystemPath(dirUrl,OS.kCFURLPOSIXPathStyle);
121 					OS.CFRelease(dirUrl);
122 					int length = OS.CFStringGetLength(dirString);
123 					char[] buffer = new char[length];
124 					CFRange range = new CFRange();
125 					range.length = length;
126 					OS.CFStringGetCharacters(dirString, range, buffer);
127 					OS.CFRelease(dirString);
128 					fileNames[i] = new String(buffer);
129 				}
130 
131 				if (OS.AEGetNthPtr(aeDesc, i + 1, typeText, aeKeyword,typeCode, dataPtr, maximumSize, actualSize) == OS.noErr) {
132 					byte[] urlRef = new byte[actualSize[0]];
133 					C.memmove(urlRef, dataPtr, actualSize[0]);
134 					fileNames[i] = new String(urlRef);
135 				}
136 			}
137 
138 			if( fileNames.length > 0 ){
139 				OpenDocAction.saveAndOpen( fileNames[0] );
140 			}
141 		}
142 
143 		return OS.noErr;
144 	}
145 }