msacm: acmDriverAdd[AW] support for ACM_DRIVERADDF_NOTIFYHWND.

Broadcast notifications are fleshed out and are now fully functional.
This commit is contained in:
Alex Villacís Lasso 2006-01-18 12:10:59 +01:00 committed by Alexandre Julliard
parent 72f7170e06
commit e3851bc7f7
3 changed files with 150 additions and 37 deletions

View File

@ -154,10 +154,12 @@ MMRESULT WINAPI acmDriverAddW(PHACMDRIVERID phadid, HINSTANCE hinstModule,
lParam Handle of notification window
dwPriority Window message to send for notification broadcasts
*/
*phadid = 0;
FIXME("(%p, %p, %ld, %ld, %ld): ACM_DRIVERADDF_NOTIFYHWND: stub\n", phadid, hinstModule, lParam, dwPriority, fdwAdd);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return MMSYSERR_ERROR;
*phadid = (HACMDRIVERID) MSACM_RegisterNotificationWindow((HWND)lParam, dwPriority);
if (!*phadid) {
ERR("Unable to register driver via ACM_DRIVERADDF_NOTIFYHWND\n");
return MMSYSERR_INVALPARAM;
}
break;
default:
ERR("invalid flag value 0x%08lx for fdwAdd\n", fdwAdd & ACM_DRIVERADDF_TYPEMASK);
return MMSYSERR_INVALFLAG;
@ -530,48 +532,71 @@ MMRESULT WINAPI acmDriverPriority(HACMDRIVERID hadid, DWORD dwPriority, DWORD fd
return MMSYSERR_NOERROR;
} else {
PWINE_ACMDRIVERID padid;
PWINE_ACMNOTIFYWND panwnd;
BOOL bPerformBroadcast = FALSE;
/* Fetch driver ID */
padid = MSACM_GetDriverID(hadid);
if (!padid) {
panwnd = MSACM_GetNotifyWnd(hadid);
if (!padid && !panwnd) {
WARN("invalid handle\n");
return MMSYSERR_INVALHANDLE;
}
/* Check whether driver ID is appropriate for requested op */
if (dwPriority) {
if (padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_LOCAL) {
return MMSYSERR_NOTSUPPORTED;
if (padid) {
/* Check whether driver ID is appropriate for requested op */
if (dwPriority) {
if (padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_LOCAL) {
return MMSYSERR_NOTSUPPORTED;
}
if (dwPriority != 1 && dwPriority != -1) {
FIXME("unexpected priority %ld, using sign only\n", dwPriority);
if (dwPriority < 0) dwPriority = -1;
if (dwPriority > 0) dwPriority = 1;
}
if (dwPriority == 1 && (padid->pPrevACMDriverID == NULL ||
(padid->pPrevACMDriverID->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_LOCAL))) {
/* do nothing - driver is first of list, or first after last
local driver */
} else if (dwPriority == -1 && padid->pNextACMDriverID == NULL) {
/* do nothing - driver is last of list */
} else {
MSACM_RePositionDriver(padid, dwPriority);
bPerformBroadcast = TRUE;
}
}
if (dwPriority != 1 && dwPriority != -1) {
FIXME("unexpected priority %ld, using sign only\n", dwPriority);
if (dwPriority < 0) dwPriority = -1;
if (dwPriority > 0) dwPriority = 1;
}
if (dwPriority == 1 && (padid->pPrevACMDriverID == NULL ||
(padid->pPrevACMDriverID->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_LOCAL))) {
/* do nothing - driver is first of list, or first after last
local driver */
} else if (dwPriority == -1 && padid->pNextACMDriverID == NULL) {
/* do nothing - driver is last of list */
} else {
MSACM_RePositionDriver(padid, dwPriority);
bPerformBroadcast = TRUE;
/* Check whether driver ID should be enabled or disabled */
if (fdwPriority & ACM_DRIVERPRIORITYF_DISABLE) {
if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED)) {
padid->fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED;
bPerformBroadcast = TRUE;
}
} else if (fdwPriority & ACM_DRIVERPRIORITYF_ENABLE) {
if (padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) {
padid->fdwSupport &= ~ACMDRIVERDETAILS_SUPPORTF_DISABLED;
bPerformBroadcast = TRUE;
}
}
}
/* Check whether driver ID should be enabled or disabled */
if (fdwPriority & ACM_DRIVERPRIORITYF_DISABLE) {
if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED)) {
padid->fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED;
bPerformBroadcast = TRUE;
if (panwnd) {
if (dwPriority) {
return MMSYSERR_NOTSUPPORTED;
}
} else if (fdwPriority & ACM_DRIVERPRIORITYF_ENABLE) {
if (padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) {
padid->fdwSupport &= ~ACMDRIVERDETAILS_SUPPORTF_DISABLED;
bPerformBroadcast = TRUE;
/* Check whether notify window should be enabled or disabled */
if (fdwPriority & ACM_DRIVERPRIORITYF_DISABLE) {
if (!(panwnd->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED)) {
panwnd->fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED;
bPerformBroadcast = TRUE;
}
} else if (fdwPriority & ACM_DRIVERPRIORITYF_ENABLE) {
if (panwnd->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) {
panwnd->fdwSupport &= ~ACMDRIVERDETAILS_SUPPORTF_DISABLED;
bPerformBroadcast = TRUE;
}
}
}
@ -590,11 +615,13 @@ MMRESULT WINAPI acmDriverPriority(HACMDRIVERID hadid, DWORD dwPriority, DWORD fd
MMRESULT WINAPI acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove)
{
PWINE_ACMDRIVERID padid;
PWINE_ACMNOTIFYWND panwnd;
TRACE("(%p, %08lx)\n", hadid, fdwRemove);
padid = MSACM_GetDriverID(hadid);
if (!padid) {
panwnd = MSACM_GetNotifyWnd(hadid);
if (!padid && !panwnd) {
WARN("invalid handle\n");
return MMSYSERR_INVALHANDLE;
}
@ -604,7 +631,8 @@ MMRESULT WINAPI acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove)
return MMSYSERR_INVALFLAG;
}
MSACM_UnregisterDriver(padid);
if (padid) MSACM_UnregisterDriver(padid);
if (panwnd) MSACM_UnRegisterNotificationWindow(panwnd);
MSACM_BroadcastNotification();
return MMSYSERR_NOERROR;

View File

@ -48,6 +48,8 @@ PWINE_ACMDRIVERID MSACM_pLastACMDriverID = NULL;
static DWORD MSACM_suspendBroadcastCount = 0;
static BOOL MSACM_pendingBroadcast = FALSE;
static PWINE_ACMNOTIFYWND MSACM_pFirstACMNotifyWnd = NULL;
static PWINE_ACMNOTIFYWND MSACM_pLastACMNotifyWnd = NULL;
static void MSACM_ReorderDriversByPriority(void);
@ -373,13 +375,44 @@ void MSACM_RegisterAllDrivers(void)
MSACM_RegisterDriver(msacm32, msacm32, 0);
}
/***********************************************************************
* MSACM_RegisterNotificationWindow()
*/
PWINE_ACMNOTIFYWND MSACM_RegisterNotificationWindow(HWND hNotifyWnd, DWORD dwNotifyMsg)
{
PWINE_ACMNOTIFYWND panwnd;
TRACE("(%p,0x%08lx)\n", hNotifyWnd, dwNotifyMsg);
panwnd = HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMNOTIFYWND));
panwnd->obj.dwType = WINE_ACMOBJ_NOTIFYWND;
panwnd->obj.pACMDriverID = 0;
panwnd->hNotifyWnd = hNotifyWnd;
panwnd->dwNotifyMsg = dwNotifyMsg;
panwnd->fdwSupport = 0;
panwnd->pNextACMNotifyWnd = NULL;
panwnd->pPrevACMNotifyWnd = MSACM_pLastACMNotifyWnd;
if (MSACM_pLastACMNotifyWnd)
MSACM_pLastACMNotifyWnd->pNextACMNotifyWnd = panwnd;
MSACM_pLastACMNotifyWnd = panwnd;
if (!MSACM_pFirstACMNotifyWnd)
MSACM_pFirstACMNotifyWnd = panwnd;
return panwnd;
}
/***********************************************************************
* MSACM_BroadcastNotification()
*/
void MSACM_BroadcastNotification(void)
{
if (MSACM_suspendBroadcastCount <= 0) {
FIXME("notification broadcast not (yet) implemented\n");
PWINE_ACMNOTIFYWND panwnd;
for (panwnd = MSACM_pFirstACMNotifyWnd; panwnd; panwnd = panwnd->pNextACMNotifyWnd)
if (!(panwnd->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED))
SendMessageW(panwnd->hNotifyWnd, panwnd->dwNotifyMsg, 0, 0);
} else {
MSACM_pendingBroadcast = TRUE;
}
@ -407,6 +440,29 @@ void MSACM_EnableNotifications(void)
}
}
/***********************************************************************
* MSACM_UnRegisterNotificationWindow()
*/
PWINE_ACMNOTIFYWND MSACM_UnRegisterNotificationWindow(PWINE_ACMNOTIFYWND panwnd)
{
PWINE_ACMNOTIFYWND p;
for (p = MSACM_pFirstACMNotifyWnd; p; p = p->pNextACMNotifyWnd) {
if (p == panwnd) {
PWINE_ACMNOTIFYWND pNext = p->pNextACMNotifyWnd;
if (p->pPrevACMNotifyWnd) p->pPrevACMNotifyWnd->pNextACMNotifyWnd = p->pNextACMNotifyWnd;
if (p->pNextACMNotifyWnd) p->pNextACMNotifyWnd->pPrevACMNotifyWnd = p->pPrevACMNotifyWnd;
if (MSACM_pFirstACMNotifyWnd == p) MSACM_pFirstACMNotifyWnd = p->pNextACMNotifyWnd;
if (MSACM_pLastACMNotifyWnd == p) MSACM_pLastACMNotifyWnd = p->pPrevACMNotifyWnd;
HeapFree(MSACM_hHeap, 0, p);
return pNext;
}
}
return NULL;
}
/***********************************************************************
* MSACM_RePositionDriver()
*/
@ -678,12 +734,17 @@ PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p)
*/
void MSACM_UnregisterAllDrivers(void)
{
PWINE_ACMNOTIFYWND panwnd = MSACM_pFirstACMNotifyWnd;
PWINE_ACMDRIVERID p = MSACM_pFirstACMDriverID;
while (p) {
MSACM_WriteCache(p);
p = MSACM_UnregisterDriver(p);
}
while (panwnd) {
panwnd = MSACM_UnRegisterNotificationWindow(panwnd);
}
}
/***********************************************************************
@ -715,6 +776,15 @@ PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver)
return (PWINE_ACMDRIVER)MSACM_GetObj((HACMOBJ)hDriver, WINE_ACMOBJ_DRIVER);
}
/***********************************************************************
* MSACM_GetNotifyWnd()
*/
PWINE_ACMNOTIFYWND MSACM_GetNotifyWnd(HACMDRIVERID hDriver)
{
return (PWINE_ACMNOTIFYWND)MSACM_GetObj((HACMOBJ)hDriver, WINE_ACMOBJ_NOTIFYWND);
}
/***********************************************************************
* MSACM_Message()
*/

