| 1 | /* -*- tab-width: 8; c-basic-offset: 4 -*- */
|
|---|
| 2 | /*
|
|---|
| 3 | * Sample MCI ANIMATION Wine Driver for Linux
|
|---|
| 4 | *
|
|---|
| 5 | * Copyright 1994 Martin Ayotte
|
|---|
| 6 | */
|
|---|
| 7 |
|
|---|
| 8 | #include <os2win.h>
|
|---|
| 9 | #include <string.h>
|
|---|
| 10 | #include "winuser.h"
|
|---|
| 11 | #include "driver.h"
|
|---|
| 12 | #include "mmddk.h"
|
|---|
| 13 | #include "debugtools.h"
|
|---|
| 14 |
|
|---|
| 15 | DEFAULT_DEBUG_CHANNEL(mcianim)
|
|---|
| 16 |
|
|---|
| 17 | #define ANIMFRAMES_PERSEC 30
|
|---|
| 18 | #define ANIMFRAMES_PERMIN 1800
|
|---|
| 19 | #define SECONDS_PERMIN 60
|
|---|
| 20 |
|
|---|
| 21 | typedef struct {
|
|---|
| 22 | UINT16 wDevID;
|
|---|
| 23 | int nUseCount; /* Incremented for each shared open */
|
|---|
| 24 | BOOL16 fShareable; /* TRUE if first open was shareable */
|
|---|
| 25 | WORD wNotifyDeviceID; /* MCI device ID with a pending notification */
|
|---|
| 26 | HANDLE16 hCallback; /* Callback handle for pending notification */
|
|---|
| 27 | MCI_OPEN_PARMSA openParms;
|
|---|
| 28 | DWORD dwTimeFormat;
|
|---|
| 29 | int mode;
|
|---|
| 30 | UINT16 nCurTrack;
|
|---|
| 31 | DWORD dwCurFrame;
|
|---|
| 32 | UINT16 nTracks;
|
|---|
| 33 | DWORD dwTotalLen;
|
|---|
| 34 | LPDWORD lpdwTrackLen;
|
|---|
| 35 | LPDWORD lpdwTrackPos;
|
|---|
| 36 | } WINE_MCIANIM;
|
|---|
| 37 |
|
|---|
| 38 | /*-----------------------------------------------------------------------*/
|
|---|
| 39 |
|
|---|
| 40 | /**************************************************************************
|
|---|
| 41 | * ANIM_drvOpen [internal]
|
|---|
| 42 | */
|
|---|
| 43 | static DWORD ANIM_drvOpen(LPSTR str, LPMCI_OPEN_DRIVER_PARMSA modp)
|
|---|
| 44 | {
|
|---|
| 45 | WINE_MCIANIM* wma = (WINE_MCIANIM*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MCIANIM));
|
|---|
| 46 |
|
|---|
| 47 | if (!wma)
|
|---|
| 48 | return 0;
|
|---|
| 49 |
|
|---|
| 50 | wma->wDevID = modp->wDeviceID;
|
|---|
| 51 | mciSetDriverData(wma->wDevID, (DWORD)wma);
|
|---|
| 52 | modp->wCustomCommandTable = MCI_NO_COMMAND_TABLE;
|
|---|
| 53 | modp->wType = MCI_DEVTYPE_DIGITAL_VIDEO;
|
|---|
| 54 | return modp->wDeviceID;
|
|---|
| 55 | }
|
|---|
| 56 |
|
|---|
| 57 | /**************************************************************************
|
|---|
| 58 | * ANIM_drvClose [internal]
|
|---|
| 59 | */
|
|---|
| 60 | static DWORD ANIM_drvClose(DWORD dwDevID)
|
|---|
| 61 | {
|
|---|
| 62 | WINE_MCIANIM* wma = (WINE_MCIANIM*)mciGetDriverData(dwDevID);
|
|---|
| 63 |
|
|---|
| 64 | if (wma) {
|
|---|
| 65 | HeapFree(GetProcessHeap(), 0, wma);
|
|---|
| 66 | return 1;
|
|---|
| 67 | }
|
|---|
| 68 | return 0;
|
|---|
| 69 | }
|
|---|
| 70 |
|
|---|
| 71 | /**************************************************************************
|
|---|
| 72 | * ANIM_mciGetOpenDrv [internal]
|
|---|
| 73 | */
|
|---|
| 74 | static WINE_MCIANIM* ANIM_mciGetOpenDrv(UINT16 wDevID)
|
|---|
| 75 | {
|
|---|
| 76 | WINE_MCIANIM* wma = (WINE_MCIANIM*)mciGetDriverData(wDevID);
|
|---|
| 77 |
|
|---|
| 78 | if (wma == NULL || wma->nUseCount == 0) {
|
|---|
| 79 | WARN("Invalid wDevID=%u\n", wDevID);
|
|---|
| 80 | return 0;
|
|---|
| 81 | }
|
|---|
| 82 | return wma;
|
|---|
| 83 | }
|
|---|
| 84 |
|
|---|
| 85 | /**************************************************************************
|
|---|
| 86 | * ANIM_mciOpen [internal]
|
|---|
| 87 | */
|
|---|
| 88 | static DWORD ANIM_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_OPEN_PARMSA lpOpenParms)
|
|---|
| 89 | {
|
|---|
| 90 | DWORD dwDeviceID;
|
|---|
| 91 | WINE_MCIANIM* wma = (WINE_MCIANIM*)mciGetDriverData(wDevID);
|
|---|
| 92 |
|
|---|
| 93 | TRACE("(%04X, %08lX, %p);\n", wDevID, dwFlags, lpOpenParms);
|
|---|
| 94 |
|
|---|
| 95 | if (lpOpenParms == NULL) return MCIERR_INTERNAL;
|
|---|
| 96 | if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
|
|---|
| 97 |
|
|---|
| 98 | if (wma->nUseCount > 0) {
|
|---|
| 99 | /* The driver already open on this channel */
|
|---|
| 100 | /* If the driver was opened shareable before and this open specifies */
|
|---|
| 101 | /* shareable then increment the use count */
|
|---|
| 102 | if (wma->fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
|
|---|
| 103 | ++wma->nUseCount;
|
|---|
| 104 | else
|
|---|
| 105 | return MCIERR_MUST_USE_SHAREABLE;
|
|---|
| 106 | } else {
|
|---|
| 107 | wma->nUseCount = 1;
|
|---|
| 108 | wma->fShareable = dwFlags & MCI_OPEN_SHAREABLE;
|
|---|
| 109 | }
|
|---|
| 110 |
|
|---|
| 111 | dwDeviceID = lpOpenParms->wDeviceID;
|
|---|
| 112 |
|
|---|
| 113 | TRACE("wDevID=%04X\n", wDevID);
|
|---|
| 114 | /* FIXME this is not consistent with other implementations */
|
|---|
| 115 | lpOpenParms->wDeviceID = wDevID;
|
|---|
| 116 |
|
|---|
| 117 | /*TRACE("lpParms->wDevID=%04X\n", lpParms->wDeviceID);*/
|
|---|
| 118 | if (dwFlags & MCI_OPEN_ELEMENT) {
|
|---|
| 119 | TRACE("MCI_OPEN_ELEMENT '%s' !\n", lpOpenParms->lpstrElementName);
|
|---|
| 120 | if (lpOpenParms->lpstrElementName && strlen(lpOpenParms->lpstrElementName) > 0) {
|
|---|
| 121 | }
|
|---|
| 122 | FIXME("element is not opened\n");
|
|---|
| 123 | }
|
|---|
| 124 | memcpy(&wma->openParms, lpOpenParms, sizeof(MCI_OPEN_PARMSA));
|
|---|
| 125 | wma->wNotifyDeviceID = dwDeviceID;
|
|---|
| 126 | wma->mode = 0;
|
|---|
| 127 | wma->dwTimeFormat = MCI_FORMAT_TMSF;
|
|---|
| 128 | wma->nCurTrack = 0;
|
|---|
| 129 | wma->nTracks = 0;
|
|---|
| 130 | wma->dwTotalLen = 0;
|
|---|
| 131 | wma->lpdwTrackLen = NULL;
|
|---|
| 132 | wma->lpdwTrackPos = NULL;
|
|---|
| 133 | /*
|
|---|
| 134 | Moved to mmsystem.c mciOpen routine
|
|---|
| 135 |
|
|---|
| 136 | if (dwFlags & MCI_NOTIFY) {
|
|---|
| 137 | TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n",
|
|---|
| 138 | lpParms->dwCallback);
|
|---|
| 139 | mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback),
|
|---|
| 140 | wma->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
|
|---|
| 141 | }
|
|---|
| 142 | */
|
|---|
| 143 | return 0;
|
|---|
| 144 | }
|
|---|
| 145 |
|
|---|
| 146 | /**************************************************************************
|
|---|
| 147 | * ANIM_mciClose [internal]
|
|---|
| 148 | */
|
|---|
| 149 | static DWORD ANIM_mciClose(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
|
|---|
| 150 | {
|
|---|
| 151 | WINE_MCIANIM* wma = ANIM_mciGetOpenDrv(wDevID);
|
|---|
| 152 |
|
|---|
| 153 | TRACE("(%u, %08lX, %p);\n", wDevID, dwParam, lpParms);
|
|---|
| 154 |
|
|---|
| 155 | if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
|
|---|
| 156 |
|
|---|
| 157 | if (--wma->nUseCount == 0) {
|
|---|
| 158 | /* do the actual clean-up */
|
|---|
| 159 | }
|
|---|
| 160 | return 0;
|
|---|
| 161 | }
|
|---|
| 162 |
|
|---|
| 163 | /**************************************************************************
|
|---|
| 164 | * ANIM_mciGetDevCaps [internal]
|
|---|
| 165 | */
|
|---|
| 166 | static DWORD ANIM_mciGetDevCaps(UINT16 wDevID, DWORD dwFlags,
|
|---|
| 167 | LPMCI_GETDEVCAPS_PARMS lpParms)
|
|---|
| 168 | {
|
|---|
| 169 | WINE_MCIANIM* wma = ANIM_mciGetOpenDrv(wDevID);
|
|---|
| 170 | DWORD ret;
|
|---|
| 171 |
|
|---|
| 172 | TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
|
|---|
| 173 |
|
|---|
| 174 | if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
|
|---|
| 175 | if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
|
|---|
| 176 |
|
|---|
| 177 | if (dwFlags & MCI_GETDEVCAPS_ITEM) {
|
|---|
| 178 | TRACE("MCI_GETDEVCAPS_ITEM dwItem=%08lX;\n", lpParms->dwItem);
|
|---|
| 179 |
|
|---|
| 180 | switch(lpParms->dwItem) {
|
|---|
| 181 | case MCI_GETDEVCAPS_CAN_RECORD:
|
|---|
| 182 | lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
|
|---|
| 183 | ret = MCI_RESOURCE_RETURNED;
|
|---|
| 184 | break;
|
|---|
| 185 | case MCI_GETDEVCAPS_HAS_AUDIO:
|
|---|
| 186 | lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
|
|---|
| 187 | ret = MCI_RESOURCE_RETURNED;
|
|---|
| 188 | break;
|
|---|
| 189 | case MCI_GETDEVCAPS_HAS_VIDEO:
|
|---|
| 190 | lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
|
|---|
| 191 | ret = MCI_RESOURCE_RETURNED;
|
|---|
| 192 | break;
|
|---|
| 193 | case MCI_GETDEVCAPS_DEVICE_TYPE:
|
|---|
| 194 | lpParms->dwReturn = MAKEMCIRESOURCE(MCI_DEVTYPE_ANIMATION, MCI_DEVTYPE_ANIMATION);
|
|---|
| 195 | ret = MCI_RESOURCE_RETURNED;
|
|---|
| 196 | break;
|
|---|
| 197 | case MCI_GETDEVCAPS_USES_FILES:
|
|---|
| 198 | lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
|
|---|
| 199 | ret = MCI_RESOURCE_RETURNED;
|
|---|
| 200 | break;
|
|---|
| 201 | case MCI_GETDEVCAPS_COMPOUND_DEVICE:
|
|---|
| 202 | lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
|
|---|
| 203 | ret = MCI_RESOURCE_RETURNED;
|
|---|
| 204 | break;
|
|---|
| 205 | case MCI_GETDEVCAPS_CAN_EJECT:
|
|---|
| 206 | lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
|
|---|
| 207 | ret = MCI_RESOURCE_RETURNED;
|
|---|
| 208 | break;
|
|---|
| 209 | case MCI_GETDEVCAPS_CAN_PLAY:
|
|---|
| 210 | lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
|
|---|
| 211 | ret = MCI_RESOURCE_RETURNED;
|
|---|
| 212 | break;
|
|---|
| 213 | case MCI_GETDEVCAPS_CAN_SAVE:
|
|---|
| 214 | lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
|
|---|
| 215 | ret = MCI_RESOURCE_RETURNED;
|
|---|
| 216 | break;
|
|---|
| 217 | default:
|
|---|
| 218 | FIXME("Unknown capability (%08lx) !\n", lpParms->dwItem);
|
|---|
| 219 | return MCIERR_UNRECOGNIZED_COMMAND;
|
|---|
| 220 | }
|
|---|
| 221 | } else {
|
|---|
| 222 | WARN("No GETDEVCAPS_ITEM !\n");
|
|---|
| 223 | return MCIERR_UNRECOGNIZED_COMMAND;
|
|---|
| 224 | }
|
|---|
| 225 | TRACE("lpParms->dwReturn=%08lX;\n", lpParms->dwReturn);
|
|---|
| 226 | return ret;
|
|---|
| 227 | }
|
|---|
| 228 |
|
|---|
| 229 |
|
|---|
| 230 | /**************************************************************************
|
|---|
| 231 | * ANIM_CalcTime [internal]
|
|---|
| 232 | */
|
|---|
| 233 | static DWORD ANIM_CalcTime(WINE_MCIANIM* wma, DWORD dwFormatType, DWORD dwFrame, LPDWORD lpRet)
|
|---|
| 234 | {
|
|---|
| 235 | DWORD dwTime = 0;
|
|---|
| 236 | UINT16 wTrack;
|
|---|
| 237 | UINT16 wMinutes;
|
|---|
| 238 | UINT16 wSeconds;
|
|---|
| 239 | UINT16 wFrames;
|
|---|
| 240 |
|
|---|
| 241 | TRACE("(%p, %08lX, %lu);\n", wma, dwFormatType, dwFrame);
|
|---|
| 242 |
|
|---|
| 243 | switch (dwFormatType) {
|
|---|
| 244 | case MCI_FORMAT_MILLISECONDS:
|
|---|
| 245 | dwTime = dwFrame / ANIMFRAMES_PERSEC * 1000;
|
|---|
| 246 | *lpRet = 0;
|
|---|
| 247 | TRACE("MILLISECONDS %lu\n", dwTime);
|
|---|
| 248 | break;
|
|---|
| 249 | case MCI_FORMAT_MSF:
|
|---|
| 250 | wMinutes = dwFrame / ANIMFRAMES_PERMIN;
|
|---|
| 251 | wSeconds = (dwFrame - ANIMFRAMES_PERMIN * wMinutes) / ANIMFRAMES_PERSEC;
|
|---|
| 252 | wFrames = dwFrame - ANIMFRAMES_PERMIN * wMinutes -
|
|---|
| 253 | ANIMFRAMES_PERSEC * wSeconds;
|
|---|
| 254 | dwTime = MCI_MAKE_MSF(wMinutes, wSeconds, wFrames);
|
|---|
| 255 | TRACE("MSF %02u:%02u:%02u -> dwTime=%lu\n",wMinutes, wSeconds, wFrames, dwTime);
|
|---|
| 256 | *lpRet = MCI_COLONIZED3_RETURN;
|
|---|
| 257 | break;
|
|---|
| 258 | default:
|
|---|
| 259 | /* unknown format ! force TMSF ! ... */
|
|---|
| 260 | dwFormatType = MCI_FORMAT_TMSF;
|
|---|
| 261 | case MCI_FORMAT_TMSF:
|
|---|
| 262 | for (wTrack = 0; wTrack < wma->nTracks; wTrack++) {
|
|---|
| 263 | /* dwTime += wma->lpdwTrackLen[wTrack - 1];
|
|---|
| 264 | TRACE("Adding trk#%u curpos=%u \n", dwTime);
|
|---|
| 265 | if (dwTime >= dwFrame) break; */
|
|---|
| 266 | if (wma->lpdwTrackPos[wTrack - 1] >= dwFrame) break;
|
|---|
| 267 | }
|
|---|
| 268 | wMinutes = dwFrame / ANIMFRAMES_PERMIN;
|
|---|
| 269 | wSeconds = (dwFrame - ANIMFRAMES_PERMIN * wMinutes) / ANIMFRAMES_PERSEC;
|
|---|
| 270 | wFrames = dwFrame - ANIMFRAMES_PERMIN * wMinutes -
|
|---|
| 271 | ANIMFRAMES_PERSEC * wSeconds;
|
|---|
| 272 | dwTime = MCI_MAKE_TMSF(wTrack, wMinutes, wSeconds, wFrames);
|
|---|
| 273 | *lpRet = MCI_COLONIZED4_RETURN;
|
|---|
| 274 | TRACE("%02u-%02u:%02u:%02u\n", wTrack, wMinutes, wSeconds, wFrames);
|
|---|
| 275 | break;
|
|---|
| 276 | }
|
|---|
| 277 | return dwTime;
|
|---|
| 278 | }
|
|---|
| 279 |
|
|---|
| 280 |
|
|---|
| 281 | /**************************************************************************
|
|---|
| 282 | * ANIM_CalcFrame [internal]
|
|---|
| 283 | */
|
|---|
| 284 | static DWORD ANIM_CalcFrame(WINE_MCIANIM* wma, DWORD dwFormatType, DWORD dwTime)
|
|---|
| 285 | {
|
|---|
| 286 | DWORD dwFrame = 0;
|
|---|
| 287 | UINT16 wTrack;
|
|---|
| 288 |
|
|---|
| 289 | TRACE("(%p, %08lX, %lu);\n", wma, dwFormatType, dwTime);
|
|---|
| 290 |
|
|---|
| 291 | switch (dwFormatType) {
|
|---|
| 292 | case MCI_FORMAT_MILLISECONDS:
|
|---|
| 293 | dwFrame = dwTime * ANIMFRAMES_PERSEC / 1000;
|
|---|
| 294 | TRACE("MILLISECONDS %lu\n", dwFrame);
|
|---|
| 295 | break;
|
|---|
| 296 | case MCI_FORMAT_MSF:
|
|---|
| 297 | TRACE("MSF %02u:%02u:%02u\n",
|
|---|
| 298 | MCI_MSF_MINUTE(dwTime), MCI_MSF_SECOND(dwTime),
|
|---|
| 299 | MCI_MSF_FRAME(dwTime));
|
|---|
| 300 | dwFrame += ANIMFRAMES_PERMIN * MCI_MSF_MINUTE(dwTime);
|
|---|
| 301 | dwFrame += ANIMFRAMES_PERSEC * MCI_MSF_SECOND(dwTime);
|
|---|
| 302 | dwFrame += MCI_MSF_FRAME(dwTime);
|
|---|
| 303 | break;
|
|---|
| 304 | default:
|
|---|
| 305 | /* unknown format ! force TMSF ! ... */
|
|---|
| 306 | dwFormatType = MCI_FORMAT_TMSF;
|
|---|
| 307 | case MCI_FORMAT_TMSF:
|
|---|
| 308 | wTrack = MCI_TMSF_TRACK(dwTime);
|
|---|
| 309 | TRACE("TMSF %02u-%02u:%02u:%02u\n",
|
|---|
| 310 | MCI_TMSF_TRACK(dwTime), MCI_TMSF_MINUTE(dwTime),
|
|---|
| 311 | MCI_TMSF_SECOND(dwTime), MCI_TMSF_FRAME(dwTime));
|
|---|
| 312 | TRACE("TMSF trackpos[%u]=%lu\n",
|
|---|
| 313 | wTrack, wma->lpdwTrackPos[wTrack - 1]);
|
|---|
| 314 | dwFrame = wma->lpdwTrackPos[wTrack - 1];
|
|---|
| 315 | dwFrame += ANIMFRAMES_PERMIN * MCI_TMSF_MINUTE(dwTime);
|
|---|
| 316 | dwFrame += ANIMFRAMES_PERSEC * MCI_TMSF_SECOND(dwTime);
|
|---|
| 317 | dwFrame += MCI_TMSF_FRAME(dwTime);
|
|---|
| 318 | break;
|
|---|
| 319 | }
|
|---|
| 320 | return dwFrame;
|
|---|
| 321 | }
|
|---|
| 322 |
|
|---|
| 323 | /**************************************************************************
|
|---|
| 324 | * ANIM_mciInfo [internal]
|
|---|
| 325 | */
|
|---|
| 326 | static DWORD ANIM_mciInfo(UINT16 wDevID, DWORD dwFlags, LPMCI_INFO_PARMS16 lpParms)
|
|---|
| 327 | {
|
|---|
| 328 | WINE_MCIANIM* wma = ANIM_mciGetOpenDrv(wDevID);
|
|---|
| 329 | LPSTR str = 0;
|
|---|
| 330 | DWORD ret = 0;
|
|---|
| 331 |
|
|---|
| 332 | TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
|
|---|
| 333 |
|
|---|
| 334 | if (lpParms == NULL || lpParms->lpstrReturn == NULL)
|
|---|
| 335 | return MCIERR_NULL_PARAMETER_BLOCK;
|
|---|
| 336 |
|
|---|
| 337 | if (wma == NULL)
|
|---|
| 338 | return MCIERR_INVALID_DEVICE_ID;
|
|---|
| 339 |
|
|---|
| 340 | TRACE("buf=%p, len=%lu\n", lpParms->lpstrReturn, lpParms->dwRetSize);
|
|---|
| 341 |
|
|---|
| 342 | switch(dwFlags) {
|
|---|
| 343 | case MCI_INFO_PRODUCT:
|
|---|
| 344 | str = "Wine's animation";
|
|---|
| 345 | break;
|
|---|
| 346 | case MCI_INFO_FILE:
|
|---|
| 347 | str = wma->openParms.lpstrElementName;
|
|---|
| 348 | break;
|
|---|
| 349 | case MCI_ANIM_INFO_TEXT:
|
|---|
| 350 | str = "Animation Window";
|
|---|
| 351 | break;
|
|---|
| 352 | default:
|
|---|
| 353 | WARN("Don't know this info command (%lu)\n", dwFlags);
|
|---|
| 354 | return MCIERR_UNRECOGNIZED_COMMAND;
|
|---|
| 355 | }
|
|---|
| 356 |
|
|---|
| 357 | if (str) {
|
|---|
| 358 | if (lpParms->dwRetSize <= strlen(str)) {
|
|---|
| 359 | lstrcpynA(lpParms->lpstrReturn, str, lpParms->dwRetSize - 1);
|
|---|
| 360 | ret = MCIERR_PARAM_OVERFLOW;
|
|---|
| 361 | } else {
|
|---|
| 362 | strcpy(lpParms->lpstrReturn, str);
|
|---|
| 363 | }
|
|---|
| 364 | } else {
|
|---|
| 365 | *lpParms->lpstrReturn = 0;
|
|---|
| 366 | }
|
|---|
| 367 | return ret;
|
|---|
| 368 | }
|
|---|
| 369 |
|
|---|
| 370 | /**************************************************************************
|
|---|
| 371 | * ANIM_mciStatus [internal]
|
|---|
| 372 | */
|
|---|
| 373 | static DWORD ANIM_mciStatus(UINT16 wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
|
|---|
| 374 | {
|
|---|
| 375 | WINE_MCIANIM* wma = ANIM_mciGetOpenDrv(wDevID);
|
|---|
| 376 | DWORD ret;
|
|---|
| 377 |
|
|---|
| 378 | TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
|
|---|
| 379 |
|
|---|
| 380 | if (lpParms == NULL) return MCIERR_INTERNAL;
|
|---|
| 381 | if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
|
|---|
| 382 |
|
|---|
| 383 | if (dwFlags & MCI_NOTIFY) {
|
|---|
| 384 | TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
|
|---|
| 385 | mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback),
|
|---|
| 386 | wma->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
|
|---|
| 387 | }
|
|---|
| 388 | if (dwFlags & MCI_STATUS_ITEM) {
|
|---|
| 389 | switch(lpParms->dwItem) {
|
|---|
| 390 | case MCI_STATUS_CURRENT_TRACK:
|
|---|
| 391 | lpParms->dwReturn = wma->nCurTrack;
|
|---|
| 392 | TRACE("CURRENT_TRACK=%lu!\n", lpParms->dwReturn);
|
|---|
| 393 | break;
|
|---|
| 394 | case MCI_STATUS_LENGTH:
|
|---|
| 395 | if (dwFlags & MCI_TRACK) {
|
|---|
| 396 | TRACE("MCI_TRACK #%lu LENGTH=??? !\n", lpParms->dwTrack);
|
|---|
| 397 | if (lpParms->dwTrack > wma->nTracks)
|
|---|
| 398 | return MCIERR_OUTOFRANGE;
|
|---|
| 399 | lpParms->dwReturn = wma->lpdwTrackLen[lpParms->dwTrack];
|
|---|
| 400 | }
|
|---|
| 401 | else
|
|---|
| 402 | lpParms->dwReturn = wma->dwTotalLen;
|
|---|
| 403 | lpParms->dwReturn = ANIM_CalcTime(wma, wma->dwTimeFormat, lpParms->dwReturn, &ret);
|
|---|
| 404 | TRACE("LENGTH=%lu !\n", lpParms->dwReturn);
|
|---|
| 405 | break;
|
|---|
| 406 | case MCI_STATUS_MODE:
|
|---|
| 407 | TRACE("MCI_STATUS_MODE=%04X !\n", wma->mode);
|
|---|
| 408 | lpParms->dwReturn = MAKEMCIRESOURCE(wma->mode, wma->mode);
|
|---|
| 409 | ret = MCI_RESOURCE_RETURNED;
|
|---|
| 410 | break;
|
|---|
| 411 | case MCI_STATUS_MEDIA_PRESENT:
|
|---|
| 412 | lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
|
|---|
| 413 | ret = MCI_RESOURCE_RETURNED;
|
|---|
| 414 | TRACE("MCI_STATUS_MEDIA_PRESENT !\n");
|
|---|
| 415 | break;
|
|---|
| 416 | case MCI_STATUS_NUMBER_OF_TRACKS:
|
|---|
| 417 | lpParms->dwReturn = 1;
|
|---|
| 418 | TRACE("MCI_STATUS_NUMBER_OF_TRACKS = %lu !\n", lpParms->dwReturn);
|
|---|
| 419 | break;
|
|---|
| 420 | case MCI_STATUS_POSITION:
|
|---|
| 421 | lpParms->dwReturn = wma->dwCurFrame;
|
|---|
| 422 | if (dwFlags & MCI_STATUS_START) {
|
|---|
| 423 | lpParms->dwReturn = 0;
|
|---|
| 424 | TRACE("get MCI_STATUS_START !\n");
|
|---|
| 425 | }
|
|---|
| 426 | if (dwFlags & MCI_TRACK) {
|
|---|
| 427 | if (lpParms->dwTrack > wma->nTracks)
|
|---|
| 428 | return MCIERR_OUTOFRANGE;
|
|---|
| 429 | lpParms->dwReturn = wma->lpdwTrackPos[lpParms->dwTrack - 1];
|
|---|
| 430 | TRACE("get MCI_TRACK #%lu !\n", lpParms->dwTrack);
|
|---|
| 431 | }
|
|---|
| 432 | lpParms->dwReturn = ANIM_CalcTime(wma, wma->dwTimeFormat, lpParms->dwReturn, &ret);
|
|---|
| 433 | TRACE("MCI_STATUS_POSITION=%08lX !\n", lpParms->dwReturn);
|
|---|
| 434 | break;
|
|---|
| 435 | case MCI_STATUS_READY:
|
|---|
| 436 | TRACE("MCI_STATUS_READY !\n");
|
|---|
| 437 | lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
|
|---|
| 438 | ret = MCI_RESOURCE_RETURNED;
|
|---|
| 439 | return 0;
|
|---|
| 440 | case MCI_STATUS_TIME_FORMAT:
|
|---|
| 441 | TRACE("MCI_STATUS_TIME_FORMAT !\n");
|
|---|
| 442 | lpParms->dwReturn = MAKEMCIRESOURCE(MCI_FORMAT_MILLISECONDS, MCI_FORMAT_MILLISECONDS);
|
|---|
| 443 | TRACE("MCI_STATUS_TIME_FORMAT => %u\n", LOWORD(lpParms->dwReturn));
|
|---|
| 444 | ret = MCI_RESOURCE_RETURNED;
|
|---|
| 445 | return 0;
|
|---|
| 446 | default:
|
|---|
| 447 | FIXME("Unknown command %08lX !\n", lpParms->dwItem);
|
|---|
| 448 | return MCIERR_UNRECOGNIZED_COMMAND;
|
|---|
| 449 | }
|
|---|
| 450 | } else {
|
|---|
| 451 | WARN("No MCI_STATUS_ITEM !\n");
|
|---|
| 452 | return MCIERR_UNRECOGNIZED_COMMAND;
|
|---|
| 453 | }
|
|---|
| 454 | return ret;
|
|---|
| 455 | }
|
|---|
| 456 |
|
|---|
| 457 |
|
|---|
| 458 | /**************************************************************************
|
|---|
| 459 | * ANIM_mciPlay [internal]
|
|---|
| 460 | */
|
|---|
| 461 | static DWORD ANIM_mciPlay(UINT16 wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
|
|---|
| 462 | {
|
|---|
| 463 | WINE_MCIANIM* wma = ANIM_mciGetOpenDrv(wDevID);
|
|---|
| 464 | int start, end;
|
|---|
| 465 |
|
|---|
| 466 | TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
|
|---|
| 467 |
|
|---|
| 468 | if (lpParms == NULL) return MCIERR_INTERNAL;
|
|---|
| 469 | if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
|
|---|
| 470 |
|
|---|
| 471 | start = 0; end = wma->dwTotalLen;
|
|---|
| 472 | wma->nCurTrack = 1;
|
|---|
| 473 | if (dwFlags & MCI_FROM) {
|
|---|
| 474 | start = ANIM_CalcFrame(wma, wma->dwTimeFormat, lpParms->dwFrom);
|
|---|
| 475 | TRACE("MCI_FROM=%08lX -> %u \n", lpParms->dwFrom, start);
|
|---|
| 476 | }
|
|---|
| 477 | if (dwFlags & MCI_TO) {
|
|---|
| 478 | end = ANIM_CalcFrame(wma, wma->dwTimeFormat, lpParms->dwTo);
|
|---|
| 479 | TRACE("MCI_TO=%08lX -> %u \n", lpParms->dwTo, end);
|
|---|
| 480 | }
|
|---|
| 481 | wma->mode = MCI_MODE_PLAY;
|
|---|
| 482 | if (dwFlags & MCI_NOTIFY) {
|
|---|
| 483 | TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n",
|
|---|
| 484 | lpParms->dwCallback);
|
|---|
| 485 | mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback),
|
|---|
| 486 | wma->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
|
|---|
| 487 | }
|
|---|
| 488 | return 0;
|
|---|
| 489 | }
|
|---|
| 490 |
|
|---|
| 491 | /**************************************************************************
|
|---|
| 492 | * ANIM_mciStop [internal]
|
|---|
| 493 | */
|
|---|
| 494 | static DWORD ANIM_mciStop(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
|
|---|
| 495 | {
|
|---|
| 496 | WINE_MCIANIM* wma = ANIM_mciGetOpenDrv(wDevID);
|
|---|
| 497 |
|
|---|
| 498 | TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
|
|---|
| 499 |
|
|---|
| 500 | if (lpParms == NULL) return MCIERR_INTERNAL;
|
|---|
| 501 | if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
|
|---|
| 502 |
|
|---|
| 503 | wma->mode = MCI_MODE_STOP;
|
|---|
| 504 | if (dwFlags & MCI_NOTIFY) {
|
|---|
| 505 | TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
|
|---|
| 506 |
|
|---|
| 507 | mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback),
|
|---|
| 508 | wma->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
|
|---|
| 509 | }
|
|---|
| 510 | return 0;
|
|---|
| 511 | }
|
|---|
| 512 |
|
|---|
| 513 | /**************************************************************************
|
|---|
| 514 | * ANIM_mciPause [internal]
|
|---|
| 515 | */
|
|---|
| 516 | static DWORD ANIM_mciPause(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
|
|---|
| 517 | {
|
|---|
| 518 | WINE_MCIANIM* wma = ANIM_mciGetOpenDrv(wDevID);
|
|---|
| 519 |
|
|---|
| 520 | TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
|
|---|
| 521 | if (lpParms == NULL) return MCIERR_INTERNAL;
|
|---|
| 522 | wma->mode = MCI_MODE_PAUSE;
|
|---|
| 523 | if (dwFlags & MCI_NOTIFY) {
|
|---|
| 524 | TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
|
|---|
| 525 |
|
|---|
| 526 | mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback),
|
|---|
| 527 | wma->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
|
|---|
| 528 | }
|
|---|
| 529 | return 0;
|
|---|
| 530 | }
|
|---|
| 531 |
|
|---|
| 532 | /**************************************************************************
|
|---|
| 533 | * ANIM_mciResume [internal]
|
|---|
| 534 | */
|
|---|
| 535 | static DWORD ANIM_mciResume(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
|
|---|
| 536 | {
|
|---|
| 537 | WINE_MCIANIM* wma = ANIM_mciGetOpenDrv(wDevID);
|
|---|
| 538 |
|
|---|
| 539 | TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
|
|---|
| 540 | if (lpParms == NULL) return MCIERR_INTERNAL;
|
|---|
| 541 | wma->mode = MCI_MODE_STOP;
|
|---|
| 542 | if (dwFlags & MCI_NOTIFY) {
|
|---|
| 543 | TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
|
|---|
| 544 |
|
|---|
| 545 | mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback),
|
|---|
| 546 | wma->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
|
|---|
| 547 | }
|
|---|
| 548 | return 0;
|
|---|
| 549 | }
|
|---|
| 550 |
|
|---|
| 551 | /**************************************************************************
|
|---|
| 552 | * ANIM_mciSeek [internal]
|
|---|
| 553 | */
|
|---|
| 554 | static DWORD ANIM_mciSeek(UINT16 wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
|
|---|
| 555 | {
|
|---|
| 556 | WINE_MCIANIM* wma = ANIM_mciGetOpenDrv(wDevID);
|
|---|
| 557 | DWORD dwRet;
|
|---|
| 558 | MCI_PLAY_PARMS PlayParms;
|
|---|
| 559 |
|
|---|
| 560 | TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
|
|---|
| 561 |
|
|---|
| 562 | if (lpParms == NULL) return MCIERR_INTERNAL;
|
|---|
| 563 | wma->mode = MCI_MODE_SEEK;
|
|---|
| 564 | switch (dwFlags) {
|
|---|
| 565 | case MCI_SEEK_TO_START:
|
|---|
| 566 | PlayParms.dwFrom = 0;
|
|---|
| 567 | break;
|
|---|
| 568 | case MCI_SEEK_TO_END:
|
|---|
| 569 | PlayParms.dwFrom = wma->dwTotalLen;
|
|---|
| 570 | break;
|
|---|
| 571 | case MCI_TO:
|
|---|
| 572 | PlayParms.dwFrom = lpParms->dwTo;
|
|---|
| 573 | break;
|
|---|
| 574 | }
|
|---|
| 575 | dwRet = ANIM_mciPlay(wDevID, MCI_WAIT | MCI_FROM, &PlayParms);
|
|---|
| 576 | if (dwRet != 0) return dwRet;
|
|---|
| 577 | dwRet = ANIM_mciStop(wDevID, MCI_WAIT, (LPMCI_GENERIC_PARMS)&PlayParms);
|
|---|
| 578 | if (dwFlags & MCI_NOTIFY) {
|
|---|
| 579 | TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
|
|---|
| 580 |
|
|---|
| 581 | mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback),
|
|---|
| 582 | wma->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
|
|---|
| 583 | }
|
|---|
| 584 | return dwRet;
|
|---|
| 585 | }
|
|---|
| 586 |
|
|---|
| 587 |
|
|---|
| 588 | /**************************************************************************
|
|---|
| 589 | * ANIM_mciSet [internal]
|
|---|
| 590 | */
|
|---|
| 591 | static DWORD ANIM_mciSet(UINT16 wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
|
|---|
| 592 | {
|
|---|
| 593 | WINE_MCIANIM* wma = ANIM_mciGetOpenDrv(wDevID);
|
|---|
| 594 |
|
|---|
| 595 | TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
|
|---|
| 596 |
|
|---|
| 597 | if (lpParms == NULL) return MCIERR_INTERNAL;
|
|---|
| 598 | if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
|
|---|
| 599 | /*
|
|---|
| 600 | TRACE("(dwTimeFormat=%08lX)\n", lpParms->dwTimeFormat);
|
|---|
| 601 | TRACE("(dwAudio=%08lX)\n", lpParms->dwAudio);
|
|---|
| 602 | */
|
|---|
| 603 | if (dwFlags & MCI_SET_TIME_FORMAT) {
|
|---|
| 604 | switch (lpParms->dwTimeFormat) {
|
|---|
| 605 | case MCI_FORMAT_MILLISECONDS:
|
|---|
| 606 | TRACE("MCI_FORMAT_MILLISECONDS !\n");
|
|---|
| 607 | break;
|
|---|
| 608 | case MCI_FORMAT_MSF:
|
|---|
| 609 | TRACE("MCI_FORMAT_MSF !\n");
|
|---|
| 610 | break;
|
|---|
| 611 | case MCI_FORMAT_TMSF:
|
|---|
| 612 | TRACE("MCI_FORMAT_TMSF !\n");
|
|---|
| 613 | break;
|
|---|
| 614 | default:
|
|---|
| 615 | WARN("Bad time format !\n");
|
|---|
| 616 | return MCIERR_BAD_TIME_FORMAT;
|
|---|
| 617 | }
|
|---|
| 618 | wma->dwTimeFormat = lpParms->dwTimeFormat;
|
|---|
| 619 | }
|
|---|
| 620 | if (dwFlags & MCI_SET_VIDEO) return MCIERR_UNSUPPORTED_FUNCTION;
|
|---|
| 621 | if (dwFlags & MCI_SET_ON) return MCIERR_UNSUPPORTED_FUNCTION;
|
|---|
| 622 | if (dwFlags & MCI_SET_OFF) return MCIERR_UNSUPPORTED_FUNCTION;
|
|---|
| 623 | if (dwFlags & MCI_NOTIFY) {
|
|---|
| 624 | TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
|
|---|
| 625 | mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback),
|
|---|
| 626 | wma->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
|
|---|
| 627 | }
|
|---|
| 628 | return 0;
|
|---|
| 629 | }
|
|---|
| 630 |
|
|---|
| 631 | /**************************************************************************
|
|---|
| 632 | * ANIM_DriverProc [sample driver]
|
|---|
| 633 | */
|
|---|
| 634 | LONG CALLBACK MCIANIM_DriverProc(DWORD dwDevID, HDRVR hDriv, DWORD wMsg,
|
|---|
| 635 | DWORD dwParam1, DWORD dwParam2)
|
|---|
| 636 | {
|
|---|
| 637 | switch (wMsg) {
|
|---|
| 638 | case DRV_LOAD: return 1;
|
|---|
| 639 | case DRV_FREE: return 1;
|
|---|
| 640 | case DRV_OPEN: return ANIM_drvOpen((LPSTR)dwParam1, (LPMCI_OPEN_DRIVER_PARMSA)dwParam2);
|
|---|
| 641 | case DRV_CLOSE: return ANIM_drvClose(dwDevID);
|
|---|
| 642 | case DRV_ENABLE: return 1;
|
|---|
| 643 | case DRV_DISABLE: return 1;
|
|---|
| 644 | case DRV_QUERYCONFIGURE: return 1;
|
|---|
| 645 | case DRV_CONFIGURE: MessageBoxA(0, "Sample MultiMedia Driver !", "Wine Driver", MB_OK); return 1;
|
|---|
| 646 | case DRV_INSTALL: return DRVCNF_RESTART;
|
|---|
| 647 | case DRV_REMOVE: return DRVCNF_RESTART;
|
|---|
| 648 |
|
|---|
| 649 | case MCI_OPEN_DRIVER: return ANIM_mciOpen(dwDevID, dwParam1, (LPMCI_OPEN_PARMSA)dwParam2);
|
|---|
| 650 | case MCI_CLOSE_DRIVER: return ANIM_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
|
|---|
| 651 | case MCI_GETDEVCAPS: return ANIM_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)dwParam2);
|
|---|
| 652 | case MCI_INFO: return ANIM_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS16)dwParam2);
|
|---|
| 653 | case MCI_STATUS: return ANIM_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)dwParam2);
|
|---|
| 654 | case MCI_SET: return ANIM_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)dwParam2);
|
|---|
| 655 | case MCI_PLAY: return ANIM_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)dwParam2);
|
|---|
| 656 | case MCI_STOP: return ANIM_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
|
|---|
| 657 | case MCI_PAUSE: return ANIM_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
|
|---|
| 658 | case MCI_RESUME: return ANIM_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
|
|---|
| 659 | case MCI_SEEK: return ANIM_mciSeek(dwDevID, dwParam1, (LPMCI_SEEK_PARMS)dwParam2);
|
|---|
| 660 | case MCI_LOAD:
|
|---|
| 661 | case MCI_SAVE:
|
|---|
| 662 | case MCI_FREEZE:
|
|---|
| 663 | case MCI_PUT:
|
|---|
| 664 | case MCI_REALIZE:
|
|---|
| 665 | case MCI_UNFREEZE:
|
|---|
| 666 | case MCI_UPDATE:
|
|---|
| 667 | case MCI_WHERE:
|
|---|
| 668 | case MCI_WINDOW:
|
|---|
| 669 | case MCI_STEP:
|
|---|
| 670 | case MCI_SPIN:
|
|---|
| 671 | case MCI_ESCAPE:
|
|---|
| 672 | case MCI_COPY:
|
|---|
| 673 | case MCI_CUT:
|
|---|
| 674 | case MCI_DELETE:
|
|---|
| 675 | case MCI_PASTE:
|
|---|
| 676 | FIXME("Unsupported message [%lu]\n", wMsg);
|
|---|
| 677 | break;
|
|---|
| 678 | case MCI_OPEN:
|
|---|
| 679 | case MCI_CLOSE:
|
|---|
| 680 | ERR("Shouldn't receive a MCI_OPEN or CLOSE message\n");
|
|---|
| 681 | break;
|
|---|
| 682 | default:
|
|---|
| 683 | TRACE("Sending msg [%lu] to default driver proc\n", wMsg);
|
|---|
| 684 | return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
|
|---|
| 685 | }
|
|---|
| 686 | return MCIERR_UNRECOGNIZED_COMMAND;
|
|---|
| 687 | }
|
|---|
| 688 |
|
|---|
| 689 | /*-----------------------------------------------------------------------*/
|
|---|