Migrate certificates, icons, logs to XDG dirs
[pidgin-git.git] / libpurple / notify.c
blob19c3be1cabaf27429a562fe4f465693845bed9fe
1 /* purple
3 * Purple is the legal property of its developers, whose names are too numerous
4 * to list here. Please refer to the COPYRIGHT file distributed with this
5 * source distribution.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
21 #define _PURPLE_NOTIFY_C_
23 #include "internal.h"
24 #include "dbus-maybe.h"
25 #include "notify.h"
27 static PurpleNotifyUiOps *notify_ui_ops = NULL;
28 static GList *handles = NULL;
30 typedef struct
32 PurpleNotifyType type;
33 void *handle;
34 void *ui_handle;
35 PurpleNotifyCloseCallback cb;
36 gpointer cb_user_data;
37 } PurpleNotifyInfo;
40 * Definition of a user info entry
42 struct _PurpleNotifyUserInfoEntry
44 char *label;
45 char *value;
46 PurpleNotifyUserInfoEntryType type;
49 struct _PurpleNotifyUserInfo
51 GQueue entries;
55 * Single column of a search result.
57 struct _PurpleNotifySearchColumn
59 char *title; /* Title of the column. */
60 gboolean visible; /* Should the column be visible to the user. Defaults to TRUE. */
64 void *
65 purple_notify_message(void *handle, PurpleNotifyMessageType type, const char *title,
66 const char *primary, const char *secondary,
67 PurpleRequestCommonParameters *cpar, PurpleNotifyCloseCallback cb,
68 gpointer user_data)
70 PurpleNotifyUiOps *ops;
72 g_return_val_if_fail(primary != NULL, NULL);
74 ops = purple_notify_get_ui_ops();
76 if (ops != NULL && ops->notify_message != NULL) {
77 void *ui_handle = ops->notify_message(type, title, primary,
78 secondary, cpar);
79 if (ui_handle != NULL) {
81 PurpleNotifyInfo *info = g_new0(PurpleNotifyInfo, 1);
82 info->type = PURPLE_NOTIFY_MESSAGE;
83 info->handle = handle;
84 info->ui_handle = ui_handle;
85 info->cb = cb;
86 info->cb_user_data = user_data;
88 handles = g_list_append(handles, info);
90 return info->ui_handle;
95 if (cb != NULL)
96 cb(user_data);
98 return NULL;
101 void *
102 purple_notify_email(void *handle, const char *subject, const char *from,
103 const char *to, const char *url, PurpleNotifyCloseCallback cb,
104 gpointer user_data)
106 PurpleNotifyUiOps *ops;
108 ops = purple_notify_get_ui_ops();
110 if (ops != NULL && ops->notify_email != NULL) {
111 void *ui_handle;
113 purple_signal_emit(purple_notify_get_handle(), "displaying-email-notification",
114 subject, from, to, url);
116 ui_handle = ops->notify_email(handle, subject, from, to, url);
118 if (ui_handle != NULL) {
120 PurpleNotifyInfo *info = g_new0(PurpleNotifyInfo, 1);
121 info->type = PURPLE_NOTIFY_EMAIL;
122 info->handle = handle;
123 info->ui_handle = ui_handle;
124 info->cb = cb;
125 info->cb_user_data = user_data;
127 handles = g_list_append(handles, info);
129 return info->ui_handle;
133 if (cb != NULL)
134 cb(user_data);
136 return NULL;
139 void *
140 purple_notify_emails(void *handle, size_t count, gboolean detailed,
141 const char **subjects, const char **froms,
142 const char **tos, const char **urls,
143 PurpleNotifyCloseCallback cb, gpointer user_data)
145 PurpleNotifyUiOps *ops;
147 if (count == 1) {
148 return purple_notify_email(handle,
149 (subjects == NULL ? NULL : *subjects),
150 (froms == NULL ? NULL : *froms),
151 (tos == NULL ? NULL : *tos),
152 (urls == NULL ? NULL : *urls),
153 cb, user_data);
156 ops = purple_notify_get_ui_ops();
158 if (ops != NULL && ops->notify_emails != NULL) {
159 void *ui_handle;
161 purple_signal_emit(purple_notify_get_handle(), "displaying-emails-notification",
162 subjects, froms, tos, urls, count);
164 ui_handle = ops->notify_emails(handle, count, detailed, subjects,
165 froms, tos, urls);
167 if (ui_handle != NULL) {
168 PurpleNotifyInfo *info = g_new0(PurpleNotifyInfo, 1);
169 info->type = PURPLE_NOTIFY_EMAILS;
170 info->handle = handle;
171 info->ui_handle = ui_handle;
172 info->cb = cb;
173 info->cb_user_data = user_data;
175 handles = g_list_append(handles, info);
177 return info->ui_handle;
182 if (cb != NULL)
183 cb(user_data);
185 return NULL;
188 void *
189 purple_notify_formatted(void *handle, const char *title, const char *primary,
190 const char *secondary, const char *text,
191 PurpleNotifyCloseCallback cb, gpointer user_data)
193 PurpleNotifyUiOps *ops;
195 g_return_val_if_fail(primary != NULL, NULL);
197 ops = purple_notify_get_ui_ops();
199 if (ops != NULL && ops->notify_formatted != NULL) {
200 void *ui_handle = ops->notify_formatted(title, primary, secondary, text);
202 if (ui_handle != NULL) {
204 PurpleNotifyInfo *info = g_new0(PurpleNotifyInfo, 1);
205 info->type = PURPLE_NOTIFY_FORMATTED;
206 info->handle = handle;
207 info->ui_handle = ui_handle;
208 info->cb = cb;
209 info->cb_user_data = user_data;
211 handles = g_list_append(handles, info);
213 return info->ui_handle;
217 if (cb != NULL)
218 cb(user_data);
219 return NULL;
222 void *
223 purple_notify_searchresults(PurpleConnection *gc, const char *title,
224 const char *primary, const char *secondary,
225 PurpleNotifySearchResults *results, PurpleNotifyCloseCallback cb,
226 gpointer user_data)
228 PurpleNotifyUiOps *ops;
230 ops = purple_notify_get_ui_ops();
232 if (ops != NULL && ops->notify_searchresults != NULL) {
233 void *ui_handle = ops->notify_searchresults(gc, title, primary,
234 secondary, results, user_data);
235 if (ui_handle != NULL) {
237 PurpleNotifyInfo *info = g_new0(PurpleNotifyInfo, 1);
238 info->type = PURPLE_NOTIFY_SEARCHRESULTS;
239 info->handle = gc;
240 info->ui_handle = ui_handle;
241 info->cb = cb;
242 info->cb_user_data = user_data;
244 handles = g_list_append(handles, info);
246 return info->ui_handle;
250 if (cb != NULL)
251 cb(user_data);
253 return NULL;
256 void
257 purple_notify_searchresults_free(PurpleNotifySearchResults *results)
259 GList *l;
261 g_return_if_fail(results != NULL);
263 for (l = results->buttons; l; l = g_list_delete_link(l, l)) {
264 PurpleNotifySearchButton *button = l->data;
265 g_free(button->label);
266 g_free(button);
269 for (l = results->rows; l; l = g_list_delete_link(l, l)) {
270 GList *row = l->data;
271 g_list_foreach(row, (GFunc)g_free, NULL);
272 g_list_free(row);
275 for (l = results->columns; l; l = g_list_delete_link(l, l)) {
276 PurpleNotifySearchColumn *column = l->data;
277 g_free(column->title);
278 g_free(column);
281 g_free(results);
284 void
285 purple_notify_searchresults_new_rows(PurpleConnection *gc,
286 PurpleNotifySearchResults *results,
287 void *data)
289 PurpleNotifyUiOps *ops;
291 ops = purple_notify_get_ui_ops();
293 if (ops != NULL && ops->notify_searchresults != NULL) {
294 ops->notify_searchresults_new_rows(gc, results, data);
298 void
299 purple_notify_searchresults_button_add(PurpleNotifySearchResults *results,
300 PurpleNotifySearchButtonType type,
301 PurpleNotifySearchResultsCallback cb)
303 PurpleNotifySearchButton *button;
305 g_return_if_fail(results != NULL);
306 g_return_if_fail(cb != NULL);
308 button = g_new0(PurpleNotifySearchButton, 1);
309 button->callback = cb;
310 button->type = type;
312 results->buttons = g_list_append(results->buttons, button);
316 void
317 purple_notify_searchresults_button_add_labeled(PurpleNotifySearchResults *results,
318 const char *label,
319 PurpleNotifySearchResultsCallback cb) {
320 PurpleNotifySearchButton *button;
322 g_return_if_fail(results != NULL);
323 g_return_if_fail(cb != NULL);
324 g_return_if_fail(label != NULL);
325 g_return_if_fail(*label != '\0');
327 button = g_new0(PurpleNotifySearchButton, 1);
328 button->callback = cb;
329 button->type = PURPLE_NOTIFY_BUTTON_LABELED;
330 button->label = g_strdup(label);
332 results->buttons = g_list_append(results->buttons, button);
336 PurpleNotifySearchResults *
337 purple_notify_searchresults_new()
339 PurpleNotifySearchResults *rs = g_new0(PurpleNotifySearchResults, 1);
341 return rs;
344 void
345 purple_notify_searchresults_column_add(PurpleNotifySearchResults *results,
346 PurpleNotifySearchColumn *column)
348 g_return_if_fail(results != NULL);
349 g_return_if_fail(column != NULL);
351 results->columns = g_list_append(results->columns, column);
354 void purple_notify_searchresults_row_add(PurpleNotifySearchResults *results,
355 GList *row)
357 g_return_if_fail(results != NULL);
358 g_return_if_fail(row != NULL);
360 results->rows = g_list_append(results->rows, row);
363 PurpleNotifySearchColumn *
364 purple_notify_searchresults_column_new(const char *title)
366 PurpleNotifySearchColumn *sc;
368 g_return_val_if_fail(title != NULL, NULL);
370 sc = g_new0(PurpleNotifySearchColumn, 1);
371 sc->title = g_strdup(title);
372 sc->visible = TRUE;
374 return sc;
377 const char *purple_notify_searchresult_column_get_title(const PurpleNotifySearchColumn *column)
379 g_return_val_if_fail(column != NULL, NULL);
381 return column->title;
384 void purple_notify_searchresult_column_set_visible(PurpleNotifySearchColumn *column, gboolean visible)
386 g_return_if_fail(column != NULL);
388 column->visible = visible;
391 gboolean
392 purple_notify_searchresult_column_is_visible(const PurpleNotifySearchColumn *column)
394 g_return_val_if_fail(column != NULL, FALSE);
396 return column->visible;
399 void *
400 purple_notify_userinfo(PurpleConnection *gc, const char *who,
401 PurpleNotifyUserInfo *user_info, PurpleNotifyCloseCallback cb, gpointer user_data)
403 PurpleNotifyUiOps *ops;
405 g_return_val_if_fail(who != NULL, NULL);
407 ops = purple_notify_get_ui_ops();
409 if (ops != NULL && ops->notify_userinfo != NULL) {
410 void *ui_handle;
412 purple_signal_emit(purple_notify_get_handle(), "displaying-userinfo",
413 purple_connection_get_account(gc), who, user_info);
415 ui_handle = ops->notify_userinfo(gc, who, user_info);
417 if (ui_handle != NULL) {
419 PurpleNotifyInfo *info = g_new0(PurpleNotifyInfo, 1);
420 info->type = PURPLE_NOTIFY_USERINFO;
421 info->handle = gc;
422 info->ui_handle = ui_handle;
423 info->cb = cb;
424 info->cb_user_data = user_data;
426 handles = g_list_append(handles, info);
428 return info->ui_handle;
432 if (cb != NULL)
433 cb(user_data);
435 return NULL;
438 PurpleNotifyUserInfoEntry *
439 purple_notify_user_info_entry_new(const char *label, const char *value)
441 PurpleNotifyUserInfoEntry *user_info_entry;
443 user_info_entry = g_new0(PurpleNotifyUserInfoEntry, 1);
444 PURPLE_DBUS_REGISTER_POINTER(user_info_entry, PurpleNotifyUserInfoEntry);
445 user_info_entry->label = g_strdup(label);
446 user_info_entry->value = g_strdup(value);
447 user_info_entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_PAIR;
449 return user_info_entry;
452 void
453 purple_notify_user_info_entry_destroy(PurpleNotifyUserInfoEntry *user_info_entry)
455 g_return_if_fail(user_info_entry != NULL);
457 g_free(user_info_entry->label);
458 g_free(user_info_entry->value);
459 PURPLE_DBUS_UNREGISTER_POINTER(user_info_entry);
460 g_free(user_info_entry);
463 PurpleNotifyUserInfo *
464 purple_notify_user_info_new()
466 PurpleNotifyUserInfo *user_info;
468 user_info = g_new0(PurpleNotifyUserInfo, 1);
469 PURPLE_DBUS_REGISTER_POINTER(user_info, PurpleNotifyUserInfo);
470 g_queue_init(&user_info->entries);
472 return user_info;
475 void
476 purple_notify_user_info_destroy(PurpleNotifyUserInfo *user_info)
478 GList *l;
480 for (l = user_info->entries.head; l != NULL; l = l->next) {
481 PurpleNotifyUserInfoEntry *user_info_entry = l->data;
483 purple_notify_user_info_entry_destroy(user_info_entry);
486 g_queue_clear(&user_info->entries);
487 PURPLE_DBUS_UNREGISTER_POINTER(user_info);
488 g_free(user_info);
491 GQueue *
492 purple_notify_user_info_get_entries(PurpleNotifyUserInfo *user_info)
494 g_return_val_if_fail(user_info != NULL, NULL);
496 return &user_info->entries;
499 char *
500 purple_notify_user_info_get_text_with_newline(PurpleNotifyUserInfo *user_info, const char *newline)
502 GList *l;
503 GString *text;
505 text = g_string_new("");
507 for (l = user_info->entries.head; l != NULL; l = l->next) {
508 PurpleNotifyUserInfoEntry *user_info_entry = l->data;
509 /* Add a newline before a section header */
510 if (user_info_entry->type == PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER)
511 g_string_append(text, newline);
513 /* Handle the label/value pair itself */
514 /* XXX Todo: Use a larger size for a section header? */
515 if (user_info_entry->label)
516 g_string_append_printf(text, "<b>%s</b>", user_info_entry->label);
517 if (user_info_entry->label && user_info_entry->value)
518 g_string_append(text, ": ");
519 if (user_info_entry->value)
520 g_string_append(text, user_info_entry->value);
522 /* Display a section break as a horizontal line */
523 if (user_info_entry->type == PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK)
524 g_string_append(text, "<HR>");
526 /* Don't insert a new line before or after a section break; <HR> does that for us */
527 if ((user_info_entry->type != PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK) &&
528 (l->next && ((((PurpleNotifyUserInfoEntry *)(l->next->data))->type != PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK))))
529 g_string_append(text, newline);
531 /* Add an extra newline after a section header */
532 if (user_info_entry->type == PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER)
533 g_string_append(text, newline);
536 return g_string_free(text, FALSE);
540 const gchar *
541 purple_notify_user_info_entry_get_label(PurpleNotifyUserInfoEntry *user_info_entry)
543 g_return_val_if_fail(user_info_entry != NULL, NULL);
545 return user_info_entry->label;
548 void
549 purple_notify_user_info_entry_set_label(PurpleNotifyUserInfoEntry *user_info_entry, const char *label)
551 g_return_if_fail(user_info_entry != NULL);
553 g_free(user_info_entry->label);
554 user_info_entry->label = g_strdup(label);
557 const gchar *
558 purple_notify_user_info_entry_get_value(PurpleNotifyUserInfoEntry *user_info_entry)
560 g_return_val_if_fail(user_info_entry != NULL, NULL);
562 return user_info_entry->value;
565 void
566 purple_notify_user_info_entry_set_value(PurpleNotifyUserInfoEntry *user_info_entry, const char *value)
568 g_return_if_fail(user_info_entry != NULL);
570 g_free(user_info_entry->value);
571 user_info_entry->value = g_strdup(value);
574 PurpleNotifyUserInfoEntryType
575 purple_notify_user_info_entry_get_entry_type(PurpleNotifyUserInfoEntry *user_info_entry)
577 g_return_val_if_fail(user_info_entry != NULL, PURPLE_NOTIFY_USER_INFO_ENTRY_PAIR);
579 return user_info_entry->type;
582 void
583 purple_notify_user_info_entry_set_entry_type(PurpleNotifyUserInfoEntry *user_info_entry,
584 PurpleNotifyUserInfoEntryType type)
586 g_return_if_fail(user_info_entry != NULL);
588 user_info_entry->type = type;
591 void
592 purple_notify_user_info_add_pair_html(PurpleNotifyUserInfo *user_info, const char *label, const char *value)
594 PurpleNotifyUserInfoEntry *entry;
596 entry = purple_notify_user_info_entry_new(label, value);
597 g_queue_push_tail(&user_info->entries, entry);
600 void
601 purple_notify_user_info_add_pair_plaintext(PurpleNotifyUserInfo *user_info, const char *label, const char *value)
603 gchar *escaped;
605 escaped = g_markup_escape_text(value, -1);
606 purple_notify_user_info_add_pair_html(user_info, label, escaped);
607 g_free(escaped);
610 void
611 purple_notify_user_info_prepend_pair_html(PurpleNotifyUserInfo *user_info, const char *label, const char *value)
613 PurpleNotifyUserInfoEntry *entry;
615 entry = purple_notify_user_info_entry_new(label, value);
616 g_queue_push_head(&user_info->entries, entry);
619 void
620 purple_notify_user_info_prepend_pair_plaintext(PurpleNotifyUserInfo *user_info, const char *label, const char *value)
622 gchar *escaped;
624 escaped = g_markup_escape_text(value, -1);
625 purple_notify_user_info_prepend_pair_html(user_info, label, escaped);
626 g_free(escaped);
629 void
630 purple_notify_user_info_remove_entry(PurpleNotifyUserInfo *user_info, PurpleNotifyUserInfoEntry *entry)
632 g_return_if_fail(user_info != NULL);
633 g_return_if_fail(entry != NULL);
635 g_queue_remove(&user_info->entries, entry);
638 void
639 purple_notify_user_info_add_section_header(PurpleNotifyUserInfo *user_info, const char *label)
641 PurpleNotifyUserInfoEntry *entry;
643 entry = purple_notify_user_info_entry_new(label, NULL);
644 entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER;
646 g_queue_push_tail(&user_info->entries, entry);
649 void
650 purple_notify_user_info_prepend_section_header(PurpleNotifyUserInfo *user_info, const char *label)
652 PurpleNotifyUserInfoEntry *entry;
654 entry = purple_notify_user_info_entry_new(label, NULL);
655 entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER;
657 g_queue_push_head(&user_info->entries, entry);
660 void
661 purple_notify_user_info_add_section_break(PurpleNotifyUserInfo *user_info)
663 PurpleNotifyUserInfoEntry *entry;
665 entry = purple_notify_user_info_entry_new(NULL, NULL);
666 entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK;
668 g_queue_push_tail(&user_info->entries, entry);
671 void
672 purple_notify_user_info_prepend_section_break(PurpleNotifyUserInfo *user_info)
674 PurpleNotifyUserInfoEntry *entry;
676 entry = purple_notify_user_info_entry_new(NULL, NULL);
677 entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK;
679 g_queue_push_head(&user_info->entries, entry);
682 void
683 purple_notify_user_info_remove_last_item(PurpleNotifyUserInfo *user_info)
685 PurpleNotifyUserInfoEntry *entry;
687 entry = g_queue_pop_tail(&user_info->entries);
688 if (entry)
689 purple_notify_user_info_entry_destroy(entry);
692 static PurpleNotifyUserInfo *
693 purple_notify_user_info_copy(PurpleNotifyUserInfo *user_info)
695 PurpleNotifyUserInfo *user_info_copy;
696 GList *l;
698 g_return_val_if_fail(user_info != NULL, NULL);
700 user_info_copy = purple_notify_user_info_new();
702 for (l = user_info->entries.head; l != NULL; l = l->next) {
703 PurpleNotifyUserInfoEntry *new_entry, *user_info_entry = l->data;
705 new_entry = purple_notify_user_info_entry_new(user_info_entry->label,
706 user_info_entry->value);
707 new_entry->type = user_info_entry->type;
708 g_queue_push_tail(&user_info_copy->entries, new_entry);
711 return user_info_copy;
714 GType
715 purple_notify_user_info_get_type(void)
717 static GType type = 0;
719 if (type == 0) {
720 type = g_boxed_type_register_static("PurpleNotifyUserInfo",
721 (GBoxedCopyFunc)purple_notify_user_info_copy,
722 (GBoxedFreeFunc)purple_notify_user_info_destroy);
725 return type;
728 void *
729 purple_notify_uri(void *handle, const char *uri)
731 PurpleNotifyUiOps *ops;
733 g_return_val_if_fail(uri != NULL, NULL);
735 ops = purple_notify_get_ui_ops();
737 if (ops != NULL && ops->notify_uri != NULL) {
739 void *ui_handle = ops->notify_uri(uri);
741 if (ui_handle != NULL) {
743 PurpleNotifyInfo *info = g_new0(PurpleNotifyInfo, 1);
744 info->type = PURPLE_NOTIFY_URI;
745 info->handle = handle;
746 info->ui_handle = ui_handle;
748 handles = g_list_append(handles, info);
750 return info->ui_handle;
754 return NULL;
757 gboolean
758 purple_notify_is_valid_ui_handle(void *ui_handle, PurpleNotifyType *type)
760 GList *it;
762 if (ui_handle == NULL)
763 return FALSE;
765 for (it = handles; it != NULL; it = g_list_next(it)) {
766 PurpleNotifyInfo *info = it->data;
768 if (info->ui_handle != ui_handle)
769 continue;
771 if (type != NULL)
772 *type = info->type;
773 return TRUE;
776 return FALSE;
779 void
780 purple_notify_close(PurpleNotifyType type, void *ui_handle)
782 GList *l;
783 PurpleNotifyUiOps *ops;
785 g_return_if_fail(ui_handle != NULL);
787 ops = purple_notify_get_ui_ops();
789 for (l = handles; l != NULL; l = l->next) {
790 PurpleNotifyInfo *info = l->data;
792 if (info->ui_handle == ui_handle) {
793 handles = g_list_remove(handles, info);
795 if (ops != NULL && ops->close_notify != NULL)
796 ops->close_notify(info->type, ui_handle);
798 if (info->cb != NULL)
799 info->cb(info->cb_user_data);
801 g_free(info);
803 break;
808 void
809 purple_notify_close_with_handle(void *handle)
811 GList *l, *prev = NULL;
812 PurpleNotifyUiOps *ops;
814 g_return_if_fail(handle != NULL);
816 ops = purple_notify_get_ui_ops();
818 for (l = handles; l != NULL; l = prev ? prev->next : handles) {
819 PurpleNotifyInfo *info = l->data;
821 if (info->handle == handle) {
822 handles = g_list_remove(handles, info);
824 if (ops != NULL && ops->close_notify != NULL)
825 ops->close_notify(info->type, info->ui_handle);
827 if (info->cb != NULL)
828 info->cb(info->cb_user_data);
830 g_free(info);
831 } else
832 prev = l;
836 static PurpleNotifyUiOps *
837 purple_notify_ui_ops_copy(PurpleNotifyUiOps *ops)
839 PurpleNotifyUiOps *ops_new;
841 g_return_val_if_fail(ops != NULL, NULL);
843 ops_new = g_new(PurpleNotifyUiOps, 1);
844 *ops_new = *ops;
846 return ops_new;
849 GType
850 purple_notify_ui_ops_get_type(void)
852 static GType type = 0;
854 if (type == 0) {
855 type = g_boxed_type_register_static("PurpleNotifyUiOps",
856 (GBoxedCopyFunc)purple_notify_ui_ops_copy,
857 (GBoxedFreeFunc)g_free);
860 return type;
863 static PurpleNotifySearchButton *
864 purple_notify_search_button_copy(PurpleNotifySearchButton *button)
866 PurpleNotifySearchButton *button_new;
868 g_return_val_if_fail(button != NULL, NULL);
870 button_new = g_new(PurpleNotifySearchButton, 1);
871 *button_new = *button;
873 return button_new;
876 GType
877 purple_notify_search_button_get_type(void)
879 static GType type = 0;
881 if (type == 0) {
882 type = g_boxed_type_register_static("PurpleNotifySearchButton",
883 (GBoxedCopyFunc)purple_notify_search_button_copy,
884 (GBoxedFreeFunc)g_free);
887 return type;
890 void
891 purple_notify_set_ui_ops(PurpleNotifyUiOps *ops)
893 notify_ui_ops = ops;
896 PurpleNotifyUiOps *
897 purple_notify_get_ui_ops(void)
899 return notify_ui_ops;
902 void *
903 purple_notify_get_handle(void)
905 static int handle;
907 return &handle;
910 void
911 purple_notify_init(void)
913 gpointer handle = purple_notify_get_handle();
915 purple_signal_register(handle, "displaying-email-notification",
916 purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER,
917 G_TYPE_NONE, 4, G_TYPE_STRING, G_TYPE_STRING,
918 G_TYPE_STRING, G_TYPE_STRING);
920 purple_signal_register(handle, "displaying-emails-notification",
921 purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT,
922 G_TYPE_NONE, 5, G_TYPE_POINTER, G_TYPE_POINTER,
923 G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_UINT);
925 purple_signal_register(handle, "displaying-emails-clear",
926 purple_marshal_VOID, G_TYPE_NONE, 0);
928 purple_signal_register(handle, "displaying-userinfo",
929 purple_marshal_VOID__POINTER_POINTER_POINTER,
930 G_TYPE_NONE, 3, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
931 PURPLE_TYPE_NOTIFY_USER_INFO);
934 void
935 purple_notify_uninit(void)
937 purple_signals_unregister_by_instance(purple_notify_get_handle());