Mercurial > pidgin.yaz
comparison libpurple/status.c @ 32692:0f94ec89f0bc
merged from im.pidgin.pidgin
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Mon, 26 Sep 2011 14:57:21 +0900 |
parents | ac6353ffa129 d2fe5f01635b |
children | 4a34689eeb33 |
comparison
equal
deleted
inserted
replaced
32438:55e678325bda | 32692:0f94ec89f0bc |
---|---|
255 | 255 |
256 return purple_status_type_new_full(primitive, id, name, TRUE, | 256 return purple_status_type_new_full(primitive, id, name, TRUE, |
257 user_settable, FALSE); | 257 user_settable, FALSE); |
258 } | 258 } |
259 | 259 |
260 static void | |
261 status_type_add_attr(PurpleStatusType *status_type, const char *id, | |
262 const char *name, PurpleValue *value) | |
263 { | |
264 PurpleStatusAttr *attr; | |
265 | |
266 g_return_if_fail(status_type != NULL); | |
267 g_return_if_fail(id != NULL); | |
268 g_return_if_fail(name != NULL); | |
269 g_return_if_fail(value != NULL); | |
270 | |
271 attr = purple_status_attr_new(id, name, value); | |
272 | |
273 status_type->attrs = g_list_append(status_type->attrs, attr); | |
274 } | |
275 | |
276 static void | |
277 status_type_add_attrs_vargs(PurpleStatusType *status_type, va_list args) | |
278 { | |
279 const char *id, *name; | |
280 PurpleValue *value; | |
281 | |
282 g_return_if_fail(status_type != NULL); | |
283 | |
284 while ((id = va_arg(args, const char *)) != NULL) | |
285 { | |
286 name = va_arg(args, const char *); | |
287 g_return_if_fail(name != NULL); | |
288 | |
289 value = va_arg(args, PurpleValue *); | |
290 g_return_if_fail(value != NULL); | |
291 | |
292 status_type_add_attr(status_type, id, name, value); | |
293 } | |
294 } | |
295 | |
260 PurpleStatusType * | 296 PurpleStatusType * |
261 purple_status_type_new_with_attrs(PurpleStatusPrimitive primitive, | 297 purple_status_type_new_with_attrs(PurpleStatusPrimitive primitive, |
262 const char *id, const char *name, | 298 const char *id, const char *name, |
263 gboolean saveable, gboolean user_settable, | 299 gboolean saveable, gboolean user_settable, |
264 gboolean independent, const char *attr_id, | 300 gboolean independent, const char *attr_id, |
275 | 311 |
276 status_type = purple_status_type_new_full(primitive, id, name, saveable, | 312 status_type = purple_status_type_new_full(primitive, id, name, saveable, |
277 user_settable, independent); | 313 user_settable, independent); |
278 | 314 |
279 /* Add the first attribute */ | 315 /* Add the first attribute */ |
280 purple_status_type_add_attr(status_type, attr_id, attr_name, attr_value); | 316 status_type_add_attr(status_type, attr_id, attr_name, attr_value); |
281 | 317 |
282 va_start(args, attr_value); | 318 va_start(args, attr_value); |
283 purple_status_type_add_attrs_vargs(status_type, args); | 319 status_type_add_attrs_vargs(status_type, args); |
284 va_end(args); | 320 va_end(args); |
285 | 321 |
286 return status_type; | 322 return status_type; |
287 } | 323 } |
288 | 324 |
297 g_list_foreach(status_type->attrs, (GFunc)purple_status_attr_destroy, NULL); | 333 g_list_foreach(status_type->attrs, (GFunc)purple_status_attr_destroy, NULL); |
298 g_list_free(status_type->attrs); | 334 g_list_free(status_type->attrs); |
299 | 335 |
300 PURPLE_DBUS_UNREGISTER_POINTER(status_type); | 336 PURPLE_DBUS_UNREGISTER_POINTER(status_type); |
301 g_free(status_type); | 337 g_free(status_type); |
302 } | |
303 | |
304 void | |
305 purple_status_type_add_attr(PurpleStatusType *status_type, const char *id, | |
306 const char *name, PurpleValue *value) | |
307 { | |
308 PurpleStatusAttr *attr; | |
309 | |
310 g_return_if_fail(status_type != NULL); | |
311 g_return_if_fail(id != NULL); | |
312 g_return_if_fail(name != NULL); | |
313 g_return_if_fail(value != NULL); | |
314 | |
315 attr = purple_status_attr_new(id, name, value); | |
316 | |
317 status_type->attrs = g_list_append(status_type->attrs, attr); | |
318 } | |
319 | |
320 void | |
321 purple_status_type_add_attrs_vargs(PurpleStatusType *status_type, va_list args) | |
322 { | |
323 const char *id, *name; | |
324 PurpleValue *value; | |
325 | |
326 g_return_if_fail(status_type != NULL); | |
327 | |
328 while ((id = va_arg(args, const char *)) != NULL) | |
329 { | |
330 name = va_arg(args, const char *); | |
331 g_return_if_fail(name != NULL); | |
332 | |
333 value = va_arg(args, PurpleValue *); | |
334 g_return_if_fail(value != NULL); | |
335 | |
336 purple_status_type_add_attr(status_type, id, name, value); | |
337 } | |
338 } | |
339 | |
340 void | |
341 purple_status_type_add_attrs(PurpleStatusType *status_type, const char *id, | |
342 const char *name, PurpleValue *value, ...) | |
343 { | |
344 va_list args; | |
345 | |
346 g_return_if_fail(status_type != NULL); | |
347 g_return_if_fail(id != NULL); | |
348 g_return_if_fail(name != NULL); | |
349 g_return_if_fail(value != NULL); | |
350 | |
351 /* Add the first attribute */ | |
352 purple_status_type_add_attr(status_type, id, name, value); | |
353 | |
354 va_start(args, value); | |
355 purple_status_type_add_attrs_vargs(status_type, args); | |
356 va_end(args); | |
357 } | 338 } |
358 | 339 |
359 PurpleStatusPrimitive | 340 PurpleStatusPrimitive |
360 purple_status_type_get_primitive(const PurpleStatusType *status_type) | 341 purple_status_type_get_primitive(const PurpleStatusType *status_type) |
361 { | 342 { |
685 old_status = NULL; | 666 old_status = NULL; |
686 | 667 |
687 notify_status_update(presence, old_status, status); | 668 notify_status_update(presence, old_status, status); |
688 } | 669 } |
689 | 670 |
690 void | 671 static void |
691 purple_status_set_active(PurpleStatus *status, gboolean active) | 672 status_set_attr_boolean(PurpleStatus *status, const char *id, |
692 { | |
693 purple_status_set_active_with_attrs_list(status, active, NULL); | |
694 } | |
695 | |
696 /* | |
697 * This used to parse the va_list directly, but now it creates a GList | |
698 * and passes it to purple_status_set_active_with_attrs_list(). That | |
699 * function was created because accounts.c needs to pass a GList of | |
700 * attributes to the status API. | |
701 */ | |
702 void | |
703 purple_status_set_active_with_attrs(PurpleStatus *status, gboolean active, va_list args) | |
704 { | |
705 GList *attrs = NULL; | |
706 const gchar *id; | |
707 gpointer data; | |
708 | |
709 while ((id = va_arg(args, const char *)) != NULL) | |
710 { | |
711 attrs = g_list_append(attrs, (char *)id); | |
712 data = va_arg(args, void *); | |
713 attrs = g_list_append(attrs, data); | |
714 } | |
715 purple_status_set_active_with_attrs_list(status, active, attrs); | |
716 g_list_free(attrs); | |
717 } | |
718 | |
719 void | |
720 purple_status_set_active_with_attrs_list(PurpleStatus *status, gboolean active, | |
721 GList *attrs) | |
722 { | |
723 gboolean changed = FALSE; | |
724 GList *l; | |
725 GList *specified_attr_ids = NULL; | |
726 PurpleStatusType *status_type; | |
727 | |
728 g_return_if_fail(status != NULL); | |
729 | |
730 if (!active && purple_status_is_exclusive(status)) | |
731 { | |
732 purple_debug_error("status", | |
733 "Cannot deactivate an exclusive status (%s).\n", | |
734 purple_status_get_id(status)); | |
735 return; | |
736 } | |
737 | |
738 if (status->active != active) | |
739 { | |
740 changed = TRUE; | |
741 } | |
742 | |
743 status->active = active; | |
744 | |
745 /* Set any attributes */ | |
746 l = attrs; | |
747 while (l != NULL) | |
748 { | |
749 const gchar *id; | |
750 PurpleValue *value; | |
751 | |
752 id = l->data; | |
753 l = l->next; | |
754 value = purple_status_get_attr_value(status, id); | |
755 if (value == NULL) | |
756 { | |
757 purple_debug_warning("status", "The attribute \"%s\" on the status \"%s\" is " | |
758 "not supported.\n", id, status->type->name); | |
759 /* Skip over the data and move on to the next attribute */ | |
760 l = l->next; | |
761 continue; | |
762 } | |
763 | |
764 specified_attr_ids = g_list_prepend(specified_attr_ids, (gpointer)id); | |
765 | |
766 if (purple_value_get_type(value) == PURPLE_TYPE_STRING) | |
767 { | |
768 const gchar *string_data = l->data; | |
769 l = l->next; | |
770 if (purple_strequal(string_data, purple_value_get_string(value))) | |
771 continue; | |
772 purple_status_set_attr_string(status, id, string_data); | |
773 changed = TRUE; | |
774 } | |
775 else if (purple_value_get_type(value) == PURPLE_TYPE_INT) | |
776 { | |
777 int int_data = GPOINTER_TO_INT(l->data); | |
778 l = l->next; | |
779 if (int_data == purple_value_get_int(value)) | |
780 continue; | |
781 purple_status_set_attr_int(status, id, int_data); | |
782 changed = TRUE; | |
783 } | |
784 else if (purple_value_get_type(value) == PURPLE_TYPE_BOOLEAN) | |
785 { | |
786 gboolean boolean_data = GPOINTER_TO_INT(l->data); | |
787 l = l->next; | |
788 if (boolean_data == purple_value_get_boolean(value)) | |
789 continue; | |
790 purple_status_set_attr_boolean(status, id, boolean_data); | |
791 changed = TRUE; | |
792 } | |
793 else | |
794 { | |
795 /* We don't know what the data is--skip over it */ | |
796 l = l->next; | |
797 } | |
798 } | |
799 | |
800 /* Reset any unspecified attributes to their default value */ | |
801 status_type = purple_status_get_type(status); | |
802 l = purple_status_type_get_attrs(status_type); | |
803 while (l != NULL) { | |
804 PurpleStatusAttr *attr; | |
805 | |
806 attr = l->data; | |
807 l = l->next; | |
808 | |
809 if (!g_list_find_custom(specified_attr_ids, attr->id, (GCompareFunc)strcmp)) { | |
810 PurpleValue *default_value; | |
811 default_value = purple_status_attr_get_value(attr); | |
812 if (purple_value_get_type(default_value) == PURPLE_TYPE_STRING) { | |
813 const char *cur = purple_status_get_attr_string(status, attr->id); | |
814 const char *def = purple_value_get_string(default_value); | |
815 if ((cur == NULL && def == NULL) | |
816 || (cur != NULL && def != NULL | |
817 && !strcmp(cur, def))) { | |
818 continue; | |
819 } | |
820 | |
821 purple_status_set_attr_string(status, attr->id, def); | |
822 } else if (purple_value_get_type(default_value) == PURPLE_TYPE_INT) { | |
823 int cur = purple_status_get_attr_int(status, attr->id); | |
824 int def = purple_value_get_int(default_value); | |
825 if (cur == def) | |
826 continue; | |
827 | |
828 purple_status_set_attr_int(status, attr->id, def); | |
829 } else if (purple_value_get_type(default_value) == PURPLE_TYPE_BOOLEAN) { | |
830 gboolean cur = purple_status_get_attr_boolean(status, attr->id); | |
831 gboolean def = purple_value_get_boolean(default_value); | |
832 if (cur == def) | |
833 continue; | |
834 | |
835 purple_status_set_attr_boolean(status, attr->id, def); | |
836 } | |
837 changed = TRUE; | |
838 } | |
839 } | |
840 g_list_free(specified_attr_ids); | |
841 | |
842 if (!changed) | |
843 return; | |
844 status_has_changed(status); | |
845 } | |
846 | |
847 void | |
848 purple_status_set_attr_boolean(PurpleStatus *status, const char *id, | |
849 gboolean value) | 673 gboolean value) |
850 { | 674 { |
851 PurpleValue *attr_value; | 675 PurpleValue *attr_value; |
852 | 676 |
853 g_return_if_fail(status != NULL); | 677 g_return_if_fail(status != NULL); |
859 g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_BOOLEAN); | 683 g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_BOOLEAN); |
860 | 684 |
861 purple_value_set_boolean(attr_value, value); | 685 purple_value_set_boolean(attr_value, value); |
862 } | 686 } |
863 | 687 |
864 void | 688 static void |
865 purple_status_set_attr_int(PurpleStatus *status, const char *id, int value) | 689 status_set_attr_int(PurpleStatus *status, const char *id, int value) |
866 { | 690 { |
867 PurpleValue *attr_value; | 691 PurpleValue *attr_value; |
868 | 692 |
869 g_return_if_fail(status != NULL); | 693 g_return_if_fail(status != NULL); |
870 g_return_if_fail(id != NULL); | 694 g_return_if_fail(id != NULL); |
875 g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_INT); | 699 g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_INT); |
876 | 700 |
877 purple_value_set_int(attr_value, value); | 701 purple_value_set_int(attr_value, value); |
878 } | 702 } |
879 | 703 |
880 void | 704 static void |
881 purple_status_set_attr_string(PurpleStatus *status, const char *id, | 705 status_set_attr_string(PurpleStatus *status, const char *id, |
882 const char *value) | 706 const char *value) |
883 { | 707 { |
884 PurpleValue *attr_value; | 708 PurpleValue *attr_value; |
885 | 709 |
886 g_return_if_fail(status != NULL); | 710 g_return_if_fail(status != NULL); |
904 /* XXX: Check if the value has actually changed. If it has, and the status | 728 /* XXX: Check if the value has actually changed. If it has, and the status |
905 * is active, should this trigger 'status_has_changed'? */ | 729 * is active, should this trigger 'status_has_changed'? */ |
906 purple_value_set_string(attr_value, value); | 730 purple_value_set_string(attr_value, value); |
907 } | 731 } |
908 | 732 |
733 void | |
734 purple_status_set_active(PurpleStatus *status, gboolean active) | |
735 { | |
736 purple_status_set_active_with_attrs_list(status, active, NULL); | |
737 } | |
738 | |
739 /* | |
740 * This used to parse the va_list directly, but now it creates a GList | |
741 * and passes it to purple_status_set_active_with_attrs_list(). That | |
742 * function was created because accounts.c needs to pass a GList of | |
743 * attributes to the status API. | |
744 */ | |
745 void | |
746 purple_status_set_active_with_attrs(PurpleStatus *status, gboolean active, va_list args) | |
747 { | |
748 GList *attrs = NULL; | |
749 const gchar *id; | |
750 gpointer data; | |
751 | |
752 while ((id = va_arg(args, const char *)) != NULL) | |
753 { | |
754 attrs = g_list_append(attrs, (char *)id); | |
755 data = va_arg(args, void *); | |
756 attrs = g_list_append(attrs, data); | |
757 } | |
758 purple_status_set_active_with_attrs_list(status, active, attrs); | |
759 g_list_free(attrs); | |
760 } | |
761 | |
762 void | |
763 purple_status_set_active_with_attrs_list(PurpleStatus *status, gboolean active, | |
764 GList *attrs) | |
765 { | |
766 gboolean changed = FALSE; | |
767 GList *l; | |
768 GList *specified_attr_ids = NULL; | |
769 PurpleStatusType *status_type; | |
770 | |
771 g_return_if_fail(status != NULL); | |
772 | |
773 if (!active && purple_status_is_exclusive(status)) | |
774 { | |
775 purple_debug_error("status", | |
776 "Cannot deactivate an exclusive status (%s).\n", | |
777 purple_status_get_id(status)); | |
778 return; | |
779 } | |
780 | |
781 if (status->active != active) | |
782 { | |
783 changed = TRUE; | |
784 } | |
785 | |
786 status->active = active; | |
787 | |
788 /* Set any attributes */ | |
789 l = attrs; | |
790 while (l != NULL) | |
791 { | |
792 const gchar *id; | |
793 PurpleValue *value; | |
794 | |
795 id = l->data; | |
796 l = l->next; | |
797 value = purple_status_get_attr_value(status, id); | |
798 if (value == NULL) | |
799 { | |
800 purple_debug_warning("status", "The attribute \"%s\" on the status \"%s\" is " | |
801 "not supported.\n", id, status->type->name); | |
802 /* Skip over the data and move on to the next attribute */ | |
803 l = l->next; | |
804 continue; | |
805 } | |
806 | |
807 specified_attr_ids = g_list_prepend(specified_attr_ids, (gpointer)id); | |
808 | |
809 if (purple_value_get_type(value) == PURPLE_TYPE_STRING) | |
810 { | |
811 const gchar *string_data = l->data; | |
812 l = l->next; | |
813 if (purple_strequal(string_data, purple_value_get_string(value))) | |
814 continue; | |
815 status_set_attr_string(status, id, string_data); | |
816 changed = TRUE; | |
817 } | |
818 else if (purple_value_get_type(value) == PURPLE_TYPE_INT) | |
819 { | |
820 int int_data = GPOINTER_TO_INT(l->data); | |
821 l = l->next; | |
822 if (int_data == purple_value_get_int(value)) | |
823 continue; | |
824 status_set_attr_int(status, id, int_data); | |
825 changed = TRUE; | |
826 } | |
827 else if (purple_value_get_type(value) == PURPLE_TYPE_BOOLEAN) | |
828 { | |
829 gboolean boolean_data = GPOINTER_TO_INT(l->data); | |
830 l = l->next; | |
831 if (boolean_data == purple_value_get_boolean(value)) | |
832 continue; | |
833 status_set_attr_boolean(status, id, boolean_data); | |
834 changed = TRUE; | |
835 } | |
836 else | |
837 { | |
838 /* We don't know what the data is--skip over it */ | |
839 l = l->next; | |
840 } | |
841 } | |
842 | |
843 /* Reset any unspecified attributes to their default value */ | |
844 status_type = purple_status_get_type(status); | |
845 l = purple_status_type_get_attrs(status_type); | |
846 while (l != NULL) { | |
847 PurpleStatusAttr *attr; | |
848 | |
849 attr = l->data; | |
850 l = l->next; | |
851 | |
852 if (!g_list_find_custom(specified_attr_ids, attr->id, (GCompareFunc)strcmp)) { | |
853 PurpleValue *default_value; | |
854 default_value = purple_status_attr_get_value(attr); | |
855 if (purple_value_get_type(default_value) == PURPLE_TYPE_STRING) { | |
856 const char *cur = purple_status_get_attr_string(status, attr->id); | |
857 const char *def = purple_value_get_string(default_value); | |
858 if ((cur == NULL && def == NULL) | |
859 || (cur != NULL && def != NULL | |
860 && !strcmp(cur, def))) { | |
861 continue; | |
862 } | |
863 | |
864 status_set_attr_string(status, attr->id, def); | |
865 } else if (purple_value_get_type(default_value) == PURPLE_TYPE_INT) { | |
866 int cur = purple_status_get_attr_int(status, attr->id); | |
867 int def = purple_value_get_int(default_value); | |
868 if (cur == def) | |
869 continue; | |
870 | |
871 status_set_attr_int(status, attr->id, def); | |
872 } else if (purple_value_get_type(default_value) == PURPLE_TYPE_BOOLEAN) { | |
873 gboolean cur = purple_status_get_attr_boolean(status, attr->id); | |
874 gboolean def = purple_value_get_boolean(default_value); | |
875 if (cur == def) | |
876 continue; | |
877 | |
878 status_set_attr_boolean(status, attr->id, def); | |
879 } | |
880 changed = TRUE; | |
881 } | |
882 } | |
883 g_list_free(specified_attr_ids); | |
884 | |
885 if (!changed) | |
886 return; | |
887 status_has_changed(status); | |
888 } | |
889 | |
909 PurpleStatusType * | 890 PurpleStatusType * |
910 purple_status_get_type(const PurpleStatus *status) | 891 purple_status_get_type(const PurpleStatus *status) |
911 { | 892 { |
912 g_return_val_if_fail(status != NULL, NULL); | 893 g_return_val_if_fail(status != NULL, NULL); |
913 | 894 |
1162 | 1143 |
1163 g_hash_table_destroy(presence->status_table); | 1144 g_hash_table_destroy(presence->status_table); |
1164 | 1145 |
1165 PURPLE_DBUS_UNREGISTER_POINTER(presence); | 1146 PURPLE_DBUS_UNREGISTER_POINTER(presence); |
1166 g_free(presence); | 1147 g_free(presence); |
1167 } | |
1168 | |
1169 void | |
1170 purple_presence_add_status(PurplePresence *presence, PurpleStatus *status) | |
1171 { | |
1172 g_return_if_fail(presence != NULL); | |
1173 g_return_if_fail(status != NULL); | |
1174 | |
1175 presence->statuses = g_list_append(presence->statuses, status); | |
1176 | |
1177 g_hash_table_insert(presence->status_table, | |
1178 g_strdup(purple_status_get_id(status)), status); | |
1179 } | |
1180 | |
1181 void | |
1182 purple_presence_add_list(PurplePresence *presence, GList *source_list) | |
1183 { | |
1184 GList *l; | |
1185 | |
1186 g_return_if_fail(presence != NULL); | |
1187 g_return_if_fail(source_list != NULL); | |
1188 | |
1189 for (l = source_list; l != NULL; l = l->next) | |
1190 purple_presence_add_status(presence, (PurpleStatus *)l->data); | |
1191 } | 1148 } |
1192 | 1149 |
1193 void | 1150 void |
1194 purple_presence_set_status_active(PurplePresence *presence, const char *status_id, | 1151 purple_presence_set_status_active(PurplePresence *presence, const char *status_id, |
1195 gboolean active) | 1152 gboolean active) |