--- /dev/null
+*.pbxuser
+*.mode1v3
+.DS_Store
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBClasses</key>
+ <array>
+ <dict>
+ <key>CLASS</key>
+ <string>NSView</string>
+ <key>LANGUAGE</key>
+ <string>ObjC</string>
+ <key>SUPERCLASS</key>
+ <string>NSResponder</string>
+ </dict>
+ <dict>
+ <key>CLASS</key>
+ <string>FirstResponder</string>
+ <key>LANGUAGE</key>
+ <string>ObjC</string>
+ <key>SUPERCLASS</key>
+ <string>NSObject</string>
+ </dict>
+ <dict>
+ <key>CLASS</key>
+ <string>NSObject</string>
+ <key>LANGUAGE</key>
+ <string>ObjC</string>
+ </dict>
+ <dict>
+ <key>CLASS</key>
+ <string>NSPreferencePane</string>
+ <key>LANGUAGE</key>
+ <string>ObjC</string>
+ <key>OUTLETS</key>
+ <dict>
+ <key>_firstKeyView</key>
+ <string>NSView</string>
+ <key>_initialKeyView</key>
+ <string>NSView</string>
+ <key>_lastKeyView</key>
+ <string>NSView</string>
+ <key>_window</key>
+ <string>NSWindow</string>
+ </dict>
+ <key>SUPERCLASS</key>
+ <string>NSObject</string>
+ </dict>
+ <dict>
+ <key>CLASS</key>
+ <string>NSWindow</string>
+ <key>LANGUAGE</key>
+ <string>ObjC</string>
+ <key>SUPERCLASS</key>
+ <string>NSResponder</string>
+ </dict>
+ <dict>
+ <key>CLASS</key>
+ <string>GrowlITTSWPrefs</string>
+ <key>LANGUAGE</key>
+ <string>ObjC</string>
+ <key>OUTLETS</key>
+ <dict>
+ <key>slider_opacity</key>
+ <string>NSSlider</string>
+ </dict>
+ <key>SUPERCLASS</key>
+ <string>NSPreferencePane</string>
+ </dict>
+ </array>
+ <key>IBVersion</key>
+ <string>1</string>
+</dict>
+</plist>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBFramework Version</key>
+ <string>672</string>
+ <key>IBLastKnownRelativeProjectPath</key>
+ <string>../../../../Growl.xcodeproj</string>
+ <key>IBOldestOS</key>
+ <integer>3</integer>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>6</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>9G55</string>
+ <key>targetFramework</key>
+ <string>IBCocoaFramework</string>
+</dict>
+</plist>
--- /dev/null
+//
+// GrowlApplicationNotification.h
+// Growl
+//
+// Created by Mac-arena the Bored Zo on 2005-07-31.
+// Copyright 2005-2006 The Growl Project. All rights reserved.
+//
+
+@interface GrowlApplicationNotification: NSObject
+{
+ NSString *name, *applicationName;
+ NSString *title, *description;
+ NSAttributedString *attributedTitle, *attributedDescription;
+
+ NSDictionary *dictionary, *auxiliaryDictionary;
+
+ unsigned GANReserved: 30;
+}
+
++ (GrowlApplicationNotification *) notificationWithDictionary:(NSDictionary *)dict;
+
+- (GrowlApplicationNotification *) initWithDictionary:(NSDictionary *)dict;
+
+//you can pass nil for description.
+- (GrowlApplicationNotification *) initWithName:(NSString *)newName
+ applicationName:(NSString *)newAppName
+ title:(NSString *)newTitle
+ description:(NSString *)newDesc;
+
+//you can pass nil for description.
+- (GrowlApplicationNotification *) initWithName:(NSString *)newName
+ applicationName:(NSString *)newAppName
+ title:(NSString *)newTitle
+ description:(NSString *)newDesc;
+
+#pragma mark -
+
+/*as of 0.8, this returns:
+ * * GROWL_NOTIFICATION_NAME
+ * * GROWL_APP_NAME
+ * * GROWL_NOTIFICATION_TITLE
+ * * GROWL_NOTIFICATION_DESCRIPTION
+ *you can pass this set to -dictionaryRepresentationWithKeys:.
+ */
++ (NSSet *) standardKeys;
+
+//same as dictionaryRepresentationWithKeys:nil.
+- (NSDictionary *) dictionaryRepresentation;
+
+/*with nil, returns all of the standard keys plus the auxiliary dictionary.
+ *with non-nil, returns only the keys (from internal storage plus the auxiliary
+ * dictionary) that are in the set.
+ *in other words, returns the intersection of the standard dictionary keys, the
+ * auxiliary dictionary, and the provided keys.
+ */
+- (NSDictionary *) dictionaryRepresentationWithKeys:(NSSet *)keys;
+
+#pragma mark -
+
+- (NSString *) name;
+- (NSString *) applicationName;
+
+- (NSString *) title;
+- (NSAttributedString *) attributedTitle;
+
+- (NSString *) notificationDescription;
+- (NSAttributedString *) attributedDescription;
+
+- (NSDictionary *) auxiliaryDictionary;
+- (void) setAuxiliaryDictionary:(NSDictionary *)newAuxDict;
+
+@end
--- /dev/null
+//
+// GrowlDefines.h
+//
+
+#ifndef _GROWLDEFINES_H
+#define _GROWLDEFINES_H
+
+#ifdef __OBJC__
+#define XSTR(x) (@x)
+#define STRING_TYPE NSString *
+#else
+#define XSTR CFSTR
+#define STRING_TYPE CFStringRef
+#endif
+
+/*! @header GrowlDefines.h
+ * @abstract Defines all the notification keys.
+ * @discussion Defines all the keys used for registration with Growl and for
+ * Growl notifications.
+ *
+ * Most applications should use the functions or methods of Growl.framework
+ * instead of posting notifications such as those described here.
+ * @updated 2004-01-25
+ */
+
+// UserInfo Keys for Registration
+#pragma mark UserInfo Keys for Registration
+
+/*! @group Registration userInfo keys */
+/* @abstract Keys for the userInfo dictionary of a GROWL_APP_REGISTRATION distributed notification.
+ * @discussion The values of these keys describe the application and the
+ * notifications it may post.
+ *
+ * Your application must register with Growl before it can post Growl
+ * notifications (and have them not be ignored). However, as of Growl 0.6,
+ * posting GROWL_APP_REGISTRATION notifications directly is no longer the
+ * preferred way to register your application. Your application should instead
+ * use Growl.framework's delegate system.
+ * See +[GrowlApplicationBridge setGrowlDelegate:] or Growl_SetDelegate for
+ * more information.
+ */
+
+/*! @defined GROWL_APP_NAME
+ * @abstract The name of your application.
+ * @discussion The name of your application. This should remain stable between
+ * different versions and incarnations of your application.
+ * For example, "SurfWriter" is a good app name, whereas "SurfWriter 2.0" and
+ * "SurfWriter Lite" are not.
+ */
+#define GROWL_APP_NAME XSTR("ApplicationName")
+/*! @defined GROWL_APP_ID
+ * @abstract The bundle identifier of your application.
+ * @discussion The bundle identifier of your application. This key should
+ * be unique for your application while there may be several applications
+ * with the same GROWL_APP_NAME.
+ * This key is optional.
+ */
+#define GROWL_APP_ID XSTR("ApplicationId")
+/*! @defined GROWL_APP_ICON
+ * @abstract The image data for your application's icon.
+ * @discussion Image data representing your application's icon. This may be
+ * superimposed on a notification icon as a badge, used as the notification
+ * icon when a notification-specific icon is not supplied, or ignored
+ * altogether, depending on the display. Must be in a format supported by
+ * NSImage, such as TIFF, PNG, GIF, JPEG, BMP, PICT, or PDF.
+ *
+ * Optional. Not supported by all display plugins.
+ */
+#define GROWL_APP_ICON XSTR("ApplicationIcon")
+/*! @defined GROWL_NOTIFICATIONS_DEFAULT
+ * @abstract The array of notifications to turn on by default.
+ * @discussion These are the names of the notifications that should be enabled
+ * by default when your application registers for the first time. If your
+ * application reregisters, Growl will look here for any new notification
+ * names found in GROWL_NOTIFICATIONS_ALL, but ignore any others.
+ */
+#define GROWL_NOTIFICATIONS_DEFAULT XSTR("DefaultNotifications")
+/*! @defined GROWL_NOTIFICATIONS_ALL
+ * @abstract The array of all notifications your application can send.
+ * @discussion These are the names of all of the notifications that your
+ * application may post. See GROWL_NOTIFICATION_NAME for a discussion of good
+ * notification names.
+ */
+#define GROWL_NOTIFICATIONS_ALL XSTR("AllNotifications")
+/*! @defined GROWL_NOTIFICATIONS_HUMAN_READABLE_DESCRIPTIONS
+ * @abstract A dictionary of human-readable names for your notifications.
+ * @discussion By default, the Growl UI will display notifications by the names given in GROWL_NOTIFICATIONS_ALL
+ * which correspond to the GROWL_NOTIFICATION_NAME. This dictionary specifies the human-readable name to display.
+ * The keys of the dictionary are GROWL_NOTIFICATION_NAME strings; the objects are the human-readable versions.
+ * For any GROWL_NOTIFICATION_NAME not specific in this dictionary, the GROWL_NOTIFICATION_NAME will be displayed.
+ *
+ * This key is optional.
+ */
+#define GROWL_NOTIFICATIONS_HUMAN_READABLE_NAMES XSTR("HumanReadableNames")
+/*! @defined GROWL_NOTIFICATIONS_DESCRIPTIONS
+* @abstract A dictionary of descriptions of _when_ each notification occurs
+* @discussion This is an NSDictionary whose keys are GROWL_NOTIFICATION_NAME strings and whose objects are
+* descriptions of _when_ each notification occurs, such as "You received a new mail message" or
+* "A file finished downloading".
+*
+* This key is optional.
+*/
+#define GROWL_NOTIFICATIONS_DESCRIPTIONS XSTR("NotificationDescriptions")
+
+/*! @defined GROWL_TICKET_VERSION
+ * @abstract The version of your registration ticket.
+ * @discussion Include this key in a ticket plist file that you put in your
+ * application bundle for auto-discovery. The current ticket version is 1.
+ */
+#define GROWL_TICKET_VERSION XSTR("TicketVersion")
+// UserInfo Keys for Notifications
+#pragma mark UserInfo Keys for Notifications
+
+/*! @group Notification userInfo keys */
+/* @abstract Keys for the userInfo dictionary of a GROWL_NOTIFICATION distributed notification.
+ * @discussion The values of these keys describe the content of a Growl
+ * notification.
+ *
+ * Not all of these keys are supported by all displays. Only the name, title,
+ * and description of a notification are universal. Most of the built-in
+ * displays do support all of these keys, and most other visual displays
+ * probably will also. But, as of 0.6, the Log, MailMe, and Speech displays
+ * support only textual data.
+ */
+
+/*! @defined GROWL_NOTIFICATION_NAME
+ * @abstract The name of the notification.
+ * @discussion The name of the notification. Note that if you do not define
+ * GROWL_NOTIFICATIONS_HUMAN_READABLE_NAMES when registering your ticket originally this name
+ * will the one displayed within the Growl preference pane and should be human-readable.
+ */
+#define GROWL_NOTIFICATION_NAME XSTR("NotificationName")
+/*! @defined GROWL_NOTIFICATION_TITLE
+ * @abstract The title to display in the notification.
+ * @discussion The title of the notification. Should be very brief.
+ * The title usually says what happened, e.g. "Download complete".
+ */
+#define GROWL_NOTIFICATION_TITLE XSTR("NotificationTitle")
+/*! @defined GROWL_NOTIFICATION_DESCRIPTION
+ * @abstract The description to display in the notification.
+ * @discussion The description should be longer and more verbose than the title.
+ * The description usually tells the subject of the action,
+ * e.g. "Growl-0.6.dmg downloaded in 5.02 minutes".
+ */
+#define GROWL_NOTIFICATION_DESCRIPTION XSTR("NotificationDescription")
+/*! @defined GROWL_NOTIFICATION_ICON
+ * @discussion Image data for the notification icon. Must be in a format
+ * supported by NSImage, such as TIFF, PNG, GIF, JPEG, BMP, PICT, or PDF.
+ *
+ * Optional. Not supported by all display plugins.
+ */
+#define GROWL_NOTIFICATION_ICON XSTR("NotificationIcon")
+/*! @defined GROWL_NOTIFICATION_APP_ICON
+ * @discussion Image data for the application icon, in case GROWL_APP_ICON does
+ * not apply for some reason. Must be in a format supported by NSImage, such
+ * as TIFF, PNG, GIF, JPEG, BMP, PICT, or PDF.
+ *
+ * Optional. Not supported by all display plugins.
+ */
+#define GROWL_NOTIFICATION_APP_ICON XSTR("NotificationAppIcon")
+/*! @defined GROWL_NOTIFICATION_PRIORITY
+ * @discussion The priority of the notification as an integer number from
+ * -2 to +2 (+2 being highest).
+ *
+ * Optional. Not supported by all display plugins.
+ */
+#define GROWL_NOTIFICATION_PRIORITY XSTR("NotificationPriority")
+/*! @defined GROWL_NOTIFICATION_STICKY
+ * @discussion A Boolean number controlling whether the notification is sticky.
+ *
+ * Optional. Not supported by all display plugins.
+ */
+#define GROWL_NOTIFICATION_STICKY XSTR("NotificationSticky")
+/*! @defined GROWL_NOTIFICATION_CLICK_CONTEXT
+ * @abstract Identifies which notification was clicked.
+ * @discussion An identifier for the notification for clicking purposes.
+ *
+ * This will be passed back to the application when the notification is
+ * clicked. It must be plist-encodable (a data, dictionary, array, number, or
+ * string object), and it should be unique for each notification you post.
+ * A good click context would be a UUID string returned by NSProcessInfo or
+ * CFUUID.
+ *
+ * Optional. Not supported by all display plugins.
+ */
+#define GROWL_NOTIFICATION_CLICK_CONTEXT XSTR("NotificationClickContext")
+
+/*! @defined GROWL_DISPLAY_PLUGIN
+ * @discussion The name of a display plugin which should be used for this notification.
+ * Optional. If this key is not set or the specified display plugin does not
+ * exist, the display plugin stored in the application ticket is used. This key
+ * allows applications to use different default display plugins for their
+ * notifications. The user can still override those settings in the preference
+ * pane.
+ */
+#define GROWL_DISPLAY_PLUGIN XSTR("NotificationDisplayPlugin")
+
+/*! @defined GROWL_NOTIFICATION_IDENTIFIER
+ * @abstract An identifier for the notification for coalescing purposes.
+ * Notifications with the same identifier fall into the same class; only
+ * the last notification of a class is displayed on the screen. If a
+ * notification of the same class is currently being displayed, it is
+ * replaced by this notification.
+ *
+ * Optional. Not supported by all display plugins.
+ */
+#define GROWL_NOTIFICATION_IDENTIFIER XSTR("GrowlNotificationIdentifier")
+
+/*! @defined GROWL_APP_PID
+ * @abstract The process identifier of the process which sends this
+ * notification. If this field is set, the application will only receive
+ * clicked and timed out notifications which originate from this process.
+ *
+ * Optional.
+ */
+#define GROWL_APP_PID XSTR("ApplicationPID")
+
+/*! @defined GROWL_NOTIFICATION_PROGRESS
+* @abstract If this key is set, it should contain a double value wrapped
+* in a NSNumber which describes some sort of progress (from 0.0 to 100.0).
+* If this is key is not set, no progress bar is shown.
+*
+* Optional. Not supported by all display plugins.
+*/
+#define GROWL_NOTIFICATION_PROGRESS XSTR("NotificationProgress")
+
+// Notifications
+#pragma mark Notifications
+
+/*! @group Notification names */
+/* @abstract Names of distributed notifications used by Growl.
+ * @discussion These are notifications used by applications (directly or
+ * indirectly) to interact with Growl, and by Growl for interaction between
+ * its components.
+ *
+ * Most of these should no longer be used in Growl 0.6 and later, in favor of
+ * Growl.framework's GrowlApplicationBridge APIs.
+ */
+
+/*! @defined GROWL_APP_REGISTRATION
+ * @abstract The distributed notification for registering your application.
+ * @discussion This is the name of the distributed notification that can be
+ * used to register applications with Growl.
+ *
+ * The userInfo dictionary for this notification can contain these keys:
+ * <ul>
+ * <li>GROWL_APP_NAME</li>
+ * <li>GROWL_APP_ICON</li>
+ * <li>GROWL_NOTIFICATIONS_ALL</li>
+ * <li>GROWL_NOTIFICATIONS_DEFAULT</li>
+ * </ul>
+ *
+ * No longer recommended as of Growl 0.6. An alternate method of registering
+ * is to use Growl.framework's delegate system.
+ * See +[GrowlApplicationBridge setGrowlDelegate:] or Growl_SetDelegate for
+ * more information.
+ */
+#define GROWL_APP_REGISTRATION XSTR("GrowlApplicationRegistrationNotification")
+/*! @defined GROWL_APP_REGISTRATION_CONF
+ * @abstract The distributed notification for confirming registration.
+ * @discussion The name of the distributed notification sent to confirm the
+ * registration. Used by the Growl preference pane. Your application probably
+ * does not need to use this notification.
+ */
+#define GROWL_APP_REGISTRATION_CONF XSTR("GrowlApplicationRegistrationConfirmationNotification")
+/*! @defined GROWL_NOTIFICATION
+ * @abstract The distributed notification for Growl notifications.
+ * @discussion This is what it all comes down to. This is the name of the
+ * distributed notification that your application posts to actually send a
+ * Growl notification.
+ *
+ * The userInfo dictionary for this notification can contain these keys:
+ * <ul>
+ * <li>GROWL_NOTIFICATION_NAME (required)</li>
+ * <li>GROWL_NOTIFICATION_TITLE (required)</li>
+ * <li>GROWL_NOTIFICATION_DESCRIPTION (required)</li>
+ * <li>GROWL_NOTIFICATION_ICON</li>
+ * <li>GROWL_NOTIFICATION_APP_ICON</li>
+ * <li>GROWL_NOTIFICATION_PRIORITY</li>
+ * <li>GROWL_NOTIFICATION_STICKY</li>
+ * <li>GROWL_NOTIFICATION_CLICK_CONTEXT</li>
+ * <li>GROWL_APP_NAME (required)</li>
+ * </ul>
+ *
+ * No longer recommended as of Growl 0.6. Three alternate methods of posting
+ * notifications are +[GrowlApplicationBridge notifyWithTitle:description:notificationName:iconData:priority:isSticky:clickContext:],
+ * Growl_NotifyWithTitleDescriptionNameIconPriorityStickyClickContext, and
+ * Growl_PostNotification.
+ */
+#define GROWL_NOTIFICATION XSTR("GrowlNotification")
+/*! @defined GROWL_SHUTDOWN
+* @abstract The distributed notification name that tells Growl to shutdown.
+* @discussion The Growl preference pane posts this notification when the
+* "Stop Growl" button is clicked.
+*/
+#define GROWL_SHUTDOWN XSTR("GrowlShutdown")
+/*! @defined GROWL_PING
+ * @abstract A distributed notification to check whether Growl is running.
+ * @discussion This is used by the Growl preference pane. If it receives a
+ * GROWL_PONG, the preference pane takes this to mean that Growl is running.
+ */
+#define GROWL_PING XSTR("Honey, Mind Taking Out The Trash")
+/*! @defined GROWL_PONG
+ * @abstract The distributed notification sent in reply to GROWL_PING.
+ * @discussion GrowlHelperApp posts this in reply to GROWL_PING.
+ */
+#define GROWL_PONG XSTR("What Do You Want From Me, Woman")
+/*! @defined GROWL_IS_READY
+ * @abstract The distributed notification sent when Growl starts up.
+ * @discussion GrowlHelperApp posts this when it has begin listening on all of
+ * its sources for new notifications. GrowlApplicationBridge (in
+ * Growl.framework), upon receiving this notification, reregisters using the
+ * registration dictionary supplied by its delegate.
+ */
+#define GROWL_IS_READY XSTR("Lend Me Some Sugar; I Am Your Neighbor!")
+/*! @defined GROWL_NOTIFICATION_CLICKED
+ * @abstract The distributed notification sent when a supported notification is clicked.
+ * @discussion When a Growl notification with a click context is clicked on by
+ * the user, Growl posts this distributed notification.
+ * The GrowlApplicationBridge responds to this notification by calling a
+ * callback in its delegate.
+ */
+#define GROWL_NOTIFICATION_CLICKED XSTR("GrowlClicked!")
+#define GROWL_NOTIFICATION_TIMED_OUT XSTR("GrowlTimedOut!")
+
+/*! @group Other symbols */
+/* Symbols which don't fit into any of the other categories. */
+
+/*! @defined GROWL_KEY_CLICKED_CONTEXT
+ * @abstract Used internally as the key for the clickedContext passed over DNC.
+ * @discussion This key is used in GROWL_NOTIFICATION_CLICKED, and contains the
+ * click context that was supplied in the original notification.
+ */
+#define GROWL_KEY_CLICKED_CONTEXT XSTR("ClickedContext")
+/*! @defined GROWL_REG_DICT_EXTENSION
+ * @abstract The filename extension for registration dictionaries.
+ * @discussion The GrowlApplicationBridge in Growl.framework registers with
+ * Growl by creating a file with the extension of .(GROWL_REG_DICT_EXTENSION)
+ * and opening it in the GrowlHelperApp. This happens whether or not Growl is
+ * running; if it was stopped, it quits immediately without listening for
+ * notifications.
+ */
+#define GROWL_REG_DICT_EXTENSION XSTR("growlRegDict")
+
+
+#define GROWL_POSITION_PREFERENCE_KEY @"GrowlSelectedPosition"
+
+#endif //ndef _GROWLDEFINES_H
--- /dev/null
+//
+// GrowlDefinesInternal.h
+// Growl
+//
+// Created by Karl Adam on Mon May 17 2004.
+// Copyright (c) 2004 the Growl Project. All rights reserved.
+//
+
+#ifndef _GROWL_GROWLDEFINESINTERNAL_H
+#define _GROWL_GROWLDEFINESINTERNAL_H
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#ifdef __OBJC__
+#define XSTR(x) (@x)
+#else /* !__OBJC__ */
+#define XSTR CFSTR
+#endif /* __OBJC__ */
+
+/*! @header GrowlDefinesInternal.h
+ * @abstract Defines internal Growl macros and types.
+ * @ignore ATTRIBUTE_PACKED
+ * @discussion These constants are used both by GrowlHelperApp and by plug-ins.
+ *
+ * Notification keys (used in GrowlHelperApp, in GrowlApplicationBridge, and
+ * by applications that don't use GrowlApplicationBridge) are defined in
+ * GrowlDefines.h.
+ */
+
+/*! @defined GROWL_TCP_PORT
+ * @abstract The TCP listen port for Growl notification servers.
+ */
+#define GROWL_TCP_PORT 23052
+
+/*! @defined GROWL_UDP_PORT
+ * @abstract The UDP listen port for Growl notification servers.
+ */
+#define GROWL_UDP_PORT 9887
+
+/*! @defined GROWL_PROTOCOL_VERSION
+ * @abstract The current version of the Growl network-notifications protocol (without encryption).
+ */
+#define GROWL_PROTOCOL_VERSION 1
+
+/*! @defined GROWL_PROTOCOL_VERSION_AES128
+* @abstract The current version of the Growl network-notifications protocol (with AES-128 encryption).
+*/
+#define GROWL_PROTOCOL_VERSION_AES128 2
+
+/*! @defined GROWL_TYPE_REGISTRATION
+ * @abstract The packet type of registration packets with MD5 authentication.
+ */
+#define GROWL_TYPE_REGISTRATION 0
+/*! @defined GROWL_TYPE_NOTIFICATION
+ * @abstract The packet type of notification packets with MD5 authentication.
+ */
+#define GROWL_TYPE_NOTIFICATION 1
+/*! @defined GROWL_TYPE_REGISTRATION_SHA256
+ * @abstract The packet type of registration packets with SHA-256 authentication.
+ */
+#define GROWL_TYPE_REGISTRATION_SHA256 2
+/*! @defined GROWL_TYPE_NOTIFICATION_SHA256
+ * @abstract The packet type of notification packets with SHA-256 authentication.
+ */
+#define GROWL_TYPE_NOTIFICATION_SHA256 3
+/*! @defined GROWL_TYPE_REGISTRATION_NOAUTH
+* @abstract The packet type of registration packets without authentication.
+*/
+#define GROWL_TYPE_REGISTRATION_NOAUTH 4
+/*! @defined GROWL_TYPE_NOTIFICATION_NOAUTH
+* @abstract The packet type of notification packets without authentication.
+*/
+#define GROWL_TYPE_NOTIFICATION_NOAUTH 5
+
+#define ATTRIBUTE_PACKED __attribute((packed))
+
+/*! @struct GrowlNetworkPacket
+ * @abstract This struct is a header common to all incoming Growl network
+ * packets which identifies the type and version of the packet.
+ */
+struct GrowlNetworkPacket {
+ unsigned char version;
+ unsigned char type;
+} ATTRIBUTE_PACKED;
+
+/*!
+ * @struct GrowlNetworkRegistration
+ * @abstract The format of a registration packet.
+ * @discussion A Growl client that wants to register with a Growl server sends
+ * a packet in this format.
+ * @field common The Growl packet header.
+ * @field appNameLen The name of the application that is registering.
+ * @field numAllNotifications The number of notifications in the list.
+ * @field numDefaultNotifications The number of notifications in the list that are enabled by default.
+ * @field data Variable-sized data.
+ */
+struct GrowlNetworkRegistration {
+ struct GrowlNetworkPacket common;
+ /* This name is used both internally and in the Growl
+ * preferences.
+ *
+ * The application name should remain stable between different versions
+ * and incarnations of your application.
+ * For example, "SurfWriter" is a good app name, whereas "SurfWriter 2.0"
+ * and "SurfWriter Lite" are not.
+ *
+ * In addition to being unsigned, the application name length is in
+ * network byte order.
+ */
+ unsigned short appNameLen;
+ /* These names are used both internally and in the Growl
+ * preferences. For this reason, they should be human-readable.
+ */
+ unsigned char numAllNotifications;
+
+ unsigned char numDefaultNotifications;
+ /* The variable-sized data of a registration is:
+ * - The application name, in UTF-8 encoding, for appNameLen bytes.
+ * - The list of all notification names.
+ * - The list of default notifications, as 8-bit unsigned indices into the list of all notifications.
+ * - The MD5/SHA256 checksum of all the data preceding the checksum.
+ *
+ * Each notification name is encoded as:
+ * - Length: two bytes, unsigned, network byte order.
+ * - Name: As many bytes of UTF-8-encoded text as the length says.
+ * And there are numAllNotifications of these.
+ */
+ unsigned char data[];
+} ATTRIBUTE_PACKED;
+
+/*!
+ * @struct GrowlNetworkNotification
+ * @abstract The format of a notification packet.
+ * @discussion A Growl client that wants to post a notification to a Growl
+ * server sends a packet in this format.
+ * @field common The Growl packet header.
+ * @field flags The priority number and the sticky bit.
+ * @field nameLen The length of the notification name.
+ * @field titleLen The length of the notification title.
+ * @field descriptionLen The length of the notification description.
+ * @field appNameLen The length of the application name.
+ * @field data Variable-sized data.
+ */
+struct GrowlNetworkNotification {
+ struct GrowlNetworkPacket common;
+ /*!
+ * @struct GrowlNetworkNotificationFlags
+ * @abstract Various flags.
+ * @discussion This 16-bit packed structure contains the priority as a
+ * signed 3-bit integer from -2 to +2, and the sticky flag as a single bit.
+ * The high 12 bits of the structure are reserved for future use.
+ * @field reserved reserved for future use.
+ * @field priority the priority as a signed 3-bit integer from -2 to +2.
+ * @field sticky the sticky flag.
+ */
+ struct GrowlNetworkNotificationFlags {
+#ifdef __BIG_ENDIAN__
+ unsigned reserved: 12;
+ signed priority: 3;
+ unsigned sticky: 1;
+#else
+ unsigned sticky: 1;
+ signed priority: 3;
+ unsigned reserved: 12;
+#endif
+ } ATTRIBUTE_PACKED flags; //size = 16 (12 + 3 + 1)
+
+ /* In addition to being unsigned, the notification name length
+ * is in network byte order.
+ */
+ unsigned short nameLen;
+ /* @discussion In addition to being unsigned, the title length is in
+ * network byte order.
+ */
+ unsigned short titleLen;
+ /* In addition to being unsigned, the description length is in
+ * network byte order.
+ */
+ unsigned short descriptionLen;
+ /* In addition to being unsigned, the application name length
+ * is in network byte order.
+ */
+ unsigned short appNameLen;
+ /* The variable-sized data of a notification is:
+ * - Notification name, in UTF-8 encoding, for nameLen bytes.
+ * - Title, in UTF-8 encoding, for titleLen bytes.
+ * - Description, in UTF-8 encoding, for descriptionLen bytes.
+ * - Application name, in UTF-8 encoding, for appNameLen bytes.
+ * - The MD5/SHA256 checksum of all the data preceding the checksum.
+ */
+ unsigned char data[];
+} ATTRIBUTE_PACKED;
+
+/*! @defined GrowlEnabledKey
+ * @abstract Preference key controlling whether Growl is enabled.
+ * @discussion If this is false, then when GrowlHelperApp is launched to open
+ * a Growl registration dictionary file, GrowlHelperApp will quit when it has
+ * finished processing the file instead of listening for notifications.
+ */
+#define GrowlEnabledKey XSTR("GrowlEnabled")
+
+/*! @defined GROWL_SCREENSHOT_MODE
+ * @abstract Preference and notification key controlling whether to save a screenshot of the notification.
+ * @discussion This is for GHA's private usage. If your application puts this
+ * key into a notification dictionary, GHA will clobber it. This key is only
+ * allowed in the notification dictionaries GHA passes to displays.
+ *
+ * If this key contains an object whose boolValue is not NO, the display is
+ * asked to save a screenshot of the notification to
+ * ~/Library/Application\ Support/Growl/Screenshots.
+ */
+#define GROWL_SCREENSHOT_MODE XSTR("ScreenshotMode")
+
+/*! @defined GROWL_APP_LOCATION
+ * @abstract The location of this application.
+ * @discussion Contains either the POSIX path to the application, or a file-data dictionary (as used by the Dock).
+ * contains the file's alias record and its pathname.
+ */
+#define GROWL_APP_LOCATION XSTR("AppLocation")
+
+/*! @defined GROWL_REMOTE_ADDRESS
+ * @abstract The address of the host who sent this notification/registration.
+ * @discussion Contains an NSData with the address of the remote host who
+ * sent this notification/registration.
+ */
+#define GROWL_REMOTE_ADDRESS XSTR("RemoteAddress")
+
+/*!
+ * @defined GROWL_PREFPANE_BUNDLE_IDENTIFIER
+ * @discussion The bundle identifier for the Growl preference pane.
+ */
+#define GROWL_PREFPANE_BUNDLE_IDENTIFIER XSTR("com.growl.prefpanel")
+/*!
+ * @defined GROWL_HELPERAPP_BUNDLE_IDENTIFIER
+ * @discussion The bundle identifier for the Growl background application (GrowlHelperApp).
+ */
+#define GROWL_HELPERAPP_BUNDLE_IDENTIFIER XSTR("com.Growl.GrowlHelperApp")
+
+/*!
+ * @defined GROWL_PREFPANE_NAME
+ * @discussion The file name of the Growl preference pane.
+ */
+#define GROWL_PREFPANE_NAME XSTR("Growl.prefPane")
+#define PREFERENCE_PANES_SUBFOLDER_OF_LIBRARY XSTR("PreferencePanes")
+#define PREFERENCE_PANE_EXTENSION XSTR("prefPane")
+
+//plug-in bundle filename extensions
+#define GROWL_PLUGIN_EXTENSION XSTR("growlPlugin")
+#define GROWL_PATHWAY_EXTENSION XSTR("growlPathway")
+#define GROWL_VIEW_EXTENSION XSTR("growlView")
+#define GROWL_STYLE_EXTENSION XSTR("growlStyle")
+
+/* --- These following macros are intended for plug-ins --- */
+
+/*! @function SYNCHRONIZE_GROWL_PREFS
+ * @abstract Synchronizes Growl prefs so they're up-to-date.
+ * @discussion This macro is intended for use by GrowlHelperApp and by
+ * plug-ins (when the prefpane is selected).
+ */
+#define SYNCHRONIZE_GROWL_PREFS() CFPreferencesAppSynchronize(CFSTR("com.Growl.GrowlHelperApp"))
+
+/*! @function UPDATE_GROWL_PREFS
+ * @abstract Tells GrowlHelperApp to update its prefs.
+ * @discussion This macro is intended for use by plug-ins.
+ * It sends a notification to tell GrowlHelperApp to update its preferences.
+ */
+#define UPDATE_GROWL_PREFS() do { \
+ SYNCHRONIZE_GROWL_PREFS(); \
+ CFStringRef _key = CFSTR("pid"); \
+ int pid = getpid(); \
+ CFNumberRef _value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &pid); \
+ CFDictionaryRef userInfo = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&_key, (const void **)&_value, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); \
+ CFRelease(_value); \
+ CFNotificationCenterPostNotification(CFNotificationCenterGetDistributedCenter(), \
+ CFSTR("GrowlPreferencesChanged"), \
+ CFSTR("GrowlUserDefaults"), \
+ userInfo, false); \
+ CFRelease(userInfo); \
+ } while(0)
+
+/*! @function READ_GROWL_PREF_VALUE
+ * @abstract Reads the given pref value from the plug-in's preferences.
+ * @discussion This macro is intended for use by plug-ins. It reads the value for the
+ * given key from the plug-in's preferences (which are stored in a dictionary inside of
+ * GrowlHelperApp's prefs).
+ * @param key The preference key to read the value of.
+ * @param domain The bundle ID of the plug-in.
+ * @param type The type of the result expected.
+ * @param result A pointer to an id. Set to the value if exists, left unchanged if not.
+ *
+ * If the value is set, you are responsible for releasing it.
+ */
+#define READ_GROWL_PREF_VALUE(key, domain, type, result) do {\
+ CFDictionaryRef prefs = (CFDictionaryRef)CFPreferencesCopyAppValue((CFStringRef)domain, \
+ CFSTR("com.Growl.GrowlHelperApp")); \
+ if (prefs) {\
+ if (CFDictionaryContainsKey(prefs, key)) {\
+ *result = (type)CFDictionaryGetValue(prefs, key); \
+ CFRetain(*result); \
+ } \
+ CFRelease(prefs); } \
+ } while(0)
+
+/*! @function WRITE_GROWL_PREF_VALUE
+ * @abstract Writes the given pref value to the plug-in's preferences.
+ * @discussion This macro is intended for use by plug-ins. It writes the given
+ * value to the plug-in's preferences.
+ * @param key The preference key to write the value of.
+ * @param value The value to write to the preferences. It should be either a
+ * CoreFoundation type or toll-free bridged with one.
+ * @param domain The bundle ID of the plug-in.
+ */
+#define WRITE_GROWL_PREF_VALUE(key, value, domain) do {\
+ CFDictionaryRef staticPrefs = (CFDictionaryRef)CFPreferencesCopyAppValue((CFStringRef)domain, \
+ CFSTR("com.Growl.GrowlHelperApp")); \
+ CFMutableDictionaryRef prefs; \
+ if (staticPrefs == NULL) {\
+ prefs = CFDictionaryCreateMutable(NULL, 0, NULL, NULL); \
+ } else {\
+ prefs = CFDictionaryCreateMutableCopy(NULL, 0, staticPrefs); \
+ CFRelease(staticPrefs); \
+ }\
+ CFDictionarySetValue(prefs, key, value); \
+ CFPreferencesSetAppValue((CFStringRef)domain, prefs, CFSTR("com.Growl.GrowlHelperApp")); \
+ CFRelease(prefs); } while(0)
+
+/*! @function READ_GROWL_PREF_BOOL
+ * @abstract Reads the given Boolean from the plug-in's preferences.
+ * @discussion This is a wrapper around READ_GROWL_PREF_VALUE() intended for
+ * use with Booleans.
+ * @param key The preference key to read the Boolean from.
+ * @param domain The bundle ID of the plug-in.
+ * @param result A pointer to a Boolean type. Left unchanged if the value doesn't exist.
+ */
+#define READ_GROWL_PREF_BOOL(key, domain, result) do {\
+ CFBooleanRef boolValue = NULL; \
+ READ_GROWL_PREF_VALUE(key, domain, CFBooleanRef, &boolValue); \
+ if (boolValue) {\
+ *result = CFBooleanGetValue(boolValue); \
+ CFRelease(boolValue); \
+ } } while(0)
+
+/*! @function WRITE_GROWL_PREF_BOOL
+ * @abstract Writes the given Boolean to the plug-in's preferences.
+ * @discussion This is a wrapper around WRITE_GROWL_PREF_VALUE() intended for
+ * use with Booleans.
+ * @param key The preference key to write the Boolean for.
+ * @param value The Boolean value to write to the preferences.
+ * @param domain The bundle ID of the plug-in.
+ */
+#define WRITE_GROWL_PREF_BOOL(key, value, domain) do {\
+ WRITE_GROWL_PREF_VALUE(key, value ? kCFBooleanTrue : kCFBooleanFalse, domain); } while(0)
+
+/*! @function READ_GROWL_PREF_INT
+ * @abstract Reads the given integer from the plug-in's preferences.
+ * @discussion This is a wrapper around READ_GROWL_PREF_VALUE() intended for
+ * use with integers.
+ * @param key The preference key to read the integer from.
+ * @param domain The bundle ID of the plug-in.
+ * @param result A pointer to an integer. Leaves unchanged if the value doesn't exist.
+ */
+#define READ_GROWL_PREF_INT(key, domain, result) do {\
+ CFNumberRef intValue = NULL; \
+ READ_GROWL_PREF_VALUE(key, domain, CFNumberRef, &intValue); \
+ if (intValue) {\
+ CFNumberGetValue(intValue, kCFNumberIntType, result); \
+ CFRelease(intValue); \
+ } } while(0)
+
+/*! @function WRITE_GROWL_PREF_INT
+ * @abstract Writes the given integer to the plug-in's preferences.
+ * @discussion This is a wrapper around WRITE_GROWL_PREF_VALUE() intended for
+ * use with integers.
+ * @param key The preference key to write the integer for.
+ * @param value The integer value to write to the preferences.
+ * @param domain The bundle ID of the plug-in.
+ */
+#define WRITE_GROWL_PREF_INT(key, value, domain) do {\
+ CFNumberRef intValue = CFNumberCreate(NULL, kCFNumberIntType, &value); \
+ WRITE_GROWL_PREF_VALUE(key, intValue, domain); \
+ CFRelease(intValue); } while(0)
+
+/*! @function READ_GROWL_PREF_FLOAT
+ * @abstract Reads the given float from the plug-in's preferences.
+ * @discussion This is a wrapper around READ_GROWL_PREF_VALUE() intended for
+ * use with floats.
+ * @param key The preference key to read the float from.
+ * @param domain The bundle ID of the plug-in.
+ * @param result A pointer to a float. Leaves unchanged if the value doesn't exist.
+ */
+#define READ_GROWL_PREF_FLOAT(key, domain, result) do {\
+ CFNumberRef floatValue = NULL; \
+ READ_GROWL_PREF_VALUE(key, domain, CFNumberRef, &floatValue); \
+ if (floatValue) {\
+ CFNumberGetValue(floatValue, kCFNumberFloatType, result); \
+ CFRelease(floatValue); \
+ } } while(0)
+
+/*! @function WRITE_GROWL_PREF_FLOAT
+ * @abstract Writes the given float to the plug-in's preferences.
+ * @discussion This is a wrapper around WRITE_GROWL_PREF_VALUE() intended for
+ * use with floats.
+ * @param key The preference key to write the float for.
+ * @param value The float value to write to the preferences.
+ * @param domain The bundle ID of the plug-in.
+ */
+#define WRITE_GROWL_PREF_FLOAT(key, value, domain) do {\
+ CFNumberRef floatValue = CFNumberCreate(NULL, kCFNumberFloatType, &value); \
+ WRITE_GROWL_PREF_VALUE(key, floatValue, domain); \
+ CFRelease(floatValue); } while(0)
+
+
+/*! @defined GROWL_CLOSE_ALL_NOTIFICATIONS
+ * @abstract Notification to close all Growl notifications
+ * @discussion Should be posted to the default notification center when a close widget is option+clicked.
+ * All notifications should close in response.
+ */
+#define GROWL_CLOSE_ALL_NOTIFICATIONS XSTR("GrowlCloseAllNotifications")
+
+#pragma mark Small utilities
+
+/*!
+ * @defined FLOAT_EQ(x,y)
+ * @abstract Compares two floats.
+ */
+#define FLOAT_EQ(x,y) (((y - FLT_EPSILON) < x) && (x < (y + FLT_EPSILON)))
+
+#endif //ndef _GROWL_GROWLDEFINESINTERNAL_H
--- /dev/null
+//
+// GrowlDisplayPlugin.h
+// Growl
+//
+// Created by Mac-arena the Bored Zo on 2005-06-01.
+// Copyright 2005-2006 The Growl Project. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+#import "GrowlPlugin.h"
+
+@class GrowlApplicationNotification, GrowlNotificationDisplayBridge;
+@class GrowlDisplayWindowController;
+
+//Info.plist keys for plug-in bundles.
+extern NSString *GrowlDisplayPluginInfoKeyUsesQueue;
+extern NSString *GrowlDisplayPluginInfoKeyWindowNibName;
+
+/*!
+ * @class GrowlDisplayPlugin
+ * @abstract Base class for all display plugins.
+ */
+@interface GrowlDisplayPlugin : GrowlPlugin {
+ Class windowControllerClass;
+
+ //for all displays
+ NSMutableDictionary *coalescableBridges;
+
+ //for non-queueing displays
+ NSMutableArray *activeBridges; //GrowlNotificationDisplayBridges currently being displayed
+
+ //for queueing displays
+ GrowlNotificationDisplayBridge *bridge;
+ NSMutableArray *queue; //GrowlNotificationDisplayBridges yet to be displayed
+}
+
+/*! @method displayNotification:
+ * @abstract Display a notification to the user.
+ * @param notification The notification to display.
+ * @discussion Unless you have a specific reason to override this method you should not do so.
+ * All the magic should happen in <code>configureBridge:</code>
+ */
+- (void) displayNotification:(GrowlApplicationNotification *)notification;
+
+/*! @method configureBridge:
+ * @abstract Configures the chosen bridge before a notificaion is displayed.
+ * @param bridge The bridge to configure.
+ * @discussion This is the place where the magic happens. Override this method and do any
+ * specific configuration here. This is the last port-of-call before a notification is displayed.
+ * The default implementation does nothing so it is important that you override and provide an
+ * implementation.
+ */
+- (void) configureBridge:(GrowlNotificationDisplayBridge *)theBridge;
+
+/*! @method windowNibName
+ * @abstract Returns the name of the display's sole nib file (resulting in
+ * the creation of a window controller for the window in that file).
+ * @discussion When subclassing <code>GrowlDisplayPlugin</code>, override this
+ * method and return the name of the nib (without the ".nib" extension) that
+ * contains the display window. This method is called by
+ * <code>displayNotification:</code> to create a
+ * <code>GrowlNotificationDisplayBridge</code>, which is the File's Owner for
+ * the nib.
+ *
+ * The default implementation returns the value of
+ * <code>GrowlDisplayWindowNibName</code> in the Info.plist of the bundle for
+ * the display plug-in.
+ * @result The name of the window nib.
+ */
+- (NSString *) windowNibName;
+
+/* */
+- (void) displayWindowControllerDidTakeDownWindow:(GrowlDisplayWindowController *)wc;
+
+@end
--- /dev/null
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 45;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
+ 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
+ FA4A47250F5A3C2A00F37A2B /* GrowlITTSWDisplay.m in Sources */ = {isa = PBXBuildFile; fileRef = FA4A471E0F5A3C2A00F37A2B /* GrowlITTSWDisplay.m */; };
+ FA4A47270F5A3C2A00F37A2B /* GrowlITTSWController.m in Sources */ = {isa = PBXBuildFile; fileRef = FA4A47220F5A3C2A00F37A2B /* GrowlITTSWController.m */; };
+ FA4A47280F5A3C2A00F37A2B /* GrowlITTSWWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = FA4A47240F5A3C2A00F37A2B /* GrowlITTSWWindow.m */; };
+ FA4A47400F5A3C7100F37A2B /* ITKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA4A473D0F5A3C6900F37A2B /* ITKit.framework */; };
+ FA4A47410F5A3C7300F37A2B /* ITFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA4A47340F5A3C5900F37A2B /* ITFoundation.framework */; };
+ FA4A47510F5A3CFC00F37A2B /* GrowlITTSWPrefs.nib in Resources */ = {isa = PBXBuildFile; fileRef = FA4A474F0F5A3CFC00F37A2B /* GrowlITTSWPrefs.nib */; };
+ FA5074430F5A56DA008DEAD9 /* ITFoundation.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = FA4A47340F5A3C5900F37A2B /* ITFoundation.framework */; };
+ FA5074440F5A56DD008DEAD9 /* ITKit.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = FA4A473D0F5A3C6900F37A2B /* ITKit.framework */; };
+ FA50774D0F5A7A2D008DEAD9 /* PreferencePanes.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA50774C0F5A7A2D008DEAD9 /* PreferencePanes.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ FA4A47330F5A3C5900F37A2B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = FA4A472F0F5A3C5900F37A2B /* ITFoundation.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = 8DC2EF5B0486A6940098B216;
+ remoteInfo = ITFoundation;
+ };
+ FA4A473C0F5A3C6900F37A2B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = FA4A47370F5A3C6900F37A2B /* ITKit.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = 8DC2EF5B0486A6940098B216;
+ remoteInfo = ITKit;
+ };
+ FA4A473E0F5A3C6900F37A2B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = FA4A47370F5A3C6900F37A2B /* ITKit.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = 7C992F87054F5389000B93EA;
+ remoteInfo = ITKitShowcase;
+ };
+ FA4A47490F5A3CD300F37A2B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = FA4A472F0F5A3C5900F37A2B /* ITFoundation.xcodeproj */;
+ proxyType = 1;
+ remoteGlobalIDString = 8DC2EF4F0486A6940098B216;
+ remoteInfo = ITFoundation;
+ };
+ FA4A474B0F5A3CD500F37A2B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = FA4A47370F5A3C6900F37A2B /* ITKit.xcodeproj */;
+ proxyType = 1;
+ remoteGlobalIDString = 8DC2EF4F0486A6940098B216;
+ remoteInfo = ITKit;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ FA50745D0F5A570F008DEAD9 /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ FA5074430F5A56DA008DEAD9 /* ITFoundation.framework in CopyFiles */,
+ FA5074440F5A56DD008DEAD9 /* ITKit.framework in CopyFiles */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
+ 089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+ 089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
+ 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+ 32DBCF630370AF2F00C91783 /* GrowlITTSW_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GrowlITTSW_Prefix.pch; sourceTree = "<group>"; };
+ 8D5B49B6048680CD000E48DA /* GrowlITTSW.growlView */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GrowlITTSW.growlView; sourceTree = BUILT_PRODUCTS_DIR; };
+ 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
+ FA4A471D0F5A3C2A00F37A2B /* GrowlITTSWDisplay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GrowlITTSWDisplay.h; sourceTree = "<group>"; };
+ FA4A471E0F5A3C2A00F37A2B /* GrowlITTSWDisplay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GrowlITTSWDisplay.m; sourceTree = "<group>"; };
+ FA4A471F0F5A3C2A00F37A2B /* GrowlITTSWPrefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GrowlITTSWPrefs.h; sourceTree = "<group>"; };
+ FA4A47200F5A3C2A00F37A2B /* GrowlITTSWPrefs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GrowlITTSWPrefs.m; sourceTree = "<group>"; };
+ FA4A47210F5A3C2A00F37A2B /* GrowlITTSWController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GrowlITTSWController.h; sourceTree = "<group>"; };
+ FA4A47220F5A3C2A00F37A2B /* GrowlITTSWController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GrowlITTSWController.m; sourceTree = "<group>"; };
+ FA4A47230F5A3C2A00F37A2B /* GrowlITTSWWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GrowlITTSWWindow.h; sourceTree = "<group>"; };
+ FA4A47240F5A3C2A00F37A2B /* GrowlITTSWWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GrowlITTSWWindow.m; sourceTree = "<group>"; };
+ FA4A472B0F5A3C3100F37A2B /* GrowlPlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GrowlPlugin.h; sourceTree = "<group>"; };
+ FA4A472C0F5A3C3100F37A2B /* GrowlDisplayPlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GrowlDisplayPlugin.h; sourceTree = "<group>"; };
+ FA4A472F0F5A3C5900F37A2B /* ITFoundation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ITFoundation.xcodeproj; path = ../ITFoundation/ITFoundation.xcodeproj; sourceTree = SOURCE_ROOT; };
+ FA4A47370F5A3C6900F37A2B /* ITKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ITKit.xcodeproj; path = ../ITKit/ITKit.xcodeproj; sourceTree = SOURCE_ROOT; };
+ FA4A47500F5A3CFC00F37A2B /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/GrowlITTSWPrefs.nib; sourceTree = "<group>"; };
+ FA50739B0F5A4D74008DEAD9 /* GrowlDefinesInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GrowlDefinesInternal.h; sourceTree = "<group>"; };
+ FA5073AA0F5A4D9A008DEAD9 /* GrowlApplicationNotification.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GrowlApplicationNotification.h; sourceTree = "<group>"; };
+ FA5074060F5A5562008DEAD9 /* GrowlDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GrowlDefines.h; sourceTree = "<group>"; };
+ FA50774C0F5A7A2D008DEAD9 /* PreferencePanes.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PreferencePanes.framework; path = /System/Library/Frameworks/PreferencePanes.framework; sourceTree = "<absolute>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 8D5B49B3048680CD000E48DA /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */,
+ FA4A47400F5A3C7100F37A2B /* ITKit.framework in Frameworks */,
+ FA4A47410F5A3C7300F37A2B /* ITFoundation.framework in Frameworks */,
+ FA50774D0F5A7A2D008DEAD9 /* PreferencePanes.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 089C166AFE841209C02AAC07 /* GrowlITTSW */ = {
+ isa = PBXGroup;
+ children = (
+ 08FB77AFFE84173DC02AAC07 /* Classes */,
+ 32C88E010371C26100C91783 /* Other Sources */,
+ 089C167CFE841241C02AAC07 /* Resources */,
+ 089C1671FE841209C02AAC07 /* Frameworks and Libraries */,
+ 19C28FB8FE9D52D311CA2CBB /* Products */,
+ );
+ name = GrowlITTSW;
+ sourceTree = "<group>";
+ };
+ 089C1671FE841209C02AAC07 /* Frameworks and Libraries */ = {
+ isa = PBXGroup;
+ children = (
+ FA4A472F0F5A3C5900F37A2B /* ITFoundation.xcodeproj */,
+ FA4A47370F5A3C6900F37A2B /* ITKit.xcodeproj */,
+ 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */,
+ 1058C7AEFEA557BF11CA2CBB /* Other Frameworks */,
+ );
+ name = "Frameworks and Libraries";
+ sourceTree = "<group>";
+ };
+ 089C167CFE841241C02AAC07 /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ FA4A474F0F5A3CFC00F37A2B /* GrowlITTSWPrefs.nib */,
+ 8D5B49B7048680CD000E48DA /* Info.plist */,
+ 089C167DFE841241C02AAC07 /* InfoPlist.strings */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
+ 08FB77AFFE84173DC02AAC07 /* Classes */ = {
+ isa = PBXGroup;
+ children = (
+ FA4A471D0F5A3C2A00F37A2B /* GrowlITTSWDisplay.h */,
+ FA4A471E0F5A3C2A00F37A2B /* GrowlITTSWDisplay.m */,
+ FA4A471F0F5A3C2A00F37A2B /* GrowlITTSWPrefs.h */,
+ FA4A47200F5A3C2A00F37A2B /* GrowlITTSWPrefs.m */,
+ FA4A47210F5A3C2A00F37A2B /* GrowlITTSWController.h */,
+ FA4A47220F5A3C2A00F37A2B /* GrowlITTSWController.m */,
+ FA4A47230F5A3C2A00F37A2B /* GrowlITTSWWindow.h */,
+ FA4A47240F5A3C2A00F37A2B /* GrowlITTSWWindow.m */,
+ );
+ name = Classes;
+ sourceTree = "<group>";
+ };
+ 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */,
+ FA50774C0F5A7A2D008DEAD9 /* PreferencePanes.framework */,
+ );
+ name = "Linked Frameworks";
+ sourceTree = "<group>";
+ };
+ 1058C7AEFEA557BF11CA2CBB /* Other Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 089C167FFE841241C02AAC07 /* AppKit.framework */,
+ D2F7E65807B2D6F200F64583 /* CoreData.framework */,
+ 089C1672FE841209C02AAC07 /* Foundation.framework */,
+ );
+ name = "Other Frameworks";
+ sourceTree = "<group>";
+ };
+ 19C28FB8FE9D52D311CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 8D5B49B6048680CD000E48DA /* GrowlITTSW.growlView */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 32C88E010371C26100C91783 /* Other Sources */ = {
+ isa = PBXGroup;
+ children = (
+ FA5074060F5A5562008DEAD9 /* GrowlDefines.h */,
+ FA50739B0F5A4D74008DEAD9 /* GrowlDefinesInternal.h */,
+ FA5073AA0F5A4D9A008DEAD9 /* GrowlApplicationNotification.h */,
+ FA4A472B0F5A3C3100F37A2B /* GrowlPlugin.h */,
+ FA4A472C0F5A3C3100F37A2B /* GrowlDisplayPlugin.h */,
+ 32DBCF630370AF2F00C91783 /* GrowlITTSW_Prefix.pch */,
+ );
+ name = "Other Sources";
+ sourceTree = "<group>";
+ };
+ FA4A47300F5A3C5900F37A2B /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ FA4A47340F5A3C5900F37A2B /* ITFoundation.framework */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ FA4A47380F5A3C6900F37A2B /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ FA4A473D0F5A3C6900F37A2B /* ITKit.framework */,
+ FA4A473F0F5A3C6900F37A2B /* ITKitShowcase.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 8D5B49AC048680CD000E48DA /* GrowlITTSW */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "GrowlITTSW" */;
+ buildPhases = (
+ 8D5B49AF048680CD000E48DA /* Resources */,
+ 8D5B49B1048680CD000E48DA /* Sources */,
+ 8D5B49B3048680CD000E48DA /* Frameworks */,
+ FA50745D0F5A570F008DEAD9 /* CopyFiles */,
+ FA50761F0F5A692D008DEAD9 /* ShellScript */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ FA4A474A0F5A3CD300F37A2B /* PBXTargetDependency */,
+ FA4A474C0F5A3CD500F37A2B /* PBXTargetDependency */,
+ );
+ name = GrowlITTSW;
+ productInstallPath = "$(HOME)/Library/Bundles";
+ productName = GrowlITTSW;
+ productReference = 8D5B49B6048680CD000E48DA /* GrowlITTSW.growlView */;
+ productType = "com.apple.product-type.bundle";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 089C1669FE841209C02AAC07 /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "GrowlITTSW" */;
+ compatibilityVersion = "Xcode 3.1";
+ hasScannedForEncodings = 1;
+ mainGroup = 089C166AFE841209C02AAC07 /* GrowlITTSW */;
+ projectDirPath = "";
+ projectReferences = (
+ {
+ ProductGroup = FA4A47300F5A3C5900F37A2B /* Products */;
+ ProjectRef = FA4A472F0F5A3C5900F37A2B /* ITFoundation.xcodeproj */;
+ },
+ {
+ ProductGroup = FA4A47380F5A3C6900F37A2B /* Products */;
+ ProjectRef = FA4A47370F5A3C6900F37A2B /* ITKit.xcodeproj */;
+ },
+ );
+ projectRoot = "";
+ targets = (
+ 8D5B49AC048680CD000E48DA /* GrowlITTSW */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXReferenceProxy section */
+ FA4A47340F5A3C5900F37A2B /* ITFoundation.framework */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.framework;
+ path = ITFoundation.framework;
+ remoteRef = FA4A47330F5A3C5900F37A2B /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ FA4A473D0F5A3C6900F37A2B /* ITKit.framework */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.framework;
+ path = ITKit.framework;
+ remoteRef = FA4A473C0F5A3C6900F37A2B /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ FA4A473F0F5A3C6900F37A2B /* ITKitShowcase.app */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.application;
+ path = ITKitShowcase.app;
+ remoteRef = FA4A473E0F5A3C6900F37A2B /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+/* End PBXReferenceProxy section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 8D5B49AF048680CD000E48DA /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */,
+ FA4A47510F5A3CFC00F37A2B /* GrowlITTSWPrefs.nib in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ FA50761F0F5A692D008DEAD9 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "install_name_tool -change \\\n\t\"@executable_path/../Frameworks/ITFoundation.framework/Versions/A/ITFoundation\" \\\n\t\"@loader_path/../Frameworks/ITFoundation.framework/Versions/A/ITFoundation\" \\\n\t\"$TARGET_BUILD_DIR/$EXECUTABLE_FOLDER_PATH/$EXECUTABLE_NAME\"\n\ninstall_name_tool -change \\\n\t\"@executable_path/../Frameworks/ITKit.framework/Versions/A/ITKit\" \\\n\t\"@loader_path/../Frameworks/ITKit.framework/Versions/A/ITKit\" \\\n\t\"$TARGET_BUILD_DIR/$EXECUTABLE_FOLDER_PATH/$EXECUTABLE_NAME\"\n\ninstall_name_tool -change \\\n\t\"@executable_path/../Frameworks/ITFoundation.framework/Versions/A/ITFoundation\" \\\n\t\"@loader_path/../../../../Frameworks/ITFoundation.framework/Versions/A/ITFoundation\" \\\n\t\"$TARGET_BUILD_DIR/$FRAMEWORKS_FOLDER_PATH/ITKit.framework/Versions/A/ITKit\"";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 8D5B49B1048680CD000E48DA /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ FA4A47250F5A3C2A00F37A2B /* GrowlITTSWDisplay.m in Sources */,
+ FA4A47270F5A3C2A00F37A2B /* GrowlITTSWController.m in Sources */,
+ FA4A47280F5A3C2A00F37A2B /* GrowlITTSWWindow.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ FA4A474A0F5A3CD300F37A2B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ name = ITFoundation;
+ targetProxy = FA4A47490F5A3CD300F37A2B /* PBXContainerItemProxy */;
+ };
+ FA4A474C0F5A3CD500F37A2B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ name = ITKit;
+ targetProxy = FA4A474B0F5A3CD500F37A2B /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ 089C167DFE841241C02AAC07 /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 089C167EFE841241C02AAC07 /* English */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "<group>";
+ };
+ FA4A474F0F5A3CFC00F37A2B /* GrowlITTSWPrefs.nib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ FA4A47500F5A3CFC00F37A2B /* English */,
+ );
+ name = GrowlITTSWPrefs.nib;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 1DEB913B08733D840010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = GrowlITTSW_Prefix.pch;
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "$(USER_LIBRARY_DIR)/Application Support/Growl/Plugins";
+ LIBRARY_STYLE = BUNDLE;
+ OTHER_LDFLAGS = (
+ "-undefined",
+ dynamic_lookup,
+ );
+ PRODUCT_NAME = GrowlITTSW;
+ REZ_RESOURCE_MAP_READ_ONLY = YES;
+ WRAPPER_EXTENSION = growlView;
+ };
+ name = Debug;
+ };
+ 1DEB913C08733D840010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_MODEL_TUNING = G5;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = GrowlITTSW_Prefix.pch;
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "$(USER_LIBRARY_DIR)/Application Support/Growl/Plugins";
+ LIBRARY_STYLE = BUNDLE;
+ OTHER_LDFLAGS = (
+ "-undefined",
+ dynamic_lookup,
+ );
+ PRODUCT_NAME = GrowlITTSW;
+ REZ_RESOURCE_MAP_READ_ONLY = YES;
+ WRAPPER_EXTENSION = growlView;
+ };
+ name = Release;
+ };
+ 1DEB913F08733D840010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ PREBINDING = NO;
+ SDKROOT = macosx10.5;
+ };
+ name = Debug;
+ };
+ 1DEB914008733D840010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ PREBINDING = NO;
+ SDKROOT = macosx10.5;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "GrowlITTSW" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB913B08733D840010E9CD /* Debug */,
+ 1DEB913C08733D840010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "GrowlITTSW" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB913F08733D840010E9CD /* Debug */,
+ 1DEB914008733D840010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 089C1669FE841209C02AAC07 /* Project object */;
+}
--- /dev/null
+//
+// GrowlITTSWController.h
+// Growl
+//
+// Created by Joseph Spiros on 2/28/09.
+// Copyright 2009 iThink Software. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+#import <ITFoundation/ITSharedController.h>
+#import "GrowlITTSWWindow.h"
+
+@interface GrowlITTSWController : ITSharedController {
+ GrowlITTSWWindow *_window;
+}
+
+- (void)showWindowWithText:(NSString *)text image:(NSImage *)image;
+
+@end
--- /dev/null
+//
+// GrowlITTSWController.m
+// Growl
+//
+// Created by Joseph Spiros on 2/28/09.
+// Copyright 2009 iThink Software. All rights reserved.
+//
+
+#import "GrowlITTSWController.h"
+#import "GrowlITTSWWindow.h"
+
+#import <ITKit/ITTSWBackgroundView.h>
+#import <ITKit/ITWindowEffect.h>
+
+@implementation NSImage (SmoothAdditions)
+
+- (NSImage *)imageScaledSmoothlyToSize:(NSSize)scaledSize
+{
+ NSImage *newImage;
+ NSImageRep *rep = [self bestRepresentationForDevice:nil];
+
+ newImage = [[NSImage alloc] initWithSize:scaledSize];
+ [newImage lockFocus];
+ {
+ [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
+ [[NSGraphicsContext currentContext] setShouldAntialias:YES];
+ [rep drawInRect:NSMakeRect(3, 3, scaledSize.width - 6, scaledSize.height - 6)];
+ }
+ [newImage unlockFocus];
+ return [newImage autorelease];
+}
+
+@end
+
+@implementation GrowlITTSWController
+
+- (id)init
+{
+ if ( ( self = [super init] ) ) {
+ NSArray *screens = [NSScreen screens];
+
+ _window = [[GrowlITTSWWindow sharedWindow] retain];
+
+ [_window setScreen:[screens objectAtIndex:0]];
+
+ [_window setExitMode:ITTransientStatusWindowExitAfterDelay];
+ [_window setExitDelay:4.0];
+
+ [_window setHorizontalPosition:ITWindowPositionRight];
+ [_window setVerticalPosition:ITWindowPositionTop];
+
+ [_window setSizing:ITTransientStatusWindowMini];
+
+ [_window setEntryEffect:[[[NSClassFromString(@"ITSlideVerticallyWindowEffect") alloc] initWithWindow:_window] autorelease]];
+ [_window setExitEffect:[[[NSClassFromString(@"ITSlideHorizontallyWindowEffect") alloc] initWithWindow:_window] autorelease]];
+
+ [[_window entryEffect] setEffectTime:0.8];
+ [[_window exitEffect] setEffectTime:0.8];
+
+ [(ITTSWBackgroundView *)[_window contentView]setBackgroundMode:
+ ITTSWBackgroundReadable];
+ }
+
+ return self;
+}
+
+- (void)dealloc
+{
+ [_window release];
+ [super dealloc];
+}
+
+- (void)showWindowWithText:(NSString *)text image:(NSImage *)image
+{
+ NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:text];
+ NSSize newSize;
+ NSSize oldSize = [image size];
+
+ if (oldSize.width > oldSize.height) {
+ newSize = NSMakeSize(110.0f, (oldSize.height * (110.0f / oldSize.width)));
+ } else {
+ newSize = NSMakeSize((oldSize.width * (110.0f / oldSize.height)), 110.0f);
+ }
+
+ image = [[[[NSImage alloc] initWithData:[image TIFFRepresentation]] autorelease] imageScaledSmoothlyToSize:newSize];
+
+ [_window setImage:image];
+ [_window buildTextWindowWithString:attributedText];
+ [_window appear:self];
+ [attributedText release];
+}
+
+@end
\ No newline at end of file
--- /dev/null
+#import <Cocoa/Cocoa.h>
+#import "GrowlDisplayPlugin.h"
+
+@class GrowlApplicationNotification;
+
+@interface GrowlITTSWDisplay : GrowlDisplayPlugin {
+}
+
+- (void) displayNotification:(GrowlApplicationNotification *)notification;
+
+@end
--- /dev/null
+#import "GrowlITTSWDisplay.h"
+#import "GrowlITTSWController.h"
+#import "GrowlITTSWPrefs.h"
+#import "GrowlDefines.h"
+#import "GrowlDefinesInternal.h"
+#import "GrowlApplicationNotification.h"
+
+@implementation GrowlITTSWDisplay
+
+- (void) dealloc {
+ [preferencePane release];
+ [super dealloc];
+}
+
+/* - (NSPreferencePane *) preferencePane {
+ if (!preferencePane)
+ preferencePane = [[GrowlITTSWPrefs alloc] initWithBundle:[NSBundle bundleWithIdentifier:@"com.ithinksw.growl.ittsw"]];
+ return preferencePane;
+}*/
+
+//we implement requiresPositioning entirely because it was added as a requirement for doing 1.1 plugins, however
+//we don't really care if positioning is required or not, because we are only ever in the menubar.
+- (BOOL)requiresPositioning {
+ return NO;
+}
+
+#pragma mark -
+- (void) displayNotification:(GrowlApplicationNotification *)notification {
+ NSDictionary *dict = [notification dictionaryRepresentation];
+ NSString *title = [dict objectForKey:GROWL_NOTIFICATION_TITLE];
+ NSString *desc = [dict objectForKey:GROWL_NOTIFICATION_DESCRIPTION];
+ NSImage *image = [dict objectForKey:GROWL_NOTIFICATION_ICON];
+ NSString *text;
+ if (desc) {
+ text = [title stringByAppendingFormat:@"\n%@", desc];
+ } else {
+ text = title;
+ }
+ [[GrowlITTSWController sharedController] showWindowWithText:text image:image];
+}
+
+@end
--- /dev/null
+#import <PreferencePanes/PreferencePanes.h>
+
+@interface GrowlITTSWPrefs : NSPreferencePane {
+}
+
+@end
--- /dev/null
+#import "GrowlITTSWPrefs.h"
+#import "GrowlDefinesInternal.h"
+
+@implementation GrowlITTSWPrefs
+
+@end
--- /dev/null
+#import <Cocoa/Cocoa.h>
+#import <ITKit/ITKit.h>
+
+#define SMALL_DIVISOR 1.33333
+#define MINI_DIVISOR 1.66667
+
+@interface GrowlITTSWWindow : ITTransientStatusWindow {
+ NSImage *_image;
+ NSTextField *_textField;
+}
+
+- (void)setImage:(NSImage *)newImage;
+- (void)buildTextWindowWithString:(id)text;
+
+@end
--- /dev/null
+//
+// GrowlITTSWWindow.m
+// Growl
+//
+// Created by Joseph Spiros on 2/28/09.
+// Copyright 2009 iThink Software. All rights reserved.
+//
+
+#import "GrowlITTSWWindow.h"
+
+#define SW_PAD 24.00
+#define SW_SPACE 24.00
+#define SW_MINW 211.00
+#define SW_BORDER 32.00
+#define SW_METER_PAD 4.00
+#define SW_BUTTON_PAD_R 30.00
+#define SW_BUTTON_PAD_B 24.00
+#define SW_BUTTON_DIV 12.00
+#define SW_BUTTON_EXTRA_W 8.00
+#define SW_SHADOW_SAT 1.25
+
+@interface GrowlITTSWWindow (Private)
+- (NSRect)setupWindowWithDataSize:(NSSize)dataSize;
+@end
+
+@implementation GrowlITTSWWindow
+
+
+/*************************************************************************/
+#pragma mark -
+#pragma mark INITIALIZATION / DEALLOCATION METHODS
+/*************************************************************************/
+
+- (id)initWithContentView:(NSView *)contentView
+ exitMode:(ITTransientStatusWindowExitMode)exitMode
+ backgroundType:(ITTransientStatusWindowBackgroundType)backgroundType
+{
+ if ( ( self = [super initWithContentView:contentView
+ exitMode:exitMode
+ backgroundType:backgroundType] ) ) {
+ // Set default values.
+ _image = [[NSImage imageNamed:@"NSApplicationIcon"] retain];
+ _sizing = ITTransientStatusWindowRegular;
+ }
+
+ return self;
+}
+
+- (void)dealloc
+{
+ [_image release];
+ [super dealloc];
+}
+
+
+/*************************************************************************/
+#pragma mark -
+#pragma mark ACCESSOR METHODS
+/*************************************************************************/
+
+- (void)setImage:(NSImage *)newImage
+{
+ [_image autorelease];
+ _image = [newImage copy];
+}
+
+- (void)setSizing:(ITTransientStatusWindowSizing)newSizing
+{
+ _sizing = newSizing;
+}
+
+/*************************************************************************/
+#pragma mark -
+#pragma mark INSTANCE METHODS
+/*************************************************************************/
+
+- (void)appear:(id)sender
+{
+ [super appear:sender];
+}
+
+- (void)vanish:(id)sender
+{
+ [super vanish:sender];
+}
+
+- (NSRect)setupWindowWithDataSize:(NSSize)dataSize
+{
+ float divisor = 1.0;
+ NSRect imageRect;
+ float imageWidth = 0.0;
+ float imageHeight = 0.0;
+ float dataWidth = dataSize.width;
+ float dataHeight = dataSize.height;
+ float contentHeight = 0.0;
+ float windowWidth = 0.0;
+ float windowHeight = 0.0;
+ NSRect visibleFrame = [[self screen] visibleFrame];
+ NSPoint screenOrigin = visibleFrame.origin;
+ float screenWidth = visibleFrame.size.width;
+ float screenHeight = visibleFrame.size.height;
+ float maxWidth = ( screenWidth - (SW_BORDER * 2) );
+ float maxHeight = ( screenHeight - (SW_BORDER * 2) );
+ float excessWidth = 0.0;
+ float excessHeight = 0.0;
+ NSPoint windowOrigin = NSZeroPoint;
+ ITImageView *imageView;
+ BOOL shouldAnimate = ( ! (([self visibilityState] == ITWindowAppearingState) ||
+ ([self visibilityState] == ITWindowVanishingState)) );
+
+ if ( _sizing == ITTransientStatusWindowSmall ) {
+ divisor = SMALL_DIVISOR;
+ } else if ( _sizing == ITTransientStatusWindowMini ) {
+ divisor = MINI_DIVISOR;
+ }
+
+ // Get image width and height.
+ imageWidth = ( [_image size].width / divisor );
+ imageHeight = ( [_image size].height / divisor );
+
+ // Set the content height to the greater of the text and image heights.
+ contentHeight = ( ( imageHeight > dataHeight ) ? imageHeight : dataHeight );
+
+ // Setup the Window, and remove all its contentview's subviews.
+ windowWidth = ( (SW_PAD / divisor) + imageWidth + ((dataWidth > 0) ? (SW_SPACE / divisor) + dataWidth : 0) + (SW_PAD / divisor) );
+ windowHeight = ( (SW_PAD / divisor) + contentHeight + (SW_PAD / divisor) );
+
+ // Constrain size to max limits. Adjust data sizes accordingly.
+ excessWidth = (windowWidth - maxWidth );
+ excessHeight = (windowHeight - maxHeight);
+
+ if ( excessWidth > 0.0 ) {
+ windowWidth = maxWidth;
+ dataWidth -= excessWidth;
+ }
+
+ if ( excessHeight > 0.0 ) {
+ windowHeight = maxHeight;
+ dataHeight -= excessHeight;
+ }
+
+ if ( [self horizontalPosition] == ITWindowPositionLeft ) {
+ windowOrigin.x = ( SW_BORDER + screenOrigin.x );
+ } else if ( [self horizontalPosition] == ITWindowPositionCenter ) {
+ windowOrigin.x = ( screenOrigin.x + (screenWidth / 2) - (windowWidth / 2) );
+ } else if ( [self horizontalPosition] == ITWindowPositionRight ) {
+ windowOrigin.x = ( screenOrigin.x + screenWidth - (windowWidth + SW_BORDER) );
+ }
+
+ if ( [self verticalPosition] == ITWindowPositionTop ) {
+ windowOrigin.y = ( screenOrigin.y + screenHeight - (windowHeight + SW_BORDER) );
+ } else if ( [self verticalPosition] == ITWindowPositionMiddle ) {
+ // Middle-oriented windows should be slightly proud of the screen's middle.
+ windowOrigin.y = ( (screenOrigin.y + (screenHeight / 2) - (windowHeight / 2)) + (screenHeight / 8) );
+ } else if ( [self verticalPosition] == ITWindowPositionBottom ) {
+ windowOrigin.y = ( SW_BORDER + screenOrigin.y );
+ }
+
+ [self setFrame:NSMakeRect( windowOrigin.x,
+ windowOrigin.y,
+ windowWidth,
+ windowHeight) display:YES animate:shouldAnimate];
+
+ [[[self contentView] subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
+
+ // Setup, position, fill, and add the image view to the content view.
+ imageRect = NSMakeRect( (SW_PAD / divisor) + ((dataWidth > 0) ? 4 : 0),
+ ((SW_PAD / divisor) + ((contentHeight - imageHeight) / 2)),
+ imageWidth,
+ imageHeight );
+ imageView = [[[ITImageView alloc] initWithFrame:imageRect] autorelease];
+ [imageView setAutoresizingMask:(NSViewMinYMargin | NSViewMaxYMargin)];
+ [imageView setImage:_image];
+ [imageView setCastsShadow:YES];
+ [[self contentView] addSubview:imageView];
+
+ return NSMakeRect( ((SW_PAD / divisor) + imageWidth + (SW_SPACE / divisor)),
+ ((SW_PAD / divisor) + ((contentHeight - dataHeight) / 2)),
+ dataWidth,
+ dataHeight);
+}
+
+- (void)buildTextWindowWithString:(id)text
+{
+ float divisor = 1.0;
+ float dataWidth = 0.0;
+ float dataHeight = 0.0;
+ NSRect dataRect;
+ NSArray *lines = [(([text isKindOfClass:[NSString class]]) ? text : [text mutableString]) componentsSeparatedByString:@"\n"];
+ id oneLine = nil;
+ NSEnumerator *lineEnum = [lines objectEnumerator];
+ float baseFontSize = 18.0;
+ ITTextField *textField;
+ NSFont *font;
+ NSDictionary *attr;
+
+ if ( _sizing == ITTransientStatusWindowSmall ) {
+ divisor = SMALL_DIVISOR;
+ } else if ( _sizing == ITTransientStatusWindowMini ) {
+ divisor = MINI_DIVISOR;
+ }
+
+ font = [NSFont fontWithName:@"LucidaGrande-Bold" size:(baseFontSize / divisor)];
+ attr = [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName];
+
+ // Iterate over each line to get text width and height
+ while ( (oneLine = [lineEnum nextObject]) ) {
+ // Get the width of one line, adding 8.0 because Apple sucks donkey rectum.
+ float oneLineWidth = ( [oneLine sizeWithAttributes:attr].width + 8.0 );
+ // Add the height of this line to the total text height
+ dataHeight += [oneLine sizeWithAttributes:attr].height;
+ // If this line wider than the last one, set it as the text width.
+ dataWidth = ( ( dataWidth > oneLineWidth ) ? dataWidth : oneLineWidth );
+ }
+
+ // Add 4.0 to the final dataHeight to accomodate the shadow.
+ dataHeight += 4.0;
+
+ dataRect = [self setupWindowWithDataSize:NSMakeSize(dataWidth, dataHeight)];
+
+ // Create, position, setup, fill, and add the text view to the content view.
+ textField = [[[ITTextField alloc] initWithFrame:dataRect] autorelease];
+ [textField setAutoresizingMask:(NSViewHeightSizable | NSViewWidthSizable)];
+ [textField setEditable:NO];
+ [textField setSelectable:NO];
+ [textField setBordered:NO];
+ [textField setDrawsBackground:NO];
+ [textField setFont:font];
+ [textField setTextColor:[NSColor whiteColor]];
+ [textField setCastsShadow:YES];
+ [[textField cell] setWraps:NO];
+
+ if ([text isKindOfClass:[NSString class]]) {
+ [textField setStringValue:text];
+ } else {
+ [textField setAttributedStringValue:text];
+ }
+
+ [textField setShadowSaturation:SW_SHADOW_SAT];
+ [[self contentView] addSubview:textField];
+
+ // Display the window.
+ [[self contentView] setNeedsDisplay:YES];
+ _textField = textField;
+}
+
+- (NSTimeInterval)animationResizeTime:(NSRect)newFrame
+{
+ return (NSTimeInterval)0.25;
+}
+
+@end
--- /dev/null
+//
+// Prefix header for all source files of the 'GrowlITTSW' target in the 'GrowlITTSW' project.
+//
+
+#ifdef __OBJC__
+ #import <Cocoa/Cocoa.h>
+#endif
--- /dev/null
+//
+// GrowlPlugin.h
+// Growl
+//
+// Created by Mac-arena the Bored Zo on 2005-06-01.
+// Copyright 2005-2006 The Growl Project. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+
+@class NSPreferencePane;
+
+/*! @class GrowlPlugin
+ * @abstract The base plug-in class.
+ * @discussion All Growl plug-in instances are a kind of this class, including
+ * display plug-ins, which are kinds of <code>GrowlDisplayPlugin</code>.
+ */
+@interface GrowlPlugin : NSObject {
+ NSString *pluginName, *pluginAuthor, *pluginVersion, *pluginDesc;
+ NSBundle *pluginBundle;
+ NSString *pluginPathname;
+
+ NSPreferencePane *preferencePane;
+ NSString *prefDomain;
+}
+
+/*!
+ * @method initWithName:author:version:pathname:
+ * @abstract Designated initializer.
+ * @param name The name of the plugin.
+ * @param author The author of the plugin.
+ * @param version The version of the plugin.
+ * @param pathname The pathname of the plugin.
+ * @result An initialized GrowlPlugin object.
+ */
+- (id) initWithName:(NSString *)name author:(NSString *)author version:(NSString *)version pathname:(NSString *)pathname;
+
+/*!
+ * @method initWithBundle:
+ * @abstract Initializer for plug-ins in bundles. The name, author, version, and pathname will be obtained from the bundle.
+ * @result An initialized GrowlPlugin object.
+ */
+- (id) initWithBundle:(NSBundle *)bundle;
+
+
+/*!
+ * @method name
+ * @abstract Returns the name of the receiver.
+ */
+- (NSString *) name;
+
+/*!
+ * @method author
+ * @abstract Returns the author of the receiver.
+ */
+- (NSString *) author;
+
+/*!
+ * @method pluginDescription
+ * @abstract Returns the description of the receiver.
+ */
+- (NSString *) pluginDescription;
+
+/*!
+ * @method version
+ * @abstract Returns the version of the receiver.
+ */
+- (NSString *) version;
+
+/*!
+ * @method bundle
+ * @abstract Returns the bundle of the receiver.
+ */
+- (NSBundle *) bundle;
+
+/*!
+ * @method pathname
+ * @abstract Returns the pathname of the receiver.
+ */
+- (NSString *) pathname;
+
+/*!
+* @method pathname
+ * @abstract Returns the string used to access the preference domain of the receiver.
+ */
+- (NSString *) prefDomain;
+
+
+/*! @method preferencePane
+ * @abstract Return an <code>NSPreferencePane</code> instance that manages
+ * the plugin's preferences.
+ * @discussion Your plug-in should put the controls for its preferences in
+ * this preference pane.
+ *
+ * Currently, the size of the preference pane's view should be 354 pixels by
+ * 289 pixels, but you should set the springs of the view and its subviews
+ * under the assumption that it can be resized horizontally and vertically to
+ * any size.
+ *
+ * The default implementation of this method returns <code>nil</code>.
+ * @result The preference pane. Can be <code>nil</code>.
+ */
+- (NSPreferencePane *) preferencePane;
+
+@end
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>GrowlITTSW</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.ithinksw.growl-ittsw</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>GrowlITTSW</string>
+ <key>CFBundlePackageType</key>
+ <string>DISP</string>
+ <key>CFBundleSignature</key>
+ <string>GRRR</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>CSResourcesFileMapped</key>
+ <string>yes</string>
+ <key>GrowlDisplayUsesQueue</key>
+ <true/>
+ <key>GrowlPluginAuthor</key>
+ <string>iThink Software</string>
+ <key>GrowlPluginDescription</key>
+ <string>ITTSW uses the ITTransientStatusWindow class from ITKit</string>
+ <key>NSPrincipalClass</key>
+ <string>GrowlITTSWDisplay</string>
+</dict>
+</plist>