Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
3e18c250
Commit
3e18c250
authored
Oct 23, 1999
by
Eric Pouech
Committed by
Alexandre Julliard
Oct 23, 1999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
First working version.
parent
aa67ac90
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
549 additions
and
148 deletions
+549
-148
animate.c
dlls/comctl32/animate.c
+514
-146
animate.h
include/animate.h
+35
-2
No files found.
dlls/comctl32/animate.c
View file @
3e18c250
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
/*
* Animation control
*
* Copyright 1998, 1999 Eric Kohl
* 1999 Eric Pouech
*
* NOTES
* This is just a dummy control. An author is needed! Any volunteers?
* I will only improve this control once in a while.
* Eric <ekohl@abo.rhein-zeitung.de>
*
* TODO:
* - All messages.
* - All notifications.
* - check for the 'rec ' list in some AVI files
* - implement some missing flags (ACS_TRANSPARENT and ACS_CENTER)
* - protection between service thread and wndproc messages handling
* concurrent access to infoPtr
*/
#include "winbase.h"
#include "commctrl.h"
#include "driver.h"
#include "animate.h"
#include "mmsystem.h"
#include "services.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL
(
animate
)
#define ANIMATE_GetInfoPtr(h
wnd) ((ANIMATE_INFO *)GetWindowLongA (hw
nd, 0))
#define ANIMATE_GetInfoPtr(h
Wnd) ((ANIMATE_INFO *)GetWindowLongA(hW
nd, 0))
static
void
ANIMATE_Notify
(
ANIMATE_INFO
*
infoPtr
,
UINT
notif
)
{
SendMessageA
(
GetParent
(
infoPtr
->
hWnd
),
WM_COMMAND
,
MAKEWPARAM
(
GetDlgCtrlID
(
infoPtr
->
hWnd
),
notif
),
(
LPARAM
)
infoPtr
->
hWnd
);
}
static
BOOL
ANIMATE_LoadResA
(
ANIMATE_INFO
*
infoPtr
,
HINSTANCE
hInst
,
LPSTR
lpName
)
static
BOOL
ANIMATE_LoadResA
(
ANIMATE_INFO
*
infoPtr
,
HINSTANCE
hInst
,
LPSTR
lpName
)
{
HRSRC
hrsrc
;
HGLOBAL
handle
;
MMIOINFO
mminfo
;
LPVOID
lpAvi
;
hrsrc
=
FindResourceA
(
hInst
,
lpName
,
"AVI"
);
hrsrc
=
FindResourceA
(
hInst
,
lpName
,
"AVI"
);
if
(
!
hrsrc
)
return
FALSE
;
handle
=
LoadResource
(
hInst
,
hrsrc
);
if
(
!
handle
)
infoPtr
->
hRes
=
LoadResource
(
hInst
,
hrsrc
);
if
(
!
infoPtr
->
hRes
)
return
FALSE
;
infoPtr
->
lpAvi
=
LockResource
(
handle
);
if
(
!
infoPtr
->
lpAvi
)
lpAvi
=
LockResource
(
infoPtr
->
hRes
);
if
(
!
lpAvi
)
return
FALSE
;
memset
(
&
mminfo
,
0
,
sizeof
(
mminfo
));
mminfo
.
fccIOProc
=
FOURCC_MEM
;
mminfo
.
pchBuffer
=
(
LPSTR
)
lpAvi
;
mminfo
.
cchBuffer
=
SizeofResource
(
hInst
,
hrsrc
);
infoPtr
->
hMMio
=
mmioOpenA
(
NULL
,
&
mminfo
,
MMIO_READ
);
if
(
!
infoPtr
->
hMMio
)
{
GlobalFree
((
HGLOBAL
)
lpAvi
);
return
FALSE
;
}
return
TRUE
;
}
static
BOOL
ANIMATE_LoadFileA
(
ANIMATE_INFO
*
infoPtr
,
LPSTR
lpName
)
static
BOOL
ANIMATE_LoadFileA
(
ANIMATE_INFO
*
infoPtr
,
LPSTR
lpName
)
{
HANDLE
handle
;
infoPtr
->
hMMio
=
mmioOpenA
((
LPSTR
)
lpName
,
NULL
,
MMIO_ALLOCBUF
|
MMIO_READ
|
MMIO_DENYWRITE
);
infoPtr
->
hFile
=
CreateFileA
(
lpName
,
GENERIC_READ
,
0
,
NULL
,
OPEN_EXISTING
,
FILE_ATTRIBUTE_NORMAL
,
0
);
if
(
!
infoPtr
->
hFile
)
if
(
!
infoPtr
->
hMMio
)
return
FALSE
;
handle
=
CreateFileMappingA
(
infoPtr
->
hFile
,
NULL
,
PAGE_READONLY
|
SEC_COMMIT
,
0
,
0
,
NULL
);
if
(
!
handle
)
{
CloseHandle
(
infoPtr
->
hFile
);
infoPtr
->
hFile
=
0
;
return
FALSE
;
return
TRUE
;
}
static
void
ANIMATE_Free
(
ANIMATE_INFO
*
infoPtr
)
{
if
(
infoPtr
->
hMMio
)
{
mmioClose
(
infoPtr
->
hMMio
,
0
);
if
(
infoPtr
->
hRes
)
{
FreeResource
(
infoPtr
->
hRes
);
infoPtr
->
hRes
=
0
;
}
if
(
infoPtr
->
lpIndex
)
{
HeapFree
(
GetProcessHeap
(),
0
,
infoPtr
->
lpIndex
);
infoPtr
->
lpIndex
=
NULL
;
}
if
(
infoPtr
->
hic
)
{
(
infoPtr
->
fnICClose
)(
infoPtr
->
hic
);
infoPtr
->
hic
=
0
;
}
if
(
infoPtr
->
inbih
)
{
HeapFree
(
GetProcessHeap
(),
0
,
infoPtr
->
inbih
);
infoPtr
->
inbih
=
NULL
;
}
if
(
infoPtr
->
outbih
)
{
HeapFree
(
GetProcessHeap
(),
0
,
infoPtr
->
outbih
);
infoPtr
->
outbih
=
NULL
;
}
HeapFree
(
GetProcessHeap
(),
0
,
infoPtr
->
indata
);
HeapFree
(
GetProcessHeap
(),
0
,
infoPtr
->
outdata
);
infoPtr
->
indata
=
infoPtr
->
outdata
=
NULL
;
infoPtr
->
hWnd
=
0
;
infoPtr
->
hMMio
=
0
;
memset
(
&
infoPtr
->
mah
,
0
,
sizeof
(
infoPtr
->
mah
));
memset
(
&
infoPtr
->
ash
,
0
,
sizeof
(
infoPtr
->
ash
));
infoPtr
->
nFromFrame
=
infoPtr
->
nToFrame
=
infoPtr
->
nLoop
=
infoPtr
->
currFrame
=
0
;
}
}
infoPtr
->
lpAvi
=
MapViewOfFile
(
handle
,
FILE_MAP_READ
,
0
,
0
,
0
);
if
(
!
infoPtr
->
lpAvi
)
{
CloseHandle
(
infoPtr
->
hFile
);
infoPtr
->
hFile
=
0
;
return
FALSE
;
static
LRESULT
ANIMATE_DoStop
(
ANIMATE_INFO
*
infoPtr
)
{
/* should stop playing */
if
(
infoPtr
->
hService
)
{
SERVICE_Delete
(
infoPtr
->
hService
);
infoPtr
->
hService
=
0
;
}
if
(
infoPtr
->
uTimer
)
{
KillTimer
(
infoPtr
->
hWnd
,
infoPtr
->
uTimer
);
infoPtr
->
uTimer
=
0
;
}
ANIMATE_Notify
(
infoPtr
,
ACN_STOP
);
return
TRUE
;
}
static
LRESULT
ANIMATE_PaintFrame
(
ANIMATE_INFO
*
infoPtr
,
HDC
hDC
)
{
if
(
hDC
)
{
StretchDIBits
(
hDC
,
0
,
0
,
infoPtr
->
outbih
->
biWidth
,
infoPtr
->
outbih
->
biHeight
,
0
,
0
,
infoPtr
->
outbih
->
biWidth
,
infoPtr
->
outbih
->
biHeight
,
infoPtr
->
outdata
,
(
LPBITMAPINFO
)
infoPtr
->
outbih
,
DIB_RGB_COLORS
,
SRCCOPY
);
}
return
TRUE
;
}
static
VOID
ANIMATE_Free
(
ANIMATE_INFO
*
infoPtr
)
static
LRESULT
ANIMATE_DrawFrame
(
ANIMATE_INFO
*
infoPtr
)
{
if
(
infoPtr
->
hFile
)
{
UnmapViewOfFile
(
infoPtr
->
lpAvi
);
CloseHandle
(
infoPtr
->
hFile
);
infoPtr
->
lpAvi
=
NULL
;
HDC
hDC
;
TRACE
(
"Drawing frame %d (loop %d)
\n
"
,
infoPtr
->
currFrame
,
infoPtr
->
nLoop
);
EnterCriticalSection
(
&
infoPtr
->
cs
);
mmioSeek
(
infoPtr
->
hMMio
,
infoPtr
->
lpIndex
[
infoPtr
->
currFrame
],
SEEK_SET
);
mmioRead
(
infoPtr
->
hMMio
,
infoPtr
->
indata
,
infoPtr
->
ash
.
dwSuggestedBufferSize
);
if
((
infoPtr
->
fnICDecompress
)(
infoPtr
->
hic
,
0
,
infoPtr
->
inbih
,
infoPtr
->
indata
,
infoPtr
->
outbih
,
infoPtr
->
outdata
)
!=
ICERR_OK
)
{
LeaveCriticalSection
(
&
infoPtr
->
cs
);
WARN
(
"Decompression error
\n
"
);
return
FALSE
;
}
else
{
GlobalFree
((
HGLOBAL
)
infoPtr
->
lpAvi
);
infoPtr
->
lpAvi
=
NULL
;
if
((
hDC
=
GetDC
(
infoPtr
->
hWnd
))
!=
0
)
{
ANIMATE_PaintFrame
(
infoPtr
,
hDC
);
ReleaseDC
(
infoPtr
->
hWnd
,
hDC
);
}
if
(
infoPtr
->
currFrame
++
>=
infoPtr
->
nToFrame
)
{
infoPtr
->
currFrame
=
infoPtr
->
nFromFrame
;
if
(
infoPtr
->
nLoop
!=
-
1
)
{
if
(
--
infoPtr
->
nLoop
==
0
)
{
ANIMATE_DoStop
(
infoPtr
);
}
}
}
LeaveCriticalSection
(
&
infoPtr
->
cs
);
return
TRUE
;
}
static
void
CALLBACK
ANIMATE_ServiceCallback
(
ULONG_PTR
ptr_
)
{
ANIMATE_INFO
*
infoPtr
=
(
ANIMATE_INFO
*
)
ptr_
;
EnterCriticalSection
(
&
infoPtr
->
cs
);
ANIMATE_DrawFrame
(
infoPtr
);
LeaveCriticalSection
(
&
infoPtr
->
cs
);
}
static
VOID
ANIMATE_GetAviInfo
(
ANIMATE_INFO
*
infoPtr
)
static
LRESULT
ANIMATE_Play
(
HWND
hWnd
,
WPARAM
wParam
,
LPARAM
lParam
)
{
ANIMATE_INFO
*
infoPtr
=
ANIMATE_GetInfoPtr
(
hWnd
);
/* nothing opened */
if
(
!
infoPtr
->
hMMio
)
return
FALSE
;
if
(
infoPtr
->
hService
||
infoPtr
->
uTimer
)
{
FIXME
(
"Already playing ? what should I do ??
\n
"
);
ANIMATE_DoStop
(
infoPtr
);
}
infoPtr
->
nFromFrame
=
(
INT
)
LOWORD
(
lParam
);
infoPtr
->
nToFrame
=
(
INT
)
HIWORD
(
lParam
);
infoPtr
->
nLoop
=
(
INT
)
wParam
;
if
(
infoPtr
->
nToFrame
==
0xFFFF
)
infoPtr
->
nToFrame
=
infoPtr
->
mah
.
dwTotalFrames
-
1
;
TRACE
(
"(repeat=%d from=%d to=%d);
\n
"
,
infoPtr
->
nLoop
,
infoPtr
->
nFromFrame
,
infoPtr
->
nToFrame
);
if
(
infoPtr
->
nFromFrame
>=
infoPtr
->
nToFrame
||
infoPtr
->
nToFrame
>=
infoPtr
->
mah
.
dwTotalFrames
)
return
FALSE
;
infoPtr
->
currFrame
=
infoPtr
->
nFromFrame
;
if
(
GetWindowLongA
(
hWnd
,
GWL_STYLE
)
&
ACS_TIMER
)
{
TRACE
(
"Using a timer
\n
"
);
/* create a timer to display AVI */
infoPtr
->
uTimer
=
SetTimer
(
hWnd
,
1
,
infoPtr
->
mah
.
dwMicroSecPerFrame
/
1000
,
NULL
);
}
else
{
TRACE
(
"Using the service thread
\n
"
);
/* time is in s */
infoPtr
->
hService
=
SERVICE_AddTimer
(
infoPtr
->
mah
.
dwMicroSecPerFrame
,
ANIMATE_ServiceCallback
,
(
DWORD
)
infoPtr
);
}
ANIMATE_Notify
(
infoPtr
,
ACN_START
);
return
TRUE
;
}
static
LRESULT
ANIMATE_OpenA
(
HWND
hwnd
,
WPARAM
wParam
,
LPARAM
lParam
)
static
BOOL
ANIMATE_GetAviInfo
(
ANIMATE_INFO
*
infoPtr
)
{
ANIMATE_INFO
*
infoPtr
=
ANIMATE_GetInfoPtr
(
hwnd
);
HINSTANCE
hInstance
=
(
HINSTANCE
)
wParam
;
MMCKINFO
ckMainRIFF
;
MMCKINFO
mmckHead
;
MMCKINFO
mmckList
;
MMCKINFO
mmckInfo
;
DWORD
numFrame
;
DWORD
insize
;
if
(
mmioDescend
(
infoPtr
->
hMMio
,
&
ckMainRIFF
,
NULL
,
0
)
!=
0
)
{
WARN
(
"Can't find 'RIFF' chunk
\n
"
);
return
FALSE
;
}
ANIMATE_Free
(
infoPtr
);
if
((
ckMainRIFF
.
ckid
!=
FOURCC_RIFF
)
||
(
ckMainRIFF
.
fccType
!=
mmioFOURCC
(
'A'
,
'V'
,
'I'
,
' '
)))
{
WARN
(
"Can't find 'AVI ' chunk
\n
"
);
return
FALSE
;
}
if
(
!
lParam
)
{
TRACE
(
"closing avi!
\n
"
);
return
TRUE
;
mmckHead
.
fccType
=
mmioFOURCC
(
'h'
,
'd'
,
'r'
,
'l'
);
if
(
mmioDescend
(
infoPtr
->
hMMio
,
&
mmckHead
,
&
ckMainRIFF
,
MMIO_FINDLIST
)
!=
0
)
{
WARN
(
"Can't find 'hdrl' list
\n
"
);
return
FALSE
;
}
if
(
HIWORD
(
lParam
))
{
FIXME
(
"(
\"
%s
\"
) empty stub!
\n
"
,
(
LPSTR
)
lParam
);
mmckInfo
.
ckid
=
mmioFOURCC
(
'a'
,
'v'
,
'i'
,
'h'
);
if
(
mmioDescend
(
infoPtr
->
hMMio
,
&
mmckInfo
,
&
mmckHead
,
MMIO_FINDCHUNK
)
!=
0
)
{
WARN
(
"Can't find 'avih' chunk
\n
"
);
return
FALSE
;
}
if
(
ANIMATE_LoadResA
(
infoPtr
,
hInstance
,
(
LPSTR
)
lParam
))
{
mmioRead
(
infoPtr
->
hMMio
,
(
LPSTR
)
&
infoPtr
->
mah
,
sizeof
(
infoPtr
->
mah
));
TRACE
(
"mah.dwMicroSecPerFrame=%ld
\n
"
,
infoPtr
->
mah
.
dwMicroSecPerFrame
);
TRACE
(
"mah.dwMaxBytesPerSec=%ld
\n
"
,
infoPtr
->
mah
.
dwMaxBytesPerSec
);
TRACE
(
"mah.dwPaddingGranularity=%ld
\n
"
,
infoPtr
->
mah
.
dwPaddingGranularity
);
TRACE
(
"mah.dwFlags=%ld
\n
"
,
infoPtr
->
mah
.
dwFlags
);
TRACE
(
"mah.dwTotalFrames=%ld
\n
"
,
infoPtr
->
mah
.
dwTotalFrames
);
TRACE
(
"mah.dwInitialFrames=%ld
\n
"
,
infoPtr
->
mah
.
dwInitialFrames
);
TRACE
(
"mah.dwStreams=%ld
\n
"
,
infoPtr
->
mah
.
dwStreams
);
TRACE
(
"mah.dwSuggestedBufferSize=%ld
\n
"
,
infoPtr
->
mah
.
dwSuggestedBufferSize
);
TRACE
(
"mah.dwWidth=%ld
\n
"
,
infoPtr
->
mah
.
dwWidth
);
TRACE
(
"mah.dwHeight=%ld
\n
"
,
infoPtr
->
mah
.
dwHeight
);
mmioAscend
(
infoPtr
->
hMMio
,
&
mmckInfo
,
0
);
mmckList
.
fccType
=
mmioFOURCC
(
's'
,
't'
,
'r'
,
'l'
);
if
(
mmioDescend
(
infoPtr
->
hMMio
,
&
mmckList
,
&
mmckHead
,
MMIO_FINDLIST
)
!=
0
)
{
WARN
(
"Can't find 'strl' list
\n
"
);
return
FALSE
;
}
FIXME
(
"AVI resource found!
\n
"
);
mmckInfo
.
ckid
=
mmioFOURCC
(
's'
,
't'
,
'r'
,
'h'
);
if
(
mmioDescend
(
infoPtr
->
hMMio
,
&
mmckInfo
,
&
mmckList
,
MMIO_FINDCHUNK
)
!=
0
)
{
WARN
(
"Can't find 'strh' chunk
\n
"
);
return
FALSE
;
}
mmioRead
(
infoPtr
->
hMMio
,
(
LPSTR
)
&
infoPtr
->
ash
,
sizeof
(
infoPtr
->
ash
));
TRACE
(
"ash.fccType='%c%c%c%c'
\n
"
,
LOBYTE
(
LOWORD
(
infoPtr
->
ash
.
fccType
)),
HIBYTE
(
LOWORD
(
infoPtr
->
ash
.
fccType
)),
LOBYTE
(
HIWORD
(
infoPtr
->
ash
.
fccType
)),
HIBYTE
(
HIWORD
(
infoPtr
->
ash
.
fccType
)));
TRACE
(
"ash.fccHandler='%c%c%c%c'
\n
"
,
LOBYTE
(
LOWORD
(
infoPtr
->
ash
.
fccHandler
)),
HIBYTE
(
LOWORD
(
infoPtr
->
ash
.
fccHandler
)),
LOBYTE
(
HIWORD
(
infoPtr
->
ash
.
fccHandler
)),
HIBYTE
(
HIWORD
(
infoPtr
->
ash
.
fccHandler
)));
TRACE
(
"ash.dwFlags=%ld
\n
"
,
infoPtr
->
ash
.
dwFlags
);
TRACE
(
"ash.wPriority=%d
\n
"
,
infoPtr
->
ash
.
wPriority
);
TRACE
(
"ash.wLanguage=%d
\n
"
,
infoPtr
->
ash
.
wLanguage
);
TRACE
(
"ash.dwInitialFrames=%ld
\n
"
,
infoPtr
->
ash
.
dwInitialFrames
);
TRACE
(
"ash.dwScale=%ld
\n
"
,
infoPtr
->
ash
.
dwScale
);
TRACE
(
"ash.dwRate=%ld
\n
"
,
infoPtr
->
ash
.
dwRate
);
TRACE
(
"ash.dwStart=%ld
\n
"
,
infoPtr
->
ash
.
dwStart
);
TRACE
(
"ash.dwLength=%ld
\n
"
,
infoPtr
->
ash
.
dwLength
);
TRACE
(
"ash.dwSuggestedBufferSize=%ld
\n
"
,
infoPtr
->
ash
.
dwSuggestedBufferSize
);
TRACE
(
"ash.dwQuality=%ld
\n
"
,
infoPtr
->
ash
.
dwQuality
);
TRACE
(
"ash.dwSampleSize=%ld
\n
"
,
infoPtr
->
ash
.
dwSampleSize
);
TRACE
(
"ash.rcFrame=(%d,%d,%d,%d)
\n
"
,
infoPtr
->
ash
.
rcFrame
.
top
,
infoPtr
->
ash
.
rcFrame
.
left
,
infoPtr
->
ash
.
rcFrame
.
bottom
,
infoPtr
->
ash
.
rcFrame
.
right
);
mmioAscend
(
infoPtr
->
hMMio
,
&
mmckInfo
,
0
);
mmckInfo
.
ckid
=
mmioFOURCC
(
's'
,
't'
,
'r'
,
'f'
);
if
(
mmioDescend
(
infoPtr
->
hMMio
,
&
mmckInfo
,
&
mmckList
,
MMIO_FINDCHUNK
)
!=
0
)
{
WARN
(
"Can't find 'strh' chunk
\n
"
);
return
FALSE
;
}
else
{
FIXME
(
"No AVI resource found!
\n
"
);
if
(
ANIMATE_LoadFileA
(
infoPtr
,
(
LPSTR
)
lParam
))
{
FIXME
(
"AVI file found!
\n
"
);
infoPtr
->
inbih
=
HeapAlloc
(
GetProcessHeap
(),
0
,
mmckInfo
.
cksize
);
if
(
!
infoPtr
->
inbih
)
{
WARN
(
"Can't alloc input BIH
\n
"
);
return
FALSE
;
}
else
{
FIXME
(
"No AVI file found!
\n
"
);
mmioRead
(
infoPtr
->
hMMio
,
(
LPSTR
)
infoPtr
->
inbih
,
mmckInfo
.
cksize
);
TRACE
(
"bih.biSize=%ld
\n
"
,
infoPtr
->
inbih
->
biSize
);
TRACE
(
"bih.biWidth=%ld
\n
"
,
infoPtr
->
inbih
->
biWidth
);
TRACE
(
"bih.biHeight=%ld
\n
"
,
infoPtr
->
inbih
->
biHeight
);
TRACE
(
"bih.biPlanes=%d
\n
"
,
infoPtr
->
inbih
->
biPlanes
);
TRACE
(
"bih.biBitCount=%d
\n
"
,
infoPtr
->
inbih
->
biBitCount
);
TRACE
(
"bih.biCompression=%ld
\n
"
,
infoPtr
->
inbih
->
biCompression
);
TRACE
(
"bih.biSizeImage=%ld
\n
"
,
infoPtr
->
inbih
->
biSizeImage
);
TRACE
(
"bih.biXPelsPerMeter=%ld
\n
"
,
infoPtr
->
inbih
->
biXPelsPerMeter
);
TRACE
(
"bih.biYPelsPerMeter=%ld
\n
"
,
infoPtr
->
inbih
->
biYPelsPerMeter
);
TRACE
(
"bih.biClrUsed=%ld
\n
"
,
infoPtr
->
inbih
->
biClrUsed
);
TRACE
(
"bih.biClrImportant=%ld
\n
"
,
infoPtr
->
inbih
->
biClrImportant
);
mmioAscend
(
infoPtr
->
hMMio
,
&
mmckInfo
,
0
);
mmioAscend
(
infoPtr
->
hMMio
,
&
mmckList
,
0
);
#if 0
/* an AVI has 0 or 1 video stream, and to be animated should not contain
* an audio stream, so only one strl is allowed
*/
mmckList.fccType = mmioFOURCC('s', 't', 'r', 'l');
if (mmioDescend(infoPtr->hMMio, &mmckList, &mmckHead, MMIO_FINDLIST) == 0) {
WARN("There should be a single 'strl' list\n");
return FALSE;
}
#endif
mmioAscend
(
infoPtr
->
hMMio
,
&
mmckHead
,
0
);
/* no need to read optional JUNK chunk */
mmckList
.
fccType
=
mmioFOURCC
(
'm'
,
'o'
,
'v'
,
'i'
);
if
(
mmioDescend
(
infoPtr
->
hMMio
,
&
mmckList
,
&
ckMainRIFF
,
MMIO_FINDLIST
)
!=
0
)
{
WARN
(
"Can't find 'movi' list
\n
"
);
return
FALSE
;
}
/* FIXME: should handle the 'rec ' LIST when present */
infoPtr
->
lpIndex
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
infoPtr
->
mah
.
dwTotalFrames
*
sizeof
(
DWORD
));
if
(
!
infoPtr
->
lpIndex
)
{
WARN
(
"Can't alloc index array
\n
"
);
return
FALSE
;
}
else
{
FIXME
(
"(%u) empty stub!
\n
"
,
(
WORD
)
LOWORD
(
lParam
));
if
(
ANIMATE_LoadResA
(
infoPtr
,
hInstance
,
MAKEINTRESOURCEA
((
INT
)
lParam
)))
{
FIXME
(
"AVI resource found!
\n
"
);
numFrame
=
insize
=
0
;
while
(
mmioDescend
(
infoPtr
->
hMMio
,
&
mmckInfo
,
&
mmckList
,
0
)
==
0
&&
numFrame
<
infoPtr
->
mah
.
dwTotalFrames
)
{
infoPtr
->
lpIndex
[
numFrame
]
=
mmckInfo
.
dwDataOffset
;
if
(
insize
<
mmckInfo
.
cksize
)
insize
=
mmckInfo
.
cksize
;
numFrame
++
;
mmioAscend
(
infoPtr
->
hMMio
,
&
mmckInfo
,
0
);
}
else
{
FIXME
(
"No AVI resource found!
\n
"
);
if
(
numFrame
!=
infoPtr
->
mah
.
dwTotalFrames
)
{
WARN
(
"Found %ld frames (/%ld)
\n
"
,
numFrame
,
infoPtr
->
mah
.
dwTotalFrames
);
return
FALSE
;
}
if
(
insize
>
infoPtr
->
ash
.
dwSuggestedBufferSize
)
{
WARN
(
"insize=%ld suggestedSize=%ld
\n
"
,
insize
,
infoPtr
->
ash
.
dwSuggestedBufferSize
);
infoPtr
->
ash
.
dwSuggestedBufferSize
=
insize
;
}
ANIMATE_GetAviInfo
(
infoPtr
);
infoPtr
->
indata
=
HeapAlloc
(
GetProcessHeap
(),
0
,
infoPtr
->
ash
.
dwSuggestedBufferSize
);
if
(
!
infoPtr
->
indata
)
{
WARN
(
"Can't alloc input buffer
\n
"
);
return
FALSE
;
}
return
TRUE
;
}
/* << ANIMATE_Open32W >> */
static
BOOL
ANIMATE_GetAviCodec
(
ANIMATE_INFO
*
infoPtr
)
{
DWORD
outSize
;
infoPtr
->
hic
=
(
infoPtr
->
fnICOpen
)(
ICTYPE_VIDEO
,
infoPtr
->
ash
.
fccHandler
,
ICMODE_DECOMPRESS
);
if
(
!
infoPtr
->
hic
)
{
WARN
(
"Can't load codec for the file
\n
"
);
return
FALSE
;
}
outSize
=
(
infoPtr
->
fnICSendMessage
)(
infoPtr
->
hic
,
ICM_DECOMPRESS_GET_FORMAT
,
(
DWORD
)
infoPtr
->
inbih
,
0L
);
infoPtr
->
outbih
=
HeapAlloc
(
GetProcessHeap
(),
0
,
outSize
);
if
(
!
infoPtr
->
outbih
)
{
WARN
(
"Can't alloc output BIH
\n
"
);
return
FALSE
;
}
if
((
infoPtr
->
fnICSendMessage
)(
infoPtr
->
hic
,
ICM_DECOMPRESS_GET_FORMAT
,
(
DWORD
)
infoPtr
->
inbih
,
(
DWORD
)
infoPtr
->
outbih
)
!=
ICERR_OK
)
{
WARN
(
"Can't get output BIH
\n
"
);
return
FALSE
;
}
static
LRESULT
ANIMATE_Play
(
HWND
hwnd
,
WPARAM
wParam
,
LPARAM
lParam
)
infoPtr
->
outdata
=
HeapAlloc
(
GetProcessHeap
(),
0
,
infoPtr
->
outbih
->
biSizeImage
);
if
(
!
infoPtr
->
outdata
)
{
WARN
(
"Can't alloc output buffer
\n
"
);
return
FALSE
;
}
if
((
infoPtr
->
fnICSendMessage
)(
infoPtr
->
hic
,
ICM_DECOMPRESS_BEGIN
,
(
DWORD
)
infoPtr
->
inbih
,
(
DWORD
)
infoPtr
->
outbih
)
!=
ICERR_OK
)
{
WARN
(
"Can't begin decompression
\n
"
);
return
FALSE
;
}
return
TRUE
;
}
static
LRESULT
ANIMATE_OpenA
(
HWND
hWnd
,
WPARAM
wParam
,
LPARAM
lParam
)
{
/* ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hwnd); */
INT
nFrom
=
(
INT
)
LOWORD
(
lParam
);
INT
nTo
=
(
INT
)
HIWORD
(
lParam
);
INT
nRepeat
=
(
INT
)
wParam
;
ANIMATE_INFO
*
infoPtr
=
ANIMATE_GetInfoPtr
(
hWnd
);
HINSTANCE
hInstance
=
(
HINSTANCE
)
wParam
;
#if 0
/* nothing opened */
if (...)
ANIMATE_Free
(
infoPtr
);
if
(
!
lParam
)
{
TRACE
(
"Closing avi!
\n
"
);
return
TRUE
;
}
if
(
!
hInstance
)
hInstance
=
GetWindowLongA
(
hWnd
,
GWL_HINSTANCE
);
if
(
HIWORD
(
lParam
))
{
TRACE
(
"(
\"
%s
\"
);
\n
"
,
(
LPSTR
)
lParam
);
if
(
!
ANIMATE_LoadResA
(
infoPtr
,
hInstance
,
(
LPSTR
)
lParam
))
{
TRACE
(
"No AVI resource found!
\n
"
);
if
(
!
ANIMATE_LoadFileA
(
infoPtr
,
(
LPSTR
)
lParam
))
{
WARN
(
"No AVI file found!
\n
"
);
return
FALSE
;
#endif
}
}
}
else
{
TRACE
(
"(%u);
\n
"
,
(
WORD
)
LOWORD
(
lParam
));
if
(
nRepeat
==
-
1
)
{
if
(
!
ANIMATE_LoadResA
(
infoPtr
,
hInstance
,
MAKEINTRESOURCEA
((
INT
)
lParam
)))
{
WARN
(
"No AVI resource found!
\n
"
);
return
FALSE
;
}
}
FIXME
(
"(loop from=%d to=%d) empty stub!
\n
"
,
nFrom
,
nTo
);
if
(
!
ANIMATE_GetAviInfo
(
infoPtr
))
{
WARN
(
"Can't get AVI information
\n
"
);
ANIMATE_Free
(
infoPtr
);
return
FALSE
;
}
if
(
!
ANIMATE_GetAviCodec
(
infoPtr
))
{
WARN
(
"Can't get AVI Codec
\n
"
);
ANIMATE_Free
(
infoPtr
);
return
FALSE
;
}
else
{
FIXME
(
"(repeat=%d from=%d to=%d) empty stub!
\n
"
,
nRepeat
,
nFrom
,
nTo
);
if
(
GetWindowLongA
(
hWnd
,
GWL_STYLE
)
&
ACS_CENTER
)
{
FIXME
(
"ACS_CENTER: NIY
\n
"
);
}
else
{
/* MoveWindow(hWnd, 0, 0, infoPtr->mah.dwWidth, infoPtr->mah.dwHeight, FALSE);*/
SetWindowPos
(
hWnd
,
0
,
0
,
0
,
infoPtr
->
mah
.
dwWidth
,
infoPtr
->
mah
.
dwHeight
,
SWP_NOACTIVATE
|
SWP_NOMOVE
|
SWP_NOZORDER
);
}
if
(
GetWindowLongA
(
hWnd
,
GWL_STYLE
)
&
ACS_TRANSPARENT
)
{
FIXME
(
"ACS_TRANSPARENT: NIY
\n
"
);
}
if
(
GetWindowLongA
(
hWnd
,
GWL_STYLE
)
&
ACS_AUTOPLAY
)
{
return
ANIMATE_Play
(
hWnd
,
-
1
,
(
LPARAM
)
MAKELONG
(
0
,
infoPtr
->
mah
.
dwTotalFrames
-
1
));
}
return
TRUE
;
}
static
LRESULT
ANIMATE_Stop
(
HWND
hwnd
,
WPARAM
wParam
,
LPARAM
lParam
)
/* << ANIMATE_Open32W >> */
static
LRESULT
ANIMATE_Stop
(
HWND
hWnd
,
WPARAM
wParam
,
LPARAM
lParam
)
{
/* ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hwnd); */
ANIMATE_INFO
*
infoPtr
=
ANIMATE_GetInfoPtr
(
hWnd
);
#if 0
/* nothing opened */
if (
...
)
if
(
!
infoPtr
->
hMMio
)
return
FALSE
;
#endif
ANIMATE_DoStop
(
infoPtr
);
return
TRUE
;
}
static
LRESULT
ANIMATE_Create
(
HWND
hwnd
,
WPARAM
wParam
,
LPARAM
lParam
)
static
LRESULT
ANIMATE_Create
(
HWND
hWnd
,
WPARAM
wParam
,
LPARAM
lParam
)
{
ANIMATE_INFO
*
infoPtr
;
ANIMATE_INFO
*
infoPtr
;
HMODULE
hModule
=
LoadLibraryA
(
"msvfw32.dll"
);
if
(
!
hModule
)
return
FALSE
;
/* allocate memory for info structure */
infoPtr
=
(
ANIMATE_INFO
*
)
COMCTL32_Alloc
(
sizeof
(
ANIMATE_INFO
));
infoPtr
=
(
ANIMATE_INFO
*
)
COMCTL32_Alloc
(
sizeof
(
ANIMATE_INFO
));
if
(
!
infoPtr
)
{
ERR
(
"could not allocate info memory!
\n
"
);
return
0
;
}
/* store pointer to info structure */
SetWindowLongA
(
hwnd
,
0
,
(
DWORD
)
infoPtr
);
/* Temporary hack until we get dllglue up and running */
infoPtr
->
fnICOpen
=
(
void
*
)
GetProcAddress
(
hModule
,
"ICOpen"
);
infoPtr
->
fnICClose
=
(
void
*
)
GetProcAddress
(
hModule
,
"ICClose"
);
infoPtr
->
fnICSendMessage
=
(
void
*
)
GetProcAddress
(
hModule
,
"ICSendMessage"
);
infoPtr
->
fnICDecompress
=
(
void
*
)
GetProcAddress
(
hModule
,
"ICDecompress"
);
TRACE
(
"Animate style=0x%08lx, parent=%08lx
\n
"
,
GetWindowLongA
(
hWnd
,
GWL_STYLE
),
(
DWORD
)
GetParent
(
hWnd
));
/* set default settings */
/* store crossref hWnd <-> info structure */
SetWindowLongA
(
hWnd
,
0
,
(
DWORD
)
infoPtr
);
infoPtr
->
hWnd
=
hWnd
;
InitializeCriticalSection
(
&
infoPtr
->
cs
);
return
0
;
}
static
LRESULT
ANIMATE_Destroy
(
HWND
hwnd
,
WPARAM
wParam
,
LPARAM
lParam
)
static
LRESULT
ANIMATE_Destroy
(
HWND
hWnd
,
WPARAM
wParam
,
LPARAM
lParam
)
{
ANIMATE_INFO
*
infoPtr
=
ANIMATE_GetInfoPtr
(
h
w
nd
);
ANIMATE_INFO
*
infoPtr
=
ANIMATE_GetInfoPtr
(
h
W
nd
);
/* free avi data */
ANIMATE_Free
(
infoPtr
);
ANIMATE_Free
(
infoPtr
);
/* free animate info data */
COMCTL32_Free
(
infoPtr
);
COMCTL32_Free
(
infoPtr
);
return
0
;
}
#if 0
static LRESULT
ANIMATE_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
static
LRESULT
ANIMATE_EraseBackground
(
HWND
hWnd
,
WPARAM
wParam
,
LPARAM
lParam
)
{
ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hwnd);
/*
HBRUSH32 hBrush = CreateSolidBrush32 (infoPtr->clrBk);
RECT32 rect;
RECT
rect
;
GetClientRect32 (wndPtr->hwndSelf, &rect);
FillRect32 ((HDC32)wParam, &rect, hBrush);
DeleteObject32 (hBrush);
*/
GetClientRect
(
hWnd
,
&
rect
);
#if 0
HBRUSH hBrush = CreateSolidBrush(infoPtr->clrBk);
FillRect((HDC)wParam, &rect, hBrush);
DeleteObject(hBrush);
#else
FillRect
((
HDC
)
wParam
,
&
rect
,
GetSysColorBrush
(
COLOR_WINDOW
));
#endif
return
TRUE
;
}
#endif
static
LRESULT
WINAPI
ANIMATE_Size
(
HWND
hWnd
,
WPARAM
wParam
,
LPARAM
lParam
)
{
ANIMATE_INFO
*
infoPtr
=
ANIMATE_GetInfoPtr
(
hWnd
);
if
(
GetWindowLongA
(
hWnd
,
GWL_STYLE
)
&
ACS_CENTER
)
{
FIXME
(
"NIY
\n
"
);
if
(
infoPtr
->
hMMio
)
{
/* centers the animation in the control, invalidates the control
*/
}
InvalidateRect
(
hWnd
,
NULL
,
TRUE
);
}
return
TRUE
;
}
static
LRESULT
WINAPI
ANIMATE_WindowProc
(
HWND
hwnd
,
UINT
uMsg
,
WPARAM
wParam
,
LPARAM
lParam
)
static
LRESULT
WINAPI
ANIMATE_WindowProc
(
HWND
hWnd
,
UINT
uMsg
,
WPARAM
wParam
,
LPARAM
lParam
)
{
switch
(
uMsg
)
{
case
ACM_OPENA
:
return
ANIMATE_OpenA
(
hw
nd
,
wParam
,
lParam
);
return
ANIMATE_OpenA
(
hW
nd
,
wParam
,
lParam
);
/* case ACM_OPEN32W:
*/
/* return ANIMATE_Open32W (hw
nd, wParam, lParam); */
/* case ACM_OPEN32W: FIXME!!
*/
/* return ANIMATE_Open32W(hW
nd, wParam, lParam); */
case
ACM_PLAY
:
return
ANIMATE_Play
(
hw
nd
,
wParam
,
lParam
);
return
ANIMATE_Play
(
hW
nd
,
wParam
,
lParam
);
case
ACM_STOP
:
return
ANIMATE_Stop
(
hw
nd
,
wParam
,
lParam
);
return
ANIMATE_Stop
(
hW
nd
,
wParam
,
lParam
);
case
WM_NCCREATE
:
ANIMATE_Create
(
hWnd
,
wParam
,
lParam
);
return
DefWindowProcA
(
hWnd
,
uMsg
,
wParam
,
lParam
);
case
WM_CREATE
:
return
ANIMATE_Create
(
hwnd
,
wParam
,
lParam
)
;
case
WM_NCHITTEST
:
return
HTTRANSPARENT
;
case
WM_DESTROY
:
return
ANIMATE_Destroy
(
hwnd
,
wParam
,
lParam
);
ANIMATE_Destroy
(
hWnd
,
wParam
,
lParam
);
return
DefWindowProcA
(
hWnd
,
uMsg
,
wParam
,
lParam
);
case
WM_ERASEBKGND
:
ANIMATE_EraseBackground
(
hWnd
,
wParam
,
lParam
);
break
;
/* case WM_ERASEBKGND: */
/* return ANIMATE_EraseBackground (hwnd, wParam, lParam); */
/* case WM_STYLECHANGED: FIXME shall we do something ?? */
/* case WM_NCCREATE: */
/* case WM_NCHITTEST: */
/* case WM_PAINT: */
/* case WM_SIZE: */
/* case WM_STYLECHANGED: */
/* case WM_TIMER: */
case
WM_TIMER
:
return
ANIMATE_DrawFrame
(
ANIMATE_GetInfoPtr
(
hWnd
));
case
WM_CLOSE
:
ANIMATE_Free
(
ANIMATE_GetInfoPtr
(
hWnd
));
return
TRUE
;
case
WM_PAINT
:
if
(
wParam
)
{
ANIMATE_PaintFrame
(
ANIMATE_GetInfoPtr
(
hWnd
),
(
HDC
)
wParam
);
}
else
{
PAINTSTRUCT
ps
;
HDC
hDC
=
BeginPaint
(
hWnd
,
&
ps
);
ANIMATE_PaintFrame
(
ANIMATE_GetInfoPtr
(
hWnd
),
hDC
);
EndPaint
(
hWnd
,
&
ps
);
}
break
;
case
WM_SIZE
:
ANIMATE_Size
(
hWnd
,
wParam
,
lParam
);
return
DefWindowProcA
(
hWnd
,
uMsg
,
wParam
,
lParam
);
default
:
if
(
uMsg
>=
WM_USER
)
ERR
(
"unknown msg %04x wp=%08x lp=%08lx
\n
"
,
uMsg
,
wParam
,
lParam
);
return
DefWindowProcA
(
hw
nd
,
uMsg
,
wParam
,
lParam
);
ERR
(
"unknown msg %04x wp=%08x lp=%08lx
\n
"
,
uMsg
,
wParam
,
lParam
);
return
DefWindowProcA
(
hW
nd
,
uMsg
,
wParam
,
lParam
);
}
return
0
;
}
VOID
ANIMATE_Register
(
void
)
void
ANIMATE_Register
(
void
)
{
WNDCLASSA
wndClass
;
if
(
GlobalFindAtomA
(
ANIMATE_CLASSA
))
return
;
if
(
GlobalFindAtomA
(
ANIMATE_CLASSA
))
return
;
ZeroMemory
(
&
wndClass
,
sizeof
(
WNDCLASSA
));
ZeroMemory
(
&
wndClass
,
sizeof
(
WNDCLASSA
));
wndClass
.
style
=
CS_GLOBALCLASS
|
CS_DBLCLKS
;
wndClass
.
lpfnWndProc
=
(
WNDPROC
)
ANIMATE_WindowProc
;
wndClass
.
cbClsExtra
=
0
;
wndClass
.
cbWndExtra
=
sizeof
(
ANIMATE_INFO
*
);
wndClass
.
hCursor
=
LoadCursorA
(
0
,
IDC_ARROWA
);
wndClass
.
hCursor
=
LoadCursorA
(
0
,
IDC_ARROWA
);
wndClass
.
hbrBackground
=
(
HBRUSH
)(
COLOR_BTNFACE
+
1
);
wndClass
.
lpszClassName
=
ANIMATE_CLASSA
;
RegisterClassA
(
&
wndClass
);
RegisterClassA
(
&
wndClass
);
}
VOID
ANIMATE_Unregister
(
void
)
void
ANIMATE_Unregister
(
void
)
{
if
(
GlobalFindAtomA
(
ANIMATE_CLASSA
))
UnregisterClassA
(
ANIMATE_CLASSA
,
(
HINSTANCE
)
NULL
);
if
(
GlobalFindAtomA
(
ANIMATE_CLASSA
))
UnregisterClassA
(
ANIMATE_CLASSA
,
(
HINSTANCE
)
NULL
);
}
include/animate.h
View file @
3e18c250
...
...
@@ -8,11 +8,44 @@
#define __WINE_ANIMATE_H
#include "windef.h"
#include "vfw.h"
typedef
struct
tagANIMATE_INFO
{
LPVOID
lpAvi
;
/* pointer to avi data */
HFILE
hFile
;
/* handle to avi file */
/* pointer to msvideo functions. it's easier to put them here.
* to be correct, they should be defined on a per process basis, but
* this would required a per process storage. We're using a per object
* storage instead, which is not efficient on memory usage, but
* will lead to less bugs in the future
*/
HIC
(
WINAPI
*
fnICOpen
)(
DWORD
,
DWORD
,
UINT
);
LRESULT
(
WINAPI
*
fnICClose
)(
HIC
);
LRESULT
(
WINAPI
*
fnICSendMessage
)(
HIC
,
UINT
,
DWORD
,
DWORD
);
DWORD
(
WINAPIV
*
fnICDecompress
)(
HIC
,
DWORD
,
LPBITMAPINFOHEADER
,
LPVOID
,
LPBITMAPINFOHEADER
,
LPVOID
);
/* reference to input stream (file or resource) */
HGLOBAL
hRes
;
HMMIO
hMMio
;
/* handle to mmio stream */
HWND
hWnd
;
/* information on the loaded AVI file */
MainAVIHeader
mah
;
AVIStreamHeader
ash
;
LPBITMAPINFOHEADER
inbih
;
LPDWORD
lpIndex
;
/* data for the decompressor */
HIC
hic
;
LPBITMAPINFOHEADER
outbih
;
LPVOID
indata
;
LPVOID
outdata
;
/* data for the background mechanism */
CRITICAL_SECTION
cs
;
HANDLE
hService
;
UINT
uTimer
;
/* data for playing the file */
int
nFromFrame
;
int
nToFrame
;
int
nLoop
;
int
currFrame
;
}
ANIMATE_INFO
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment