Coverage Report

Created: 2025-08-28 06:24

/src/pidgin/libpurple/sound.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * purple
3
 *
4
 * Purple is the legal property of its developers, whose names are too numerous
5
 * to list here.  Please refer to the COPYRIGHT file distributed with this
6
 * source distribution.
7
 *
8
 * This program is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
21
 *
22
 */
23
#include "internal.h"
24
25
#include "blist.h"
26
#include "prefs.h"
27
#include "sound.h"
28
#include "sound-theme-loader.h"
29
#include "theme-manager.h"
30
31
static PurpleSoundUiOps *sound_ui_ops = NULL;
32
33
0
#define STATUS_AVAILABLE 1
34
0
#define STATUS_AWAY 2
35
36
static time_t last_played[PURPLE_NUM_SOUNDS];
37
38
static gboolean
39
purple_sound_play_required(const PurpleAccount *account)
40
0
{
41
0
  gint pref_status = purple_prefs_get_int("/purple/sound/while_status");
42
43
0
  if (pref_status == 3)
44
0
  {
45
    /* Play sounds: Always */
46
0
    return TRUE;
47
0
  }
48
49
0
  if (account != NULL)
50
0
  {
51
0
    PurpleStatus *status = purple_account_get_active_status(account);
52
53
0
    if (purple_status_is_online(status))
54
0
    {
55
0
      gboolean available = purple_status_is_available(status);
56
0
      return (( available && pref_status == STATUS_AVAILABLE) ||
57
0
              (!available && pref_status == STATUS_AWAY));
58
0
    }
59
0
  }
60
61
  /* We get here a couple of ways.  Either the request has been OK'ed
62
   * by purple_sound_play_event() and we're here because the UI has
63
   * called purple_sound_play_file(), or we're here for something
64
   * not related to an account (like testing a sound). */
65
0
  return TRUE;
66
0
}
67
68
void
69
purple_sound_play_file(const char *filename, const PurpleAccount *account)
70
0
{
71
0
  if (!purple_sound_play_required(account))
72
0
    return;
73
74
0
  if(sound_ui_ops && sound_ui_ops->play_file)
75
0
    sound_ui_ops->play_file(filename);
76
0
}
77
78
void
79
purple_sound_play_event(PurpleSoundEventID event, const PurpleAccount *account)
80
0
{
81
0
  if (!purple_sound_play_required(account))
82
0
    return;
83
84
0
  if (time(NULL) - last_played[event] < 2)
85
0
    return;
86
0
  last_played[event] = time(NULL);
87
88
0
  if(sound_ui_ops && sound_ui_ops->play_event) {
89
0
    int plugin_return;
90
91
0
    plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1(
92
0
      purple_sounds_get_handle(), "playing-sound-event",
93
0
      event, account));
94
95
0
    if (plugin_return)
96
0
      return;
97
0
    else
98
0
      sound_ui_ops->play_event(event);
99
0
  }
100
0
}
101
102
void
103
purple_sound_set_ui_ops(PurpleSoundUiOps *ops)
104
0
{
105
0
  if(sound_ui_ops && sound_ui_ops->uninit)
106
0
    sound_ui_ops->uninit();
107
108
0
  sound_ui_ops = ops;
109
110
0
  if(sound_ui_ops && sound_ui_ops->init)
111
0
    sound_ui_ops->init();
112
0
}
113
114
PurpleSoundUiOps *
115
purple_sound_get_ui_ops(void)
116
0
{
117
0
  return sound_ui_ops;
118
0
}
119
120
void
121
purple_sound_init()
122
0
{
123
0
  void *handle = purple_sounds_get_handle();
124
125
  /**********************************************************************
126
   * Register signals
127
  **********************************************************************/
128
129
0
  purple_signal_register(handle, "playing-sound-event",
130
0
                       purple_marshal_BOOLEAN__INT_POINTER,
131
0
                       purple_value_new(PURPLE_TYPE_BOOLEAN), 2,
132
0
                       purple_value_new(PURPLE_TYPE_INT),
133
0
                       purple_value_new(PURPLE_TYPE_SUBTYPE,
134
0
                                      PURPLE_SUBTYPE_ACCOUNT));
135
136
0
  purple_prefs_add_none("/purple/sound");
137
0
  purple_prefs_add_int("/purple/sound/while_status", STATUS_AVAILABLE);
138
0
  memset(last_played, 0, sizeof(last_played));
139
140
0
  purple_theme_manager_register_type(g_object_new(PURPLE_TYPE_SOUND_THEME_LOADER, "type", "sound", NULL));
141
0
}
142
143
void
144
purple_sound_uninit()
145
0
{
146
0
  if(sound_ui_ops && sound_ui_ops->uninit)
147
0
    sound_ui_ops->uninit();
148
149
0
  purple_signals_unregister_by_instance(purple_sounds_get_handle());
150
0
}
151
152
void *
153
purple_sounds_get_handle()
154
0
{
155
0
  static int handle;
156
157
0
  return &handle;
158
0
}