SUPKeyboardService-darwin.cpp revision 3d4f1a1fbce7d1542dd1de08b3eaf5dff8da97d4
/* $Id$ */
/** @file
* VirtualBox Support Driver - VBoxKeyboard IOService.
*/
/*
* Copyright (C) 2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*/
#define LOG_GROUP LOG_GROUP_SUP_DRV
#include <IOKit/IOService.h>
#include <IOKit/IOUserClient.h>
#include <iprt/semaphore.h>
#define superservice IOService
#define superclient IOUserClient
#define VBOX_KEYBOARD_SERVICE_REQ_TIMEOUT (1000)
/** The number of IOService class instances. */
static bool volatile g_fInstantiated = 0;
class org_virtualbox_VBoxKeyboard : public IOService
{
protected:
public:
IOReturn syncKeyboardDevicesLeds(void);
};
class org_virtualbox_VBoxKeyboardClient : public IOUserClient
{
protected:
virtual IOReturn externalMethod(uint32_t iCmd, IOExternalMethodArguments *pArgs, IOExternalMethodDispatch *pDispatchFn, OSObject *pTarget, void *pReference);
public:
virtual IOReturn clientClose(void);
};
{
return false;
/* Low level initialization should be performed only once */
if (!ASMAtomicCmpXchgBool(&g_fInstantiated, true, false))
{
return false;
}
{
Log2(("Unable to create mutex\n"));
return false;
}
return true;
}
{
if (RTSemMutexDestroy(lock) != 0)
{
Log2(("Unable to destroy mutex\n"));
}
ASMAtomicWriteBool(&g_fInstantiated, false);
}
{
}
{
Log2(("org_virtualbox_VBoxKeyboardClient::syncKeyboardDevicesLeds\n"));
if (pMatchingDictionary)
{
int rc;
if (RT_SUCCESS(rc))
{
if (pIter)
{
unsigned fLeds;
unsigned fNewFlags;
unsigned fDeviceFlags;
{
/* Take care about CAPSLOCK */
fNewFlags = ((fLeds & kHIDUsage_LED_CapsLock)) ? fDeviceFlags | NX_ALPHASHIFTMASK : fDeviceFlags & ~NX_ALPHASHIFTMASK;
/* Take care about NUMLOCK */
fNewFlags = ((fLeds & kHIDUsage_LED_NumLock )) ? fDeviceFlags | NX_NUMERICPADMASK : fDeviceFlags & ~NX_NUMERICPADMASK;
}
}
}
}
return 0;
}
{
if (pServiceProvider)
{
return true;
}
return false;
}
{
if (pServiceProvider)
{
if (pServiceProvider->isOpen(this))
pServiceProvider->close(this);
else
return kIOReturnError;
}
if (superclient::terminate())
{
Log2(("Terminated successfully\n"));
return kIOReturnSuccess;
}
else
{
Log2(("Failed to terminate\n"));
return kIOReturnError;
}
}
IOReturn org_virtualbox_VBoxKeyboardClient::externalMethod(uint32_t iCmd, IOExternalMethodArguments *pArgs,
{
switch (iCmd)
{
case 0:
break;
default:
}
/* Do not call parent class externalMethod()! */
return rc;
}