Much improved mciavi driver. Fixed synchronization, RIFF file with
[wine] / dlls / winmm / mciavi / wnd.c
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
2
3 /*
4  * Digital video MCI Wine Driver
5  *
6  * Copyright 1999, 2000 Eric POUECH
7  * Copyright 2003 Dmitry Timoshkov
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24 #include <string.h>
25 #include "private_mciavi.h"
26 #include "wine/debug.h"
27
28 WINE_DEFAULT_DEBUG_CHANNEL(mciavi);
29
30 static LRESULT WINAPI MCIAVI_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
31 {
32     TRACE("hwnd=%p msg=%x wparam=%x lparam=%lx\n", hWnd, uMsg, wParam, lParam);
33
34     switch (uMsg) {
35     case WM_CREATE:
36         SetWindowLongA(hWnd, 0, (LPARAM)((CREATESTRUCTA*)lParam)->lpCreateParams);
37         return DefWindowProcA(hWnd, uMsg, wParam, lParam);
38
39     case WM_DESTROY:
40         MCIAVI_mciClose(GetWindowLongA(hWnd, 0), MCI_WAIT, NULL);
41         SetWindowLongA(hWnd, 0, 0);
42         return DefWindowProcA(hWnd, uMsg, wParam, lParam);
43
44     case WM_ERASEBKGND:
45         {
46             RECT        rect;
47             GetClientRect(hWnd, &rect);
48             FillRect((HDC)wParam, &rect, GetStockObject(BLACK_BRUSH));
49         }
50        return 1;
51
52     case WM_PAINT:
53         {
54             WINE_MCIAVI *wma = (WINE_MCIAVI *)mciGetDriverData(GetWindowLongA(hWnd, 0));
55
56             if (!wma)
57                 return DefWindowProcA(hWnd, uMsg, wParam, lParam);
58             
59             EnterCriticalSection(&wma->cs);
60
61             /* the animation isn't playing, don't paint */
62             if (wma->dwStatus == MCI_MODE_NOT_READY)
63             {
64                 LeaveCriticalSection(&wma->cs);
65                 /* default paint handling */
66                 return DefWindowProcA(hWnd, uMsg, wParam, lParam);
67             }
68
69             if (wParam)
70                 MCIAVI_PaintFrame(wma, (HDC)wParam);
71             else
72             {
73                 PAINTSTRUCT ps;
74                 HDC hDC = BeginPaint(hWnd, &ps);
75                 MCIAVI_PaintFrame(wma, hDC);
76                 EndPaint(hWnd, &ps);
77             }
78
79             LeaveCriticalSection(&wma->cs);
80         }
81        return 1;
82
83     default:
84         return DefWindowProcA(hWnd, uMsg, wParam, lParam);
85     }
86     return 0;
87 }
88
89 BOOL    MCIAVI_CreateWindow(WINE_MCIAVI* wma, DWORD dwFlags, LPMCI_DGV_OPEN_PARMSA lpOpenParms)
90 {
91     WNDCLASSA   wndClass;
92     HWND        hParent = 0;
93     DWORD       dwStyle = WS_OVERLAPPEDWINDOW;
94     int         p = CW_USEDEFAULT;
95     RECT rc;
96
97     /* what should be done ? */
98     if (wma->hWnd) return TRUE;
99
100     ZeroMemory(&wndClass, sizeof(WNDCLASSA));
101     wndClass.style         = CS_DBLCLKS;
102     wndClass.lpfnWndProc   = (WNDPROC)MCIAVI_WindowProc;
103     wndClass.cbClsExtra    = 0;
104     wndClass.cbWndExtra    = sizeof(MCIDEVICEID);
105     wndClass.hInstance     = MCIAVI_hInstance;
106     wndClass.hCursor       = LoadCursorA(0, (LPSTR)IDC_ARROW);
107     wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
108     wndClass.lpszClassName = "MCIAVI";
109
110     if (!RegisterClassA(&wndClass)) return FALSE;
111
112     if (dwFlags & MCI_DGV_OPEN_PARENT)  hParent = lpOpenParms->hWndParent;
113     if (dwFlags & MCI_DGV_OPEN_WS)      dwStyle = lpOpenParms->dwStyle;
114     if (dwStyle & WS_CHILD)             p = 0;
115
116     rc.left = p;
117     rc.top = p;
118     rc.right = (wma->hic ? wma->outbih : wma->inbih)->biWidth;
119     rc.bottom = (wma->hic ? wma->outbih : wma->inbih)->biHeight;
120     AdjustWindowRect(&rc, dwStyle, FALSE);
121
122     wma->hWnd = CreateWindowA("MCIAVI", "Wine MCI-AVI player",
123                              dwStyle, rc.left, rc.top,
124                              rc.right, rc.bottom,
125                              hParent, 0, MCIAVI_hInstance,
126                               (LPVOID)wma->wDevID);
127     wma->hWndPaint = wma->hWnd;
128     return (BOOL)wma->hWnd;
129 }
130
131 /***************************************************************************
132  *                              MCIAVI_mciPut                   [internal]
133  */
134 DWORD   MCIAVI_mciPut(UINT wDevID, DWORD dwFlags, LPMCI_DGV_PUT_PARMS lpParms)
135 {
136     WINE_MCIAVI*        wma = MCIAVI_mciGetOpenDev(wDevID);
137     RECT                rc;
138
139     TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms);
140
141     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
142     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
143
144     EnterCriticalSection(&wma->cs);
145
146     if (dwFlags & MCI_DGV_RECT) {
147         rc = lpParms->rc;
148     } else {
149         GetClientRect(wma->hWndPaint, &rc);
150     }
151
152     if (dwFlags & MCI_DGV_PUT_CLIENT) {
153         FIXME("PUT_CLIENT %s\n", wine_dbgstr_rect(&rc));
154         LeaveCriticalSection(&wma->cs);
155         return MCIERR_UNRECOGNIZED_COMMAND;
156     }
157     if (dwFlags & MCI_DGV_PUT_DESTINATION) {
158         TRACE("PUT_DESTINATION %s\n", wine_dbgstr_rect(&rc));
159         wma->dest = rc;
160     }
161     if (dwFlags & MCI_DGV_PUT_FRAME) {
162         FIXME("PUT_FRAME %s\n", wine_dbgstr_rect(&rc));
163         LeaveCriticalSection(&wma->cs);
164         return MCIERR_UNRECOGNIZED_COMMAND;
165     }
166     if (dwFlags & MCI_DGV_PUT_SOURCE) {
167         TRACE("PUT_SOURCE %s\n", wine_dbgstr_rect(&rc));
168         wma->source = rc;
169     }
170     if (dwFlags & MCI_DGV_PUT_VIDEO) {
171         FIXME("PUT_VIDEO %s\n", wine_dbgstr_rect(&rc));
172         LeaveCriticalSection(&wma->cs);
173         return MCIERR_UNRECOGNIZED_COMMAND;
174     }
175     if (dwFlags & MCI_DGV_PUT_WINDOW) {
176         FIXME("PUT_WINDOW %s\n", wine_dbgstr_rect(&rc));
177         LeaveCriticalSection(&wma->cs);
178         return MCIERR_UNRECOGNIZED_COMMAND;
179     }
180     LeaveCriticalSection(&wma->cs);
181     return 0;
182 }
183
184 /******************************************************************************
185  *                              MCIAVI_mciWhere                 [internal]
186  */
187 DWORD   MCIAVI_mciWhere(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lpParms)
188 {
189     WINE_MCIAVI*        wma = MCIAVI_mciGetOpenDev(wDevID);
190
191     TRACE("(%04x, %08lx, %p)\n", wDevID, dwFlags, lpParms);
192
193     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
194     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
195
196     if (dwFlags & MCI_DGV_WHERE_MAX)
197     {
198         FIXME("WHERE_MAX\n");
199         return MCIERR_UNRECOGNIZED_COMMAND;
200     }
201
202     EnterCriticalSection(&wma->cs);
203
204     if (dwFlags & MCI_DGV_WHERE_DESTINATION) {
205         TRACE("WHERE_DESTINATION %s\n", wine_dbgstr_rect(&wma->dest));
206         lpParms->rc = wma->dest;
207     }
208     if (dwFlags & MCI_DGV_WHERE_FRAME) {
209        FIXME("MCI_DGV_WHERE_FRAME\n");
210         LeaveCriticalSection(&wma->cs);
211         return MCIERR_UNRECOGNIZED_COMMAND;
212     }
213     if (dwFlags & MCI_DGV_WHERE_SOURCE) {
214         TRACE("WHERE_SOURCE %s\n", wine_dbgstr_rect(&wma->source));
215         lpParms->rc = wma->source;
216     }
217     if (dwFlags & MCI_DGV_WHERE_VIDEO) {
218        FIXME("WHERE_VIDEO\n");
219         LeaveCriticalSection(&wma->cs);
220         return MCIERR_UNRECOGNIZED_COMMAND;
221     }
222     if (dwFlags & MCI_DGV_WHERE_WINDOW) {
223         GetClientRect(wma->hWndPaint, &lpParms->rc);
224         TRACE("WHERE_WINDOW %s\n", wine_dbgstr_rect(&lpParms->rc));
225     }
226     LeaveCriticalSection(&wma->cs);
227     return 0;
228 }
229
230 /***************************************************************************
231  *                              MCIAVI_mciWindow                        [internal]
232  */
233 DWORD   MCIAVI_mciWindow(UINT wDevID, DWORD dwFlags, LPMCI_DGV_WINDOW_PARMSA lpParms)
234 {
235     WINE_MCIAVI*        wma = MCIAVI_mciGetOpenDev(wDevID);
236
237     TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms);
238
239     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
240     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
241
242     EnterCriticalSection(&wma->cs);
243
244     if (dwFlags & MCI_DGV_WINDOW_HWND) {
245         if (IsWindow(lpParms->hWnd))
246         {
247             TRACE("Setting hWnd to %p\n", lpParms->hWnd);
248             if (wma->hWnd) ShowWindow(wma->hWnd, SW_HIDE);
249             wma->hWndPaint = (lpParms->hWnd == MCI_DGV_WINDOW_DEFAULT) ? wma->hWnd : lpParms->hWnd;
250             InvalidateRect(wma->hWndPaint, NULL, FALSE);
251         }
252     }
253     if (dwFlags & MCI_DGV_WINDOW_STATE) {
254         TRACE("Setting nCmdShow to %d\n", lpParms->nCmdShow);
255        ShowWindow(wma->hWndPaint, lpParms->nCmdShow);
256     }
257     if (dwFlags & MCI_DGV_WINDOW_TEXT) {
258         TRACE("Setting caption to '%s'\n", lpParms->lpstrText);
259        SetWindowTextA(wma->hWndPaint, lpParms->lpstrText);
260     }
261
262     LeaveCriticalSection(&wma->cs);
263     return 0;
264 }