Fix a loop playing failure and a problem with choppy sound.
[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  */
8
9 #include <string.h>
10 #include "private_mciavi.h"
11 #include "debugtools.h"
12
13 DEFAULT_DEBUG_CHANNEL(mciavi);
14
15 static LRESULT WINAPI MCIAVI_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
16 {
17     TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hWnd, uMsg, wParam, lParam);
18     
19     if (!(WINE_MCIAVI*)GetWindowLongA(hWnd, 0) && uMsg != WM_CREATE)
20         return DefWindowProcA(hWnd, uMsg, wParam, lParam);
21     
22     switch (uMsg) {
23     case WM_CREATE:
24         SetWindowLongA(hWnd, 0, (LPARAM)((CREATESTRUCTA*)lParam)->lpCreateParams);
25         return DefWindowProcA(hWnd, uMsg, wParam, lParam);
26         
27     case WM_DESTROY:
28         SetWindowLongA(hWnd, 0, 0);
29         return DefWindowProcA(hWnd, uMsg, wParam, lParam);
30         
31     case WM_ERASEBKGND:
32         {
33             RECT        rect;
34             GetClientRect(hWnd, &rect);
35             FillRect((HDC)wParam, &rect, GetStockObject(BLACK_BRUSH));
36         }
37         break;
38     case WM_PAINT:
39         {
40             WINE_MCIAVI* wma = (WINE_MCIAVI*)GetWindowLongA(hWnd, 0);
41             
42             /* the animation isn't playing, don't paint */
43             if (wma->dwStatus == MCI_MODE_NOT_READY)
44                 /* default paint handling */
45                 return DefWindowProcA(hWnd, uMsg, wParam, lParam);
46             
47             if (wParam) {
48                 EnterCriticalSection(&wma->cs);
49                 MCIAVI_PaintFrame(wma, (HDC)wParam);
50                 LeaveCriticalSection(&wma->cs);
51             } else {
52                 PAINTSTRUCT ps;
53                 HDC hDC = BeginPaint(hWnd, &ps);
54                 
55                 EnterCriticalSection(&wma->cs);
56                 MCIAVI_PaintFrame(wma, hDC);
57                 LeaveCriticalSection(&wma->cs);
58                 
59                 EndPaint(hWnd, &ps);
60             }
61         }
62         break;
63         
64     default:
65         return DefWindowProcA(hWnd, uMsg, wParam, lParam);
66     }
67     return 0;
68 }
69
70 BOOL    MCIAVI_CreateWindow(WINE_MCIAVI* wma, DWORD dwFlags, LPMCI_DGV_OPEN_PARMSA lpOpenParms)
71 {
72     WNDCLASSA   wndClass;
73     HWND        hParent = 0;
74     DWORD       dwStyle = WS_OVERLAPPEDWINDOW;
75     int         p = CW_USEDEFAULT;
76
77     /* what should be done ? */
78     if (wma->hWnd) return TRUE;
79     
80     ZeroMemory(&wndClass, sizeof(WNDCLASSA));
81     wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS;
82     wndClass.lpfnWndProc   = (WNDPROC)MCIAVI_WindowProc;
83     wndClass.cbClsExtra    = 0;
84     wndClass.cbWndExtra    = sizeof(WINE_MCIAVI*);
85     wndClass.hCursor       = LoadCursorA(0, IDC_ARROWA);
86     wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
87     wndClass.lpszClassName = "MCIAVI";
88     
89     RegisterClassA(&wndClass);
90
91     if (dwFlags & MCI_DGV_OPEN_PARENT)  hParent = lpOpenParms->hWndParent;
92     if (dwFlags & MCI_DGV_OPEN_WS)      dwStyle = lpOpenParms->dwStyle;
93     if (dwStyle & WS_CHILD)             p = 0;
94
95     wma->hWnd = CreateWindowA("MCIAVI", "Wine MCI-AVI player", 
96                               dwStyle, p, p, 
97                               (wma->hic ? wma->outbih : wma->inbih)->biWidth, 
98                               (wma->hic ? wma->outbih : wma->inbih)->biHeight, 
99                               hParent, 0, MCIAVI_hInstance, wma);
100     return (BOOL)wma->hWnd;
101 }
102
103 /***************************************************************************
104  *                              MCIAVI_mciPut                   [internal]
105  */
106 DWORD   MCIAVI_mciPut(UINT wDevID, DWORD dwFlags, LPMCI_DGV_PUT_PARMS lpParms)
107 {
108     WINE_MCIAVI*        wma = MCIAVI_mciGetOpenDev(wDevID);
109     RECT                rc;
110     char                buffer[256];
111     
112     FIXME("(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
113     
114     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
115     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
116     
117     if (dwFlags & MCI_DGV_RECT) {
118         rc = lpParms->rc;
119     } else {
120         SetRectEmpty(&rc);
121     }
122     
123     *buffer = 0;
124     if (dwFlags & MCI_DGV_PUT_CLIENT) {
125         strncat(buffer, "PUT_CLIENT", sizeof(buffer));
126     }
127     if (dwFlags & MCI_DGV_PUT_DESTINATION) {
128         strncat(buffer, "PUT_DESTINATION", sizeof(buffer));
129     }
130     if (dwFlags & MCI_DGV_PUT_FRAME) {
131         strncat(buffer, "PUT_FRAME", sizeof(buffer));
132     }
133     if (dwFlags & MCI_DGV_PUT_SOURCE) {
134         strncat(buffer, "PUT_SOURCE", sizeof(buffer));
135     }
136     if (dwFlags & MCI_DGV_PUT_VIDEO) {
137         strncat(buffer, "PUT_VIDEO", sizeof(buffer));
138     }
139     if (dwFlags & MCI_DGV_PUT_WINDOW) {
140         strncat(buffer, "PUT_WINDOW", sizeof(buffer));
141     }
142     TRACE("%s (%d,%d,%d,%d)\n", buffer, rc.left, rc.top, rc.right, rc.bottom);
143     
144     return 0;
145 }
146
147 /******************************************************************************
148  *                              MCIAVI_mciWhere                 [internal]
149  */
150 DWORD   MCIAVI_mciWhere(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lpParms)
151 {
152     WINE_MCIAVI*        wma = MCIAVI_mciGetOpenDev(wDevID);
153     LPSTR               x = "";
154
155     TRACE("(%04x, %08lx, %p)\n", wDevID, dwFlags, lpParms);
156     
157     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
158     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
159     
160     if (dwFlags & MCI_DGV_WHERE_MAX) FIXME("Max NIY\n");
161
162     if (dwFlags & MCI_DGV_WHERE_DESTINATION) {
163         x = "Dest";
164         GetClientRect(wma->hWnd, &lpParms->rc);
165     }
166     if (dwFlags & MCI_DGV_WHERE_FRAME) {
167         FIXME(x = "Frame\n");
168         return MCIERR_UNRECOGNIZED_COMMAND;
169     }
170     if (dwFlags & MCI_DGV_WHERE_SOURCE) {
171         x = "Source";
172         lpParms->rc.left = lpParms->rc.top = 0;
173         lpParms->rc.right = wma->mah.dwWidth;
174         lpParms->rc.bottom = wma->mah.dwHeight;
175     }
176     if (dwFlags & MCI_DGV_WHERE_VIDEO) {
177         FIXME(x = "Video\n");
178         return MCIERR_UNRECOGNIZED_COMMAND;
179     }
180     if (dwFlags & MCI_DGV_WHERE_WINDOW) {
181         x = "Window";
182         GetClientRect(wma->hWnd, &lpParms->rc);
183     }
184     TRACE("%s -> (%d,%d,%d,%d)\n", 
185           x, lpParms->rc.left, lpParms->rc.top, lpParms->rc.right, lpParms->rc.bottom);
186
187     return 0;
188 }
189
190 /***************************************************************************
191  *                              MCIAVI_mciWindow                        [internal]
192  */
193 DWORD   MCIAVI_mciWindow(UINT wDevID, DWORD dwFlags, LPMCI_DGV_WINDOW_PARMSA lpParms)
194 {
195     WINE_MCIAVI*        wma = MCIAVI_mciGetOpenDev(wDevID);
196     
197     TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms);
198     
199     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
200     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
201     
202     if (dwFlags & MCI_DGV_WINDOW_HWND) {
203         FIXME("Setting hWnd to %08lx\n", (DWORD)lpParms->hWnd);
204 #if 0
205         if (wma->hWnd) DestroyWindow(wma->hWnd);
206         /* is the window to be subclassed ? */
207         wma->hWnd = lpParms->hWnd;
208 #endif
209     }
210     if (dwFlags & MCI_DGV_WINDOW_STATE) {
211         TRACE("Setting nCmdShow to %d\n", lpParms->nCmdShow);
212         ShowWindow(wma->hWnd, lpParms->nCmdShow);
213     }
214     if (dwFlags & MCI_DGV_WINDOW_TEXT) {
215         TRACE("Setting caption to '%s'\n", lpParms->lpstrText);
216         SetWindowTextA(wma->hWnd, lpParms->lpstrText);
217     }
218     
219     return 0;
220 }
221