Bumping to version 1.0.1, which uses the latest ITKit. This resolves GrowlITTSW bug #4.
[GrowlITTSW.git] / GrowlDefinesInternal.h
1 //
2 //  GrowlDefinesInternal.h
3 //  Growl
4 //
5 //  Created by Karl Adam on Mon May 17 2004.
6 //  Copyright (c) 2004 the Growl Project. All rights reserved.
7 //
8
9 #ifndef _GROWL_GROWLDEFINESINTERNAL_H
10 #define _GROWL_GROWLDEFINESINTERNAL_H
11
12 #include <CoreFoundation/CoreFoundation.h>
13 #include <sys/types.h>
14 #include <unistd.h>
15
16 #ifdef __OBJC__
17 #define XSTR(x) (@x)
18 #else /* !__OBJC__ */
19 #define XSTR CFSTR
20 #endif /* __OBJC__ */
21
22 /*!     @header GrowlDefinesInternal.h
23  *      @abstract       Defines internal Growl macros and types.
24  *  @ignore ATTRIBUTE_PACKED
25  *      @discussion     These constants are used both by GrowlHelperApp and by plug-ins.
26  *
27  *       Notification keys (used in GrowlHelperApp, in GrowlApplicationBridge, and
28  *       by applications that don't use GrowlApplicationBridge) are defined in
29  *       GrowlDefines.h.
30  */
31
32 /*!     @defined        GROWL_TCP_PORT
33  *      @abstract       The TCP listen port for Growl notification servers.
34  */
35 #define GROWL_TCP_PORT  23052
36
37 /*!     @defined        GROWL_UDP_PORT
38  *      @abstract       The UDP listen port for Growl notification servers.
39  */
40 #define GROWL_UDP_PORT  9887
41
42 /*!     @defined        GROWL_PROTOCOL_VERSION
43  *      @abstract       The current version of the Growl network-notifications protocol (without encryption).
44  */
45 #define GROWL_PROTOCOL_VERSION  1
46
47 /*!     @defined        GROWL_PROTOCOL_VERSION_AES128
48 *       @abstract       The current version of the Growl network-notifications protocol (with AES-128 encryption).
49 */
50 #define GROWL_PROTOCOL_VERSION_AES128   2
51
52 /*!     @defined        GROWL_TYPE_REGISTRATION
53  *      @abstract       The packet type of registration packets with MD5 authentication.
54  */
55 #define GROWL_TYPE_REGISTRATION                 0
56 /*!     @defined        GROWL_TYPE_NOTIFICATION
57  *      @abstract       The packet type of notification packets with MD5 authentication.
58  */
59 #define GROWL_TYPE_NOTIFICATION                 1
60 /*!     @defined        GROWL_TYPE_REGISTRATION_SHA256
61  *      @abstract       The packet type of registration packets with SHA-256 authentication.
62  */
63 #define GROWL_TYPE_REGISTRATION_SHA256  2
64 /*!     @defined        GROWL_TYPE_NOTIFICATION_SHA256
65  *      @abstract       The packet type of notification packets with SHA-256 authentication.
66  */
67 #define GROWL_TYPE_NOTIFICATION_SHA256  3
68 /*!     @defined        GROWL_TYPE_REGISTRATION_NOAUTH
69 *       @abstract       The packet type of registration packets without authentication.
70 */
71 #define GROWL_TYPE_REGISTRATION_NOAUTH  4
72 /*!     @defined        GROWL_TYPE_NOTIFICATION_NOAUTH
73 *       @abstract       The packet type of notification packets without authentication.
74 */
75 #define GROWL_TYPE_NOTIFICATION_NOAUTH  5
76
77 #define ATTRIBUTE_PACKED __attribute((packed))
78
79 /*!     @struct GrowlNetworkPacket
80  *      @abstract       This struct is a header common to all incoming Growl network
81  *       packets which identifies the type and version of the packet.
82  */
83 struct GrowlNetworkPacket {
84         unsigned char version;
85         unsigned char type;
86 } ATTRIBUTE_PACKED;
87
88 /*!
89  * @struct GrowlNetworkRegistration
90  * @abstract The format of a registration packet.
91  * @discussion A Growl client that wants to register with a Growl server sends
92  * a packet in this format.
93  * @field common The Growl packet header.
94  * @field appNameLen The name of the application that is registering.
95  * @field numAllNotifications The number of notifications in the list.
96  * @field numDefaultNotifications The number of notifications in the list that are enabled by default.
97  * @field data Variable-sized data.
98  */
99 struct GrowlNetworkRegistration {
100         struct GrowlNetworkPacket common;
101         /*      This name is used both internally and in the Growl
102          *       preferences.
103          *
104          *       The application name should remain stable between different versions
105          *       and incarnations of your application.
106          *       For example, "SurfWriter" is a good app name, whereas "SurfWriter 2.0"
107          *       and "SurfWriter Lite" are not.
108          *
109          *       In addition to being unsigned, the application name length is in
110          *       network byte order.
111          */
112         unsigned short appNameLen;
113         /*      These names are used both internally and in the Growl
114          *       preferences. For this reason, they should be human-readable.
115          */
116         unsigned char numAllNotifications;
117
118         unsigned char numDefaultNotifications;
119         /*      The variable-sized data of a registration is:
120          *       - The application name, in UTF-8 encoding, for appNameLen bytes.
121          *       - The list of all notification names.
122          *       - The list of default notifications, as 8-bit unsigned indices into the list of all notifications.
123          *       - The MD5/SHA256 checksum of all the data preceding the checksum.
124          *
125          *       Each notification name is encoded as:
126          *       - Length: two bytes, unsigned, network byte order.
127          *       - Name: As many bytes of UTF-8-encoded text as the length says.
128          *       And there are numAllNotifications of these.
129          */
130         unsigned char data[];
131 } ATTRIBUTE_PACKED;
132
133 /*!
134  * @struct GrowlNetworkNotification
135  * @abstract The format of a notification packet.
136  * @discussion  A Growl client that wants to post a notification to a Growl
137  * server sends a packet in this format.
138  * @field common The Growl packet header.
139  * @field flags The priority number and the sticky bit.
140  * @field nameLen The length of the notification name.
141  * @field titleLen The length of the notification title.
142  * @field descriptionLen The length of the notification description.
143  * @field appNameLen The length of the application name.
144  * @field data Variable-sized data.
145  */
146 struct GrowlNetworkNotification {
147         struct GrowlNetworkPacket common;
148         /*!
149          * @struct GrowlNetworkNotificationFlags
150          * @abstract Various flags.
151          * @discussion This 16-bit packed structure contains the priority as a
152          *  signed 3-bit integer from -2 to +2, and the sticky flag as a single bit.
153          *  The high 12 bits of the structure are reserved for future use.
154          * @field reserved reserved for future use.
155          * @field priority the priority as a signed 3-bit integer from -2 to +2.
156          * @field sticky the sticky flag.
157          */
158         struct GrowlNetworkNotificationFlags {
159 #ifdef __BIG_ENDIAN__
160                 unsigned reserved: 12;
161                 signed   priority: 3;
162                 unsigned sticky:   1;
163 #else
164                 unsigned sticky:   1;
165                 signed   priority: 3;
166                 unsigned reserved: 12;
167 #endif
168         } ATTRIBUTE_PACKED flags; //size = 16 (12 + 3 + 1)
169
170         /*      In addition to being unsigned, the notification name length
171          *       is in network byte order.
172          */
173         unsigned short nameLen;
174         /*      @discussion     In addition to being unsigned, the title length is in
175          *       network byte order.
176          */
177         unsigned short titleLen;
178         /*      In addition to being unsigned, the description length is in
179          *       network byte order.
180          */
181         unsigned short descriptionLen;
182         /*      In addition to being unsigned, the application name length
183          *       is in network byte order.
184          */
185         unsigned short appNameLen;
186         /*      The variable-sized data of a notification is:
187          *       - Notification name, in UTF-8 encoding, for nameLen bytes.
188          *       - Title, in UTF-8 encoding, for titleLen bytes.
189          *       - Description, in UTF-8 encoding, for descriptionLen bytes.
190          *       - Application name, in UTF-8 encoding, for appNameLen bytes.
191          *       - The MD5/SHA256 checksum of all the data preceding the checksum.
192          */
193         unsigned char data[];
194 } ATTRIBUTE_PACKED;
195
196 /*!     @defined        GrowlEnabledKey
197  *      @abstract       Preference key controlling whether Growl is enabled.
198  *      @discussion     If this is false, then when GrowlHelperApp is launched to open
199  *       a Growl registration dictionary file, GrowlHelperApp will quit when it has
200  *       finished processing the file instead of listening for notifications.
201  */
202 #define GrowlEnabledKey                                 XSTR("GrowlEnabled")
203
204 /*!     @defined        GROWL_SCREENSHOT_MODE
205  *      @abstract       Preference and notification key controlling whether to save a screenshot of the notification.
206  *      @discussion     This is for GHA's private usage. If your application puts this
207  *       key into a notification dictionary, GHA will clobber it. This key is only
208  *       allowed in the notification dictionaries GHA passes to displays.
209  *
210  *       If this key contains an object whose boolValue is not NO, the display is
211  *       asked to save a screenshot of the notification to
212  *       ~/Library/Application\ Support/Growl/Screenshots.
213  */
214 #define GROWL_SCREENSHOT_MODE                   XSTR("ScreenshotMode")
215
216 /*!     @defined        GROWL_APP_LOCATION
217  *      @abstract       The location of this application.
218  *      @discussion     Contains either the POSIX path to the application, or a file-data dictionary (as used by the Dock).
219  *       contains the file's alias record and its pathname.
220  */
221 #define GROWL_APP_LOCATION                              XSTR("AppLocation")
222
223 /*!     @defined        GROWL_REMOTE_ADDRESS
224  *      @abstract       The address of the host who sent this notification/registration.
225  *      @discussion     Contains an NSData with the address of the remote host who
226  *    sent this notification/registration.
227  */
228 #define GROWL_REMOTE_ADDRESS                    XSTR("RemoteAddress")
229
230 /*!
231  *      @defined    GROWL_PREFPANE_BUNDLE_IDENTIFIER
232  *      @discussion The bundle identifier for the Growl preference pane.
233  */
234 #define GROWL_PREFPANE_BUNDLE_IDENTIFIER                XSTR("com.growl.prefpanel")
235 /*!
236  *      @defined    GROWL_HELPERAPP_BUNDLE_IDENTIFIER
237  *      @discussion The bundle identifier for the Growl background application (GrowlHelperApp).
238  */
239 #define GROWL_HELPERAPP_BUNDLE_IDENTIFIER       XSTR("com.Growl.GrowlHelperApp")
240
241 /*!
242  *      @defined    GROWL_PREFPANE_NAME
243  *      @discussion The file name of the Growl preference pane.
244  */
245 #define GROWL_PREFPANE_NAME                                             XSTR("Growl.prefPane")
246 #define PREFERENCE_PANES_SUBFOLDER_OF_LIBRARY   XSTR("PreferencePanes")
247 #define PREFERENCE_PANE_EXTENSION                               XSTR("prefPane")
248
249 //plug-in bundle filename extensions
250 #define GROWL_PLUGIN_EXTENSION                  XSTR("growlPlugin")
251 #define GROWL_PATHWAY_EXTENSION                 XSTR("growlPathway")
252 #define GROWL_VIEW_EXTENSION                                    XSTR("growlView")
253 #define GROWL_STYLE_EXTENSION                                   XSTR("growlStyle")
254
255 /* --- These following macros are intended for plug-ins --- */
256
257 /*!     @function    SYNCHRONIZE_GROWL_PREFS
258  *      @abstract    Synchronizes Growl prefs so they're up-to-date.
259  *      @discussion  This macro is intended for use by GrowlHelperApp and by
260  *       plug-ins (when the prefpane is selected).
261  */
262 #define SYNCHRONIZE_GROWL_PREFS() CFPreferencesAppSynchronize(CFSTR("com.Growl.GrowlHelperApp"))
263
264 /*!     @function    UPDATE_GROWL_PREFS
265  *      @abstract    Tells GrowlHelperApp to update its prefs.
266  *      @discussion  This macro is intended for use by plug-ins.
267  *       It sends a notification to tell GrowlHelperApp to update its preferences.
268  */
269 #define UPDATE_GROWL_PREFS() do { \
270         SYNCHRONIZE_GROWL_PREFS(); \
271         CFStringRef _key = CFSTR("pid"); \
272         int pid = getpid(); \
273         CFNumberRef _value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &pid); \
274         CFDictionaryRef userInfo = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&_key, (const void **)&_value, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); \
275         CFRelease(_value); \
276         CFNotificationCenterPostNotification(CFNotificationCenterGetDistributedCenter(), \
277                                                                                  CFSTR("GrowlPreferencesChanged"), \
278                                                                                  CFSTR("GrowlUserDefaults"), \
279                                                                                  userInfo, false); \
280         CFRelease(userInfo); \
281         } while(0)
282
283 /*!     @function    READ_GROWL_PREF_VALUE
284  *      @abstract    Reads the given pref value from the plug-in's preferences.
285  *      @discussion  This macro is intended for use by plug-ins. It reads the value for the
286  *       given key from the plug-in's preferences (which are stored in a dictionary inside of
287  *       GrowlHelperApp's prefs).
288  *      @param  key     The preference key to read the value of.
289  *      @param  domain  The bundle ID of the plug-in.
290  *      @param  type    The type of the result expected.
291  *      @param  result  A pointer to an id. Set to the value if exists, left unchanged if not.
292  *
293  *       If the value is set, you are responsible for releasing it.
294  */
295 #define READ_GROWL_PREF_VALUE(key, domain, type, result) do {\
296         CFDictionaryRef prefs = (CFDictionaryRef)CFPreferencesCopyAppValue((CFStringRef)domain, \
297                                                                                                                                                 CFSTR("com.Growl.GrowlHelperApp")); \
298         if (prefs) {\
299                 if (CFDictionaryContainsKey(prefs, key)) {\
300                         *result = (type)CFDictionaryGetValue(prefs, key); \
301                         CFRetain(*result); \
302                 } \
303                 CFRelease(prefs); } \
304         } while(0)
305
306 /*!     @function    WRITE_GROWL_PREF_VALUE
307  *      @abstract    Writes the given pref value to the plug-in's preferences.
308  *      @discussion  This macro is intended for use by plug-ins. It writes the given
309  *       value to the plug-in's preferences.
310  *      @param  key     The preference key to write the value of.
311  *      @param  value   The value to write to the preferences. It should be either a
312  *       CoreFoundation type or toll-free bridged with one.
313  *      @param  domain  The bundle ID of the plug-in.
314  */
315 #define WRITE_GROWL_PREF_VALUE(key, value, domain) do {\
316         CFDictionaryRef staticPrefs = (CFDictionaryRef)CFPreferencesCopyAppValue((CFStringRef)domain, \
317                                                                                                                                                          CFSTR("com.Growl.GrowlHelperApp")); \
318         CFMutableDictionaryRef prefs; \
319         if (staticPrefs == NULL) {\
320                 prefs = CFDictionaryCreateMutable(NULL, 0, NULL, NULL); \
321         } else {\
322                 prefs = CFDictionaryCreateMutableCopy(NULL, 0, staticPrefs); \
323                 CFRelease(staticPrefs); \
324         }\
325         CFDictionarySetValue(prefs, key, value); \
326         CFPreferencesSetAppValue((CFStringRef)domain, prefs, CFSTR("com.Growl.GrowlHelperApp")); \
327         CFRelease(prefs); } while(0)
328
329 /*!     @function    READ_GROWL_PREF_BOOL
330  *      @abstract    Reads the given Boolean from the plug-in's preferences.
331  *      @discussion  This is a wrapper around READ_GROWL_PREF_VALUE() intended for
332  *       use with Booleans.
333  *      @param  key     The preference key to read the Boolean from.
334  *      @param  domain  The bundle ID of the plug-in.
335  *      @param  result  A pointer to a Boolean type. Left unchanged if the value doesn't exist.
336  */
337 #define READ_GROWL_PREF_BOOL(key, domain, result) do {\
338         CFBooleanRef boolValue = NULL; \
339         READ_GROWL_PREF_VALUE(key, domain, CFBooleanRef, &boolValue); \
340         if (boolValue) {\
341                 *result = CFBooleanGetValue(boolValue); \
342                 CFRelease(boolValue); \
343         } } while(0)
344
345 /*!     @function    WRITE_GROWL_PREF_BOOL
346  *      @abstract    Writes the given Boolean to the plug-in's preferences.
347  *      @discussion  This is a wrapper around WRITE_GROWL_PREF_VALUE() intended for
348  *       use with Booleans.
349  *      @param  key     The preference key to write the Boolean for.
350  *      @param  value   The Boolean value to write to the preferences.
351  *      @param  domain  The bundle ID of the plug-in.
352  */
353 #define WRITE_GROWL_PREF_BOOL(key, value, domain) do {\
354         WRITE_GROWL_PREF_VALUE(key, value ? kCFBooleanTrue : kCFBooleanFalse, domain); } while(0)
355
356 /*!     @function    READ_GROWL_PREF_INT
357  *      @abstract    Reads the given integer from the plug-in's preferences.
358  *      @discussion  This is a wrapper around READ_GROWL_PREF_VALUE() intended for
359  *       use with integers.
360  *      @param  key     The preference key to read the integer from.
361  *      @param  domain  The bundle ID of the plug-in.
362  *      @param  result  A pointer to an integer. Leaves unchanged if the value doesn't exist.
363  */
364 #define READ_GROWL_PREF_INT(key, domain, result) do {\
365         CFNumberRef intValue = NULL; \
366         READ_GROWL_PREF_VALUE(key, domain, CFNumberRef, &intValue); \
367         if (intValue) {\
368                 CFNumberGetValue(intValue, kCFNumberIntType, result); \
369                 CFRelease(intValue); \
370         } } while(0)
371
372 /*!     @function    WRITE_GROWL_PREF_INT
373  *      @abstract    Writes the given integer to the plug-in's preferences.
374  *      @discussion  This is a wrapper around WRITE_GROWL_PREF_VALUE() intended for
375  *       use with integers.
376  *      @param  key     The preference key to write the integer for.
377  *      @param  value   The integer value to write to the preferences.
378  *      @param  domain  The bundle ID of the plug-in.
379  */
380 #define WRITE_GROWL_PREF_INT(key, value, domain) do {\
381         CFNumberRef intValue = CFNumberCreate(NULL, kCFNumberIntType, &value); \
382         WRITE_GROWL_PREF_VALUE(key, intValue, domain); \
383         CFRelease(intValue); } while(0)
384
385 /*!     @function    READ_GROWL_PREF_FLOAT
386  *      @abstract    Reads the given float from the plug-in's preferences.
387  *      @discussion  This is a wrapper around READ_GROWL_PREF_VALUE() intended for
388  *       use with floats.
389  *      @param  key     The preference key to read the float from.
390  *      @param  domain  The bundle ID of the plug-in.
391  *      @param  result  A pointer to a float. Leaves unchanged if the value doesn't exist.
392  */
393 #define READ_GROWL_PREF_FLOAT(key, domain, result) do {\
394         CFNumberRef floatValue = NULL; \
395         READ_GROWL_PREF_VALUE(key, domain, CFNumberRef, &floatValue); \
396         if (floatValue) {\
397                 CFNumberGetValue(floatValue, kCFNumberFloatType, result); \
398                 CFRelease(floatValue); \
399         } } while(0)
400
401 /*!     @function    WRITE_GROWL_PREF_FLOAT
402  *      @abstract    Writes the given float to the plug-in's preferences.
403  *      @discussion  This is a wrapper around WRITE_GROWL_PREF_VALUE() intended for
404  *       use with floats.
405  *      @param  key     The preference key to write the float for.
406  *      @param  value   The float value to write to the preferences.
407  *      @param  domain  The bundle ID of the plug-in.
408  */
409 #define WRITE_GROWL_PREF_FLOAT(key, value, domain) do {\
410         CFNumberRef floatValue = CFNumberCreate(NULL, kCFNumberFloatType, &value); \
411         WRITE_GROWL_PREF_VALUE(key, floatValue, domain); \
412         CFRelease(floatValue); } while(0)
413
414
415 /*!     @defined        GROWL_CLOSE_ALL_NOTIFICATIONS
416  *      @abstract       Notification to close all Growl notifications
417  *      @discussion     Should be posted to the default notification center when a close widget is option+clicked.
418  *    All notifications should close in response. 
419  */
420 #define GROWL_CLOSE_ALL_NOTIFICATIONS XSTR("GrowlCloseAllNotifications")
421
422 #pragma mark Small utilities
423
424 /*!
425  * @defined FLOAT_EQ(x,y)
426  * @abstract Compares two floats.
427  */
428 #define FLOAT_EQ(x,y) (((y - FLT_EPSILON) < x) && (x < (y + FLT_EPSILON)))
429
430 #endif //ndef _GROWL_GROWLDEFINESINTERNAL_H