📄 mcianim.c
字号:
/* -*- tab-width: 8; c-basic-offset: 4 -*- *//* * Sample MCI ANIMATION Wine Driver for Linux * * Copyright 1994 Martin Ayotte * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <stdarg.h>#include <string.h>#include "windef.h"#include "winbase.h"#include "wingdi.h"#include "winuser.h"#include "wownt32.h"#include "mmddk.h"#include "wine/debug.h"WINE_DEFAULT_DEBUG_CHANNEL(mcianim);#define ANIMFRAMES_PERSEC 30#define ANIMFRAMES_PERMIN 1800#define SECONDS_PERMIN 60typedef struct { UINT wDevID; int nUseCount; /* Incremented for each shared open */ BOOL fShareable; /* TRUE if first open was shareable */ WORD wNotifyDeviceID; /* MCI device ID with a pending notification */ MCI_OPEN_PARMSA openParms; DWORD dwTimeFormat; int mode; UINT nCurTrack; DWORD dwCurFrame; UINT nTracks; DWORD dwTotalLen; LPDWORD lpdwTrackLen; LPDWORD lpdwTrackPos;} WINE_MCIANIM;/*-----------------------------------------------------------------------*//************************************************************************** * MCIANIM_drvOpen [internal] */static DWORD MCIANIM_drvOpen(LPSTR str, LPMCI_OPEN_DRIVER_PARMSA modp){ WINE_MCIANIM* wma; if (!modp) return 0xFFFFFFFF; wma = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MCIANIM)); if (!wma) return 0; wma->wDevID = modp->wDeviceID; mciSetDriverData(wma->wDevID, (DWORD)wma); modp->wCustomCommandTable = MCI_NO_COMMAND_TABLE; modp->wType = MCI_DEVTYPE_DIGITAL_VIDEO; return modp->wDeviceID;}/************************************************************************** * MCIANIM_drvClose [internal] */static DWORD MCIANIM_drvClose(DWORD dwDevID){ WINE_MCIANIM* wma = (WINE_MCIANIM*)mciGetDriverData(dwDevID); if (wma) { HeapFree(GetProcessHeap(), 0, wma); return 1; } return (dwDevID == 0xFFFFFFFF) ? 1 : 0;}/************************************************************************** * MCIANIM_mciGetOpenDrv [internal] */static WINE_MCIANIM* MCIANIM_mciGetOpenDrv(UINT16 wDevID){ WINE_MCIANIM* wma = (WINE_MCIANIM*)mciGetDriverData(wDevID); if (wma == NULL || wma->nUseCount == 0) { WARN("Invalid wDevID=%u\n", wDevID); return 0; } return wma;}/************************************************************************** * MCIANIM_mciOpen [internal] */static DWORD MCIANIM_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_OPEN_PARMSA lpOpenParms){ DWORD dwDeviceID; WINE_MCIANIM* wma = (WINE_MCIANIM*)mciGetDriverData(wDevID); TRACE("(%04X, %08lX, %p);\n", wDevID, dwFlags, lpOpenParms); if (lpOpenParms == NULL) return MCIERR_INTERNAL; if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; if (wma->nUseCount > 0) { /* The driver already open on this channel */ /* If the driver was opened shareable before and this open specifies */ /* shareable then increment the use count */ if (wma->fShareable && (dwFlags & MCI_OPEN_SHAREABLE)) ++wma->nUseCount; else return MCIERR_MUST_USE_SHAREABLE; } else { wma->nUseCount = 1; wma->fShareable = dwFlags & MCI_OPEN_SHAREABLE; } dwDeviceID = lpOpenParms->wDeviceID; TRACE("wDevID=%04X\n", wDevID); /* FIXME this is not consistent with other implementations */ lpOpenParms->wDeviceID = wDevID; /*TRACE("lpParms->wDevID=%04X\n", lpParms->wDeviceID);*/ if (dwFlags & MCI_OPEN_ELEMENT) { TRACE("MCI_OPEN_ELEMENT '%s' !\n", lpOpenParms->lpstrElementName); if (lpOpenParms->lpstrElementName && strlen(lpOpenParms->lpstrElementName) > 0) { } FIXME("element is not opened\n"); } memcpy(&wma->openParms, lpOpenParms, sizeof(MCI_OPEN_PARMSA)); wma->wNotifyDeviceID = dwDeviceID; wma->mode = 0; wma->dwTimeFormat = MCI_FORMAT_TMSF; wma->nCurTrack = 0; wma->nTracks = 0; wma->dwTotalLen = 0; wma->lpdwTrackLen = NULL; wma->lpdwTrackPos = NULL; /* Moved to mmsystem.c mciOpen routine if (dwFlags & MCI_NOTIFY) { TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback); mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback), wma->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL); } */ return 0;}/************************************************************************** * MCIANIM_mciClose [internal] */static DWORD MCIANIM_mciClose(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms){ WINE_MCIANIM* wma = MCIANIM_mciGetOpenDrv(wDevID); TRACE("(%u, %08lX, %p);\n", wDevID, dwParam, lpParms); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; if (--wma->nUseCount == 0) { /* do the actual clean-up */ } return 0;}/************************************************************************** * MCIANIM_mciGetDevCaps [internal] */static DWORD MCIANIM_mciGetDevCaps(UINT16 wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS lpParms){ WINE_MCIANIM* wma = MCIANIM_mciGetOpenDrv(wDevID); DWORD ret; TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms); if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; if (dwFlags & MCI_GETDEVCAPS_ITEM) { TRACE("MCI_GETDEVCAPS_ITEM dwItem=%08lX;\n", lpParms->dwItem); switch(lpParms->dwItem) { case MCI_GETDEVCAPS_CAN_RECORD: lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); ret = MCI_RESOURCE_RETURNED; break; case MCI_GETDEVCAPS_HAS_AUDIO: lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); ret = MCI_RESOURCE_RETURNED; break; case MCI_GETDEVCAPS_HAS_VIDEO: lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); ret = MCI_RESOURCE_RETURNED; break; case MCI_GETDEVCAPS_DEVICE_TYPE: lpParms->dwReturn = MAKEMCIRESOURCE(MCI_DEVTYPE_ANIMATION, MCI_DEVTYPE_ANIMATION); ret = MCI_RESOURCE_RETURNED; break; case MCI_GETDEVCAPS_USES_FILES: lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE); ret = MCI_RESOURCE_RETURNED; break; case MCI_GETDEVCAPS_COMPOUND_DEVICE: lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); ret = MCI_RESOURCE_RETURNED; break; case MCI_GETDEVCAPS_CAN_EJECT: lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE); ret = MCI_RESOURCE_RETURNED; break; case MCI_GETDEVCAPS_CAN_PLAY: lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); ret = MCI_RESOURCE_RETURNED; break; case MCI_GETDEVCAPS_CAN_SAVE: lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); ret = MCI_RESOURCE_RETURNED; break; default: FIXME("Unknown capability (%08lx) !\n", lpParms->dwItem); return MCIERR_UNRECOGNIZED_COMMAND; } } else { WARN("No GETDEVCAPS_ITEM !\n"); return MCIERR_UNRECOGNIZED_COMMAND; } TRACE("lpParms->dwReturn=%08lX;\n", lpParms->dwReturn); return ret;}/************************************************************************** * MCIANIM_CalcTime [internal] */static DWORD MCIANIM_CalcTime(WINE_MCIANIM* wma, DWORD dwFormatType, DWORD dwFrame, LPDWORD lpRet){ DWORD dwTime = 0; UINT16 wTrack; UINT16 wMinutes; UINT16 wSeconds; UINT16 wFrames; TRACE("(%p, %08lX, %lu);\n", wma, dwFormatType, dwFrame); switch (dwFormatType) { case MCI_FORMAT_MILLISECONDS: dwTime = dwFrame / ANIMFRAMES_PERSEC * 1000; *lpRet = 0; TRACE("MILLISECONDS %lu\n", dwTime); break; case MCI_FORMAT_MSF: wMinutes = dwFrame / ANIMFRAMES_PERMIN; wSeconds = (dwFrame - ANIMFRAMES_PERMIN * wMinutes) / ANIMFRAMES_PERSEC; wFrames = dwFrame - ANIMFRAMES_PERMIN * wMinutes - ANIMFRAMES_PERSEC * wSeconds; dwTime = MCI_MAKE_MSF(wMinutes, wSeconds, wFrames); TRACE("MSF %02u:%02u:%02u -> dwTime=%lu\n",wMinutes, wSeconds, wFrames, dwTime); *lpRet = MCI_COLONIZED3_RETURN; break; default: /* unknown format ! force TMSF ! ... */ dwFormatType = MCI_FORMAT_TMSF; case MCI_FORMAT_TMSF: for (wTrack = 0; wTrack < wma->nTracks; wTrack++) { /* dwTime += wma->lpdwTrackLen[wTrack - 1]; TRACE("Adding trk#%u curpos=%u \n", dwTime); if (dwTime >= dwFrame) break; */ if (wma->lpdwTrackPos[wTrack - 1] >= dwFrame) break; } wMinutes = dwFrame / ANIMFRAMES_PERMIN; wSeconds = (dwFrame - ANIMFRAMES_PERMIN * wMinutes) / ANIMFRAMES_PERSEC; wFrames = dwFrame - ANIMFRAMES_PERMIN * wMinutes - ANIMFRAMES_PERSEC * wSeconds; dwTime = MCI_MAKE_TMSF(wTrack, wMinutes, wSeconds, wFrames); *lpRet = MCI_COLONIZED4_RETURN; TRACE("%02u-%02u:%02u:%02u\n", wTrack, wMinutes, wSeconds, wFrames); break; } return dwTime;}/************************************************************************** * MCIANIM_CalcFrame [internal] */static DWORD MCIANIM_CalcFrame(WINE_MCIANIM* wma, DWORD dwFormatType, DWORD dwTime){ DWORD dwFrame = 0; UINT16 wTrack; TRACE("(%p, %08lX, %lu);\n", wma, dwFormatType, dwTime); switch (dwFormatType) { case MCI_FORMAT_MILLISECONDS: dwFrame = dwTime * ANIMFRAMES_PERSEC / 1000; TRACE("MILLISECONDS %lu\n", dwFrame); break; case MCI_FORMAT_MSF: TRACE("MSF %02u:%02u:%02u\n", MCI_MSF_MINUTE(dwTime), MCI_MSF_SECOND(dwTime), MCI_MSF_FRAME(dwTime)); dwFrame += ANIMFRAMES_PERMIN * MCI_MSF_MINUTE(dwTime); dwFrame += ANIMFRAMES_PERSEC * MCI_MSF_SECOND(dwTime); dwFrame += MCI_MSF_FRAME(dwTime); break; default: /* unknown format ! force TMSF ! ... */ dwFormatType = MCI_FORMAT_TMSF; case MCI_FORMAT_TMSF: wTrack = MCI_TMSF_TRACK(dwTime); TRACE("TMSF %02u-%02u:%02u:%02u\n", MCI_TMSF_TRACK(dwTime), MCI_TMSF_MINUTE(dwTime), MCI_TMSF_SECOND(dwTime), MCI_TMSF_FRAME(dwTime)); TRACE("TMSF trackpos[%u]=%lu\n", wTrack, wma->lpdwTrackPos[wTrack - 1]); dwFrame = wma->lpdwTrackPos[wTrack - 1]; dwFrame += ANIMFRAMES_PERMIN * MCI_TMSF_MINUTE(dwTime); dwFrame += ANIMFRAMES_PERSEC * MCI_TMSF_SECOND(dwTime); dwFrame += MCI_TMSF_FRAME(dwTime); break; } return dwFrame;}/************************************************************************** * MCIANIM_mciInfo [internal] */static DWORD MCIANIM_mciInfo(UINT16 wDevID, DWORD dwFlags, LPMCI_INFO_PARMSA lpParms){ WINE_MCIANIM* wma = MCIANIM_mciGetOpenDrv(wDevID); LPCSTR str = 0; DWORD ret = 0; TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms); if (lpParms == NULL || lpParms->lpstrReturn == NULL) return MCIERR_NULL_PARAMETER_BLOCK; if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -