- New implementation of SendMessage, ReceiveMessage, ReplyMessage functions
[wine] / multimedia / mciavi.c
1 /*
2  * Digital video MCI Wine Driver
3  *
4  * Copyright 1999 Eric POUECH
5  */
6
7 #include "wine/winuser16.h"
8 #include "multimedia.h"
9 #include "user.h"
10 #include "driver.h"
11 #include "xmalloc.h"
12 #include "debug.h"
13 #include "callback.h"
14 #include "options.h"
15
16 typedef struct {
17     int                 nUseCount;              /* Incremented for each shared open          */
18     BOOL16              fShareable;             /* TRUE if first open was shareable          */
19     WORD                wNotifyDeviceID;        /* MCI device ID with a pending notification */
20     HANDLE16            hCallback;              /* Callback handle for pending notification  */
21     HMMIO32             hFile;                  /* mmio file handle open as Element          */
22     MCI_OPEN_PARMS32A   openParms;
23     DWORD               dwTimeFormat;
24 } WINE_MCIAVI;
25
26 #define MAX_MCIAVIDRV   (1)
27 static WINE_MCIAVI      MCIAviDev[MAX_MCIAVIDRV];
28
29 /*======================================================================*
30  *                          MCI AVI implemantation                      *
31  *======================================================================*/
32
33 /**************************************************************************
34  *                              AVI_mciGetOpenDev               [internal]      
35  */
36 static WINE_MCIAVI*  AVI_mciGetOpenDev(UINT16 wDevID)
37 {
38     if (wDevID >= MAX_MCIAVIDRV || MCIAviDev[wDevID].nUseCount == 0) {
39         WARN(mciavi, "Invalid wDevID=%u\n", wDevID);
40         return 0;
41     }
42     return &MCIAviDev[wDevID];
43 }
44
45 static  DWORD   AVI_mciStop(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
46
47 static  DWORD   AVI_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_OPEN_PARMS32A lpParms)
48 {
49     WINE_MCIAVI*        wma;
50
51     TRACE(mciavi, "(%04x, %08lX, %p) : semi-stub\n", wDevID, dwFlags, lpParms);
52
53     if (lpParms == NULL)                return MCIERR_NULL_PARAMETER_BLOCK;
54     if (wDevID > MAX_MCIAVIDRV)         return MCIERR_INVALID_DEVICE_ID;
55
56     wma = &MCIAviDev[wDevID];
57
58     if (wma->nUseCount > 0) {
59         /* The driver is already open on this channel */
60         /* If the driver was opened shareable before and this open specifies */
61         /* shareable then increment the use count */
62         if (wma->fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
63             ++wma->nUseCount;
64         else
65             return MCIERR_MUST_USE_SHAREABLE;
66     } else {
67         wma->nUseCount = 1;
68         wma->fShareable = dwFlags & MCI_OPEN_SHAREABLE;
69     }
70     if (dwFlags & MCI_OPEN_ELEMENT) {
71         TRACE(cdaudio,"MCI_OPEN_ELEMENT !\n");
72         /*              return MCIERR_NO_ELEMENT_ALLOWED; */
73     }
74
75     wma->openParms.dwCallback = lpParms->dwCallback;
76     wma->openParms.wDeviceID  = (WORD)lpParms->wDeviceID;
77     wma->openParms.lpstrDeviceType = lpParms->lpstrDeviceType;
78     wma->openParms.lpstrElementName = lpParms->lpstrElementName;
79     wma->openParms.lpstrAlias = lpParms->lpstrAlias;
80
81     wma->wNotifyDeviceID = lpParms->wDeviceID;
82     /* FIXME: do real open */
83     /*    wmcda->mciMode = MCI_MODE_STOP; */
84     wma->dwTimeFormat = MCI_FORMAT_TMSF;
85
86     return 0;
87
88 }
89
90 static  DWORD   AVI_mciClose(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
91 {
92     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
93
94     TRACE(mciavi, "(%04x, %08lX, %p) : semi-stub\n", wDevID, dwFlags, lpParms);    
95
96     if (wma == NULL)    return MCIERR_INVALID_DEVICE_ID;
97     
98     if (wma->nUseCount == 1) {
99         AVI_mciStop(wDevID, 0, NULL);
100         /* FIXME: do real closing */
101     }
102     wma->nUseCount--;
103     return 0;
104 }
105
106 static  DWORD   AVI_mciPlay(UINT16 wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
107 {
108     TRACE(mciavi, "(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
109     return 0;
110 }
111
112 static  DWORD   AVI_mciRecord(UINT16 wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms)
113 {
114     TRACE(mciavi, "(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
115     return 0;
116 }
117
118 static  DWORD   AVI_mciStop(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
119 {
120     TRACE(mciavi, "(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
121     return 0;
122 }
123
124 static  DWORD   AVI_mciSet(UINT16 wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
125 {
126     TRACE(mciavi, "(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
127     return 0;
128 }
129
130 static  DWORD   AVI_mciPause(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
131 {
132     TRACE(mciavi, "(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
133     return 0;
134 }
135
136 static  DWORD   AVI_mciResume(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
137 {
138     TRACE(mciavi, "(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
139     return 0;
140 }
141
142 static  DWORD   AVI_mciStatus(UINT16 wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
143 {
144     TRACE(mciavi, "(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
145     return 0;
146 }
147
148 static  DWORD   AVI_mciGetDevCaps(UINT16 wDevID, DWORD dwFlags,  LPMCI_GETDEVCAPS_PARMS lpParms)
149 {
150     WINE_MCIAVI*        wmm = AVI_mciGetOpenDev(wDevID);
151     
152     TRACE(mciavi, "(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
153     
154     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
155     if (wmm == NULL)            return MCIERR_INVALID_DEVICE_ID;
156     
157     if (dwFlags & MCI_GETDEVCAPS_ITEM) {
158         switch (lpParms->dwItem) {
159         case MCI_GETDEVCAPS_DEVICE_TYPE:
160             TRACE(mciavi, "MCI_GETDEVCAPS_DEVICE_TYPE !\n");
161             lpParms->dwReturn = MCI_DEVTYPE_DIGITAL_VIDEO;
162             break;
163         case MCI_GETDEVCAPS_HAS_AUDIO:
164             TRACE(mciavi, "MCI_GETDEVCAPS_HAS_AUDIO !\n");
165             lpParms->dwReturn = TRUE;
166             break;
167         case MCI_GETDEVCAPS_HAS_VIDEO:
168             TRACE(mciavi, "MCI_GETDEVCAPS_HAS_VIDEO !\n");
169             lpParms->dwReturn = TRUE;
170             break;
171         case MCI_GETDEVCAPS_USES_FILES:
172             TRACE(mciavi, "MCI_GETDEVCAPS_USES_FILES !\n");
173             lpParms->dwReturn = TRUE;
174             break;
175         case MCI_GETDEVCAPS_COMPOUND_DEVICE:
176             TRACE(mciavi, "MCI_GETDEVCAPS_COMPOUND_DEVICE !\n");
177             lpParms->dwReturn = TRUE;
178             break;
179         case MCI_GETDEVCAPS_CAN_EJECT:
180             TRACE(mciavi, "MCI_GETDEVCAPS_CAN_EJECT !\n");
181             lpParms->dwReturn = FALSE;
182             break;
183         case MCI_GETDEVCAPS_CAN_PLAY:
184             TRACE(mciavi, "MCI_GETDEVCAPS_CAN_PLAY !\n");
185             lpParms->dwReturn = TRUE;
186             break;
187         case MCI_GETDEVCAPS_CAN_RECORD:
188             TRACE(mciavi, "MCI_GETDEVCAPS_CAN_RECORD !\n");
189             lpParms->dwReturn = FALSE;
190             break;
191         case MCI_GETDEVCAPS_CAN_SAVE:
192             TRACE(mciavi, "MCI_GETDEVCAPS_CAN_SAVE !\n");
193             lpParms->dwReturn = FALSE;
194             break;
195         default:
196             TRACE(mciavi, "Unknown capability (%08lx) !\n", lpParms->dwItem);
197             return MCIERR_UNRECOGNIZED_COMMAND;
198         }
199     } else {
200         TRACE(mciavi, "No GetDevCaps-Item !\n");
201         return MCIERR_UNRECOGNIZED_COMMAND;
202     }
203     return 0;
204 }
205
206 static  DWORD   AVI_mciInfo(UINT16 wDevID, DWORD dwFlags, LPMCI_INFO_PARMS32A lpParms)
207 {
208     DWORD               ret = 0;
209     LPSTR               str = 0;
210     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
211
212     TRACE(mciavi, "(%04X, %08lX, %p) : stub;\n", wDevID, dwFlags, lpParms);
213     
214     if (lpParms == NULL || lpParms->lpstrReturn == NULL) {
215         ret = MCIERR_NULL_PARAMETER_BLOCK;
216     } else if (wma == NULL) {
217         ret = MCIERR_INVALID_DEVICE_ID;
218     } else {
219         TRACE(mciavi, "buf=%p, len=%lu\n", lpParms->lpstrReturn, lpParms->dwRetSize);
220         
221         switch (dwFlags) {
222         case MCI_INFO_PRODUCT:
223             str = "Wine's AVI player";
224             break;
225         case MCI_INFO_FILE:
226             str = "";
227             break;
228 #if 0
229             /* FIXME: the following manifest constants are not defined in <WINE>/include/mmsystem.h */
230         case MCI_INFO_COPYRIGHT:
231             break;
232         case MCI_INFO_NAME:
233             break;
234 #endif
235         default:
236             WARN(mciavi, "Don't know this info command (%lu)\n", dwFlags);
237             ret = MCIERR_UNRECOGNIZED_COMMAND;
238         }
239     }
240     if (str) {
241         ret = MCI_WriteString(lpParms->lpstrReturn, lpParms->dwRetSize, str);
242     } else {
243         lpParms->lpstrReturn[0] = 0;
244     }
245     
246     return ret;
247 }
248
249 static  DWORD   AVI_mciSeek(UINT16 wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
250 {
251     TRACE(mciavi, "(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
252     return 0;
253 }
254
255
256 /*======================================================================*
257  *                          MCI AVI entry points                        *
258  *======================================================================*/
259
260 /**************************************************************************
261  *                              MCIAVI_DriverProc32     [sample driver]
262  */
263 LONG MCIAVI_DriverProc32(DWORD dwDevID, HDRVR16 hDriv, DWORD wMsg, 
264                                  DWORD dwParam1, DWORD dwParam2)
265 {
266     switch (wMsg) {
267     case DRV_LOAD:              return 1;
268     case DRV_FREE:              return 1;
269     case DRV_OPEN:              return 1;
270     case DRV_CLOSE:             return 1;
271     case DRV_ENABLE:            return 1;
272     case DRV_DISABLE:           return 1;
273     case DRV_QUERYCONFIGURE:    return 1;
274     case DRV_CONFIGURE:         MessageBox32A(0, "Sample AVI Wine Driver !", "MM-Wine Driver", MB_OK); return 1;
275     case DRV_INSTALL:           return DRVCNF_RESTART;
276     case DRV_REMOVE:            return DRVCNF_RESTART;
277     case MCI_OPEN_DRIVER:       return AVI_mciOpen      (dwDevID, dwParam1, (LPMCI_OPEN_PARMS32A)   dwParam2);
278     case MCI_CLOSE_DRIVER:      return AVI_mciClose     (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)   dwParam2);
279     case MCI_PLAY:              return AVI_mciPlay      (dwDevID, dwParam1, (LPMCI_PLAY_PARMS)      dwParam2);
280     case MCI_RECORD:            return AVI_mciRecord    (dwDevID, dwParam1, (LPMCI_RECORD_PARMS)    dwParam2);
281     case MCI_STOP:              return AVI_mciStop      (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)   dwParam2);
282     case MCI_SET:               return AVI_mciSet       (dwDevID, dwParam1, (LPMCI_SET_PARMS)       dwParam2);
283     case MCI_PAUSE:             return AVI_mciPause     (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)   dwParam2);
284     case MCI_RESUME:            return AVI_mciResume    (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)   dwParam2);
285     case MCI_STATUS:            return AVI_mciStatus    (dwDevID, dwParam1, (LPMCI_STATUS_PARMS)    dwParam2);
286     case MCI_GETDEVCAPS:        return AVI_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)dwParam2);
287     case MCI_INFO:              return AVI_mciInfo      (dwDevID, dwParam1, (LPMCI_INFO_PARMS32A)   dwParam2);
288     case MCI_SEEK:              return AVI_mciSeek      (dwDevID, dwParam1, (LPMCI_SEEK_PARMS)      dwParam2);
289     case MCI_LOAD:              
290     case MCI_SAVE:              
291     case MCI_FREEZE:            
292     case MCI_PUT:               
293     case MCI_REALIZE:           
294     case MCI_UNFREEZE:          
295     case MCI_UPDATE:            
296     case MCI_WHERE:             
297     case MCI_WINDOW:            
298     case MCI_STEP:              
299     case MCI_SPIN:              
300     case MCI_ESCAPE:            
301     case MCI_COPY:              
302     case MCI_CUT:               
303     case MCI_DELETE:            
304     case MCI_PASTE:             
305         WARN(mciavi, "Unsupported command=%s\n", MCI_CommandToString(wMsg));
306         break;
307     case MCI_OPEN:
308     case MCI_CLOSE:
309         FIXME(mciavi, "Shouldn't receive a MCI_OPEN or CLOSE message\n");
310         break;
311     default:                    
312         TRACE(mciavi, "Sending msg=%s to default driver proc\n", MCI_CommandToString(wMsg));
313         return DefDriverProc32(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
314     }
315     return MCIERR_UNRECOGNIZED_COMMAND;
316 }