NotificationDevelopmentGuidelines
Attachment 'append-hint-example.c'
Download
Toggle line numbers
1 /*******************************************************************************
2 **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
3 ** 10 20 30 40 50 60 70 80
4 **
5 ** Info:
6 ** Example of how to use libnotify correctly and at the same time comply to
7 ** the new jaunty notification spec (read: visual guidelines)
8 **
9 ** Compile:
10 ** gcc -O0 -ggdb -Wall -Werror `pkg-config --cflags --libs libnotify \
11 ** glib-2.0` append-hint-example.c -o append-hint-example
12 **
13 ** Copyright 2009 Canonical Ltd.
14 **
15 ** Author:
16 ** Mirco "MacSlow" Mueller <mirco.mueller@canonical.com>
17 **
18 ** This program is free software: you can redistribute it and/or modify it
19 ** under the terms of the GNU General Public License version 3, as published
20 ** by the Free Software Foundation.
21 **
22 ** This program is distributed in the hope that it will be useful, but
23 ** WITHOUT ANY WARRANTY; without even the implied warranties of
24 ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
25 ** PURPOSE. See the GNU General Public License for more details.
26 **
27 ** You should have received a copy of the GNU General Public License along
28 ** with this program. If not, see <http://www.gnu.org/licenses/>.
29 **
30 *******************************************************************************/
31
32
33 #include <glib.h>
34 #include <unistd.h>
35 #include <libnotify/notify.h>
36
37 typedef enum _Capability {
38 CAP_ACTIONS = 0,
39 CAP_BODY,
40 CAP_BODY_HYPERLINKS,
41 CAP_BODY_IMAGES,
42 CAP_BODY_MARKUP,
43 CAP_ICON_MULTI,
44 CAP_ICON_STATIC,
45 CAP_SOUND,
46 CAP_IMAGE_SVG,
47 CAP_SYNCHRONOUS,
48 CAP_APPEND,
49 CAP_LAYOUT_ICON_ONLY,
50 CAP_MAX
51 } Capability;
52
53 #define ACTIONS "actions"
54 #define BODY "body"
55 #define BODY_HYPERLINKS "body-hyperlinks"
56 #define BODY_IMAGES "body-images"
57 #define BODY_MARKUP "body-markup"
58 #define ICON_MULTI "icon-multi"
59 #define ICON_STATIC "icon-static"
60 #define SOUND "sound"
61 #define IMAGE_SVG "image/svg+xml"
62 #define SYNCHRONOUS "private-synchronous"
63 #define APPEND "append"
64 #define LAYOUT_ICON_ONLY "private-icon-only"
65
66 /* this is globally nasty :), do something nicer in your own code */
67 gboolean g_capabilities[CAP_MAX] = {FALSE, /* actions */
68 FALSE, /* body */
69 FALSE, /* body-hyperlinks */
70 FALSE, /* body-imges */
71 FALSE, /* body-markup */
72 FALSE, /* icon-multi */
73 FALSE, /* icon-static */
74 FALSE, /* sound */
75 FALSE, /* image/svg+xml */
76 FALSE, /* synchronous-hint */
77 FALSE, /* append-hint */
78 FALSE /* icon-only-hint */};
79
80 void
81 closed_handler (NotifyNotification* notification,
82 gpointer data)
83 {
84 g_print ("closed_handler() called");
85
86 return;
87 }
88
89 void
90 set_cap (gpointer data,
91 gpointer user_data)
92 {
93 /* test for "actions" */
94 if (!g_strcmp0 (ACTIONS, (gchar*) data))
95 g_capabilities[CAP_ACTIONS] = TRUE;
96
97 /* test for "body" */
98 if (!g_strcmp0 (BODY, (gchar*) data))
99 g_capabilities[CAP_BODY] = TRUE;
100
101 /* test for "body-hyperlinks" */
102 if (!g_strcmp0 (BODY_HYPERLINKS, (gchar*) data))
103 g_capabilities[CAP_BODY_HYPERLINKS] = TRUE;
104
105 /* test for "body-images" */
106 if (!g_strcmp0 (BODY_IMAGES, (gchar*) data))
107 g_capabilities[CAP_BODY_IMAGES] = TRUE;
108
109 /* test for "body-markup" */
110 if (!g_strcmp0 (BODY_MARKUP, (gchar*) data))
111 g_capabilities[CAP_BODY_MARKUP] = TRUE;
112
113 /* test for "icon-multi" */
114 if (!g_strcmp0 (ICON_MULTI, (gchar*) data))
115 g_capabilities[CAP_ICON_MULTI] = TRUE;
116
117 /* test for "icon-static" */
118 if (!g_strcmp0 (ICON_STATIC, (gchar*) data))
119 g_capabilities[CAP_ICON_STATIC] = TRUE;
120
121 /* test for "sound" */
122 if (!g_strcmp0 (SOUND, (gchar*) data))
123 g_capabilities[CAP_SOUND] = TRUE;
124
125 /* test for "image/svg+xml" */
126 if (!g_strcmp0 (IMAGE_SVG, (gchar*) data))
127 g_capabilities[CAP_IMAGE_SVG] = TRUE;
128
129 /* test for "canonical-private-1" */
130 if (!g_strcmp0 (SYNCHRONOUS, (gchar*) data))
131 g_capabilities[CAP_SYNCHRONOUS] = TRUE;
132
133 /* test for "canonical-private-2" */
134 if (!g_strcmp0 (APPEND, (gchar*) data))
135 g_capabilities[CAP_APPEND] = TRUE;
136
137 /* test for "canonical-private-3" */
138 if (!g_strcmp0 (LAYOUT_ICON_ONLY, (gchar*) data))
139 g_capabilities[CAP_LAYOUT_ICON_ONLY] = TRUE;
140 }
141
142 void
143 init_caps (void)
144 {
145 GList* caps_list;
146
147 caps_list = notify_get_server_caps ();
148 if (caps_list)
149 {
150 g_list_foreach (caps_list, set_cap, NULL);
151 g_list_foreach (caps_list, (GFunc) g_free, NULL);
152 g_list_free (caps_list);
153 }
154 }
155
156 gboolean
157 has_cap (Capability cap)
158 {
159 return g_capabilities[cap];
160 }
161
162 void
163 print_caps (void)
164 {
165 gchar* name;
166 gchar* vendor;
167 gchar* version;
168 gchar* spec_version;
169
170 notify_get_server_info (&name, &vendor, &version, &spec_version);
171
172 g_print ("Name: %s\n"
173 "Vendor: %s\n"
174 "Version: %s\n"
175 "Spec. Version: %s\n",
176 name,
177 vendor,
178 version,
179 spec_version);
180
181 g_print ("Supported capabilities/hints:\n");
182
183 if (has_cap (CAP_ACTIONS))
184 g_print ("\tactions\n");
185
186 if (has_cap (CAP_BODY))
187 g_print ("\tbody\n");
188
189 if (has_cap (CAP_BODY_HYPERLINKS))
190 g_print ("\tbody-hyperlinks\n");
191
192 if (has_cap (CAP_BODY_IMAGES))
193 g_print ("\tbody-images\n");
194
195 if (has_cap (CAP_BODY_MARKUP))
196 g_print ("\tbody-markup\n");
197
198 if (has_cap (CAP_ICON_MULTI))
199 g_print ("\ticon-multi\n");
200
201 if (has_cap (CAP_ICON_STATIC))
202 g_print ("\ticon-static\n");
203
204 if (has_cap (CAP_SOUND))
205 g_print ("\tsound\n");
206
207 if (has_cap (CAP_IMAGE_SVG))
208 g_print ("\timage/svg+xml\n");
209
210 if (has_cap (CAP_SYNCHRONOUS))
211 g_print ("\tprivate-synchronous\n");
212
213 if (has_cap (CAP_APPEND))
214 g_print ("\tappend\n");
215
216 if (has_cap (CAP_LAYOUT_ICON_ONLY))
217 g_print ("\tprivate-icon-only\n");
218
219 g_print ("Notes:\n");
220 if (!g_strcmp0 ("notify-osd", name))
221 {
222 g_print ("\tx- and y-coordinates hints are ignored\n");
223 g_print ("\texpire-timeout is ignored\n");
224 g_print ("\tbody-markup is accepted but filtered\n");
225 }
226 else
227 g_print ("\tnone");
228
229 g_free ((gpointer) name);
230 g_free ((gpointer) vendor);
231 g_free ((gpointer) version);
232 g_free ((gpointer) spec_version);
233 }
234
235 int
236 main (int argc,
237 char** argv)
238 {
239 NotifyNotification* notification;
240 gboolean success;
241 GError* error = NULL;
242
243 if (!notify_init ("append-hint-example"))
244 return 1;
245
246 /* call this so we can savely use has_cap(CAP_SOMETHING) later */
247 init_caps ();
248
249 /* show what's supported */
250 print_caps ();
251
252 /* try the append-hint */
253 if (has_cap (CAP_APPEND))
254 {
255 notification = notify_notification_new (
256 "Cole Raby",
257 "Hey Bro Coly!",
258 "notification-message-IM",
259 NULL);
260 notify_notification_set_hint_string (notification,
261 "append",
262 "allowed");
263 error = NULL;
264 success = notify_notification_show (notification, &error);
265 if (!success)
266 {
267 g_print ("That did not work ... \"%s\".\n",
268 error->message);
269 }
270 g_signal_connect (G_OBJECT (notification),
271 "closed",
272 G_CALLBACK (closed_handler),
273 NULL);
274 sleep (2); /* simulate a user typing */
275 success = notify_notification_update (
276 notification,
277 "Cole Raby",
278 "What's up dude?",
279 "notification-message-IM");
280 success = notify_notification_show (notification, &error);
281 if (!success)
282 {
283 g_print ("That did not work ... \"%s\".\n",
284 error->message);
285 }
286 g_signal_connect (G_OBJECT (notification),
287 "closed",
288 G_CALLBACK (closed_handler),
289 NULL);
290 sleep (2); /* simulate a user typing */
291 success = notify_notification_update (
292 notification,
293 "Cole Raby",
294 "Did you watch the air-race in Oshkosh last week?",
295 "notification-message-IM");
296 success = notify_notification_show (notification, &error);
297 if (!success)
298 {
299 g_print ("That did not work ... \"%s\".\n",
300 error->message);
301 }
302 g_signal_connect (G_OBJECT (notification),
303 "closed",
304 G_CALLBACK (closed_handler),
305 NULL);
306 sleep (2); /* simulate a user typing */
307 success = notify_notification_update (
308 notification,
309 "Cole Raby",
310 "Phil owned the place like no one before him!",
311 "notification-message-IM");
312 success = notify_notification_show (notification, &error);
313 if (!success)
314 {
315 g_print ("That did not work ... \"%s\".\n",
316 error->message);
317 }
318 g_signal_connect (G_OBJECT (notification),
319 "closed",
320 G_CALLBACK (closed_handler),
321 NULL);
322 }
323
324 notify_uninit ();
325
326 return 0;
327 }
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.