NS_METHOD nsSound::Play(nsIURL *aURL) { if (!mInited) Init(); if (!libcanberra) return NS_ERROR_NOT_AVAILABLE; bool isFile; nsresult rv = aURL->SchemeIs("file", &isFile); if (NS_SUCCEEDED(rv) && isFile) { ca_context* ctx = ca_context_get_default(); if (!ctx) { return NS_ERROR_OUT_OF_MEMORY; } nsAutoCString spec; rv = aURL->GetSpec(spec); if (NS_FAILED(rv)) { return rv; } gchar *path = g_filename_from_uri(spec.get(), NULL, NULL); if (!path) { return NS_ERROR_FILE_UNRECOGNIZED_PATH; } ca_context_play(ctx, 0, "media.filename", path, NULL); g_free(path); } else { nsCOMPtr<nsIStreamLoader> loader; rv = NS_NewStreamLoader(getter_AddRefs(loader), aURL, this); } return rv; }
NS_METHOD nsSound::Play(nsIURL *aURL) { if (!mInited) Init(); if (!libcanberra) return NS_ERROR_NOT_AVAILABLE; bool isFile; nsresult rv = aURL->SchemeIs("file", &isFile); if (NS_SUCCEEDED(rv) && isFile) { ca_context* ctx = ca_context_get_default(); if (!ctx) { return NS_ERROR_OUT_OF_MEMORY; } nsCAutoString path; rv = aURL->GetPath(path); if (NS_FAILED(rv)) { return rv; } ca_context_play(ctx, 0, "media.filename", path.get(), NULL); } else { nsCOMPtr<nsIStreamLoader> loader; rv = NS_NewStreamLoader(getter_AddRefs(loader), aURL, this); } return rv; }
NS_IMETHODIMP nsSound::PlayEventSound(uint32_t aEventId) { if (!mInited) Init(); if (!libcanberra) return NS_OK; // Do we even want alert sounds? GtkSettings* settings = gtk_settings_get_default(); if (g_object_class_find_property(G_OBJECT_GET_CLASS(settings), "gtk-enable-event-sounds")) { gboolean enable_sounds = TRUE; g_object_get(settings, "gtk-enable-event-sounds", &enable_sounds, NULL); if (!enable_sounds) { return NS_OK; } } ca_context* ctx = ca_context_get_default(); if (!ctx) { return NS_ERROR_OUT_OF_MEMORY; } switch (aEventId) { case EVENT_ALERT_DIALOG_OPEN: ca_context_play(ctx, 0, "event.id", "dialog-warning", NULL); break; case EVENT_CONFIRM_DIALOG_OPEN: ca_context_play(ctx, 0, "event.id", "dialog-question", NULL); break; case EVENT_NEW_MAIL_RECEIVED: ca_context_play(ctx, 0, "event.id", "message-new-email", NULL); break; case EVENT_MENU_EXECUTE: ca_context_play(ctx, 0, "event.id", "menu-click", NULL); break; case EVENT_MENU_POPUP: ca_context_play(ctx, 0, "event.id", "menu-popup", NULL); break; } return NS_OK; }
NS_IMETHODIMP nsSound::OnStreamComplete(nsIStreamLoader *aLoader, nsISupports *context, nsresult aStatus, uint32_t dataLen, const uint8_t *data) { // print a load error on bad status, and return if (NS_FAILED(aStatus)) { #ifdef DEBUG if (aLoader) { nsCOMPtr<nsIRequest> request; aLoader->GetRequest(getter_AddRefs(request)); if (request) { nsCOMPtr<nsIURI> uri; nsCOMPtr<nsIChannel> channel = do_QueryInterface(request); if (channel) { channel->GetURI(getter_AddRefs(uri)); if (uri) { nsAutoCString uriSpec; uri->GetSpec(uriSpec); printf("Failed to load %s\n", uriSpec.get()); } } } } #endif return aStatus; } nsCOMPtr<nsIFile> tmpFile; nsDirectoryService::gService->Get(NS_OS_TEMP_DIR, NS_GET_IID(nsIFile), getter_AddRefs(tmpFile)); nsresult rv = tmpFile->AppendNative(nsDependentCString("mozilla_audio_sample")); if (NS_FAILED(rv)) { return rv; } rv = tmpFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, PR_IRUSR | PR_IWUSR); if (NS_FAILED(rv)) { return rv; } ScopedCanberraFile canberraFile(tmpFile); mozilla::AutoFDClose fd; rv = canberraFile->OpenNSPRFileDesc(PR_WRONLY, PR_IRUSR | PR_IWUSR, &fd.rwget()); if (NS_FAILED(rv)) { return rv; } // XXX: Should we do this on another thread? uint32_t length = dataLen; while (length > 0) { int32_t amount = PR_Write(fd, data, length); if (amount < 0) { return NS_ERROR_FAILURE; } length -= amount; data += amount; } ca_context* ctx = ca_context_get_default(); if (!ctx) { return NS_ERROR_OUT_OF_MEMORY; } ca_proplist *p; ca_proplist_create(&p); if (!p) { return NS_ERROR_OUT_OF_MEMORY; } nsAutoCString path; rv = canberraFile->GetNativePath(path); if (NS_FAILED(rv)) { return rv; } ca_proplist_sets(p, "media.filename", path.get()); if (ca_context_play_full(ctx, 0, p, ca_finish_cb, canberraFile) >= 0) { // Don't delete the temporary file here if ca_context_play_full succeeds canberraFile.forget(); } ca_proplist_destroy(p); return NS_OK; }