IOAudioControlUserClient.cpp [plain text]
#include "IOAudioDebug.h"
#include "IOAudioControlUserClient.h"
#include "IOAudioControl.h"
#include "IOAudioTypes.h"
#include "IOAudioDefines.h"
#include <IOKit/IOLib.h>
#include <IOKit/IOCommandGate.h>
#include <IOKit/IOKitKeys.h>
#define super IOUserClient
OSDefineMetaClassAndStructors(IOAudioControlUserClient, IOUserClient)
OSMetaClassDefineReservedUsed(IOAudioControlUserClient, 0);
OSMetaClassDefineReservedUsed(IOAudioControlUserClient, 1);
OSMetaClassDefineReservedUnused(IOAudioControlUserClient, 2);
OSMetaClassDefineReservedUnused(IOAudioControlUserClient, 3);
OSMetaClassDefineReservedUnused(IOAudioControlUserClient, 4);
OSMetaClassDefineReservedUnused(IOAudioControlUserClient, 5);
OSMetaClassDefineReservedUnused(IOAudioControlUserClient, 6);
OSMetaClassDefineReservedUnused(IOAudioControlUserClient, 7);
OSMetaClassDefineReservedUnused(IOAudioControlUserClient, 8);
OSMetaClassDefineReservedUnused(IOAudioControlUserClient, 9);
OSMetaClassDefineReservedUnused(IOAudioControlUserClient, 10);
OSMetaClassDefineReservedUnused(IOAudioControlUserClient, 11);
OSMetaClassDefineReservedUnused(IOAudioControlUserClient, 12);
OSMetaClassDefineReservedUnused(IOAudioControlUserClient, 13);
OSMetaClassDefineReservedUnused(IOAudioControlUserClient, 14);
OSMetaClassDefineReservedUnused(IOAudioControlUserClient, 15);
bool IOAudioControlUserClient::initWithAudioControl(IOAudioControl *control, task_t task, void *securityID, UInt32 type, OSDictionary *properties)
{
if (properties) {
properties->setObject(kIOUserClientCrossEndianCompatibleKey, kOSBooleanTrue);
}
if (!initWithTask(task, securityID, type, properties)) {
return false;
}
if (!control) {
return false;
}
audioControl = control;
audioControl->retain();
clientTask = task;
notificationMessage = 0;
return true;
}
void IOAudioControlUserClient::sendChangeNotification(UInt32 notificationType)
{
if (notificationMessage) {
kern_return_t kr;
notificationMessage->type = notificationType;
kr = mach_msg_send_from_kernel(¬ificationMessage->messageHeader, notificationMessage->messageHeader.msgh_size);
if ((kr != MACH_MSG_SUCCESS) && (kr != MACH_SEND_TIMED_OUT)) {
IOLog("IOAudioControlUserClient: sendRangeChangeNotification() failed - msg_send returned: %d\n", kr);
}
}
}
IOAudioControlUserClient *IOAudioControlUserClient::withAudioControl(IOAudioControl *control, task_t clientTask, void *securityID, UInt32 type, OSDictionary *properties)
{
IOAudioControlUserClient *client;
client = new IOAudioControlUserClient;
if (client) {
if (!client->initWithAudioControl(control, clientTask, securityID, type, properties)) {
client->release();
client = 0;
}
}
return client;
}
IOAudioControlUserClient *IOAudioControlUserClient::withAudioControl(IOAudioControl *control, task_t clientTask, void *securityID, UInt32 type)
{
IOAudioControlUserClient *client;
client = new IOAudioControlUserClient;
if (client) {
if (!client->initWithAudioControl(control, clientTask, securityID, type)) {
client->release();
client = 0;
}
}
return client;
}
bool IOAudioControlUserClient::initWithAudioControl(IOAudioControl *control, task_t task, void *securityID, UInt32 type)
{
if (!initWithTask(task, securityID, type)) {
return false;
}
if (!control) {
return false;
}
audioControl = control;
audioControl->retain();
clientTask = task;
notificationMessage = 0;
return true;
}
void IOAudioControlUserClient::free()
{
audioDebugIOLog(3, "IOAudioControlUserClient[%p]::free()", this);
if (notificationMessage) {
IOFreeAligned(notificationMessage, sizeof(IOAudioNotificationMessage));
notificationMessage = 0;
}
if (audioControl) {
audioControl->release ();
audioControl = 0;
}
if (reserved) {
IOFree (reserved, sizeof(struct ExpansionData));
}
super::free();
}
IOReturn IOAudioControlUserClient::clientClose()
{
audioDebugIOLog(3, "IOAudioControlUserClient[%p]::clientClose()", this);
if (audioControl) {
if (!audioControl->isInactive () && !isInactive()) {
audioControl->clientClosed(this);
}
audioControl->release();
audioControl = 0;
}
return kIOReturnSuccess;
}
IOReturn IOAudioControlUserClient::clientDied()
{
audioDebugIOLog(3, "IOAudioControlUserClient[%p]::clientDied()", this);
return clientClose();
}
IOReturn IOAudioControlUserClient::registerNotificationPort(mach_port_t port,
UInt32 type, UInt32 refCon)
{
IOReturn result = kIOReturnSuccess;
if (!isInactive()) {
if (notificationMessage == 0) {
notificationMessage = (IOAudioNotificationMessage *)IOMallocAligned(sizeof(IOAudioNotificationMessage), sizeof (IOAudioNotificationMessage *));
if (!notificationMessage) {
return kIOReturnNoMemory;
}
}
notificationMessage->messageHeader.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
notificationMessage->messageHeader.msgh_size = sizeof(IOAudioNotificationMessage);
notificationMessage->messageHeader.msgh_remote_port = port;
notificationMessage->messageHeader.msgh_local_port = MACH_PORT_NULL;
notificationMessage->messageHeader.msgh_reserved = 0;
notificationMessage->messageHeader.msgh_id = 0;
notificationMessage->ref = refCon;
} else {
result = kIOReturnNoDevice;
}
return result;
}
void IOAudioControlUserClient::sendValueChangeNotification()
{
return sendChangeNotification(kIOAudioControlValueChangeNotification);
}