Added stubs for AccessCheckByType, AddAuditAccessAce,
[wine] / dlls / msvideo / mciwnd.c
1 /*
2  * Copyright 2000 Eric Pouech
3  *
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 #define COM_NO_WINDOWS_H
21 #include <stdarg.h>
22 #include <stdio.h>
23 #include <string.h>
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winnls.h"
28 #include "wingdi.h"
29 #include "winuser.h"
30 #include "vfw.h"
31 #include "digitalv.h"
32 #include "commctrl.h"
33 #include "wine/debug.h"
34
35 WINE_DEFAULT_DEBUG_CHANNEL(mci);
36
37 typedef struct {
38    DWORD        dwStyle;
39    MCIDEVICEID  mci;
40    LPSTR        lpName;
41    HWND         hWnd;
42    UINT         uTimer;
43 } MCIWndInfo;
44
45 static LRESULT WINAPI   MCIWndProc(HWND hWnd, UINT wMsg, WPARAM lParam1, LPARAM lParam2);
46
47 #define CTL_PLAYSTOP    0x3200
48 #define CTL_MENU        0x3201
49 #define CTL_TRACKBAR    0x3202
50
51 /***********************************************************************
52  *              MCIWndRegisterClass             [MSVFW32.@]
53  */
54 BOOL WINAPI MCIWndRegisterClass(HINSTANCE hInst)
55 {
56    WNDCLASSA            wc;
57
58    /* since window creation will also require some common controls, init them */
59    InitCommonControls();
60
61    wc.style = 0;
62    wc.lpfnWndProc = MCIWndProc;
63    wc.cbClsExtra = 0;
64    wc.cbWndExtra = sizeof(MCIWndInfo*);
65    wc.hInstance = hInst;
66    wc.hIcon = 0;
67    wc.hCursor = 0;
68    wc.hbrBackground = 0;
69    wc.lpszMenuName = NULL;
70    wc.lpszClassName = "MCIWndClass";
71
72    return RegisterClassA(&wc);
73
74 }
75
76 /***********************************************************************
77  *              MCIWndCreate            [MSVFW32.@]
78  *              MCIWndCreateA           [MSVFW32.@]
79  */
80 HWND VFWAPIV MCIWndCreateA(HWND hwndParent, HINSTANCE hInstance,
81                            DWORD dwStyle, LPCSTR szFile)
82 {
83    DWORD        wndStyle;
84    MCIWndInfo*  mwi;
85
86    TRACE("%p %p %lx %s\n", hwndParent, hInstance, dwStyle, szFile);
87
88    MCIWndRegisterClass(hInstance);
89
90    mwi = HeapAlloc(GetProcessHeap(), 0, sizeof(*mwi));
91    if (!mwi) return 0;
92
93    mwi->dwStyle = dwStyle;
94    if (szFile)
95      mwi->lpName = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(szFile) + 1), szFile);
96    else
97      mwi->lpName = NULL;
98    mwi->uTimer = 0;
99
100    wndStyle = ((hwndParent) ? (WS_CHILD|WS_BORDER) : WS_OVERLAPPEDWINDOW) |
101               WS_VISIBLE | (dwStyle & 0xFFFF0000);
102
103    if (CreateWindowExA(0, "MCIWndClass", NULL, wndStyle,
104                        CW_USEDEFAULT, CW_USEDEFAULT,
105                        CW_USEDEFAULT, CW_USEDEFAULT,
106                        hwndParent, NULL, hInstance, mwi))
107       return mwi->hWnd;
108
109    if(mwi->lpName) HeapFree(GetProcessHeap(), 0, mwi->lpName);
110    HeapFree(GetProcessHeap(), 0, mwi);
111    return 0;
112 }
113
114 /***********************************************************************
115  *              MCIWndCreateW                           [MSVFW32.@]
116  */
117 HWND VFWAPIV MCIWndCreateW(HWND hwndParent, HINSTANCE hInstance,
118                            DWORD dwStyle, LPCWSTR szFile)
119 {
120    FIXME("%p %p %lx %s\n", hwndParent, hInstance, dwStyle, debugstr_w(szFile));
121
122    MCIWndRegisterClass(hInstance);
123
124    return 0;
125 }
126
127 static DWORD MCIWND_GetStatus(MCIWndInfo* mwi)
128 {
129    MCI_DGV_STATUS_PARMSA        mdsp;
130
131    memset(&mdsp, 0, sizeof(mdsp));
132    mdsp.dwItem = MCI_STATUS_MODE;
133    if (mciSendCommandA(mwi->mci, MCI_STATUS, MCI_WAIT|MCI_STATUS_ITEM, (DWORD)&mdsp))
134       return MCI_MODE_NOT_READY;
135    if (mdsp.dwReturn == MCI_MODE_STOP && mwi->uTimer) {
136       TRACE("Killing timer\n");
137       KillTimer(mwi->hWnd, 0);
138       mwi->uTimer = 0;
139    }
140    return mdsp.dwReturn;
141 }
142
143 static DWORD MCIWND_Get(MCIWndInfo* mwi, DWORD what)
144 {
145    MCI_DGV_STATUS_PARMSA        mdsp;
146
147    memset(&mdsp, 0, sizeof(mdsp));
148    mdsp.dwItem = what;
149    if (mciSendCommandA(mwi->mci, MCI_STATUS, MCI_WAIT|MCI_STATUS_ITEM, (DWORD)&mdsp))
150       return 0;
151    return mdsp.dwReturn;
152 }
153
154 static void MCIWND_SetText(MCIWndInfo* mwi)
155 {
156    char buffer[1024];
157
158    if (mwi->dwStyle & MCIWNDF_SHOWNAME) {
159       strcpy(buffer, mwi->lpName);
160    } else {
161       *buffer = 0;
162    }
163
164    if (mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) {
165       if (*buffer) strcat(buffer, " ");
166       strcat(buffer, "(");
167    }
168
169    if (mwi->dwStyle & MCIWNDF_SHOWPOS) {
170       sprintf(buffer + strlen(buffer), "%ld", MCIWND_Get(mwi, MCI_STATUS_POSITION));
171    }
172
173    if ((mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) == (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) {
174       strcat(buffer, " - ");
175    }
176
177    if (mwi->dwStyle & MCIWNDF_SHOWMODE) {
178       switch (MCIWND_GetStatus(mwi)) {
179       case MCI_MODE_NOT_READY:  strcat(buffer, "not ready");    break;
180       case MCI_MODE_PAUSE:      strcat(buffer, "paused");       break;
181       case MCI_MODE_PLAY:       strcat(buffer, "playing");      break;
182       case MCI_MODE_STOP:       strcat(buffer, "stopped");      break;
183       case MCI_MODE_OPEN:       strcat(buffer, "open");         break;
184       case MCI_MODE_RECORD:     strcat(buffer, "recording");    break;
185       case MCI_MODE_SEEK:       strcat(buffer, "seeking");      break;
186       default:                  strcat(buffer, "???");          break;
187       }
188    }
189    if (mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) {
190       strcat(buffer, " )");
191    }
192    TRACE("=> '%s'\n", buffer);
193    SetWindowTextA(mwi->hWnd, buffer);
194 }
195
196 static void MCIWND_Create(HWND hWnd, LPCREATESTRUCTA cs)
197 {
198    MCI_DGV_OPEN_PARMSA  mdopn;
199    MCI_DGV_RECT_PARMS   mdrct;
200    MMRESULT             mmr;
201    int                  cx, cy;
202    HWND                 hChld;
203    MCIWndInfo*          mwi = (MCIWndInfo*)cs->lpCreateParams;
204
205    SetWindowLongA(hWnd, 0, (LPARAM)mwi);
206    mwi->hWnd = hWnd;
207
208    /* now open MCI player for AVI file */
209    memset(&mdopn, 0, sizeof(mdopn));
210    mdopn.lpstrElementName = mwi->lpName;
211    mdopn.dwStyle = WS_VISIBLE|WS_CHILD;
212    mdopn.hWndParent = hWnd;
213
214    mmr = mciSendCommandA(0,  MCI_OPEN, MCI_OPEN_ELEMENT|MCI_DGV_OPEN_PARENT|MCI_DGV_OPEN_WS, (LPARAM)&mdopn);
215    if (mmr) {
216       MessageBoxA(GetTopWindow(hWnd), "Cannot open file", "MciWnd", MB_OK);
217       return;
218    }
219    mwi->mci = mdopn.wDeviceID;
220
221    /* grab AVI window size */
222    memset(&mdrct, 0, sizeof(mdrct));
223    mmr = mciSendCommandA(mwi->mci,  MCI_WHERE, MCI_DGV_WHERE_DESTINATION, (LPARAM)&mdrct);
224    if (mmr) {
225       WARN("Cannot get window rect\n");
226       return;
227    }
228    cx = mdrct.rc.right - mdrct.rc.left;
229    cy = mdrct.rc.bottom - mdrct.rc.top;
230
231    AdjustWindowRect(&mdrct.rc, GetWindowLongA(hWnd, GWL_STYLE), FALSE);
232    SetWindowPos(hWnd, 0, 0, 0, mdrct.rc.right - mdrct.rc.left,
233                 mdrct.rc.bottom - mdrct.rc.top + 32, SWP_NOMOVE|SWP_NOZORDER);
234
235    /* adding the other elements: play/stop button, menu button, status */
236    hChld = CreateWindowExA(0, "BUTTON", "Play", WS_CHILD|WS_VISIBLE, 0, cy, 32, 32,
237                            hWnd, (HMENU)CTL_PLAYSTOP,
238                            (HINSTANCE)GetWindowLongA(hWnd, GWL_HINSTANCE), 0L);
239    TRACE("Get Button1: %p\n", hChld);
240    hChld = CreateWindowExA(0, "BUTTON", "Menu", WS_CHILD|WS_VISIBLE, 32, cy, 32, 32,
241                            hWnd, (HMENU)CTL_MENU,
242                            (HINSTANCE)GetWindowLongA(hWnd, GWL_HINSTANCE), 0L);
243    TRACE("Get Button2: %p\n", hChld);
244    hChld = CreateWindowExA(0, TRACKBAR_CLASSA, "", WS_CHILD|WS_VISIBLE, 64, cy, cx - 64, 32,
245                            hWnd, (HMENU)CTL_TRACKBAR,
246                            (HINSTANCE)GetWindowLongA(hWnd, GWL_HINSTANCE), 0L);
247    TRACE("Get status: %p\n", hChld);
248    SendMessageA(hChld, TBM_SETRANGEMIN, 0L, 0L);
249    SendMessageA(hChld, TBM_SETRANGEMAX, 1L, MCIWND_Get(mwi, MCI_STATUS_LENGTH));
250
251    /* FIXME: no need to set it if child window */
252    MCIWND_SetText(mwi);
253 }
254
255 static void MCIWND_Paint(MCIWndInfo* mwi, WPARAM wParam)
256 {
257    HDC          hdc;
258    PAINTSTRUCT  ps;
259
260    hdc = (wParam) ? (HDC)wParam : BeginPaint(mwi->hWnd, &ps);
261    /* something to do ? */
262    if (!wParam) EndPaint(mwi->hWnd, &ps);
263 }
264
265 static void MCIWND_ToggleState(MCIWndInfo* mwi)
266 {
267    MCI_GENERIC_PARMS    mgp;
268    MCI_DGV_PLAY_PARMS   mdply;
269
270    memset(&mgp, 0, sizeof(mgp));
271    memset(&mdply, 0, sizeof(mdply));
272
273    switch (MCIWND_GetStatus(mwi)) {
274    case MCI_MODE_NOT_READY:
275    case MCI_MODE_RECORD:
276    case MCI_MODE_SEEK:
277    case MCI_MODE_OPEN:
278       TRACE("Cannot do much...\n");
279       break;
280    case MCI_MODE_PAUSE:
281       mciSendCommandA(mwi->mci, MCI_RESUME, MCI_WAIT, (LPARAM)&mgp);
282       break;
283    case MCI_MODE_PLAY:
284       mciSendCommandA(mwi->mci, MCI_PAUSE, MCI_WAIT, (LPARAM)&mgp);
285       break;
286    case MCI_MODE_STOP:
287       mdply.dwFrom = 0L;
288       mciSendCommandA(mwi->mci, MCI_PLAY, MCI_FROM, (LPARAM)&mdply);
289       mwi->uTimer = SetTimer(mwi->hWnd, 0, 333, 0L);
290       TRACE("Timer=%u\n", mwi->uTimer);
291       break;
292    }
293 }
294
295 static LRESULT MCIWND_Command(MCIWndInfo* mwi, WPARAM wParam, LPARAM lParam)
296 {
297    switch (LOWORD(wParam)) {
298    case CTL_PLAYSTOP:   MCIWND_ToggleState(mwi);        break;
299    case CTL_MENU:
300    case CTL_TRACKBAR:
301    default:
302       MessageBoxA(0, "ooch", "NIY", MB_OK);
303    }
304    return 0L;
305 }
306
307 static void MCIWND_Timer(MCIWndInfo* mwi, WPARAM wParam, LPARAM lParam)
308 {
309    TRACE("%ld\n", MCIWND_Get(mwi, MCI_STATUS_POSITION));
310    SendDlgItemMessageA(mwi->hWnd, CTL_TRACKBAR, TBM_SETPOS, 1, MCIWND_Get(mwi, MCI_STATUS_POSITION));
311    MCIWND_SetText(mwi);
312 }
313
314 static void MCIWND_Close(MCIWndInfo* mwi)
315 {
316    MCI_GENERIC_PARMS    mgp;
317
318    memset(&mgp, 0, sizeof(mgp));
319
320    mciSendCommandA(mwi->mci, MCI_CLOSE, 0, (LPARAM)&mgp);
321 }
322
323 static LRESULT WINAPI   MCIWndProc(HWND hWnd, UINT wMsg, WPARAM lParam1, LPARAM lParam2)
324 {
325    MCIWndInfo*  mwi = (MCIWndInfo*)GetWindowLongA(hWnd, 0);
326
327    if (mwi || wMsg == WM_CREATE) {
328       switch (wMsg) {
329       case WM_CREATE:
330          MCIWND_Create(hWnd, (CREATESTRUCTA*)lParam2);
331          return 0;
332       case WM_DESTROY:
333          MCIWND_Close(mwi);
334          HeapFree(GetProcessHeap(), 0, mwi->lpName);
335          HeapFree(GetProcessHeap(), 0, mwi);
336          break;
337       case WM_PAINT:
338          MCIWND_Paint(mwi, lParam1);
339          break;
340       case WM_COMMAND:
341          return MCIWND_Command(mwi, lParam1, lParam2);
342       case WM_TIMER:
343          MCIWND_Timer(mwi, lParam1, lParam2);
344          return TRUE;
345       }
346    }
347
348    return DefWindowProcA(hWnd, wMsg, lParam1, lParam2);
349 }