View File

@ -291,6 +291,7 @@ typedef struct _WINE_ACMDRIVER *PWINE_ACMDRIVER;
#define WINE_ACMOBJ_DRIVERID 0x5EED0001
#define WINE_ACMOBJ_DRIVER 0x5EED0002
#define WINE_ACMOBJ_STREAM 0x5EED0003
#define WINE_ACMOBJ_NOTIFYWND 0x5EED0004
typedef struct _WINE_ACMOBJ
{
@ -332,6 +333,17 @@ typedef struct _WINE_ACMDRIVERID
}* aFormatTag;
} WINE_ACMDRIVERID;
typedef struct _WINE_ACMNOTIFYWND * PWINE_ACMNOTIFYWND;
typedef struct _WINE_ACMNOTIFYWND
{
WINE_ACMOBJ obj;
HWND hNotifyWnd; /* Window to notify on ACM events: driver add, driver removal, priority change */
DWORD dwNotifyMsg; /* Notification message to send to window */
DWORD fdwSupport;
PWINE_ACMNOTIFYWND pNextACMNotifyWnd;
PWINE_ACMNOTIFYWND pPrevACMNotifyWnd;
} WINE_ACMNOTIFYWND;
/* From internal.c */
extern HANDLE MSACM_hHeap;
extern PWINE_ACMDRIVERID MSACM_pFirstACMDriverID;
@ -343,6 +355,7 @@ extern PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p);
extern void MSACM_UnregisterAllDrivers(void);
extern PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID);
extern PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver);
extern PWINE_ACMNOTIFYWND MSACM_GetNotifyWnd(HACMDRIVERID hDriver);
extern PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj, DWORD type);
extern MMRESULT MSACM_Message(HACMDRIVER, UINT, LPARAM, LPARAM);
@ -353,6 +366,8 @@ extern void MSACM_WriteCurrentPriorities(void);
extern void MSACM_BroadcastNotification(void);
extern void MSACM_DisableNotifications(void);
extern void MSACM_EnableNotifications(void);
extern PWINE_ACMNOTIFYWND MSACM_RegisterNotificationWindow(HWND hNotifyWnd, DWORD dwNotifyMsg);
extern PWINE_ACMNOTIFYWND MSACM_UnRegisterNotificationWindow(PWINE_ACMNOTIFYWND);
extern PWINE_ACMDRIVERID MSACM_RegisterDriverFromRegistry(LPCWSTR pszRegEntry);