-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGrowlDefinesInternal.h
430 lines (392 loc) · 16.7 KB
/
GrowlDefinesInternal.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
//
// 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