mirror of
https://github.com/moparisthebest/davmail
synced 2024-12-04 14:52:24 -05:00
Initial growl import from http://forums.cocoaforge.com/viewtopic.php?f=6&t=17320
git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@1047 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
parent
335402a52d
commit
437837e21c
70
libgrowl/build.xml
Normal file
70
libgrowl/build.xml
Normal file
@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project name="UpdateTesting" default="build">
|
||||
|
||||
<property name="build.dir" value="build" />
|
||||
<property name="classes.dir" value="${build.dir}/classes" />
|
||||
<property name="target.dir" value="${build.dir}/dist" />
|
||||
<property name="javadoc.dir" value="${build.dir}/apidocs" />
|
||||
|
||||
<property name="src.java.dir" value="src/java" />
|
||||
<property name="src.native.dir" value="src/native" />
|
||||
<property name="src.resources.dir" value="src/resources" />
|
||||
|
||||
<target name="build-java">
|
||||
<mkdir dir="${classes.dir}" />
|
||||
<javac debug="true" destdir="${classes.dir}" srcdir="${src.java.dir}" />
|
||||
</target>
|
||||
|
||||
<target name="build-headers" depends="build-java">
|
||||
<javah destdir="${src.native.dir}" classpath="${classes.dir}">
|
||||
<class name="info.growl.GrowlNative" />
|
||||
</javah>
|
||||
</target>
|
||||
|
||||
<target name="build-native">
|
||||
<exec executable="make" dir="${src.native.dir}" failonerror="yes" />
|
||||
|
||||
<copy todir="${target.dir}">
|
||||
<fileset dir="${src.native.dir}" includes="**/*.jnilib" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="copy-resources">
|
||||
<copy todir="${classes.dir}">
|
||||
<fileset dir="${src.resources.dir}" includes="**/*" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="build-jar" depends="build-java, copy-resources">
|
||||
<mkdir dir="${target.dir}" />
|
||||
<jar destfile="${target.dir}/Growl.jar" basedir="${classes.dir}">
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="build" depends="build-jar,build-headers,build-native" />
|
||||
|
||||
<target name="javadoc" depends="build-jar">
|
||||
<mkdir dir="${javadoc.dir}" />
|
||||
|
||||
<javadoc sourcepath="${src.java.dir}" destdir="${javadoc.dir}"
|
||||
author="yes" header="Growl Java APIs" />
|
||||
</target>
|
||||
|
||||
<target name="clean">
|
||||
<delete dir="${build.dir}" />
|
||||
<delete>
|
||||
<fileset dir="${src.native.dir}" includes="**/info_growl_*.h" />
|
||||
</delete>
|
||||
|
||||
<exec executable="make" dir="${src.native.dir}" failonerror="yes">
|
||||
<arg line="clean" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="run" depends="build">
|
||||
<java classname="info.growl.test.TestGrowl" fork="true" dir="${target.dir}" classpath="${target.dir}/Growl.jar">
|
||||
<jvmarg line="-Djava.library.path=."/>
|
||||
</java>
|
||||
</target>
|
||||
</project>
|
100
libgrowl/src/java/info/growl/DummyGrowl.java
Normal file
100
libgrowl/src/java/info/growl/DummyGrowl.java
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Michael Stringer
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Growl nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package info.growl;
|
||||
|
||||
import java.awt.image.RenderedImage;
|
||||
|
||||
/**
|
||||
* Dummy implementation of the Growl API for situations where the native code
|
||||
* cannot be loaded (non-Mac systems).
|
||||
*
|
||||
* @author Michael Stringer
|
||||
* @version 0.1
|
||||
*/
|
||||
class DummyGrowl implements Growl {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void addNotification(String name, boolean enabledByDefault) {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void register() throws GrowlException {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body)
|
||||
throws GrowlException {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body,
|
||||
RenderedImage icon) throws GrowlException {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void setIcon(RenderedImage icon) throws GrowlException {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body,
|
||||
String callbackContext) throws GrowlException {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body,
|
||||
String callbackContext, RenderedImage icon) throws GrowlException {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void addCallbackListener(GrowlCallbackListener listener) {
|
||||
// does nothing
|
||||
}
|
||||
}
|
160
libgrowl/src/java/info/growl/Growl.java
Normal file
160
libgrowl/src/java/info/growl/Growl.java
Normal file
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Michael Stringer
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Growl nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package info.growl;
|
||||
|
||||
import java.awt.image.RenderedImage;
|
||||
|
||||
/**
|
||||
* Interface for sending notifications to Growl.
|
||||
*
|
||||
* @author Michael Stringer
|
||||
* @version 0.1
|
||||
*/
|
||||
public interface Growl {
|
||||
/**
|
||||
* Registers this Growl object with the Growl service.
|
||||
*
|
||||
* @throws GrowlException
|
||||
* If an error occurs during the registration.
|
||||
*/
|
||||
public void register() throws GrowlException;
|
||||
|
||||
/**
|
||||
* Sets the icon to display for notifications from this <code>Growl</code>.
|
||||
*
|
||||
* This <b>must</b> be called before calling {@link #register()}. If the
|
||||
* icon is changed after {@link #register()} has been called then another
|
||||
* call to {@link #register()} must be made.
|
||||
*
|
||||
* @param icon
|
||||
* The icon to display.
|
||||
* @throws GrowlException
|
||||
* If an error occurs while setting the icon.
|
||||
*/
|
||||
public void setIcon(RenderedImage icon) throws GrowlException;
|
||||
|
||||
/**
|
||||
* Adds a notification type for this <code>Growl</code>. This <b>must</b>
|
||||
* be called before calling {@link #register()}. If the another
|
||||
* notification type is added after {@link #register()} has been called then
|
||||
* another call to {@link #register()} must be made.
|
||||
*
|
||||
* @param name
|
||||
* The name of the notification type. This is what appears in
|
||||
* the Growl settings.
|
||||
* @param enabledByDefault
|
||||
* <code>true</code> if this notification type should be
|
||||
* enabled by default. This can be overridden by the user in
|
||||
* the Growl settings.
|
||||
*/
|
||||
public void addNotification(String name, boolean enabledByDefault);
|
||||
|
||||
/**
|
||||
* Adds a click callback listener.
|
||||
*
|
||||
* @param listener
|
||||
* The callback listener to add.
|
||||
*/
|
||||
public void addCallbackListener(GrowlCallbackListener listener);
|
||||
|
||||
/**
|
||||
* Sends a notification to Growl for displaying. This <b>must</b> be called
|
||||
* after calling {@link #register()}.
|
||||
*
|
||||
* @param name
|
||||
* Name of the notification type that has been registered.
|
||||
* @param title
|
||||
* The title of the notification.
|
||||
* @param body
|
||||
* The body of the notification.
|
||||
* @throws GrowlException
|
||||
* If the notification could not be sent.
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body)
|
||||
throws GrowlException;
|
||||
|
||||
/**
|
||||
* Sends a notification to Growl for displaying. This <b>must</b> be called
|
||||
* after calling {@link #register()}.
|
||||
*
|
||||
* @param name
|
||||
* Name of the notification type that has been registered.
|
||||
* @param title
|
||||
* The title of the notification.
|
||||
* @param body
|
||||
* The body of the notification.
|
||||
* @param icon
|
||||
* The icon to display with the notification.
|
||||
* @throws GrowlException
|
||||
* If the notification could not be sent.
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body,
|
||||
RenderedImage icon) throws GrowlException;
|
||||
|
||||
/**
|
||||
* Sends a notification to Growl for displaying. This <b>must</b> be called
|
||||
* after calling {@link #register()}.
|
||||
*
|
||||
* @param name
|
||||
* Name of the notification type that has been registered.
|
||||
* @param title
|
||||
* The title of the notification.
|
||||
* @param body
|
||||
* The body of the notification.
|
||||
* @param callbackContext
|
||||
* A unique ID that will be sent to any registered
|
||||
* {@link GrowlCallbackListener}s. If this is
|
||||
* <code>null</code> then clicks will be ignored.
|
||||
* @throws GrowlException
|
||||
* If the notification could not be sent.
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body,
|
||||
String callbackContext) throws GrowlException;
|
||||
|
||||
/**
|
||||
* Sends a notification to Growl for displaying. This <b>must</b> be called
|
||||
* after calling {@link #register()}.
|
||||
*
|
||||
* @param name
|
||||
* Name of the notification type that has been registered.
|
||||
* @param title
|
||||
* The title of the notification.
|
||||
* @param body
|
||||
* The body of the notification.
|
||||
* @param callbackContext
|
||||
* A unique ID that will be sent to any registered
|
||||
* {@link GrowlCallbackListener}s. If this is
|
||||
* <code>null</code> then clicks will be ignored.
|
||||
* @param icon
|
||||
* The icon to display with the notification.
|
||||
* @throws GrowlException
|
||||
* If the notification could not be sent.
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body,
|
||||
String callbackContext, RenderedImage icon) throws GrowlException;
|
||||
}
|
46
libgrowl/src/java/info/growl/GrowlCallbackListener.java
Normal file
46
libgrowl/src/java/info/growl/GrowlCallbackListener.java
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Michael Stringer
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Growl nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package info.growl;
|
||||
|
||||
/**
|
||||
* Callback interface for handling users clicking on notifications.
|
||||
*
|
||||
* @author Michael Stringer
|
||||
* @version 0.1
|
||||
*/
|
||||
public interface GrowlCallbackListener {
|
||||
|
||||
/**
|
||||
* Signals that the user has clicked on a notification with an identifier of
|
||||
* <code>clickContext</code>.
|
||||
*
|
||||
* @param clickContext
|
||||
* The ID of the notification clicked.
|
||||
*/
|
||||
public void notificationWasClicked(String clickContext);
|
||||
}
|
60
libgrowl/src/java/info/growl/GrowlException.java
Normal file
60
libgrowl/src/java/info/growl/GrowlException.java
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Michael Stringer
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Growl nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package info.growl;
|
||||
|
||||
/**
|
||||
* An exception class for handling errors while sending messages to Growl.
|
||||
*
|
||||
* @author Michael Stringer
|
||||
* @version 0.1
|
||||
*/
|
||||
public class GrowlException extends Exception {
|
||||
private static final long serialVersionUID = 2642457707267962686L;
|
||||
|
||||
/**
|
||||
* Creates a new <code>GrowlException</code>.
|
||||
*
|
||||
* @param message
|
||||
* The error message.
|
||||
*/
|
||||
public GrowlException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>GrowlException</code>.
|
||||
*
|
||||
* @param message
|
||||
* The error message.
|
||||
* @param cause
|
||||
* The underlying cause.
|
||||
*/
|
||||
public GrowlException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
211
libgrowl/src/java/info/growl/GrowlNative.java
Normal file
211
libgrowl/src/java/info/growl/GrowlNative.java
Normal file
@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Michael Stringer
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Growl nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package info.growl;
|
||||
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
/**
|
||||
* Growl notification implementation. This uses JNI to send messages to Growl.
|
||||
*
|
||||
* @author Michael Stringer
|
||||
* @version 0.1
|
||||
*/
|
||||
class GrowlNative implements Growl {
|
||||
private String appName;
|
||||
private List<NotificationType> notifications;
|
||||
private List<GrowlCallbackListener> callbackListeners;
|
||||
private byte[] imageData;
|
||||
|
||||
private native void sendNotification(String appName, String name,
|
||||
String title, String message, String callbackContext, byte[] icon);
|
||||
|
||||
private native void registerApp(String appName, byte[] image,
|
||||
List<NotificationType> notifications);
|
||||
|
||||
/**
|
||||
* Creates a new <code>GrowlNative</code> instance for the specified
|
||||
* application name.
|
||||
*
|
||||
* @param appName
|
||||
* The name of the application sending notifications.
|
||||
*/
|
||||
GrowlNative(String appName) {
|
||||
notifications = new ArrayList<NotificationType>();
|
||||
callbackListeners = new ArrayList<GrowlCallbackListener>();
|
||||
this.appName = appName;
|
||||
}
|
||||
|
||||
void fireCallbacks(String callbackContext) {
|
||||
for (GrowlCallbackListener listener : callbackListeners) {
|
||||
listener.notificationWasClicked(callbackContext);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void register() throws GrowlException {
|
||||
registerApp(appName, imageData, notifications);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void addNotification(String name, boolean enabledByDefault) {
|
||||
notifications.add(new NotificationType(name, enabledByDefault));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void addCallbackListener(GrowlCallbackListener listener) {
|
||||
callbackListeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void setIcon(RenderedImage icon) throws GrowlException {
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ImageIO.write(icon, "png", baos);
|
||||
|
||||
imageData = baos.toByteArray();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body)
|
||||
throws GrowlException {
|
||||
if (!notifications.contains(new NotificationType(name, false))) {
|
||||
System.out.println("contains: " + notifications);
|
||||
throw new GrowlException("Unregistered notification name [" + name
|
||||
+ "]");
|
||||
}
|
||||
sendNotification(appName, name, title, body, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body,
|
||||
RenderedImage icon) throws GrowlException {
|
||||
if (!notifications.contains(new NotificationType(name, false))) {
|
||||
System.out.println("contains: " + notifications);
|
||||
throw new GrowlException("Unregistered notification name [" + name
|
||||
+ "]");
|
||||
}
|
||||
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ImageIO.write(icon, "png", baos);
|
||||
|
||||
byte[] image = baos.toByteArray();
|
||||
|
||||
sendNotification(appName, name, title, body, null, image);
|
||||
} catch (IOException ioe) {
|
||||
throw new GrowlException("Failed to convert Image", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body,
|
||||
String callbackContext) throws GrowlException {
|
||||
if (!notifications.contains(new NotificationType(name, false))) {
|
||||
System.out.println("contains: " + notifications);
|
||||
throw new GrowlException("Unregistered notification name [" + name
|
||||
+ "]");
|
||||
}
|
||||
|
||||
sendNotification(appName, name, title, body, callbackContext, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void sendNotification(String name, String title, String body,
|
||||
String callbackContext, RenderedImage icon) throws GrowlException {
|
||||
if (!notifications.contains(new NotificationType(name, false))) {
|
||||
System.out.println("contains: " + notifications);
|
||||
throw new GrowlException("Unregistered notification name [" + name
|
||||
+ "]");
|
||||
}
|
||||
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ImageIO.write(icon, "png", baos);
|
||||
|
||||
byte[] image = baos.toByteArray();
|
||||
|
||||
sendNotification(appName, name, title, body, callbackContext, image);
|
||||
} catch (IOException ioe) {
|
||||
throw new GrowlException("Failed to convert Image", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
private class NotificationType {
|
||||
private String name;
|
||||
private boolean enabledByDefault;
|
||||
|
||||
public NotificationType(String name, boolean enabledByDefault) {
|
||||
this.name = name;
|
||||
this.enabledByDefault = enabledByDefault;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean isEnabledByDefault() {
|
||||
return enabledByDefault;
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof NotificationType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NotificationType otherType = (NotificationType) other;
|
||||
|
||||
return name.equals(otherType.name);
|
||||
}
|
||||
}
|
||||
}
|
96
libgrowl/src/java/info/growl/GrowlUtils.java
Normal file
96
libgrowl/src/java/info/growl/GrowlUtils.java
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Michael Stringer
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Growl nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package info.growl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Utility class for sending notifications using Growl.
|
||||
*
|
||||
* @author Michael Stringer
|
||||
* @version 0.1
|
||||
*/
|
||||
public final class GrowlUtils {
|
||||
private static final boolean GROWL_LOADED;
|
||||
private static Map<String, Growl> instances = new HashMap<String, Growl>();
|
||||
|
||||
static {
|
||||
boolean loaded = false;
|
||||
try {
|
||||
System.loadLibrary("growl");
|
||||
loaded = true;
|
||||
} catch (UnsatisfiedLinkError ule) {
|
||||
System.out.println("Failed to load Growl library");
|
||||
}
|
||||
|
||||
GROWL_LOADED = loaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method - should not be instantiated.
|
||||
*/
|
||||
private GrowlUtils() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a <code>Growl</code> instance to use for the specified application
|
||||
* name. Multiple calls to this method will return the same instance.
|
||||
*
|
||||
* @param appName
|
||||
* The name of the application.
|
||||
* @return The <code>Growl</code> instance to use.
|
||||
*/
|
||||
public static Growl getGrowlInstance(String appName) {
|
||||
Growl instance = instances.get(appName);
|
||||
|
||||
if (instance == null) {
|
||||
if (GROWL_LOADED) {
|
||||
instance = new GrowlNative(appName);
|
||||
} else {
|
||||
instance = new DummyGrowl();
|
||||
}
|
||||
|
||||
instances.put(appName, instance);
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether messages can be sent to Growl. If this returns
|
||||
* <code>false</code> then {@link #getGrowlInstance(String)} will return a
|
||||
* dummy object.
|
||||
*
|
||||
* @return <code>true</code> if messages can be sent to Growl.
|
||||
*/
|
||||
public static boolean isGrowlLoaded() {
|
||||
return GROWL_LOADED;
|
||||
}
|
||||
}
|
186
libgrowl/src/java/info/growl/test/TestGrowl.java
Normal file
186
libgrowl/src/java/info/growl/test/TestGrowl.java
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Michael Stringer
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Growl nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package info.growl.test;
|
||||
|
||||
import info.growl.Growl;
|
||||
import info.growl.GrowlCallbackListener;
|
||||
import info.growl.GrowlException;
|
||||
import info.growl.GrowlUtils;
|
||||
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
/**
|
||||
* Simple test class for Growl.
|
||||
*
|
||||
* @author Michael Stringer
|
||||
* @version 0.1
|
||||
*/
|
||||
public class TestGrowl extends JFrame {
|
||||
private static final String APP_NAME = "Test Java App";
|
||||
private static final String NOTIF_3_CALLBACK = "Notif3";
|
||||
|
||||
public TestGrowl() {
|
||||
super("Growl for Java");
|
||||
setSize(320, 290);
|
||||
|
||||
buildComponents();
|
||||
setVisible(true);
|
||||
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
||||
}
|
||||
|
||||
private void buildComponents() {
|
||||
getContentPane().setLayout(new GridLayout(6, 1));
|
||||
|
||||
Action action = new AbstractAction("Register") {
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
try {
|
||||
Growl growl = GrowlUtils.getGrowlInstance(APP_NAME);
|
||||
|
||||
growl.addNotification("Test Notification 1", true);
|
||||
growl.addNotification("Test Notification 2", false);
|
||||
growl.addNotification("Test Notification 3", true);
|
||||
|
||||
GrowlCallbackListener listener = new GrowlCallbackListener() {
|
||||
public void notificationWasClicked(
|
||||
final String clickContext) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
if (NOTIF_3_CALLBACK.equals(clickContext)) {
|
||||
JOptionPane
|
||||
.showMessageDialog(
|
||||
TestGrowl.this,
|
||||
"User clicked on 'Test Notification 3'");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
growl.addCallbackListener(listener);
|
||||
growl.register();
|
||||
} catch (GrowlException ge) {
|
||||
ge.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
getContentPane().add(new JButton(action));
|
||||
|
||||
action = new AbstractAction("Send 'Test Notification 1'") {
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
try {
|
||||
Growl growl = GrowlUtils.getGrowlInstance(APP_NAME);
|
||||
|
||||
growl.sendNotification("Test Notification 1",
|
||||
"Test Notif 1", "This is a test");
|
||||
} catch (GrowlException ge) {
|
||||
ge.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
getContentPane().add(new JButton(action));
|
||||
|
||||
action = new AbstractAction("Send 'Test Notification 2'") {
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
try {
|
||||
Growl growl = GrowlUtils.getGrowlInstance(APP_NAME);
|
||||
BufferedImage image = ImageIO.read(TestGrowl.class
|
||||
.getResource("/images/duke.gif"));
|
||||
growl.sendNotification("Test Notification 2",
|
||||
"Test Notif 2", "This is another test", image);
|
||||
} catch (GrowlException ge) {
|
||||
ge.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
getContentPane().add(new JButton(action));
|
||||
|
||||
action = new AbstractAction("Test Callback 'Notification 3'") {
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
try {
|
||||
Growl growl = GrowlUtils.getGrowlInstance(APP_NAME);
|
||||
|
||||
growl.sendNotification("Test Notification 3",
|
||||
"Callback Test", "Click me - I dares you!", NOTIF_3_CALLBACK);
|
||||
} catch (GrowlException ge) {
|
||||
ge.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
getContentPane().add(new JButton(action));
|
||||
|
||||
action = new AbstractAction("Reg & Test App 2") {
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
try {
|
||||
Growl growl = GrowlUtils.getGrowlInstance("Other App");
|
||||
|
||||
growl.addNotification("A Notification", true);
|
||||
|
||||
BufferedImage image = ImageIO.read(TestGrowl.class
|
||||
.getResource("/images/duke.gif"));
|
||||
growl.setIcon(image);
|
||||
|
||||
growl.register();
|
||||
growl.sendNotification("A Notification", "Testin",
|
||||
"Blah de blah blah");
|
||||
} catch (GrowlException ge) {
|
||||
ge.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
getContentPane().add(new JButton(action));
|
||||
|
||||
action = new AbstractAction("Exit") {
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
System.exit(0);
|
||||
}
|
||||
};
|
||||
getContentPane().add(new JButton(action));
|
||||
}
|
||||
|
||||
public static final void main(String[] args) {
|
||||
new TestGrowl();
|
||||
}
|
||||
}
|
180
libgrowl/src/native/GrowlJava.mm
Normal file
180
libgrowl/src/native/GrowlJava.mm
Normal file
@ -0,0 +1,180 @@
|
||||
|
||||
#import <jni.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
#import "info_growl_GrowlNative.h"
|
||||
#import "GrowlJavaCallback.h"
|
||||
|
||||
jclass jListClass;
|
||||
jmethodID jListSize;
|
||||
jmethodID jListGet;
|
||||
|
||||
jclass gnClass;
|
||||
jmethodID gnFireCallbacks;
|
||||
|
||||
jclass ntClass;
|
||||
jmethodID ntGetName;
|
||||
jmethodID ntIsEnabledByDefault;
|
||||
|
||||
jclass gcClass;
|
||||
jmethodID gcNotificationWasClicked;
|
||||
|
||||
/*
|
||||
* Convert a Java String into a Cocoa NSString.
|
||||
*/
|
||||
NSString *convertJavaStringToCocoa(JNIEnv *env, jstring javaString) {
|
||||
NSString *cocoaString;
|
||||
const char *nativeString;
|
||||
|
||||
nativeString = env->GetStringUTFChars(javaString, JNI_FALSE);
|
||||
cocoaString = [NSString stringWithUTF8String:nativeString];
|
||||
|
||||
return cocoaString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise references to the necessary Java classes & methods.
|
||||
*/
|
||||
void initJavaRefs(JNIEnv *env) {
|
||||
jListClass = env->FindClass("java/util/List");
|
||||
jListSize = env->GetMethodID(jListClass, "size", "()I");
|
||||
jListGet = env->GetMethodID(jListClass, "get", "(I)Ljava/lang/Object;");
|
||||
|
||||
gnClass = env->FindClass("info/growl/GrowlNative");
|
||||
gnFireCallbacks = env->GetMethodID(gnClass, "fireCallbacks", "(Ljava/lang/String;)V");
|
||||
|
||||
ntClass = env->FindClass("info/growl/GrowlNative$NotificationType");
|
||||
ntGetName = env->GetMethodID(ntClass, "getName", "()Ljava/lang/String;");
|
||||
ntIsEnabledByDefault = env->GetMethodID(ntClass, "isEnabledByDefault", "()Z");
|
||||
|
||||
gcClass = env->FindClass("info/growl/GrowlCallbackListener");
|
||||
gcNotificationWasClicked = env->GetMethodID(gcClass, "notificationWasClicked", "(Ljava/lang/String;)V");
|
||||
|
||||
env->ExceptionDescribe();
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: info_growl_GrowlNative
|
||||
* Method: sendNotification
|
||||
* Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[B)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_info_growl_GrowlNative_sendNotification
|
||||
(JNIEnv *env, jobject, jstring jAppName, jstring jNotifName, jstring jTitle, jstring jBody,
|
||||
jstring jCallbackId, jbyteArray jImage) {
|
||||
NSAutoreleasePool *releasePool = [[NSAutoreleasePool alloc] init];
|
||||
NSString *appName = convertJavaStringToCocoa(env, jAppName);
|
||||
NSString *notifName = convertJavaStringToCocoa(env, jNotifName);
|
||||
NSString *title = convertJavaStringToCocoa(env, jTitle);
|
||||
NSString *body = convertJavaStringToCocoa(env, jBody);
|
||||
NSDistributedNotificationCenter *notifCenter = [NSDistributedNotificationCenter defaultCenter];
|
||||
NSMutableDictionary *notifDictionary = [[NSMutableDictionary alloc] init];
|
||||
|
||||
// initialise Java classes/methods
|
||||
initJavaRefs(env);
|
||||
|
||||
// build the dictionary for the notification
|
||||
[notifDictionary setObject:appName forKey:@"ApplicationName"];
|
||||
|
||||
[notifDictionary setObject:appName forKey:@"ApplicationName"];
|
||||
[notifDictionary setObject:notifName forKey:@"NotificationName"];
|
||||
[notifDictionary setObject:title forKey:@"NotificationTitle"];
|
||||
[notifDictionary setObject:body forKey:@"NotificationDescription"];
|
||||
|
||||
if (jCallbackId != NULL) {
|
||||
// notification has a callback - register it
|
||||
NSString *callbackId = convertJavaStringToCocoa(env, jCallbackId);
|
||||
[notifDictionary setObject:callbackId forKey:@"NotificationClickContext"];
|
||||
}
|
||||
|
||||
if (jImage != NULL) {
|
||||
// notification has a custom icon - add it
|
||||
jbyte *nativeImageData = env->GetByteArrayElements(jImage, NULL);
|
||||
NSData *imageData = [NSData dataWithBytes:nativeImageData length:env->GetArrayLength(jImage)];
|
||||
env->ReleaseByteArrayElements(jImage, nativeImageData, JNI_ABORT);
|
||||
|
||||
NSImage *image = [[NSImage alloc] initWithData:imageData];
|
||||
|
||||
[notifDictionary setObject:[image TIFFRepresentation] forKey:@"NotificationIcon"];
|
||||
}
|
||||
|
||||
// send the notification
|
||||
[notifCenter postNotificationName:@"GrowlNotification"
|
||||
object:nil
|
||||
userInfo:notifDictionary
|
||||
deliverImmediately:true];
|
||||
|
||||
// clean up
|
||||
[releasePool release];
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: info_growl_GrowlNative
|
||||
* Method: registerApp
|
||||
* Signature: (Ljava/lang/String;[BLjava/util/List;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_info_growl_GrowlNative_registerApp
|
||||
(JNIEnv *env, jobject jThis, jstring jAppName, jbyteArray jImage, jobject jNotifList) {
|
||||
NSAutoreleasePool *releasePool = [[NSAutoreleasePool alloc] init];
|
||||
NSDistributedNotificationCenter *notifCenter = [NSDistributedNotificationCenter defaultCenter];
|
||||
NSMutableDictionary *regDictionary = [[NSMutableDictionary alloc] init];
|
||||
NSString *appName = convertJavaStringToCocoa(env, jAppName);
|
||||
NSMutableArray *notifNames = [[NSMutableArray alloc] init];
|
||||
NSMutableArray *defaultNotifs = [[NSMutableArray alloc] init];
|
||||
|
||||
// initialise Java classes/methods
|
||||
initJavaRefs(env);
|
||||
|
||||
// build the dictionary for the registration
|
||||
[regDictionary setObject:appName forKey:@"ApplicationName"];
|
||||
|
||||
// loop through the notifications and add them to the list
|
||||
int notifSize = env->CallIntMethod(jNotifList, jListSize);
|
||||
for (int i = 0; i < notifSize; i++) {
|
||||
jobject notifType = env->CallObjectMethod(jNotifList, jListGet, i);
|
||||
jstring jNotifName = (jstring)env->CallObjectMethod(notifType, ntGetName);
|
||||
NSString *notifName = convertJavaStringToCocoa(env, jNotifName);
|
||||
|
||||
[notifNames addObject:notifName];
|
||||
|
||||
if (env->CallBooleanMethod(notifType, ntIsEnabledByDefault)) {
|
||||
// add to default list
|
||||
[defaultNotifs addObject:notifName];
|
||||
}
|
||||
}
|
||||
|
||||
[regDictionary setObject:notifNames forKey:@"AllNotifications"];
|
||||
[regDictionary setObject:defaultNotifs forKey:@"DefaultNotifications"];
|
||||
|
||||
// register the click callback
|
||||
jobject callbackRef = env->NewGlobalRef(jThis);
|
||||
GrowlJavaCallback *callback = [[GrowlJavaCallback alloc] initWithCallback:callbackRef];
|
||||
|
||||
NSString *growlNotifName = [[NSString alloc] initWithFormat:@"%@%@",
|
||||
appName, @"GrowlClicked!"];
|
||||
|
||||
[notifCenter addObserver:callback
|
||||
selector:@selector(growlNotificationWasClicked:)
|
||||
name:growlNotifName
|
||||
object:nil];
|
||||
|
||||
if (jImage != NULL) {
|
||||
// set the image for this application's registration
|
||||
jbyte *nativeImageData = env->GetByteArrayElements(jImage, NULL);
|
||||
NSData *imageData = [NSData dataWithBytes:nativeImageData length:env->GetArrayLength(jImage)];
|
||||
env->ReleaseByteArrayElements(jImage, nativeImageData, JNI_ABORT);
|
||||
|
||||
NSImage *image = [[NSImage alloc] initWithData:imageData];
|
||||
|
||||
[regDictionary setObject:[image TIFFRepresentation] forKey:@"ApplicationIcon"];
|
||||
}
|
||||
|
||||
// send the registration
|
||||
[notifCenter postNotificationName:@"GrowlApplicationRegistrationNotification"
|
||||
object:nil
|
||||
userInfo:regDictionary
|
||||
deliverImmediately:true];
|
||||
|
||||
// clean up
|
||||
[releasePool release];
|
||||
}
|
14
libgrowl/src/native/GrowlJavaCallback.h
Normal file
14
libgrowl/src/native/GrowlJavaCallback.h
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
#import <jni.h>
|
||||
|
||||
@interface GrowlJavaCallback : NSObject {
|
||||
jobject _callbackObject;
|
||||
jclass _callbackClass;
|
||||
jmethodID _callbackMethod;
|
||||
}
|
||||
|
||||
- (id) initWithCallback : (jobject) callback;
|
||||
|
||||
- (void) growlNotificationWasClicked : (NSNotification *)notification;
|
||||
|
||||
@end
|
51
libgrowl/src/native/GrowlJavaCallback.mm
Normal file
51
libgrowl/src/native/GrowlJavaCallback.mm
Normal file
@ -0,0 +1,51 @@
|
||||
|
||||
#import <jni.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
#import "GrowlJavaCallback.h"
|
||||
|
||||
static JavaVM *cachedJVM = NULL;
|
||||
@implementation GrowlJavaCallback
|
||||
|
||||
- (id) initWithCallback : (jobject) callback {
|
||||
self = [super init];
|
||||
|
||||
_callbackObject = callback;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) growlNotificationWasClicked : (NSNotification *)notification {
|
||||
// get the callback id
|
||||
NSDictionary *callbackDictionary = (NSDictionary *)[notification userInfo];
|
||||
NSString *callbackId = (NSString *)[callbackDictionary objectForKey:@"ClickedContext"];
|
||||
const char *nativeString;
|
||||
jstring convertedString;
|
||||
|
||||
if (cachedJVM == NULL) {
|
||||
jsize jvmCount;
|
||||
jint jvmError = JNI_GetCreatedJavaVMs(&cachedJVM, 1, &jvmCount);
|
||||
|
||||
if (jvmError != 0) {
|
||||
// TODO panic like crazy
|
||||
NSLog(@"Error error error");
|
||||
}
|
||||
}
|
||||
|
||||
if (cachedJVM != NULL) {
|
||||
JNIEnv *env = NULL;
|
||||
cachedJVM->GetEnv((void **)&env, JNI_VERSION_1_2);
|
||||
|
||||
_callbackClass = env->GetObjectClass(_callbackObject);
|
||||
_callbackMethod = env->GetMethodID(_callbackClass, "fireCallbacks", "(Ljava/lang/String;)V");
|
||||
|
||||
nativeString = [callbackId UTF8String];
|
||||
convertedString = env->NewStringUTF(nativeString);
|
||||
|
||||
// fire off the callback
|
||||
env->CallVoidMethod(_callbackObject, _callbackMethod, convertedString);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
30
libgrowl/src/native/Makefile
Normal file
30
libgrowl/src/native/Makefile
Normal file
@ -0,0 +1,30 @@
|
||||
CXX = g++
|
||||
CXXFLAGS = -W -Wall -c -I/System/Library/Frameworks/JavaVM.framework/Headers -I/System/Library/Frameworks/AppKit.framework/Headers -I/System/Library/Frameworks/Foundation.framework/Headers -isysroot /Developer/SDKs/MacOSX10.5.sdk -arch i386 -arch ppc -arch x86_64 -mmacosx-version-min=10.4
|
||||
MMFLAGS = -Wno-protocol -Wundeclared-selector
|
||||
LDFLAGS = -dynamiclib -isysroot /Developer/SDKs/MacOSX10.5.sdk -arch i386 -arch ppc -arch x86_64 -mmacosx-version-min=10.4
|
||||
LDSUFFIXES = -framework JavaVM -framework Foundation -framework AppKit
|
||||
SO_NAME = libgrowl.jnilib
|
||||
|
||||
.SUFFIXES: .o .mm
|
||||
.mm.o:
|
||||
$(CXX) $(MMFLAGS) $(CXXFLAGS) $<
|
||||
|
||||
MMSRCS = GrowlJava.mm \
|
||||
GrowlJavaCallback.mm
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(SO_NAME)
|
||||
|
||||
SO_o = $(MMSRCS:.mm=.o)
|
||||
|
||||
.cpp.o:
|
||||
$(CXX) $(CXXFLAGS) $(INCLUDES) $(EXTRA_INCLUDES) -o $@ $<
|
||||
|
||||
$(SO_NAME): $(SO_o)
|
||||
$(CXX) $(LDFLAGS) $(LIBS) $(SO_o) -o $@ $(LDSUFFIXES)
|
||||
|
||||
clean:
|
||||
rm -f *.jnilib
|
||||
rm -f *.o
|
||||
|
BIN
libgrowl/src/resources/images/duke.gif
Normal file
BIN
libgrowl/src/resources/images/duke.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.6 KiB |
Loading…
Reference in New Issue
Block a user