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