00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00025
00026
00027
00028
00029
00030 #include <config.h>
00031 #include <sys/stat.h>
00032 #include <errno.h>
00033 #include <fcntl.h>
00034 #include <pthread.h>
00035 #include <stdio.h>
00036 #include <unistd.h>
00037 #include <sys/ioctl.h>
00038 #include <sys/soundcard.h>
00039
00040
00041 #ifndef SNDCTL_POWER_OFF
00042 #define SNDCTL_POWER_OFF _SIO('P', 99)
00043 #define SNDCTL_POWER_ON _SIO('P', 100)
00044 #endif
00045
00046 #include <glib.h>
00047
00048 #include <liberregxml/erregapi.h>
00049
00050 #include "contentListerLog.h"
00051 #include "click.h"
00052
00053 #define MIXER "/dev/mixer"
00054
00055
00056 static int g_volume_settings = 0;
00057
00058 static wavFile_t g_wav_files[playUndefined] =
00059 {
00060 {FILENAME_KEY_CLICK, 0, NULL},
00061 {FILENAME_KEY_CLICK_DISCARDED, 0, NULL},
00062 {FILENAME_PEN_CLICK, 0, NULL}
00063 };
00064
00065 static pthread_mutex_t g_click_mutex;
00066
00067 static playSoundType_e g_play_sound;
00068
00069
00070 static void *click_thread (void *arg);
00071
00072
00073 static void destroy_waveforms()
00074 {
00075 int i;
00076 for (i=0; i<playUndefined; i++)
00077 {
00078 if (g_wav_files[i].wav_file_size)
00079 {
00080 g_free(g_wav_files[i].waveform);
00081 g_wav_files[i].waveform = NULL;
00082 g_wav_files[i].wav_file_size = 0;
00083 }
00084 }
00085 }
00086
00087
00088 static gboolean read_waveforms()
00089 {
00090 int i, n, fd;
00091 for (i=0; i<playUndefined; i++)
00092 {
00093 fd = open(g_wav_files[i].wav_file_path, O_RDONLY);
00094 if (fd <= 0)
00095 {
00096 CL_ERRORPRINTF ("Open error [%d] file [%s]", errno, g_wav_files[i].wav_file_path);
00097 goto Error;
00098 }
00099
00100 g_wav_files[i].wav_file_size = lseek(fd, 0, SEEK_END);
00101 g_wav_files[i].waveform = g_new(char, g_wav_files[i].wav_file_size);
00102 if (NULL == g_wav_files[i].waveform)
00103 {
00104 CL_ERRORPRINTF("Error allocating memory for waveforms.");
00105 close(fd);
00106 goto Error;
00107 }
00108
00109 lseek (fd, 0, SEEK_SET);
00110 n = read (fd, g_wav_files[i].waveform, g_wav_files[i].wav_file_size);
00111 if (n != g_wav_files[i].wav_file_size)
00112 {
00113 CL_ERRORPRINTF("Read error [%d] file [%s]", errno, g_wav_files[i].wav_file_path);
00114 close(fd);
00115 goto Error;
00116 }
00117
00118
00119 close(fd);
00120 }
00121
00122 return TRUE;
00123
00124 Error:
00125 destroy_waveforms();
00126 return FALSE;
00127 }
00128
00129 static void enable_audio_device(gboolean bEnable)
00130 {
00131 int audio_fd = open(AUDIO_DEVICE, O_RDWR);
00132 g_assert(audio_fd >= 0);
00133 int result = ioctl(audio_fd, bEnable ? SNDCTL_POWER_ON : SNDCTL_POWER_OFF, 0);
00134 g_assert (result != -1);
00135 close(audio_fd);
00136 }
00137
00138 static void set_volume(int volume)
00139 {
00140 int mixer_fd = open (MIXER, O_RDWR);
00141 g_assert (mixer_fd >= 0);
00142 volume = (volume << 8) | volume;
00143 int result = ioctl (mixer_fd, SOUND_MIXER_WRITE_VOLUME, &volume);
00144 g_assert (result != -1);
00145 close (mixer_fd);
00146 }
00147
00148
00149
00150 gboolean click_init ()
00151 {
00152 int err;
00153 pthread_t click_tid;
00154 regUserSetting_t *theUserSetting = NULL;
00155
00156
00157
00158 theUserSetting = erRegGetUserSetting();
00159 if (theUserSetting)
00160 {
00161 g_volume_settings = theUserSetting->volume;
00162 erRegFreeUserSetting (theUserSetting);
00163 }
00164 else
00165 {
00166
00167 g_volume_settings = 75;
00168 }
00169
00170
00171 enable_audio_device(g_volume_settings>0 ? TRUE : FALSE);
00172
00173 if (g_volume_settings > 0)
00174 {
00175
00176 set_volume(g_volume_settings);
00177 }
00178
00179
00180 if (!read_waveforms())
00181 {
00182 CL_ERRORPRINTF("Error reading waveforms.");
00183 return FALSE;
00184 }
00185
00186
00187 err = pthread_mutex_init (&g_click_mutex, NULL);
00188 if (err != 0)
00189 {
00190 CL_ERRORPRINTF ("Mutex init error [%d]", err);
00191 destroy_waveforms();
00192 return FALSE;
00193 }
00194
00195
00196 err = pthread_create (&click_tid, NULL, click_thread, NULL);
00197 if (err != 0)
00198 {
00199 CL_ERRORPRINTF ("start click-thread error [%d]", err);
00200 destroy_waveforms();
00201 return FALSE;
00202 }
00203
00204
00205 return TRUE;
00206 }
00207
00208 void handle_sound_settings_changed(int volume)
00209 {
00210 g_volume_settings = volume;
00211
00212
00213 enable_audio_device(g_volume_settings>0 ? TRUE : FALSE);
00214
00215 if (g_volume_settings > 0)
00216 {
00217
00218 set_volume(g_volume_settings);
00219 }
00220 }
00221
00222
00223 static void play_sound(playSoundType_e sound)
00224 {
00225 CL_LOGPRINTF("click: play %d sound", g_play_sound);
00226
00227 if (0 == g_volume_settings)
00228 {
00229
00230 return;
00231 }
00232
00233 if ( (sound >= playClickedKey) && (sound < playUndefined) )
00234 {
00235 g_play_sound = sound;
00236 }
00237 else
00238 {
00239 g_play_sound = playClickedKey;
00240 }
00241
00242 pthread_mutex_unlock (&g_click_mutex);
00243 }
00244
00245 void click_key()
00246 {
00247 play_sound(playClickedKey);
00248 }
00249
00250 void click_key_discard()
00251 {
00252 play_sound(playClickedKeyDiscarded);
00253 }
00254
00255 void click_pen()
00256 {
00257 play_sound(playClickedPen);
00258 }
00259
00260 static void *click_thread (void *arg)
00261 {
00262 int fd;
00263
00264 pthread_mutex_lock (&g_click_mutex);
00265 while (1)
00266 {
00267 char* waveform = NULL;
00268 int size=0;
00269
00270
00271 pthread_mutex_lock (&g_click_mutex);
00272
00273
00274 waveform = g_wav_files[g_play_sound].waveform;
00275 size = g_wav_files[g_play_sound].wav_file_size;
00276
00277 if (waveform != NULL && size != 0)
00278 {
00279 fd = open (AUDIO_DEVICE, O_WRONLY);
00280 if (fd <= 0)
00281 {
00282 CL_ERRORPRINTF("Open error [%d] device [%s]", errno, AUDIO_DEVICE);
00283 }
00284 else
00285 {
00286 write (fd, waveform, size);
00287 close (fd);
00288 }
00289 }
00290 }
00291 }
00292