Sat, 09 Aug 2025 17:37:27 +0800
Fix the birb header path
The birb header referred would only work with birb provided by wrap casuing
build to fail because of system-installed birb dependency. The commit points
it to the correct path <birb.h>.
See: https://keep.imfreedom.org/birb/birb/file/5bf00c7d7f80/birb/meson.build#l77
| 42915 | 1 | /* |
| 2 | * Purple - Internet Messaging Library | |
| 3 | * Copyright (C) Pidgin Developers <devel@pidgin.im> | |
| 4 | * | |
| 5 | * Purple is the legal property of its developers, whose names are too numerous | |
| 6 | * to list here. Please refer to the COPYRIGHT file distributed with this | |
| 7 | * source distribution. | |
| 8 | * | |
| 9 | * This library is free software; you can redistribute it and/or modify it | |
| 10 | * under the terms of the GNU General Public License as published by the Free | |
| 11 | * Software Foundation; either version 2 of the License, or (at your option) | |
| 12 | * any later version. | |
| 13 | * | |
| 14 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
| 15 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 16 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
| 17 | * more details. | |
| 18 | * | |
| 19 | * You should have received a copy of the GNU General Public License along with | |
| 20 | * this library; if not, see <https://www.gnu.org/licenses/>. | |
| 21 | */ | |
| 22 | ||
| 23 | #include "purplebadge.h" | |
| 24 | ||
| 25 | #include "util.h" | |
| 26 | ||
| 27 | struct _PurpleBadge { | |
| 28 | GObject parent; | |
| 29 | ||
| 30 | char *id; | |
| 31 | int priority; | |
| 32 | char *icon_name; | |
| 33 | char *mnemonic; | |
| 34 | char *tooltip_text; | |
| 35 | char *description; | |
| 36 | ||
| 37 | char *link_text; | |
| 38 | char *link_uri; | |
| 39 | }; | |
| 40 | ||
| 41 | enum { | |
| 42 | PROP_0, | |
| 43 | PROP_ID, | |
| 44 | PROP_PRIORITY, | |
| 45 | PROP_ICON_NAME, | |
| 46 | PROP_MNEMONIC, | |
| 47 | PROP_TOOLTIP_TEXT, | |
| 48 | PROP_DESCRIPTION, | |
| 49 | PROP_LINK_TEXT, | |
| 50 | PROP_LINK_URI, | |
| 51 | N_PROPERTIES, | |
| 52 | }; | |
| 53 | static GParamSpec *properties[N_PROPERTIES] = {NULL, }; | |
| 54 | ||
| 55 | /****************************************************************************** | |
| 56 | * Helpers | |
| 57 | *****************************************************************************/ | |
| 58 | static void | |
| 59 | purple_badge_set_id(PurpleBadge *badge, const char *id) { | |
| 60 | g_return_if_fail(PURPLE_IS_BADGE(badge)); | |
| 61 | ||
| 62 | if(g_set_str(&badge->id, id)) { | |
| 63 | g_object_notify_by_pspec(G_OBJECT(badge), properties[PROP_ID]); | |
| 64 | } | |
| 65 | } | |
| 66 | ||
| 67 | static void | |
| 68 | purple_badge_set_priority(PurpleBadge *badge, int priority) { | |
| 69 | g_return_if_fail(PURPLE_IS_BADGE(badge)); | |
| 70 | ||
| 71 | if(badge->priority != priority) { | |
| 72 | badge->priority = priority; | |
| 73 | ||
| 74 | g_object_notify_by_pspec(G_OBJECT(badge), properties[PROP_PRIORITY]); | |
| 75 | } | |
| 76 | } | |
| 77 | ||
| 78 | static void | |
| 79 | purple_badge_set_icon_name(PurpleBadge *badge, const char *icon_name) { | |
| 80 | g_return_if_fail(PURPLE_IS_BADGE(badge)); | |
| 81 | ||
| 82 | if(g_set_str(&badge->icon_name, icon_name)) { | |
| 83 | g_object_notify_by_pspec(G_OBJECT(badge), properties[PROP_ICON_NAME]); | |
| 84 | } | |
| 85 | } | |
| 86 | ||
| 87 | static void | |
| 88 | purple_badge_set_mnemonic(PurpleBadge *badge, const char *mnemonic) { | |
| 89 | g_return_if_fail(PURPLE_IS_BADGE(badge)); | |
| 90 | ||
| 91 | if(g_set_str(&badge->mnemonic, mnemonic)) { | |
| 92 | g_object_notify_by_pspec(G_OBJECT(badge), properties[PROP_MNEMONIC]); | |
| 93 | } | |
| 94 | } | |
| 95 | ||
| 96 | /****************************************************************************** | |
| 97 | * GObject Implementation | |
| 98 | *****************************************************************************/ | |
| 99 | G_DEFINE_FINAL_TYPE(PurpleBadge, purple_badge, | |
| 100 | G_TYPE_OBJECT) | |
| 101 | ||
| 102 | static void | |
| 103 | purple_badge_get_property(GObject *obj, guint param_id, GValue *value, | |
| 104 | GParamSpec *pspec) | |
| 105 | { | |
| 106 | PurpleBadge *badge = PURPLE_BADGE(obj); | |
| 107 | ||
| 108 | switch(param_id) { | |
| 109 | case PROP_ID: | |
| 110 | g_value_set_string(value, purple_badge_get_id(badge)); | |
| 111 | break; | |
| 112 | case PROP_PRIORITY: | |
| 113 | g_value_set_int(value, purple_badge_get_priority(badge)); | |
| 114 | break; | |
| 115 | case PROP_ICON_NAME: | |
| 116 | g_value_set_string(value, purple_badge_get_icon_name(badge)); | |
| 117 | break; | |
| 118 | case PROP_MNEMONIC: | |
| 119 | g_value_set_string(value, purple_badge_get_mnemonic(badge)); | |
| 120 | break; | |
| 121 | case PROP_TOOLTIP_TEXT: | |
| 122 | g_value_set_string(value, purple_badge_get_tooltip_text(badge)); | |
| 123 | break; | |
| 124 | case PROP_DESCRIPTION: | |
| 125 | g_value_set_string(value, purple_badge_get_description(badge)); | |
| 126 | break; | |
| 127 | case PROP_LINK_TEXT: | |
| 128 | g_value_set_string(value, purple_badge_get_link_text(badge)); | |
| 129 | break; | |
| 130 | case PROP_LINK_URI: | |
| 131 | g_value_set_string(value, purple_badge_get_link_uri(badge)); | |
| 132 | break; | |
| 133 | default: | |
| 134 | G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); | |
| 135 | break; | |
| 136 | } | |
| 137 | } | |
| 138 | ||
| 139 | static void | |
| 140 | purple_badge_set_property(GObject *obj, guint param_id, const GValue *value, | |
| 141 | GParamSpec *pspec) | |
| 142 | { | |
| 143 | PurpleBadge *badge = PURPLE_BADGE(obj); | |
| 144 | ||
| 145 | switch(param_id) { | |
| 146 | case PROP_ID: | |
| 147 | purple_badge_set_id(badge, g_value_get_string(value)); | |
| 148 | break; | |
| 149 | case PROP_PRIORITY: | |
| 150 | purple_badge_set_priority(badge, g_value_get_int(value)); | |
| 151 | break; | |
| 152 | case PROP_ICON_NAME: | |
| 153 | purple_badge_set_icon_name(badge, g_value_get_string(value)); | |
| 154 | break; | |
| 155 | case PROP_MNEMONIC: | |
| 156 | purple_badge_set_mnemonic(badge, g_value_get_string(value)); | |
| 157 | break; | |
| 158 | case PROP_TOOLTIP_TEXT: | |
| 159 | purple_badge_set_tooltip_text(badge, g_value_get_string(value)); | |
| 160 | break; | |
| 161 | case PROP_DESCRIPTION: | |
| 162 | purple_badge_set_description(badge, g_value_get_string(value)); | |
| 163 | break; | |
| 164 | case PROP_LINK_TEXT: | |
| 165 | purple_badge_set_link_text(badge, g_value_get_string(value)); | |
| 166 | break; | |
| 167 | case PROP_LINK_URI: | |
| 168 | purple_badge_set_link_uri(badge, g_value_get_string(value)); | |
| 169 | break; | |
| 170 | default: | |
| 171 | G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); | |
| 172 | break; | |
| 173 | } | |
| 174 | } | |
| 175 | ||
| 176 | static void | |
| 177 | purple_badge_finalize(GObject *obj) { | |
| 178 | PurpleBadge *badge = PURPLE_BADGE(obj); | |
| 179 | ||
| 180 | g_clear_pointer(&badge->id, g_free); | |
| 181 | g_clear_pointer(&badge->icon_name, g_free); | |
| 182 | g_clear_pointer(&badge->mnemonic, g_free); | |
| 183 | g_clear_pointer(&badge->tooltip_text, g_free); | |
| 184 | g_clear_pointer(&badge->description, g_free); | |
| 185 | g_clear_pointer(&badge->link_text, g_free); | |
| 186 | g_clear_pointer(&badge->link_uri, g_free); | |
| 187 | ||
| 188 | G_OBJECT_CLASS(purple_badge_parent_class)->finalize(obj); | |
| 189 | } | |
| 190 | ||
| 191 | static void | |
| 192 | purple_badge_init(G_GNUC_UNUSED PurpleBadge *badge) { | |
| 193 | } | |
| 194 | ||
| 195 | static void | |
| 196 | purple_badge_class_init(PurpleBadgeClass *klass) | |
| 197 | { | |
| 198 | GObjectClass *obj_class = G_OBJECT_CLASS(klass); | |
| 199 | ||
| 200 | obj_class->get_property = purple_badge_get_property; | |
| 201 | obj_class->set_property = purple_badge_set_property; | |
| 202 | obj_class->finalize = purple_badge_finalize; | |
| 203 | ||
| 204 | /** | |
| 205 | * PurpleBadge:id: | |
| 206 | * | |
| 207 | * The id for this badge. | |
| 208 | * | |
| 209 | * This should be name spaced to avoid collisions. For example, the IRCv3 | |
| 210 | * protocol would use ircv3-prefix-operator for operators. | |
| 211 | * | |
| 212 | * Since: 3.0 | |
| 213 | */ | |
| 214 | properties[PROP_ID] = g_param_spec_string( | |
| 215 | "id", NULL, NULL, | |
| 216 | NULL, | |
| 217 | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); | |
| 218 | ||
| 219 | /** | |
| 220 | * PurpleBadge:priority: | |
| 221 | * | |
| 222 | * The priority of this badge. | |
| 223 | * | |
| 224 | * Badges with higher priorities will be sorted first. | |
| 225 | * | |
| 226 | * Since: 3.0 | |
| 227 | */ | |
| 228 | properties[PROP_PRIORITY] = g_param_spec_int( | |
| 229 | "priority", NULL, NULL, | |
| 230 | G_MININT32, G_MAXINT32, 0, | |
| 231 | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); | |
| 232 | ||
| 233 | /** | |
| 234 | * PurpleBadge:icon-name: | |
| 235 | * | |
| 236 | * The name of the icon for the badge. | |
| 237 | * | |
| 238 | * Since: 3.0 | |
| 239 | */ | |
| 240 | properties[PROP_ICON_NAME] = g_param_spec_string( | |
| 241 | "icon-name", NULL, NULL, | |
| 242 | NULL, | |
| 243 | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); | |
| 244 | ||
| 245 | /** | |
| 246 | * PurpleBadge:mnemonic: | |
| 247 | * | |
| 248 | * The mnemonic for the badge. | |
| 249 | * | |
| 250 | * The mnemonic is a fallback in case that the icon can not be found or can | |
| 251 | * be used by text interfaces. | |
| 252 | * | |
| 253 | * Since: 3.0 | |
| 254 | */ | |
| 255 | properties[PROP_MNEMONIC] = g_param_spec_string( | |
| 256 | "mnemonic", NULL, NULL, | |
| 257 | NULL, | |
| 258 | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); | |
| 259 | ||
| 260 | /** | |
| 261 | * PurpleBadge:tooltip-text: | |
| 262 | * | |
| 263 | * Text to be displayed in the tooltip for this badge. | |
| 264 | * | |
| 265 | * Since: 3.0 | |
| 266 | */ | |
| 267 | properties[PROP_TOOLTIP_TEXT] = g_param_spec_string( | |
| 268 | "tooltip-text", NULL, NULL, | |
| 269 | NULL, | |
| 270 | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); | |
| 271 | ||
| 272 | /** | |
| 273 | * PurpleBadge:description: | |
| 274 | * | |
| 275 | * The description of the badge. | |
| 276 | * | |
| 277 | * This may be shown as part of the tooltip to describe to the end user | |
| 278 | * what this badge is for. | |
| 279 | * | |
| 280 | * Since: 3.0 | |
| 281 | */ | |
| 282 | properties[PROP_DESCRIPTION] = g_param_spec_string( | |
| 283 | "description", NULL, NULL, | |
| 284 | NULL, | |
| 285 | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); | |
| 286 | ||
| 287 | /** | |
| 288 | * PurpleBadge:link-text: | |
| 289 | * | |
| 290 | * The text to display for the link of the badge. | |
| 291 | * | |
| 292 | * Since: 3.0 | |
| 293 | */ | |
| 294 | properties[PROP_LINK_TEXT] = g_param_spec_string( | |
| 295 | "link-text", NULL, NULL, | |
| 296 | NULL, | |
| 297 | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); | |
| 298 | ||
| 299 | /** | |
| 300 | * PurpleBadge:link-uri: | |
| 301 | * | |
| 302 | * A URI for the badge that could link to a page describing more about it. | |
| 303 | * | |
| 304 | * Since: 3.0 | |
| 305 | */ | |
| 306 | properties[PROP_LINK_URI] = g_param_spec_string( | |
| 307 | "link-uri", NULL, NULL, | |
| 308 | NULL, | |
| 309 | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); | |
| 310 | ||
| 311 | g_object_class_install_properties(obj_class, N_PROPERTIES, properties); | |
| 312 | } | |
| 313 | ||
| 314 | /****************************************************************************** | |
| 315 | * Public API | |
| 316 | *****************************************************************************/ | |
| 317 | PurpleBadge * | |
| 318 | purple_badge_new(const char *id, int priority, const char *icon_name, | |
| 319 | const char *mnemonic) | |
| 320 | { | |
| 321 | g_return_val_if_fail(!purple_strempty(id), NULL); | |
| 322 | g_return_val_if_fail(!purple_strempty(icon_name), NULL); | |
| 323 | g_return_val_if_fail(!purple_strempty(mnemonic), NULL); | |
| 324 | ||
| 325 | return g_object_new( | |
| 326 | PURPLE_TYPE_BADGE, | |
| 327 | "id", id, | |
| 328 | "priority", priority, | |
| 329 | "icon-name", icon_name, | |
| 330 | "mnemonic", mnemonic, | |
| 331 | NULL); | |
| 332 | } | |
| 333 | ||
| 334 | const char * | |
| 335 | purple_badge_get_id(PurpleBadge *badge) { | |
| 336 | g_return_val_if_fail(PURPLE_IS_BADGE(badge), NULL); | |
| 337 | ||
| 338 | return badge->id; | |
| 339 | } | |
| 340 | ||
| 341 | int | |
| 342 | purple_badge_get_priority(PurpleBadge *badge) { | |
| 343 | g_return_val_if_fail(PURPLE_IS_BADGE(badge), 0); | |
| 344 | ||
| 345 | return badge->priority; | |
| 346 | } | |
| 347 | ||
| 348 | const char * | |
| 349 | purple_badge_get_icon_name(PurpleBadge *badge) { | |
| 350 | g_return_val_if_fail(PURPLE_IS_BADGE(badge), NULL); | |
| 351 | ||
| 352 | return badge->icon_name; | |
| 353 | } | |
| 354 | ||
| 355 | const char * | |
| 356 | purple_badge_get_mnemonic(PurpleBadge *badge) { | |
| 357 | g_return_val_if_fail(PURPLE_IS_BADGE(badge), NULL); | |
| 358 | ||
| 359 | return badge->mnemonic; | |
| 360 | } | |
| 361 | ||
| 362 | const char * | |
| 363 | purple_badge_get_tooltip_text(PurpleBadge *badge) { | |
| 364 | g_return_val_if_fail(PURPLE_IS_BADGE(badge), NULL); | |
| 365 | ||
| 366 | return badge->tooltip_text; | |
| 367 | } | |
| 368 | ||
| 369 | void | |
| 370 | purple_badge_set_tooltip_text(PurpleBadge *badge, const char *tooltip_text) { | |
| 371 | g_return_if_fail(PURPLE_IS_BADGE(badge)); | |
| 372 | ||
| 373 | if(g_set_str(&badge->tooltip_text, tooltip_text)) { | |
| 374 | g_object_notify_by_pspec(G_OBJECT(badge), | |
| 375 | properties[PROP_TOOLTIP_TEXT]); | |
| 376 | } | |
| 377 | } | |
| 378 | ||
| 379 | const char * | |
| 380 | purple_badge_get_description(PurpleBadge *badge) { | |
| 381 | g_return_val_if_fail(PURPLE_IS_BADGE(badge), NULL); | |
| 382 | ||
| 383 | return badge->description; | |
| 384 | } | |
| 385 | ||
| 386 | void | |
| 387 | purple_badge_set_description(PurpleBadge *badge, const char *description) { | |
| 388 | g_return_if_fail(PURPLE_IS_BADGE(badge)); | |
| 389 | ||
| 390 | if(g_set_str(&badge->description, description)) { | |
| 391 | g_object_notify_by_pspec(G_OBJECT(badge), | |
| 392 | properties[PROP_DESCRIPTION]); | |
| 393 | } | |
| 394 | } | |
| 395 | ||
| 396 | const char * | |
| 397 | purple_badge_get_link_text(PurpleBadge *badge) { | |
| 398 | g_return_val_if_fail(PURPLE_IS_BADGE(badge), NULL); | |
| 399 | ||
| 400 | return badge->link_text; | |
| 401 | } | |
| 402 | ||
| 403 | void | |
| 404 | purple_badge_set_link_text(PurpleBadge *badge, const char *link_text) { | |
| 405 | g_return_if_fail(PURPLE_IS_BADGE(badge)); | |
| 406 | ||
| 407 | if(g_set_str(&badge->link_text, link_text)) { | |
| 408 | g_object_notify_by_pspec(G_OBJECT(badge), properties[PROP_LINK_TEXT]); | |
| 409 | } | |
| 410 | } | |
| 411 | ||
| 412 | const char * | |
| 413 | purple_badge_get_link_uri(PurpleBadge *badge) { | |
| 414 | g_return_val_if_fail(PURPLE_IS_BADGE(badge), NULL); | |
| 415 | ||
| 416 | return badge->link_uri; | |
| 417 | } | |
| 418 | ||
| 419 | void | |
| 420 | purple_badge_set_link_uri(PurpleBadge *badge, const char *link_uri) { | |
| 421 | g_return_if_fail(PURPLE_IS_BADGE(badge)); | |
| 422 | ||
| 423 | if(g_set_str(&badge->link_uri, link_uri)) { | |
| 424 | g_object_notify_by_pspec(G_OBJECT(badge), properties[PROP_LINK_URI]); | |
| 425 | } | |
| 426 | } | |
| 427 | ||
| 428 | int | |
| 429 | purple_badge_compare(PurpleBadge *badge1, PurpleBadge *badge2) { | |
| 430 | if(badge1 == NULL && badge2 == NULL) { | |
| 431 | return 0; | |
| 432 | } | |
| 433 | ||
| 434 | if(!PURPLE_IS_BADGE(badge1)) { | |
| 435 | return 1; | |
| 436 | } | |
| 437 | ||
| 438 | if(!PURPLE_IS_BADGE(badge2)) { | |
| 439 | return -1; | |
| 440 | } | |
| 441 | ||
| 442 | return badge2->priority - badge1->priority; | |
| 443 | } | |
| 444 | ||
| 445 | gboolean | |
| 446 | purple_badge_equal(PurpleBadge *badge1, PurpleBadge *badge2) { | |
| 447 | g_return_val_if_fail(PURPLE_IS_BADGE(badge1), FALSE); | |
| 448 | g_return_val_if_fail(PURPLE_IS_BADGE(badge2), FALSE); | |
| 449 | ||
| 450 | return purple_strequal(badge1->id, badge2->id); | |
| 451 | } |